summaryrefslogtreecommitdiff
path: root/libavcodec/sgidec.c
diff options
context:
space:
mode:
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>2009-09-19 11:42:41 +0000
committerReimar Döffinger <Reimar.Doeffinger@gmx.de>2009-09-19 11:42:41 +0000
commitfbc030045c0877c30772e879f088e58b06ec8e7e (patch)
treec6c77f3ca722b735026e82125220ae1cf29b78c7 /libavcodec/sgidec.c
parentbdb156c7b1d9e6899b915c355c547009c54e6e36 (diff)
Support uncompressed 16 bit sgi image format, as e.g. used by the files at
http://media.xiph.org/svt/2160p50_CgrLevels_Master_SVTdec05_/1_CrowdRun_2160p50_CgrLevels_MASTER_SVTdec05_/ Originally committed as revision 19926 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/sgidec.c')
-rw-r--r--libavcodec/sgidec.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/libavcodec/sgidec.c b/libavcodec/sgidec.c
index dadbc19d22..2670140b28 100644
--- a/libavcodec/sgidec.c
+++ b/libavcodec/sgidec.c
@@ -28,6 +28,7 @@ typedef struct SgiState {
unsigned int width;
unsigned int height;
unsigned int depth;
+ unsigned int bytes_per_channel;
int linesize;
} SgiState;
@@ -125,7 +126,7 @@ static int read_uncompressed_sgi(unsigned char* out_buf, uint8_t* out_end,
{
int x, y, z;
const uint8_t *ptr;
- unsigned int offset = s->height * s->width;
+ unsigned int offset = s->height * s->width * s->bytes_per_channel;
/* Test buffer size. */
if (offset * s->depth > in_end - in_buf) {
@@ -135,9 +136,10 @@ static int read_uncompressed_sgi(unsigned char* out_buf, uint8_t* out_end,
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;
}
}
@@ -155,7 +157,7 @@ static int decode_frame(AVCodecContext *avctx,
AVFrame *picture = data;
AVFrame *p = &s->picture;
const uint8_t *in_end = in_buf + buf_size;
- unsigned int dimension, bytes_per_channel, rle;
+ unsigned int dimension, rle;
int ret = 0;
uint8_t *out_buf, *out_end;
@@ -171,13 +173,13 @@ static int decode_frame(AVCodecContext *avctx,
}
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;
}
@@ -189,10 +191,10 @@ static int decode_frame(AVCodecContext *avctx,
}
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");