Browse code

lavc: add IFF ANIM decoder

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

Paul B Mahol authored on 2016/05/11 06:48:50
Showing 4 changed files
... ...
@@ -33,6 +33,7 @@ version <next>:
33 33
 - VAAPI-accelerated H.264/HEVC/MJPEG encoding
34 34
 - DTS Express (LBR) decoder
35 35
 - Generic OpenMAX IL encoder with support for Raspberry Pi
36
+- IFF ANIM demuxer & decoder
36 37
 
37 38
 version 3.0:
38 39
 - Common Encryption (CENC) MP4 encoding and decoding support
... ...
@@ -887,7 +887,7 @@ static const AVCodecDescriptor codec_descriptors[] = {
887 887
         .id        = AV_CODEC_ID_IFF_ILBM,
888 888
         .type      = AVMEDIA_TYPE_VIDEO,
889 889
         .name      = "iff_ilbm",
890
-        .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
890
+        .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM"),
891 891
         .props     = AV_CODEC_PROP_LOSSY,
892 892
     },
893 893
     {
... ...
@@ -1,7 +1,8 @@
1 1
 /*
2
- * IFF ACBM/DEEP/ILBM/PBM bitmap decoder
2
+ * IFF ACBM/ANIM/DEEP/ILBM/PBM bitmap decoder
3 3
  * Copyright (c) 2010 Peter Ross <pross@xvid.org>
4 4
  * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
5
+ * Copyright (c) 2016 Paul B Mahol
5 6
  *
6 7
  * This file is part of FFmpeg.
7 8
  *
... ...
@@ -22,7 +23,7 @@
22 22
 
23 23
 /**
24 24
  * @file
25
- * IFF ACBM/DEEP/ILBM/PBM bitmap decoder
25
+ * IFF ACBM/ANIM/DEEP/ILBM/PBM bitmap decoder
26 26
  */
27 27
 
28 28
 #include <stdint.h>
... ...
@@ -30,8 +31,8 @@
30 30
 #include "libavutil/imgutils.h"
31 31
 #include "bytestream.h"
32 32
 #include "avcodec.h"
33
-#include "get_bits.h"
34 33
 #include "internal.h"
34
+#include "mathops.h"
35 35
 
36 36
 // TODO: masking bits
37 37
 typedef enum {
... ...
@@ -50,6 +51,7 @@ typedef struct IffContext {
50 50
     uint32_t *mask_buf;     ///< temporary buffer for palette indices
51 51
     uint32_t *mask_palbuf;  ///< masking palette table
52 52
     unsigned  compression;  ///< delta compression method used
53
+    unsigned  is_short;     ///< short compression method used
53 54
     unsigned  bpp;          ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
54 55
     unsigned  ham;          ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
55 56
     unsigned  flags;        ///< 1 for EHB, 0 is no extra half darkening
... ...
@@ -57,6 +59,11 @@ typedef struct IffContext {
57 57
     unsigned  masking;      ///< TODO: masking method used
58 58
     int init; // 1 if buffer and palette data already initialized, 0 otherwise
59 59
     int16_t   tvdc[16];     ///< TVDC lookup table
60
+    GetByteContext gb;
61
+    uint8_t *video[2];
62
+    unsigned video_size;
63
+    uint32_t *pal[2];
64
+    int first;
60 65
 } IffContext;
61 66
 
62 67
 #define LUT8_PART(plane, v)                             \
... ...
@@ -189,10 +196,11 @@ static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
189 189
  * @return >= 0 in case of success, a negative error code otherwise
190 190
  */
191 191
 static int extract_header(AVCodecContext *const avctx,
192
-                          const AVPacket *const avpkt) {
193
-    const uint8_t *buf;
194
-    unsigned buf_size;
192
+                          const AVPacket *const avpkt)
193
+{
195 194
     IffContext *s = avctx->priv_data;
195
+    const uint8_t *buf;
196
+    unsigned buf_size = 0;
196 197
     int i, palette_size;
197 198
 
198 199
     if (avctx->extradata_size < 2) {
... ...
@@ -201,20 +209,51 @@ static int extract_header(AVCodecContext *const avctx,
201 201
     }
202 202
     palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
203 203
 
204
-    if (avpkt) {
205
-        int image_size;
206
-        if (avpkt->size < 2)
207
-            return AVERROR_INVALIDDATA;
208
-        image_size = avpkt->size - AV_RB16(avpkt->data);
209
-        buf = avpkt->data;
210
-        buf_size = bytestream_get_be16(&buf);
211
-        if (buf_size <= 1 || image_size <= 1) {
212
-            av_log(avctx, AV_LOG_ERROR,
213
-                   "Invalid image size received: %u -> image data offset: %d\n",
214
-                   buf_size, image_size);
215
-            return AVERROR_INVALIDDATA;
204
+    if (avpkt && avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
205
+        uint32_t chunk_id;
206
+        uint64_t data_size;
207
+        GetByteContext *gb = &s->gb;
208
+
209
+        bytestream2_skip(gb, 4);
210
+        while (bytestream2_get_bytes_left(gb) >= 1) {
211
+            chunk_id  = bytestream2_get_le32(gb);
212
+            data_size = bytestream2_get_be32(gb);
213
+
214
+            if (chunk_id == MKTAG('B', 'M', 'H', 'D')) {
215
+                bytestream2_skip(gb, data_size + (data_size & 1));
216
+            } else if (chunk_id == MKTAG('A', 'N', 'H', 'D')) {
217
+                if (data_size < 40)
218
+                    return AVERROR_INVALIDDATA;
219
+
220
+                s->compression = (bytestream2_get_byte(gb) << 8) | (s->compression & 0xFF);
221
+                bytestream2_skip(gb, 19);
222
+                s->is_short = !(bytestream2_get_be32(gb) & 1);
223
+                data_size -= 24;
224
+                bytestream2_skip(gb, data_size + (data_size & 1));
225
+            } else if (chunk_id == MKTAG('D', 'L', 'T', 'A') ||
226
+                       chunk_id == MKTAG('B', 'O', 'D', 'Y')) {
227
+                if (chunk_id == MKTAG('B','O','D','Y'))
228
+                    s->compression &= 0xFF;
229
+                break;
230
+            } else if (chunk_id == MKTAG('C', 'M', 'A', 'P')) {
231
+                int count = data_size / 3;
232
+                uint32_t *pal = s->pal[0];
233
+
234
+                if (count > 256)
235
+                    return AVERROR_INVALIDDATA;
236
+                if (s->ham) {
237
+                    for (i = 0; i < count; i++)
238
+                        pal[i] = 0xFF000000 | bytestream2_get_le24(gb);
239
+                } else {
240
+                    for (i = 0; i < count; i++)
241
+                        pal[i] = 0xFF000000 | bytestream2_get_be24(gb);
242
+                }
243
+                bytestream2_skip(gb, data_size & 1);
244
+            } else {
245
+                bytestream2_skip(gb, data_size + (data_size&1));
246
+            }
216 247
         }
217
-    } else {
248
+    } else if (!avpkt) {
218 249
         buf = avctx->extradata;
219 250
         buf_size = bytestream_get_be16(&buf);
220 251
         if (buf_size <= 1 || palette_size < 0) {
... ...
@@ -323,10 +362,13 @@ static int extract_header(AVCodecContext *const avctx,
323 323
 static av_cold int decode_end(AVCodecContext *avctx)
324 324
 {
325 325
     IffContext *s = avctx->priv_data;
326
-    av_frame_free(&s->frame);
327 326
     av_freep(&s->planebuf);
328 327
     av_freep(&s->ham_buf);
329 328
     av_freep(&s->ham_palbuf);
329
+    av_freep(&s->video[0]);
330
+    av_freep(&s->video[1]);
331
+    av_freep(&s->pal[0]);
332
+    av_freep(&s->pal[1]);
330 333
     return 0;
331 334
 }
332 335
 
... ...
@@ -371,10 +413,16 @@ static av_cold int decode_init(AVCodecContext *avctx)
371 371
         return AVERROR(ENOMEM);
372 372
 
373 373
     s->bpp = avctx->bits_per_coded_sample;
374
-    s->frame = av_frame_alloc();
375
-    if (!s->frame) {
376
-        decode_end(avctx);
377
-        return AVERROR(ENOMEM);
374
+
375
+    if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
376
+        s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
377
+        s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
378
+        s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
379
+        s->pal[0] = av_calloc(256, sizeof(*s->pal[0]));
380
+        s->pal[1] = av_calloc(256, sizeof(*s->pal[1]));
381
+        if (!s->video[0] || !s->video[1] || !s->pal[0] || !s->pal[1])
382
+            return AVERROR(ENOMEM);
383
+        s->first = 1;
378 384
     }
379 385
 
380 386
     if ((err = extract_header(avctx, NULL)) < 0)
... ...
@@ -480,20 +528,18 @@ static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
480 480
  * @return number of consumed bytes in byterun1 compressed bitstream
481 481
  */
482 482
 static int decode_byterun(uint8_t *dst, int dst_size,
483
-                          const uint8_t *buf, const uint8_t *const buf_end)
483
+                          GetByteContext *gb)
484 484
 {
485
-    const uint8_t *const buf_start = buf;
486 485
     unsigned x;
487
-    for (x = 0; x < dst_size && buf < buf_end;) {
486
+    for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
488 487
         unsigned length;
489
-        const int8_t value = *buf++;
488
+        const int8_t value = bytestream2_get_byte(gb);
490 489
         if (value >= 0) {
491
-            length = FFMIN3(value + 1, dst_size - x, buf_end - buf);
492
-            memcpy(dst + x, buf, length);
493
-            buf += length;
490
+            length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
491
+            bytestream2_get_buffer(gb, dst + x, length);
494 492
         } else if (value > -128) {
495 493
             length = FFMIN(-value + 1, dst_size - x);
496
-            memset(dst + x, *buf++, length);
494
+            memset(dst + x, bytestream2_get_byte(gb), length);
497 495
         } else { // noop
498 496
             continue;
499 497
         }
... ...
@@ -503,7 +549,7 @@ static int decode_byterun(uint8_t *dst, int dst_size,
503 503
         av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
504 504
         memset(dst+x, 0, dst_size - x);
505 505
     }
506
-    return buf - buf_start;
506
+    return bytestream2_tell(gb);
507 507
 }
508 508
 
509 509
 #define DECODE_RGBX_COMMON(type) \
... ...
@@ -660,10 +706,525 @@ static void decode_deep_tvdc32(uint8_t *dst, const uint8_t *src, int src_size, i
660 660
     }
661 661
 }
662 662
 
663
+static void decode_byte_vertical_delta(uint8_t *dst,
664
+                                       const uint8_t *buf, const uint8_t *buf_end,
665
+                                       int w, int bpp, int dst_size)
666
+{
667
+    int ncolumns = ((w + 15) / 16) * 2;
668
+    int dstpitch = ncolumns * bpp;
669
+    unsigned ofsdst, ofssrc, opcode, x;
670
+    GetByteContext ptrs, gb;
671
+    PutByteContext pb;
672
+    int i, j, k;
673
+
674
+    bytestream2_init(&ptrs, buf, buf_end - buf);
675
+    bytestream2_init_writer(&pb, dst, dst_size);
676
+
677
+    for (k = 0; k < bpp; k++) {
678
+        ofssrc = bytestream2_get_be32(&ptrs);
679
+
680
+        if (!ofssrc)
681
+            continue;
682
+
683
+        if (ofssrc >= buf_end - buf)
684
+            continue;
685
+
686
+        bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
687
+        for (j = 0; j < ncolumns; j++) {
688
+            ofsdst = j + k * ncolumns;
689
+
690
+            i = bytestream2_get_byte(&gb);
691
+            while (i > 0) {
692
+                opcode = bytestream2_get_byte(&gb);
693
+
694
+                if (opcode == 0) {
695
+                    opcode  = bytestream2_get_byte(&gb);
696
+                    x = bytestream2_get_byte(&gb);
697
+
698
+                    while (opcode) {
699
+                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
700
+                        bytestream2_put_byte(&pb, x);
701
+                        ofsdst += dstpitch;
702
+                        opcode--;
703
+                    }
704
+                } else if (opcode < 0x80) {
705
+                    ofsdst += opcode * dstpitch;
706
+                } else {
707
+                    opcode &= 0x7f;
708
+
709
+                    while (opcode) {
710
+                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
711
+                        bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
712
+                        ofsdst += dstpitch;
713
+                        opcode--;
714
+                    }
715
+                }
716
+                i--;
717
+            }
718
+        }
719
+    }
720
+}
721
+
722
+static void decode_delta_j(uint8_t *dst,
723
+                           const uint8_t *buf, const uint8_t *buf_end,
724
+                           int w, int h, int bpp, int dst_size)
725
+{
726
+    int32_t pitch;
727
+    uint8_t *end = dst + dst_size, *ptr;
728
+    uint32_t type, flag, cols, groups, rows, bytes;
729
+    uint32_t offset;
730
+    int planepitch_byte = (w + 7) / 8;
731
+    int planepitch = ((w + 15) / 16) * 2;
732
+    int kludge_j, b, g, r, d;
733
+    GetByteContext gb;
734
+
735
+    pitch = planepitch * bpp;
736
+    kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
737
+
738
+    bytestream2_init(&gb, buf, buf_end - buf);
739
+
740
+    while (bytestream2_get_bytes_left(&gb) >= 2) {
741
+        type = bytestream2_get_be16(&gb);
742
+
743
+        switch (type) {
744
+        case 0:
745
+            return;
746
+        case 1:
747
+            flag   = bytestream2_get_be16(&gb);
748
+            cols   = bytestream2_get_be16(&gb);
749
+            groups = bytestream2_get_be16(&gb);
750
+
751
+            for (g = 0; g < groups; g++) {
752
+                offset = bytestream2_get_be16(&gb);
753
+
754
+                if (kludge_j)
755
+                    offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
756
+                else
757
+                    offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
758
+
759
+                ptr = dst + offset;
760
+                if (ptr >= end)
761
+                    return;
762
+
763
+                for (b = 0; b < cols; b++) {
764
+                    for (d = 0; d < bpp; d++) {
765
+                        uint8_t value = bytestream2_get_byte(&gb);
766
+
767
+                        if (flag)
768
+                            ptr[0] ^= value;
769
+                        else
770
+                            ptr[0]  = value;
771
+
772
+                        ptr += planepitch;
773
+                        if (ptr >= end)
774
+                            return;
775
+                    }
776
+                }
777
+                if ((cols * bpp) & 1)
778
+                    bytestream2_skip(&gb, 1);
779
+            }
780
+            break;
781
+        case 2:
782
+            flag   = bytestream2_get_be16(&gb);
783
+            rows   = bytestream2_get_be16(&gb);
784
+            bytes  = bytestream2_get_be16(&gb);
785
+            groups = bytestream2_get_be16(&gb);
786
+
787
+            for (g = 0; g < groups; g++) {
788
+                offset = bytestream2_get_be16(&gb);
789
+
790
+                if (kludge_j)
791
+                    offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
792
+                else
793
+                    offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
794
+
795
+                for (r = 0; r < rows; r++) {
796
+                    for (d = 0; d < bpp; d++) {
797
+                        ptr = dst + offset + (r * pitch) + d * planepitch;
798
+                        if (ptr >= end)
799
+                            return;
800
+
801
+                        for (b = 0; b < bytes; b++) {
802
+                            uint8_t value = bytestream2_get_byte(&gb);
803
+
804
+                            if (flag)
805
+                                ptr[0] ^= value;
806
+                            else
807
+                                ptr[0]  = value;
808
+
809
+                            ptr++;
810
+                            if (ptr >= end)
811
+                                return;
812
+                        }
813
+                    }
814
+                }
815
+                if ((rows * bytes * bpp) & 1)
816
+                    bytestream2_skip(&gb, 1);
817
+            }
818
+            break;
819
+        default:
820
+            return;
821
+        }
822
+    }
823
+}
824
+
825
+static void decode_short_vertical_delta(uint8_t *dst,
826
+                                        const uint8_t *buf, const uint8_t *buf_end,
827
+                                        int w, int bpp, int dst_size)
828
+{
829
+    int ncolumns = (w + 15) >> 4;
830
+    int dstpitch = ncolumns * bpp * 2;
831
+    unsigned ofsdst, ofssrc, ofsdata, opcode, x;
832
+    GetByteContext ptrs, gb, dptrs, dgb;
833
+    PutByteContext pb;
834
+    int i, j, k;
835
+
836
+    if (buf_end - buf <= 64)
837
+        return;
838
+
839
+    bytestream2_init(&ptrs, buf, buf_end - buf);
840
+    bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
841
+    bytestream2_init_writer(&pb, dst, dst_size);
842
+
843
+    for (k = 0; k < bpp; k++) {
844
+        ofssrc = bytestream2_get_be32(&ptrs);
845
+        ofsdata = bytestream2_get_be32(&dptrs);
846
+
847
+        if (!ofssrc)
848
+            continue;
849
+
850
+        if (ofssrc >= buf_end - buf)
851
+            return;
852
+
853
+        if (ofsdata >= buf_end - buf)
854
+            return;
855
+
856
+        bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
857
+        bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
858
+        for (j = 0; j < ncolumns; j++) {
859
+            ofsdst = (j + k * ncolumns) * 2;
860
+
861
+            i = bytestream2_get_byte(&gb);
862
+            while (i > 0) {
863
+                opcode = bytestream2_get_byte(&gb);
864
+
865
+                if (opcode == 0) {
866
+                    opcode = bytestream2_get_byte(&gb);
867
+                    x = bytestream2_get_be16(&dgb);
868
+
869
+                    while (opcode) {
870
+                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
871
+                        bytestream2_put_be16(&pb, x);
872
+                        ofsdst += dstpitch;
873
+                        opcode--;
874
+                    }
875
+                } else if (opcode < 0x80) {
876
+                    ofsdst += opcode * dstpitch;
877
+                } else {
878
+                    opcode &= 0x7f;
879
+
880
+                    while (opcode) {
881
+                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
882
+                        bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
883
+                        ofsdst += dstpitch;
884
+                        opcode--;
885
+                    }
886
+                }
887
+                i--;
888
+            }
889
+        }
890
+    }
891
+}
892
+
893
+static void decode_long_vertical_delta(uint8_t *dst,
894
+                                       const uint8_t *buf, const uint8_t *buf_end,
895
+                                       int w, int bpp, int dst_size)
896
+{
897
+    int ncolumns = (w + 31) >> 5;
898
+    int dstpitch = ((w + 15) / 16 * 2) * bpp;
899
+    unsigned ofsdst, ofssrc, ofsdata, opcode, x;
900
+    GetByteContext ptrs, gb, dptrs, dgb;
901
+    PutByteContext pb;
902
+    int i, j, k, h;
903
+
904
+    if (buf_end - buf <= 64)
905
+        return;
906
+
907
+    h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
908
+    bytestream2_init(&ptrs, buf, buf_end - buf);
909
+    bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
910
+    bytestream2_init_writer(&pb, dst, dst_size);
911
+
912
+    for (k = 0; k < bpp; k++) {
913
+        ofssrc = bytestream2_get_be32(&ptrs);
914
+        ofsdata = bytestream2_get_be32(&dptrs);
915
+
916
+        if (!ofssrc)
917
+            continue;
918
+
919
+        if (ofssrc >= buf_end - buf)
920
+            return;
921
+
922
+        if (ofsdata >= buf_end - buf)
923
+            return;
924
+
925
+        bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
926
+        bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
927
+        for (j = 0; j < ncolumns; j++) {
928
+            ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
929
+
930
+            i = bytestream2_get_byte(&gb);
931
+            while (i > 0) {
932
+                opcode = bytestream2_get_byte(&gb);
933
+
934
+                if (opcode == 0) {
935
+                    opcode = bytestream2_get_byte(&gb);
936
+                    if (h && (j == (ncolumns - 1))) {
937
+                        x = bytestream2_get_be16(&dgb);
938
+                        bytestream2_skip(&dgb, 2);
939
+                    } else {
940
+                        x = bytestream2_get_be32(&dgb);
941
+                    }
942
+
943
+                    while (opcode) {
944
+                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
945
+                        if (h && (j == (ncolumns - 1))) {
946
+                            bytestream2_put_be16(&pb, x);
947
+                        } else {
948
+                            bytestream2_put_be32(&pb, x);
949
+                        }
950
+                        ofsdst += dstpitch;
951
+                        opcode--;
952
+                    }
953
+                } else if (opcode < 0x80) {
954
+                    ofsdst += opcode * dstpitch;
955
+                } else {
956
+                    opcode &= 0x7f;
957
+
958
+                    while (opcode) {
959
+                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
960
+                        if (h && (j == (ncolumns - 1))) {
961
+                            bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
962
+                            bytestream2_skip(&dgb, 2);
963
+                        } else {
964
+                            bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
965
+                        }
966
+                        ofsdst += dstpitch;
967
+                        opcode--;
968
+                    }
969
+                }
970
+                i--;
971
+            }
972
+        }
973
+    }
974
+}
975
+
976
+static void decode_short_vertical_delta2(uint8_t *dst,
977
+                                         const uint8_t *buf, const uint8_t *buf_end,
978
+                                         int w, int bpp, int dst_size)
979
+{
980
+    int ncolumns = (w + 15) >> 4;
981
+    int dstpitch = ncolumns * bpp * 2;
982
+    unsigned ofsdst, ofssrc, opcode, x;
983
+    GetByteContext ptrs, gb;
984
+    PutByteContext pb;
985
+    int i, j, k;
986
+
987
+    bytestream2_init(&ptrs, buf, buf_end - buf);
988
+    bytestream2_init_writer(&pb, dst, dst_size);
989
+
990
+    for (k = 0; k < bpp; k++) {
991
+        ofssrc = bytestream2_get_be32(&ptrs);
992
+
993
+        if (!ofssrc)
994
+            continue;
995
+
996
+        if (ofssrc >= buf_end - buf)
997
+            continue;
998
+
999
+        bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1000
+        for (j = 0; j < ncolumns; j++) {
1001
+            ofsdst = (j + k * ncolumns) * 2;
1002
+
1003
+            i = bytestream2_get_be16(&gb);
1004
+            while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1005
+                opcode = bytestream2_get_be16(&gb);
1006
+
1007
+                if (opcode == 0) {
1008
+                    opcode = bytestream2_get_be16(&gb);
1009
+                    x = bytestream2_get_be16(&gb);
1010
+
1011
+                    while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1012
+                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1013
+                        bytestream2_put_be16(&pb, x);
1014
+                        ofsdst += dstpitch;
1015
+                        opcode--;
1016
+                    }
1017
+                } else if (opcode < 0x8000) {
1018
+                    ofsdst += opcode * dstpitch;
1019
+                } else {
1020
+                    opcode &= 0x7fff;
1021
+
1022
+                    while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1023
+                           bytestream2_get_bytes_left_p(&pb) > 1) {
1024
+                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1025
+                        bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1026
+                        ofsdst += dstpitch;
1027
+                        opcode--;
1028
+                    }
1029
+                }
1030
+                i--;
1031
+            }
1032
+        }
1033
+    }
1034
+}
1035
+
1036
+static void decode_long_vertical_delta2(uint8_t *dst,
1037
+                                        const uint8_t *buf, const uint8_t *buf_end,
1038
+                                        int w, int bpp, int dst_size)
1039
+{
1040
+    int ncolumns = (w + 31) >> 5;
1041
+    int dstpitch = ((w + 15) / 16 * 2) * bpp;
1042
+    unsigned ofsdst, ofssrc, opcode, x;
1043
+    unsigned skip = 0x80000000, mask = skip - 1;
1044
+    GetByteContext ptrs, gb;
1045
+    PutByteContext pb;
1046
+    int i, j, k, h;
1047
+
1048
+    h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1049
+    bytestream2_init(&ptrs, buf, buf_end - buf);
1050
+    bytestream2_init_writer(&pb, dst, dst_size);
1051
+
1052
+    for (k = 0; k < bpp; k++) {
1053
+        ofssrc = bytestream2_get_be32(&ptrs);
1054
+
1055
+        if (!ofssrc)
1056
+            continue;
1057
+
1058
+        if (ofssrc >= buf_end - buf)
1059
+            continue;
1060
+
1061
+        bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1062
+        for (j = 0; j < ncolumns; j++) {
1063
+            ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1064
+
1065
+            if (h && (j == (ncolumns - 1))) {
1066
+                skip = 0x8000;
1067
+                mask = skip - 1;
1068
+            }
1069
+
1070
+            i = bytestream2_get_be32(&gb);
1071
+            while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1072
+                opcode = bytestream2_get_be32(&gb);
1073
+
1074
+                if (opcode == 0) {
1075
+                    if (h && (j == ncolumns - 1)) {
1076
+                        opcode = bytestream2_get_be16(&gb);
1077
+                        x = bytestream2_get_be16(&gb);
1078
+                    } else {
1079
+                        opcode = bytestream2_get_be32(&gb);
1080
+                        x = bytestream2_get_be32(&gb);
1081
+                    }
1082
+
1083
+                    while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1084
+                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1085
+                        if (h && (j == ncolumns - 1))
1086
+                            bytestream2_put_be16(&pb, x);
1087
+                        else
1088
+                            bytestream2_put_be32(&pb, x);
1089
+                        ofsdst += dstpitch;
1090
+                        opcode--;
1091
+                    }
1092
+                } else if (opcode < skip) {
1093
+                    ofsdst += opcode * dstpitch;
1094
+                } else {
1095
+                    opcode &= mask;
1096
+
1097
+                    while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1098
+                           bytestream2_get_bytes_left_p(&pb) > 1) {
1099
+                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1100
+                        if (h && (j == ncolumns - 1)) {
1101
+                            bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1102
+                        } else {
1103
+                            bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1104
+                        }
1105
+                        ofsdst += dstpitch;
1106
+                        opcode--;
1107
+                    }
1108
+                }
1109
+                i--;
1110
+            }
1111
+        }
1112
+    }
1113
+}
1114
+
1115
+static void decode_delta_l(uint8_t *dst,
1116
+                           const uint8_t *buf, const uint8_t *buf_end,
1117
+                           int w, int flag, int bpp, int dst_size)
1118
+{
1119
+    GetByteContext off0, off1, dgb, ogb;
1120
+    PutByteContext pb;
1121
+    unsigned poff0, poff1;
1122
+    int i, k, dstpitch;
1123
+    int planepitch_byte = (w + 7) / 8;
1124
+    int planepitch = ((w + 15) / 16) * 2;
1125
+    int pitch = planepitch * bpp;
1126
+
1127
+    if (buf_end - buf <= 64)
1128
+        return;
1129
+
1130
+    bytestream2_init(&off0, buf, buf_end - buf);
1131
+    bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1132
+    bytestream2_init_writer(&pb, dst, dst_size);
1133
+
1134
+    dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1135
+
1136
+    for (k = 0; k < bpp; k++) {
1137
+        poff0 = bytestream2_get_be32(&off0);
1138
+        poff1 = bytestream2_get_be32(&off1);
1139
+
1140
+        if (!poff0)
1141
+            continue;
1142
+
1143
+        if (2LL * poff0 >= buf_end - buf)
1144
+            return;
1145
+
1146
+        if (2LL * poff1 >= buf_end - buf)
1147
+            return;
1148
+
1149
+        bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1150
+        bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1151
+
1152
+        while ((bytestream2_peek_be16(&ogb)) != 0xFFFF) {
1153
+            uint16_t offset = bytestream2_get_be16(&ogb);
1154
+            int16_t cnt = bytestream2_get_be16(&ogb);
1155
+            uint16_t data;
1156
+
1157
+            offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1158
+            if (cnt < 0) {
1159
+                bytestream2_seek_p(&pb, offset, SEEK_SET);
1160
+                cnt = -cnt;
1161
+                data = bytestream2_get_be16(&dgb);
1162
+                for (i = 0; i < cnt; i++) {
1163
+                    bytestream2_put_be16(&pb, data);
1164
+                    bytestream2_skip_p(&pb, dstpitch - 2);
1165
+                }
1166
+            } else {
1167
+                bytestream2_seek_p(&pb, offset, SEEK_SET);
1168
+                for (i = 0; i < cnt; i++) {
1169
+                    data = bytestream2_get_be16(&dgb);
1170
+                    bytestream2_put_be16(&pb, data);
1171
+                    bytestream2_skip_p(&pb, dstpitch - 2);
1172
+                }
1173
+            }
1174
+        }
1175
+    }
1176
+}
1177
+
663 1178
 static int unsupported(AVCodecContext *avctx)
664 1179
 {
665 1180
     IffContext *s = avctx->priv_data;
666
-    avpriv_request_sample(avctx, "bitmap (compression %i, bpp %i, ham %i)", s->compression, s->bpp, s->ham);
1181
+    avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i)", s->compression, s->bpp, s->ham);
667 1182
     return AVERROR_INVALIDDATA;
668 1183
 }
669 1184
 
... ...
@@ -672,23 +1233,30 @@ static int decode_frame(AVCodecContext *avctx,
672 672
                         AVPacket *avpkt)
673 673
 {
674 674
     IffContext *s          = avctx->priv_data;
675
-    const uint8_t *buf     = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
676
-    const int buf_size     = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
675
+    AVFrame *frame         = data;
676
+    const uint8_t *buf     = avpkt->data;
677
+    int buf_size           = avpkt->size;
677 678
     const uint8_t *buf_end = buf + buf_size;
678 679
     int y, plane, res;
679
-    GetByteContext gb;
680
+    GetByteContext *gb = &s->gb;
680 681
     const AVPixFmtDescriptor *desc;
681 682
 
683
+    bytestream2_init(gb, avpkt->data, avpkt->size);
684
+
682 685
     if ((res = extract_header(avctx, avpkt)) < 0)
683 686
         return res;
684
-    if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
687
+
688
+    if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
685 689
         return res;
690
+    s->frame = frame;
686 691
 
692
+    buf      += bytestream2_tell(gb);
693
+    buf_size -= bytestream2_tell(gb);
687 694
     desc = av_pix_fmt_desc_get(avctx->pix_fmt);
688 695
 
689 696
     if (!s->init && avctx->bits_per_coded_sample <= 8 &&
690 697
         avctx->pix_fmt == AV_PIX_FMT_PAL8) {
691
-        if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame->data[1])) < 0)
698
+        if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
692 699
             return res;
693 700
     } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
