summaryrefslogtreecommitdiff
path: root/libavcodec/iff.c
diff options
context:
space:
mode:
authorPeter Ross <pross@xvid.org>2012-11-22 21:25:33 +1100
committerPeter Ross <pross@xvid.org>2012-11-26 23:29:02 +1100
commit929a24efff9a208a52748605eb412ffb915c1403 (patch)
treeaedee29aa8cab74e756f2e7616feb5c3314c0928 /libavcodec/iff.c
parentf2dc82b90ffe4191ea5f207e6b3ffc473e093f65 (diff)
downloadffmpeg-929a24efff9a208a52748605eb412ffb915c1403.tar.gz
iff decoder: merge iff ilbm and byterun1 decoders
Signed-off-by: Peter Ross <pross@xvid.org> Reviewed-by: Paul B Mahol <onemda@gmail.com>
Diffstat (limited to 'libavcodec/iff.c')
-rw-r--r--libavcodec/iff.c187
1 files changed, 82 insertions, 105 deletions
diff --git a/libavcodec/iff.c b/libavcodec/iff.c
index a52a1bc6a9..be02b85b2d 100644
--- a/libavcodec/iff.c
+++ b/libavcodec/iff.c
@@ -479,7 +479,63 @@ static int decode_byterun(uint8_t *dst, int dst_size,
return buf - buf_start;
}
-static int decode_frame_ilbm(AVCodecContext *avctx,
+/**
+ * Decode DEEP RLE 32-bit buffer
+ * @param[out] dst Destination buffer
+ * @param[in] src Source buffer
+ * @param src_size Source buffer size (bytes)
+ * @param width Width of destination buffer (pixels)
+ * @param height Height of destination buffer (pixels)
+ * @param linesize Line size of destination buffer (bytes)
+ */
+static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
+{
+ const uint8_t *src_end = src + src_size;
+ int x = 0, y = 0, i;
+ while (src + 5 <= src_end) {
+ int opcode;
+ opcode = *(int8_t *)src++;
+ if (opcode >= 0) {
+ int size = opcode + 1;
+ for (i = 0; i < size; i++) {
+ int length = FFMIN(size - i, width);
+ memcpy(dst + y*linesize + x * 4, src, length * 4);
+ src += length * 4;
+ x += length;
+ i += length;
+ if (x >= width) {
+ x = 0;
+ y += 1;
+ if (y >= height)
+ return;
+ }
+ }
+ } else {
+ int size = -opcode + 1;
+ uint32_t pixel = AV_RL32(src);
+ for (i = 0; i < size; i++) {
+ *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
+ x += 1;
+ if (x >= width) {
+ x = 0;
+ y += 1;
+ if (y >= height)
+ return;
+ }
+ }
+ src += 4;
+ }
+ }
+}
+
+static int unsupported(AVCodecContext *avctx)
+{
+ IffContext *s = avctx->priv_data;
+ av_log_ask_for_sample(avctx, "unsupported bitmap (compression %i, bpp %i, ham %i)\n", s->compression, s->bpp, s->ham);
+ return AVERROR_INVALIDDATA;
+}
+
+static int decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
AVPacket *avpkt)
{
@@ -491,7 +547,6 @@ static int decode_frame_ilbm(AVCodecContext *avctx,
if ((res = extract_header(avctx, avpkt)) < 0)
return res;
-
if (s->init) {
if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
@@ -503,9 +558,14 @@ static int decode_frame_ilbm(AVCodecContext *avctx,
} else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
return res;
+ } else if (avctx->pix_fmt == AV_PIX_FMT_RGB32 && avctx->bits_per_coded_sample <= 8) {
+ if ((res = ff_cmap_read_palette(avctx, s->mask_palbuf)) < 0)
+ return res;
}
s->init = 1;
+ switch (s->compression) {
+ case 0:
if (avctx->codec_tag == MKTAG('A','C','B','M')) {
if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
@@ -529,7 +589,8 @@ static int decode_frame_ilbm(AVCodecContext *avctx,
}
decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
}
- }
+ } else
+ return unsupported(avctx);
} else if (avctx->codec_tag == MKTAG('D','E','E','P')) {
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
@@ -587,95 +648,11 @@ static int decode_frame_ilbm(AVCodecContext *avctx,
buf += avctx->width + (avctx->width & 1); // padding if odd
decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
}
- } else {
- av_log_ask_for_sample(avctx, "unsupported bpp\n");
- return AVERROR_INVALIDDATA;
- }
- }
-
- *data_size = sizeof(AVFrame);
- *(AVFrame*)data = s->frame;
- return buf_size;
-}
-
-/**
- * Decode DEEP RLE 32-bit buffer
- * @param[out] dst Destination buffer
- * @param[in] src Source buffer
- * @param src_size Source buffer size (bytes)
- * @param width Width of destination buffer (pixels)
- * @param height Height of destination buffer (pixels)
- * @param linesize Line size of destination buffer (bytes)
- */
-static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
-{
- const uint8_t *src_end = src + src_size;
- int x = 0, y = 0, i;
- while (src + 5 <= src_end) {
- int opcode;
- opcode = *(int8_t *)src++;
- if (opcode >= 0) {
- int size = opcode + 1;
- for (i = 0; i < size; i++) {
- int length = FFMIN(size - i, width);
- memcpy(dst + y*linesize + x * 4, src, length * 4);
- src += length * 4;
- x += length;
- i += length;
- if (x >= width) {
- x = 0;
- y += 1;
- if (y >= height)
- return;
- }
- }
- } else {
- int size = -opcode + 1;
- uint32_t pixel = AV_RL32(src);
- for (i = 0; i < size; i++) {
- *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
- x += 1;
- if (x >= width) {
- x = 0;
- y += 1;
- if (y >= height)
- return;
- }
- }
- src += 4;
- }
+ } else
+ return unsupported(avctx);
}
-}
-
-static int decode_frame_byterun1(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
-{
- IffContext *s = avctx->priv_data;
- const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
- const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
- const uint8_t *buf_end = buf+buf_size;
- int y, plane, res;
-
- if ((res = extract_header(avctx, avpkt)) < 0)
- return res;
- if (s->init) {
- if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
- return res;
- }
- } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
- return res;
- } else if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
- if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
- return res;
- } else if (avctx->pix_fmt == AV_PIX_FMT_RGB32 && avctx->bits_per_coded_sample <= 8) {
- if ((res = ff_cmap_read_palette(avctx, s->mask_palbuf)) < 0)
- return res;
- }
- s->init = 1;
-
+ break;
+ case 1:
if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
for(y = 0; y < avctx->height ; y++ ) {
@@ -728,18 +705,18 @@ static int decode_frame_byterun1(AVCodecContext *avctx,
buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
}
- } else {
- av_log_ask_for_sample(avctx, "unsupported bpp\n");
- return AVERROR_INVALIDDATA;
- }
+ } else
+ return unsupported(avctx);
} else if (avctx->codec_tag == MKTAG('D','E','E','P')) { // IFF-DEEP
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
if (av_get_bits_per_pixel(desc) == 32)
decode_deep_rle32(s->frame.data[0], buf, buf_size, avctx->width, avctx->height, s->frame.linesize[0]);
- else {
- av_log_ask_for_sample(avctx, "unsupported bpp\n");
- return AVERROR_INVALIDDATA;
- }
+ else
+ return unsupported(avctx);
+ }
+ break;
+ default:
+ return unsupported(avctx);
}
*data_size = sizeof(AVFrame);
@@ -760,27 +737,27 @@ static av_cold int decode_end(AVCodecContext *avctx)
#if CONFIG_IFF_ILBM_DECODER
AVCodec ff_iff_ilbm_decoder = {
- .name = "iff_ilbm",
+ .name = "iff",
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_IFF_ILBM,
.priv_data_size = sizeof(IffContext),
.init = decode_init,
.close = decode_end,
- .decode = decode_frame_ilbm,
+ .decode = decode_frame,
.capabilities = CODEC_CAP_DR1,
- .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
+ .long_name = NULL_IF_CONFIG_SMALL("IFF"),
};
#endif
#if CONFIG_IFF_BYTERUN1_DECODER
AVCodec ff_iff_byterun1_decoder = {
- .name = "iff_byterun1",
+ .name = "iff",
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_IFF_BYTERUN1,
.priv_data_size = sizeof(IffContext),
.init = decode_init,
.close = decode_end,
- .decode = decode_frame_byterun1,
+ .decode = decode_frame,
.capabilities = CODEC_CAP_DR1,
- .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
+ .long_name = NULL_IF_CONFIG_SMALL("IFF"),
};
#endif