unsigned int width;
unsigned int height;
unsigned int depth;
+ unsigned int bytes_per_channel;
int linesize;
} SgiState;
* @param pixelstride pixel stride of input buffer
* @return size of output in bytes, -1 if buffer overflows
*/
-static int expand_rle_row(uint8_t *in_buf, uint8_t* in_end,
+static int expand_rle_row(const uint8_t *in_buf, const uint8_t* in_end,
unsigned char *out_buf, uint8_t* out_end, int pixelstride)
{
unsigned char pixel, count;
* @param s the current image state
* @return 0 if no error, else return error number.
*/
-static int read_rle_sgi(unsigned char* out_buf, uint8_t *in_buf,
- uint8_t *in_end, SgiState* s)
+static int read_rle_sgi(unsigned char* out_buf, const uint8_t *in_buf,
+ const uint8_t *in_end, SgiState* s)
{
uint8_t *dest_row;
unsigned int len = s->height * s->depth * 4;
- uint8_t *start_table = in_buf;
+ const uint8_t *start_table = in_buf;
unsigned int y, z;
unsigned int start_offset;
* @return 0 if read success, otherwise return -1.
*/
static int read_uncompressed_sgi(unsigned char* out_buf, uint8_t* out_end,
- uint8_t *in_buf, uint8_t *in_end, SgiState* s)
+ const uint8_t *in_buf, const uint8_t *in_end, SgiState* s)
{
int x, y, z;
- uint8_t *ptr;
- unsigned int offset = s->height * s->width;
+ const uint8_t *ptr;
+ unsigned int offset = s->height * s->width * s->bytes_per_channel;
/* Test buffer size. */
if (offset * s->depth > in_end - in_buf) {
for (y = s->height - 1; y >= 0; y--) {
out_end = out_buf + (y * s->linesize);
for (x = s->width; x > 0; x--) {
- ptr = in_buf++;
+ ptr = in_buf += s->bytes_per_channel;
for(z = 0; z < s->depth; z ++) {
- bytestream_put_byte(&out_end, *ptr);
+ memcpy(out_end, ptr, s->bytes_per_channel);
+ out_end += s->bytes_per_channel;
ptr += offset;
}
}
static int decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
- uint8_t *in_buf, int buf_size)
+ AVPacket *avpkt)
{
+ const uint8_t *in_buf = avpkt->data;
+ int buf_size = avpkt->size;
SgiState *s = avctx->priv_data;
AVFrame *picture = data;
AVFrame *p = &s->picture;
- uint8_t *in_end = in_buf + buf_size;
- unsigned int dimension, bytes_per_channel, rle;
+ const uint8_t *in_end = in_buf + buf_size;
+ unsigned int dimension, rle;
int ret = 0;
uint8_t *out_buf, *out_end;
}
rle = bytestream_get_byte(&in_buf);
- bytes_per_channel = bytestream_get_byte(&in_buf);
+ s->bytes_per_channel = bytestream_get_byte(&in_buf);
dimension = bytestream_get_be16(&in_buf);
s->width = bytestream_get_be16(&in_buf);
s->height = bytestream_get_be16(&in_buf);
s->depth = bytestream_get_be16(&in_buf);
- if (bytes_per_channel != 1) {
+ if (s->bytes_per_channel != 1 && (s->bytes_per_channel != 2 || rle)) {
av_log(avctx, AV_LOG_ERROR, "wrong channel number\n");
return -1;
}
}
if (s->depth == SGI_GRAYSCALE) {
- avctx->pix_fmt = PIX_FMT_GRAY8;
+ avctx->pix_fmt = s->bytes_per_channel == 2 ? PIX_FMT_GRAY16BE : PIX_FMT_GRAY8;
} else if (s->depth == SGI_RGB) {
- avctx->pix_fmt = PIX_FMT_RGB24;
- } else if (s->depth == SGI_RGBA) {
+ avctx->pix_fmt = s->bytes_per_channel == 2 ? PIX_FMT_RGB48BE : PIX_FMT_RGB24;
+ } else if (s->depth == SGI_RGBA && s->bytes_per_channel == 1) {
avctx->pix_fmt = PIX_FMT_RGBA;
} else {
av_log(avctx, AV_LOG_ERROR, "wrong picture format\n");
}
}
-static int sgi_init(AVCodecContext *avctx){
+static av_cold int sgi_init(AVCodecContext *avctx){
SgiState *s = avctx->priv_data;
avcodec_get_frame_defaults(&s->picture);
return 0;
}
-static int sgi_end(AVCodecContext *avctx)
+static av_cold int sgi_end(AVCodecContext *avctx)
{
SgiState * const s = avctx->priv_data;
AVCodec sgi_decoder = {
"sgi",
- CODEC_TYPE_VIDEO,
+ AVMEDIA_TYPE_VIDEO,
CODEC_ID_SGI,
sizeof(SgiState),
sgi_init,
NULL,
sgi_end,
decode_frame,
+ .long_name = NULL_IF_CONFIG_SMALL("SGI image"),
};