694 701
                avctx->pix_fmt == AV_PIX_FMT_RGB32) {
... ...
@@ -697,22 +1265,33 @@ static int decode_frame(AVCodecContext *avctx,
697 697
     }
698 698
     s->init = 1;
699 699
 
700
+    if (s->compression <= 0xff && avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
701
+        if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
702
+            memcpy(s->pal[0], s->frame->data[1], 256 * 4);
703
+    }
704
+
705
+    if (s->compression > 0xff && s->first) {
706
+        memcpy(s->video[1], s->video[0], s->video_size);
707
+        memcpy(s->pal[1], s->pal[0], 256 * 4);
708
+        s->first = 0;
709
+    }
710
+
700 711
     switch (s->compression) {
701
-    case 0:
712
+    case 0x0:
702 713
         if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
703 714
             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
704
-                memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
715
+                memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
705 716
                 for (plane = 0; plane < s->bpp; plane++) {
706 717
                     for (y = 0; y < avctx->height && buf < buf_end; y++) {
707
-                        uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
718
+                        uint8_t *row = &frame->data[0][y * frame->linesize[0]];
708 719
                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
709 720
                         buf += s->planesize;
710 721
                     }
711 722
                 }
712 723
             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
713
-                memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
724
+                memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
714 725
                 for (y = 0; y < avctx->height; y++) {
715
-                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
726
+                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
716 727
                     memset(s->ham_buf, 0, s->planesize * 8);
717 728
                     for (plane = 0; plane < s->bpp; plane++) {
718 729
                         const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
... ...
@@ -728,7 +1307,7 @@ static int decode_frame(AVCodecContext *avctx,
728 728
             int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
729 729
             int x;
730 730
             for (y = 0; y < avctx->height && buf < buf_end; y++) {
731
-                uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
731
+                uint8_t *row = &frame->data[0][y * frame->linesize[0]];
732 732
                 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
733 733
                 buf += raw_width;
734 734
                 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
... ...
@@ -736,10 +1315,13 @@ static int decode_frame(AVCodecContext *avctx,
736 736
                         row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
737 737
                 }
738 738
             }
739
-        } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
739
+        } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
740
+                   avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
740 741
             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
742
+                if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
743
+                    memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
741 744
                 for (y = 0; y < avctx->height; y++) {
742
-                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
745
+                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
743 746
                     memset(row, 0, avctx->width);
744 747
                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
745 748
                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
... ...
@@ -748,7 +1330,7 @@ static int decode_frame(AVCodecContext *avctx,
748 748
                 }
749 749
             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
750 750
                 for (y = 0; y < avctx->height; y++) {
751
-                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
751
+                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
752 752
                     memset(s->ham_buf, 0, s->planesize * 8);
753 753
                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
754 754
                         decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
... ...
@@ -758,7 +1340,7 @@ static int decode_frame(AVCodecContext *avctx,
758 758
                 }
759 759
             } else { // AV_PIX_FMT_BGR32
760 760
                 for (y = 0; y < avctx->height; y++) {
761
-                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
761
+                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
762 762
                     memset(row, 0, avctx->width << 2);
763 763
                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
764 764
                         decodeplane32((uint32_t *)row, buf,
... ...
@@ -770,13 +1352,13 @@ static int decode_frame(AVCodecContext *avctx,
770 770
         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
771 771
             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
772 772
                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
773
-                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
773
+                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
774 774
                     memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
775 775
                     buf += avctx->width + (avctx->width % 2); // padding if odd
776 776
                 }
777 777
             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
778 778
                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
779
-                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
779
+                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
780 780
                     memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
781 781
                     buf += avctx->width + (avctx->width & 1); // padding if odd
782 782
                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
... ...
@@ -785,43 +1367,55 @@ static int decode_frame(AVCodecContext *avctx,
785 785
                 return unsupported(avctx);
786 786
         }
787 787
         break;
788
-    case 1:
789
-        if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
788
+    case 0x1:
789
+        if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
790
+            avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
790 791
             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
792
+                uint8_t *video = s->video[0];
793
+
791 794
                 for (y = 0; y < avctx->height; y++) {
792
-                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
795
+                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
793 796
                     memset(row, 0, avctx->width);
794 797
                     for (plane = 0; plane < s->bpp; plane++) {
795
-                        buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
798
+                        buf += decode_byterun(s->planebuf, s->planesize, gb);
799
+                        if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
800
+                            memcpy(video, s->planebuf, s->planesize);
801
+                            video += s->planesize;
802
+                        }
796 803
                         decodeplane8(row, s->planebuf, s->planesize, plane);
797 804
                     }
798 805
                 }
799 806
             } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
800 807
                 for (y = 0; y < avctx->height; y++) {
801
-                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
808
+                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
802 809
                     memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
803 810
                     for (plane = 0; plane < s->bpp; plane++) {
804
-                        buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
811
+                        buf += decode_byterun(s->planebuf, s->planesize, gb);
805 812
                         decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
806 813
                     }
807 814
                     lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
808 815
                 }
809 816
             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
817
+                uint8_t *video = s->video[0];
810 818
                 for (y = 0; y < avctx->height; y++) {
811
-                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
819
+                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
812 820
                     memset(s->ham_buf, 0, s->planesize * 8);
813 821
                     for (plane = 0; plane < s->bpp; plane++) {
814
-                        buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
822
+                        buf += decode_byterun(s->planebuf, s->planesize, gb);
823
+                        if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
824
+                            memcpy(video, s->planebuf, s->planesize);
825
+                            video += s->planesize;
826
+                        }
815 827
                         decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
816 828
                     }
817 829
                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
818 830
                 }
819 831
             } else { // AV_PIX_FMT_BGR32
820 832
                 for (y = 0; y < avctx->height; y++) {
821
-                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
833
+                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
822 834
                     memset(row, 0, avctx->width << 2);
823 835
                     for (plane = 0; plane < s->bpp; plane++) {
824
-                        buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
836
+                        buf += decode_byterun(s->planebuf, s->planesize, gb);
825 837
                         decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
826 838
                     }
827 839
                 }
... ...
@@ -829,48 +1423,129 @@ static int decode_frame(AVCodecContext *avctx,
829 829
         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
830 830
             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
831 831
                 for (y = 0; y < avctx->height; y++) {
832
-                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
833
-                    buf += decode_byterun(row, avctx->width, buf, buf_end);
832
+                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
833
+                    buf += decode_byterun(row, avctx->width, gb);
834 834
                 }
835 835
             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
836 836
                 for (y = 0; y < avctx->height; y++) {
837
-                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
838
-                    buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
837
+                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
838
+                    buf += decode_byterun(s->ham_buf, avctx->width, gb);
839 839
                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
840 840
                 }
841 841
             } else
842 842
                 return unsupported(avctx);
843 843
         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
844 844
             if (av_get_bits_per_pixel(desc) == 32)
845
-                decode_deep_rle32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0]);
845
+                decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
846 846
             else
847 847
                 return unsupported(avctx);
848 848
         }
849 849
         break;
850
-    case 4:
851
-        bytestream2_init(&gb, buf, buf_size);
850
+    case 0x4:
852 851
         if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
853
-            decode_rgb8(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
852
+            decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
854 853
         else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
855
-            decode_rgbn(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
854
+            decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
856 855
         else
857 856
             return unsupported(avctx);
858 857
         break;
859
-    case 5:
858
+    case 0x5:
860 859
         if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
861 860
             if (av_get_bits_per_pixel(desc) == 32)
862
-                decode_deep_tvdc32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0], s->tvdc);
861
+                decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
863 862
             else
864 863
                 return unsupported(avctx);
865 864
         } else
