[FFmpeg-cvslog] avcodec/iff: add support for ANBR files

Paul B Mahol git at videolan.org
Thu May 19 17:07:49 CEST 2016


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Wed May 18 21:52:26 2016 +0200| [a5c5ae5ed855f65f33abf27ce2f5839e07c7c8e9] | committer: Paul B Mahol

avcodec/iff: add support for ANBR files

Signed-off-by: Paul B Mahol <onemda at gmail.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a5c5ae5ed855f65f33abf27ce2f5839e07c7c8e9
---

 libavcodec/iff.c |   24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/libavcodec/iff.c b/libavcodec/iff.c
index dc3cb4b..f92f238 100644
--- a/libavcodec/iff.c
+++ b/libavcodec/iff.c
@@ -53,6 +53,7 @@ typedef struct IffContext {
     unsigned  compression;  ///< delta compression method used
     unsigned  is_short;     ///< short compression method used
     unsigned  is_interlaced;///< video is interlaced
+    unsigned  is_brush;     ///< video is in ANBR format
     unsigned  bpp;          ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
     unsigned  ham;          ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
     unsigned  flags;        ///< 1 for EHB, 0 is no extra half darkening
@@ -230,6 +231,7 @@ static int extract_header(AVCodecContext *const avctx,
                 bytestream2_skip(gb, 19);
                 extra = bytestream2_get_be32(gb);
                 s->is_short = !(extra & 1);
+                s->is_brush = extra == 2;
                 s->is_interlaced = !!(extra & 0x40);
                 data_size -= 24;
                 bytestream2_skip(gb, data_size + (data_size & 1));
@@ -763,7 +765,7 @@ static void decode_short_horizontal_delta(uint8_t *dst,
 
 static void decode_byte_vertical_delta(uint8_t *dst,
                                        const uint8_t *buf, const uint8_t *buf_end,
-                                       int w, int bpp, int dst_size)
+                                       int w, int xor, int bpp, int dst_size)
 {
     int ncolumns = ((w + 15) / 16) * 2;
     int dstpitch = ncolumns * bpp;
@@ -798,7 +800,11 @@ static void decode_byte_vertical_delta(uint8_t *dst,
 
                     while (opcode) {
                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
-                        bytestream2_put_byte(&pb, x);
+                        if (xor && ofsdst < dst_size) {
+                            bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
+                        } else {
+                            bytestream2_put_byte(&pb, x);
+                        }
                         ofsdst += dstpitch;
                         opcode--;
                     }
@@ -809,7 +815,11 @@ static void decode_byte_vertical_delta(uint8_t *dst,
 
                     while (opcode) {
                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
-                        bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
+                        if (xor && ofsdst < dst_size) {
+                            bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
+                        } else {
+                            bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
+                        }
                         ofsdst += dstpitch;
                         opcode--;
                     }
@@ -1627,7 +1637,7 @@ static int decode_frame(AVCodecContext *avctx,
         break;
     case 0x500:
     case 0x501:
-        decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
+        decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
         break;
     case 0x700:
     case 0x701:
@@ -1719,8 +1729,10 @@ static int decode_frame(AVCodecContext *avctx,
             return unsupported(avctx);
         }
 
-        FFSWAP(uint8_t *, s->video[0], s->video[1]);
-        FFSWAP(uint32_t *, s->pal[0], s->pal[1]);
+        if (!s->is_brush) {
+            FFSWAP(uint8_t *, s->video[0], s->video[1]);
+            FFSWAP(uint32_t *, s->pal[0], s->pal[1]);
+        }
     }
 
     if (avpkt->flags & AV_PKT_FLAG_KEY) {



More information about the ffmpeg-cvslog mailing list