summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorVittorio Giovara <vittorio.giovara@gmail.com>2014-03-13 01:19:12 +0100
committerVittorio Giovara <vittorio.giovara@gmail.com>2014-04-01 01:19:03 +0200
commit6c1df1f2287401b6022773e382ebc3a3bfed0b38 (patch)
treea2e010bac0fa189e9900730a4cbd6cd4b3119a76 /libavcodec
parentf8dea10d3f09376894613d0266c34d1a16ac735f (diff)
downloadffmpeg-6c1df1f2287401b6022773e382ebc3a3bfed0b38.tar.gz
sgi: encode images with 4 channels at 8 and 16 bits
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/sgienc.c54
1 files changed, 47 insertions, 7 deletions
diff --git a/libavcodec/sgienc.c b/libavcodec/sgienc.c
index 003f6be484..bfc0995a5a 100644
--- a/libavcodec/sgienc.c
+++ b/libavcodec/sgienc.c
@@ -50,6 +50,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
uint8_t *offsettab, *lengthtab, *in_buf, *encode_buf, *buf;
int x, y, z, length, tablesize, ret;
unsigned int width, height, depth, dimension;
+ unsigned int bytes_per_channel, pixmax, put_be;
unsigned char *end_buf;
avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
@@ -57,6 +58,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
width = avctx->width;
height = avctx->height;
+ bytes_per_channel = 1;
+ pixmax = 0xFF;
+ put_be = HAVE_BIGENDIAN;
switch (avctx->pix_fmt) {
case AV_PIX_FMT_GRAY8:
@@ -71,6 +75,33 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
dimension = SGI_MULTI_CHAN;
depth = SGI_RGBA;
break;
+ case AV_PIX_FMT_GRAY16LE:
+ put_be = !HAVE_BIGENDIAN;
+ case AV_PIX_FMT_GRAY16BE:
+ avctx->coder_type = FF_CODER_TYPE_RAW;
+ bytes_per_channel = 2;
+ pixmax = 0xFFFF;
+ dimension = SGI_SINGLE_CHAN;
+ depth = SGI_GRAYSCALE;
+ break;
+ case AV_PIX_FMT_RGB48LE:
+ put_be = !HAVE_BIGENDIAN;
+ case AV_PIX_FMT_RGB48BE:
+ avctx->coder_type = FF_CODER_TYPE_RAW;
+ bytes_per_channel = 2;
+ pixmax = 0xFFFF;
+ dimension = SGI_MULTI_CHAN;
+ depth = SGI_RGB;
+ break;
+ case AV_PIX_FMT_RGBA64LE:
+ put_be = !HAVE_BIGENDIAN;
+ case AV_PIX_FMT_RGBA64BE:
+ avctx->coder_type = FF_CODER_TYPE_RAW;
+ bytes_per_channel = 2;
+ pixmax = 0xFFFF;
+ dimension = SGI_MULTI_CHAN;
+ depth = SGI_RGBA;
+ break;
default:
return AVERROR_INVALIDDATA;
}
@@ -82,7 +113,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
else // assume ff_rl_encode() produces at most 2x size of input
length += tablesize * 2 + depth * height * (2 * width + 1);
- if ((ret = ff_alloc_packet(pkt, length)) < 0) {
+ if ((ret = ff_alloc_packet(pkt, bytes_per_channel * length)) < 0) {
av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n", length);
return ret;
}
@@ -92,15 +123,14 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
/* Encode header. */
bytestream_put_be16(&buf, SGI_MAGIC);
bytestream_put_byte(&buf, avctx->coder_type != FF_CODER_TYPE_RAW); /* RLE 1 - VERBATIM 0*/
- bytestream_put_byte(&buf, 1); /* bytes_per_channel */
+ bytestream_put_byte(&buf, bytes_per_channel);
bytestream_put_be16(&buf, dimension);
bytestream_put_be16(&buf, width);
bytestream_put_be16(&buf, height);
bytestream_put_be16(&buf, depth);
- /* The rest are constant in this implementation. */
bytestream_put_be32(&buf, 0L); /* pixmin */
- bytestream_put_be32(&buf, 255L); /* pixmax */
+ bytestream_put_be32(&buf, pixmax);
bytestream_put_be32(&buf, 0L); /* dummy */
/* name */
@@ -150,11 +180,17 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
av_free(encode_buf);
} else {
for (z = 0; z < depth; z++) {
- in_buf = p->data[0] + p->linesize[0] * (height - 1) + z;
+ in_buf = p->data[0] + p->linesize[0] * (height - 1) + z * bytes_per_channel;
for (y = 0; y < height; y++) {
for (x = 0; x < width * depth; x += depth)
- bytestream_put_byte(&buf, in_buf[x]);
+ if (bytes_per_channel == 1)
+ bytestream_put_byte(&buf, in_buf[x]);
+ else
+ if (put_be)
+ bytestream_put_be16(&buf, ((uint16_t *)in_buf)[x]);
+ else
+ bytestream_put_le16(&buf, ((uint16_t *)in_buf)[x]);
in_buf -= p->linesize[0];
}
@@ -184,6 +220,10 @@ AVCodec ff_sgi_encoder = {
.encode2 = encode_frame,
.close = encode_close,
.pix_fmts = (const enum AVPixelFormat[]) {
- AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
+ AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA,
+ AV_PIX_FMT_RGB48LE, AV_PIX_FMT_RGB48BE,
+ AV_PIX_FMT_RGBA64LE, AV_PIX_FMT_RGBA64BE,
+ AV_PIX_FMT_GRAY16LE, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_GRAY8,
+ AV_PIX_FMT_NONE
},
};