866 865
             return unsupported(avctx);
867 866
         break;
867
+    case 0x500:
868
+    case 0x501:
869
+        decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
870
+        break;
871
+    case 0x700:
872
+    case 0x701:
873
+        if (s->is_short)
874
+            decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
875
+        else
876
+            decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
877
+        break;
878
+    case 0x800:
879
+    case 0x801:
880
+        if (s->is_short)
881
+            decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
882
+        else
883
+            decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
884
+        break;
885
+    case 0x4a00:
886
+    case 0x4a01:
887
+        decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
888
+        break;
889
+    case 0x6c00:
890
+    case 0x6c01:
891
+        decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
892
+        break;
868 893
     default:
869 894
         return unsupported(avctx);
870 895
     }
871 896
 
872
-    if ((res = av_frame_ref(data, s->frame)) < 0)
873
-        return res;
897
+    if (s->compression > 0xff) {
898
+        if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
899
+            buf = s->video[0];
900
+            for (y = 0; y < avctx->height; y++) {
901
+                uint8_t *row = &frame->data[0][y * frame->linesize[0]];
902
+                memset(row, 0, avctx->width);
903
+                for (plane = 0; plane < s->bpp; plane++) {
904
+                    decodeplane8(row, buf, s->planesize, plane);
905
+                    buf += s->planesize;
906
+                }
907
+            }
908
+            memcpy(frame->data[1], s->pal[0], 256 * 4);
909
+        } else if (s->ham) {
910
+            int i, count = 1 << s->ham;
911
+
912
+            buf = s->video[0];
913
+            memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
914
+            for (i = 0; i < count; i++) {
915
+                s->ham_palbuf[i*2+1] = s->pal[0][i];
916
+            }
917
+            for (i = 0; i < count; i++) {
918
+                uint32_t tmp = i << (8 - s->ham);
919
+                tmp |= tmp >> s->ham;
920
+                s->ham_palbuf[(i+count)*2]     = 0xFF00FFFF;
921
+                s->ham_palbuf[(i+count*2)*2]   = 0xFFFFFF00;
922
+                s->ham_palbuf[(i+count*3)*2]   = 0xFFFF00FF;
923
+                s->ham_palbuf[(i+count)*2+1]   = 0xFF000000 | tmp << 16;
924
+                s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
925
+                s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
926
+            }
927
+            if (s->masking == MASK_HAS_MASK) {
928
+                for (i = 0; i < 8 * (1 << s->ham); i++)
929
+                    s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
930
+            }
931
+            for (y = 0; y < avctx->height; y++) {
932
+                uint8_t *row = &frame->data[0][y * frame->linesize[0]];
933
+                memset(s->ham_buf, 0, s->planesize * 8);
934
+                for (plane = 0; plane < s->bpp; plane++) {
935
+                    decodeplane8(s->ham_buf, buf, s->planesize, plane);
936
+                    buf += s->planesize;
937
+                }
938
+                decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
939
+            }
940
+        } else {
941
+            return unsupported(avctx);
942
+        }
943
+
944
+        FFSWAP(uint8_t *, s->video[0], s->video[1]);
945
+        FFSWAP(uint32_t *, s->pal[0], s->pal[1]);
946
+    }
947
+
948
+    if (avpkt->flags & AV_PKT_FLAG_KEY) {
949
+        frame->key_frame = 1;
950
+        frame->pict_type = AV_PICTURE_TYPE_I;
951
+    } else {
952
+        frame->key_frame = 0;
953
+        frame->pict_type = AV_PICTURE_TYPE_P;
954
+    }
874 955
 
875 956
     *got_frame = 1;
876 957
 
... ...
@@ -880,7 +1555,7 @@ static int decode_frame(AVCodecContext *avctx,
880 880
 #if CONFIG_IFF_ILBM_DECODER
881 881
 AVCodec ff_iff_ilbm_decoder = {
882 882
     .name           = "iff",
883
-    .long_name      = NULL_IF_CONFIG_SMALL("IFF"),
883
+    .long_name      = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM"),
884 884
     .type           = AVMEDIA_TYPE_VIDEO,
885 885
     .id             = AV_CODEC_ID_IFF_ILBM,
886 886
     .priv_data_size = sizeof(IffContext),
... ...
@@ -60,6 +60,8 @@
60 60
 #define ID_RGBN       MKTAG('R','G','B','N')
61 61
 #define ID_DSD        MKTAG('D','S','D',' ')
62 62
 #define ID_ANIM       MKTAG('A','N','I','M')
63
+#define ID_ANHD       MKTAG('A','N','H','D')
64
+#define ID_DLTA       MKTAG('D','L','T','A')
63 65
 
64 66
 #define ID_FORM       MKTAG('F','O','R','M')
65 67
 #define ID_FRM8       MKTAG('F','R','M','8')
... ...
@@ -113,6 +115,7 @@ typedef struct IffDemuxContext {
113 113
     unsigned  transparency; ///< transparency color index in palette
114 114
     unsigned  masking;      ///< masking method used
115 115
     uint8_t   tvdc[32];     ///< TVDC lookup table
116
+    int64_t   pts;
116 117
 } IffDemuxContext;
117 118
 
118 119
 /* Metadata string read */
... ...
@@ -147,7 +150,6 @@ static int iff_probe(AVProbeData *p)
147 147
           AV_RL32(d+8) == ID_DEEP ||
148 148
           AV_RL32(d+8) == ID_ILBM ||
149 149
           AV_RL32(d+8) == ID_RGB8 ||
150
-          AV_RL32(d+8) == ID_RGB8 ||
151 150
           AV_RL32(d+8) == ID_ANIM ||
152 151
           AV_RL32(d+8) == ID_RGBN)) ||
153 152
          (AV_RL32(d) == ID_FRM8 && AV_RL32(d+12) == ID_DSD))
... ...
@@ -367,8 +369,7 @@ static int iff_read_header(AVFormatContext *s)
367 367
     // codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content
368 368
     st->codecpar->codec_tag = avio_rl32(pb);
369 369
     if (st->codecpar->codec_tag == ID_ANIM) {
370
-        avio_skip(pb, 8);
371
-        st->codecpar->codec_tag = avio_rl32(pb);
370
+        avio_skip(pb, 12);
372 371
     }
373 372
     iff->bitmap_compression = -1;
374 373
     iff->svx8_compression = -1;
... ...
@@ -484,6 +485,9 @@ static int iff_read_header(AVFormatContext *s)
484 484
             }
485 485
             break;
486 486
 
487
+        case ID_ANHD:
488
+            break;
489
+
487 490
         case ID_DPEL:
488 491
             if (data_size < 4 || (data_size & 3))
489 492
                 return AVERROR_INVALIDDATA;
... ...
@@ -626,7 +630,10 @@ static int iff_read_header(AVFormatContext *s)
626 626
         avio_skip(pb, data_size - (avio_tell(pb) - orig_pos) + (data_size & 1));
627 627
     }
628 628
 
629
-    avio_seek(pb, iff->body_pos, SEEK_SET);
629
+    if (st->codecpar->codec_tag == ID_ANIM)
630
+        avio_seek(pb, 12, SEEK_SET);
631
+    else
632
+        avio_seek(pb, iff->body_pos, SEEK_SET);
630 633
 
631 634
     switch(st->codecpar->codec_type) {
632 635
     case AVMEDIA_TYPE_AUDIO:
... ...
@@ -672,6 +679,8 @@ static int iff_read_header(AVFormatContext *s)
672 672
 
673 673
     case AVMEDIA_TYPE_VIDEO:
674 674
         iff->bpp          = st->codecpar->bits_per_coded_sample;
675
+        if (st->codecpar->codec_tag == ID_ANIM)
676
+            avpriv_set_pts_info(st, 32, 1, 60);
675 677
         if ((screenmode & 0x800 /* Hold And Modify */) && iff->bpp <= 8) {
676 678
             iff->ham      = iff->bpp > 6 ? 6 : 4;
677 679
             st->codecpar->bits_per_coded_sample = 24;
... ...
@@ -705,6 +714,28 @@ static int iff_read_header(AVFormatContext *s)
705 705
     return 0;
706 706
 }
707 707
 
708
+static unsigned get_anim_duration(uint8_t *buf, int size)
709
+{
710
+    GetByteContext gb;
711
+
712
+    bytestream2_init(&gb, buf, size);
713
+    bytestream2_skip(&gb, 4);
714
+    while (bytestream2_get_bytes_left(&gb) > 8) {
715
+        unsigned chunk = bytestream2_get_le32(&gb);
716
+        unsigned size = bytestream2_get_be32(&gb);
717
+
718
+        if (chunk == ID_ANHD) {
719
+            if (size < 40)
720
+                break;
721
+            bytestream2_skip(&gb, 14);
722
+            return bytestream2_get_be32(&gb);
723
+        } else {
724
+            bytestream2_skip(&gb, size + size & 1);
725
+        }
726
+    }
727
+    return 10;
728
+}
729
+
708 730
 static int iff_read_packet(AVFormatContext *s,
709 731
                            AVPacket *pkt)
710 732
 {
... ...
@@ -714,8 +745,12 @@ static int iff_read_packet(AVFormatContext *s,
714 714
     int ret;
715 715
     int64_t pos = avio_tell(pb);
716 716
 
717
-    if (pos >= iff->body_end)
717
+    if (st->codecpar->codec_tag == ID_ANIM) {
718
+        if (avio_feof(pb))
719
+            return AVERROR_EOF;
720
+    } else if (pos >= iff->body_end) {
718 721
         return AVERROR_EOF;
722
+    }
719 723
 
720 724
     if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
721 725
         if (st->codecpar->codec_tag == ID_DSD || st->codecpar->codec_tag == ID_MAUD) {
... ...
@@ -725,28 +760,39 @@ static int iff_read_packet(AVFormatContext *s,
725 725
                 return AVERROR_INVALIDDATA;
726 726
             ret = av_get_packet(pb, pkt, iff->body_size);
727 727
         }
728
-    } else if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
729
-        uint8_t *buf;
728
+    } else if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
729
+               st->codecpar->codec_tag  == ID_ANIM) {
730
+        uint64_t data_size, orig_pos;
731
+        uint32_t chunk_id = 0;
730 732
 
731
-        if (iff->body_size > INT_MAX - 2)
732
-            return AVERROR_INVALIDDATA;
733
-        if (av_new_packet(pkt, iff->body_size + 2) < 0) {
734
-            return AVERROR(ENOMEM);
735
-        }
733
+        while (!avio_feof(pb)) {
734
+            if (avio_feof(pb))
735
+                return AVERROR_EOF;
736
+
737
+            chunk_id  = avio_rl32(pb);
738
+            data_size = avio_rb32(pb);
739
+            orig_pos  = avio_tell(pb);
736 740
 
737
-        buf = pkt->data;
738
-        bytestream_put_be16(&buf, 2);
739
-        ret = avio_read(pb, buf, iff->body_size);
740
-        if (ret<0) {
741
-            av_packet_unref(pkt);
742
-        } else if (ret < iff->body_size)
743
-            av_shrink_packet(pkt, ret + 2);
741
+            if (chunk_id == ID_FORM)
742
+                break;
743
+            else
744
+                avio_skip(pb, data_size);
745
+        }
746
+        ret = av_get_packet(pb, pkt, data_size);
747
+        pkt->pos = orig_pos;
748
+        pkt->duration = get_anim_duration(pkt->data, pkt->size);
749
+        if (pos == 12)
750
+            pkt->flags |= AV_PKT_FLAG_KEY;
751
+    } else if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
752
+               st->codecpar->codec_tag  != ID_ANIM) {
753
+        ret = av_get_packet(pb, pkt, iff->body_size);
754
+        pkt->pos = pos;
755
+        if (pos == iff->body_pos)
756
+            pkt->flags |= AV_PKT_FLAG_KEY;
744 757
     } else {
745 758
         av_assert0(0);
746 759
     }
747 760
 
748
-    if (pos == iff->body_pos)
749
-        pkt->flags |= AV_PKT_FLAG_KEY;
750 761
     if (ret < 0)
751 762
         return ret;
752 763
     pkt->stream_index = 0;