LCOV - code coverage report
Current view: top level - libavcodec - iff.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 134 1065 12.6 %
Date: 2017-12-14 01:15:32 Functions: 7 27 25.9 %

          Line data    Source code
       1             : /*
       2             :  * IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN bitmap decoder
       3             :  * Copyright (c) 2010 Peter Ross <pross@xvid.org>
       4             :  * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
       5             :  * Copyright (c) 2016 Paul B Mahol
       6             :  *
       7             :  * This file is part of FFmpeg.
       8             :  *
       9             :  * FFmpeg is free software; you can redistribute it and/or
      10             :  * modify it under the terms of the GNU Lesser General Public
      11             :  * License as published by the Free Software Foundation; either
      12             :  * version 2.1 of the License, or (at your option) any later version.
      13             :  *
      14             :  * FFmpeg is distributed in the hope that it will be useful,
      15             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17             :  * Lesser General Public License for more details.
      18             :  *
      19             :  * You should have received a copy of the GNU Lesser General Public
      20             :  * License along with FFmpeg; if not, write to the Free Software
      21             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      22             :  */
      23             : 
      24             : /**
      25             :  * @file
      26             :  * IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN bitmap decoder
      27             :  */
      28             : 
      29             : #include <stdint.h>
      30             : 
      31             : #include "libavutil/imgutils.h"
      32             : 
      33             : #include "bytestream.h"
      34             : #include "avcodec.h"
      35             : #include "internal.h"
      36             : #include "mathops.h"
      37             : 
      38             : // TODO: masking bits
      39             : typedef enum {
      40             :     MASK_NONE,
      41             :     MASK_HAS_MASK,
      42             :     MASK_HAS_TRANSPARENT_COLOR,
      43             :     MASK_LASSO
      44             : } mask_type;
      45             : 
      46             : typedef struct IffContext {
      47             :     AVFrame *frame;
      48             :     int planesize;
      49             :     uint8_t * planebuf;
      50             :     uint8_t * ham_buf;      ///< temporary buffer for planar to chunky conversation
      51             :     uint32_t *ham_palbuf;   ///< HAM decode table
      52             :     uint32_t *mask_buf;     ///< temporary buffer for palette indices
      53             :     uint32_t *mask_palbuf;  ///< masking palette table
      54             :     unsigned  compression;  ///< delta compression method used
      55             :     unsigned  is_short;     ///< short compression method used
      56             :     unsigned  is_interlaced;///< video is interlaced
      57             :     unsigned  is_brush;     ///< video is in ANBR format
      58             :     unsigned  bpp;          ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
      59             :     unsigned  ham;          ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
      60             :     unsigned  flags;        ///< 1 for EHB, 0 is no extra half darkening
      61             :     unsigned  transparency; ///< TODO: transparency color index in palette
      62             :     unsigned  masking;      ///< TODO: masking method used
      63             :     int init; // 1 if buffer and palette data already initialized, 0 otherwise
      64             :     int16_t   tvdc[16];     ///< TVDC lookup table
      65             :     GetByteContext gb;
      66             :     uint8_t *video[2];
      67             :     unsigned video_size;
      68             :     uint32_t *pal;
      69             : } IffContext;
      70             : 
      71             : #define LUT8_PART(plane, v)                             \
      72             :     AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane,  \
      73             :     AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane,  \
      74             :     AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane,  \
      75             :     AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane,  \
      76             :     AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane,  \
      77             :     AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane,  \
      78             :     AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane,  \
      79             :     AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane,  \
      80             :     AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane,  \
      81             :     AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane,  \
      82             :     AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane,  \
      83             :     AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane,  \
      84             :     AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane,  \
      85             :     AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane,  \
      86             :     AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane,  \
      87             :     AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
      88             : 
      89             : #define LUT8(plane) {                           \
      90             :     LUT8_PART(plane, 0x0000000),                \
      91             :     LUT8_PART(plane, 0x1000000),                \
      92             :     LUT8_PART(plane, 0x0010000),                \
      93             :     LUT8_PART(plane, 0x1010000),                \
      94             :     LUT8_PART(plane, 0x0000100),                \
      95             :     LUT8_PART(plane, 0x1000100),                \
      96             :     LUT8_PART(plane, 0x0010100),                \
      97             :     LUT8_PART(plane, 0x1010100),                \
      98             :     LUT8_PART(plane, 0x0000001),                \
      99             :     LUT8_PART(plane, 0x1000001),                \
     100             :     LUT8_PART(plane, 0x0010001),                \
     101             :     LUT8_PART(plane, 0x1010001),                \
     102             :     LUT8_PART(plane, 0x0000101),                \
     103             :     LUT8_PART(plane, 0x1000101),                \
     104             :     LUT8_PART(plane, 0x0010101),                \
     105             :     LUT8_PART(plane, 0x1010101),                \
     106             : }
     107             : 
     108             : // 8 planes * 8-bit mask
     109             : static const uint64_t plane8_lut[8][256] = {
     110             :     LUT8(0), LUT8(1), LUT8(2), LUT8(3),
     111             :     LUT8(4), LUT8(5), LUT8(6), LUT8(7),
     112             : };
     113             : 
     114             : #define LUT32(plane) {                                \
     115             :              0,          0,          0,          0,   \
     116             :              0,          0,          0, 1 << plane,   \
     117             :              0,          0, 1 << plane,          0,   \
     118             :              0,          0, 1 << plane, 1 << plane,   \
     119             :              0, 1 << plane,          0,          0,   \
     120             :              0, 1 << plane,          0, 1 << plane,   \
     121             :              0, 1 << plane, 1 << plane,          0,   \
     122             :              0, 1 << plane, 1 << plane, 1 << plane,   \
     123             :     1 << plane,          0,          0,          0,   \
     124             :     1 << plane,          0,          0, 1 << plane,   \
     125             :     1 << plane,          0, 1 << plane,          0,   \
     126             :     1 << plane,          0, 1 << plane, 1 << plane,   \
     127             :     1 << plane, 1 << plane,          0,          0,   \
     128             :     1 << plane, 1 << plane,          0, 1 << plane,   \
     129             :     1 << plane, 1 << plane, 1 << plane,          0,   \
     130             :     1 << plane, 1 << plane, 1 << plane, 1 << plane,   \
     131             : }
     132             : 
     133             : // 32 planes * 4-bit mask * 4 lookup tables each
     134             : static const uint32_t plane32_lut[32][16*4] = {
     135             :     LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
     136             :     LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
     137             :     LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
     138             :     LUT32(12), LUT32(13), LUT32(14), LUT32(15),
     139             :     LUT32(16), LUT32(17), LUT32(18), LUT32(19),
     140             :     LUT32(20), LUT32(21), LUT32(22), LUT32(23),
     141             :     LUT32(24), LUT32(25), LUT32(26), LUT32(27),
     142             :     LUT32(28), LUT32(29), LUT32(30), LUT32(31),
     143             : };
     144             : 
     145             : // Gray to RGB, required for palette table of grayscale images with bpp < 8
     146           0 : static av_always_inline uint32_t gray2rgb(const uint32_t x) {
     147           0 :     return x << 16 | x << 8 | x;
     148             : }
     149             : 
     150             : /**
     151             :  * Convert CMAP buffer (stored in extradata) to lavc palette format
     152             :  */
     153           2 : static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
     154             : {
     155           2 :     IffContext *s = avctx->priv_data;
     156             :     int count, i;
     157           2 :     const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
     158           2 :     int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
     159             : 
     160           2 :     if (avctx->bits_per_coded_sample > 8) {
     161           0 :         av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
     162           0 :         return AVERROR_INVALIDDATA;
     163             :     }
     164             : 
     165           2 :     count = 1 << avctx->bits_per_coded_sample;
     166             :     // If extradata is smaller than actually needed, fill the remaining with black.
     167           2 :     count = FFMIN(palette_size / 3, count);
     168           2 :     if (count) {
     169         514 :         for (i = 0; i < count; i++)
     170         512 :             pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
     171           2 :         if (s->flags && count >= 32) { // EHB
     172           0 :             for (i = 0; i < 32; i++)
     173           0 :                 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
     174           0 :             count = FFMAX(count, 64);
     175             :         }
     176             :     } else { // Create gray-scale color palette for bps < 8
     177           0 :         count = 1 << avctx->bits_per_coded_sample;
     178             : 
     179           0 :         for (i = 0; i < count; i++)
     180           0 :             pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
     181             :     }
     182           2 :     if (s->masking == MASK_HAS_MASK) {
     183           0 :         memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
     184           0 :         for (i = 0; i < count; i++)
     185           0 :             pal[i] &= 0xFFFFFF;
     186           2 :     } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
     187           0 :         s->transparency < 1 << avctx->bits_per_coded_sample)
     188           0 :         pal[s->transparency] &= 0xFFFFFF;
     189           2 :     return 0;
     190             : }
     191             : 
     192             : /**
     193             :  * Extracts the IFF extra context and updates internal
     194             :  * decoder structures.
     195             :  *
     196             :  * @param avctx the AVCodecContext where to extract extra context to
     197             :  * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
     198             :  * @return >= 0 in case of success, a negative error code otherwise
     199             :  */
     200           6 : static int extract_header(AVCodecContext *const avctx,
     201             :                           const AVPacket *const avpkt)
     202             : {
     203           6 :     IffContext *s = avctx->priv_data;
     204             :     const uint8_t *buf;
     205           6 :     unsigned buf_size = 0;
     206             :     int i, palette_size;
     207             : 
     208           6 :     if (avctx->extradata_size < 2) {
     209           0 :         av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
     210           0 :         return AVERROR_INVALIDDATA;
     211             :     }
     212           6 :     palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
     213             : 
     214           6 :     if (avpkt && avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
     215             :         uint32_t chunk_id;
     216             :         uint64_t data_size;
     217           0 :         GetByteContext *gb = &s->gb;
     218             : 
     219           0 :         bytestream2_skip(gb, 4);
     220           0 :         while (bytestream2_get_bytes_left(gb) >= 1) {
     221           0 :             chunk_id  = bytestream2_get_le32(gb);
     222           0 :             data_size = bytestream2_get_be32(gb);
     223             : 
     224           0 :             if (chunk_id == MKTAG('B', 'M', 'H', 'D')) {
     225           0 :                 bytestream2_skip(gb, data_size + (data_size & 1));
     226           0 :             } else if (chunk_id == MKTAG('A', 'N', 'H', 'D')) {
     227             :                 unsigned extra;
     228           0 :                 if (data_size < 40)
     229           0 :                     return AVERROR_INVALIDDATA;
     230             : 
     231           0 :                 s->compression = (bytestream2_get_byte(gb) << 8) | (s->compression & 0xFF);
     232           0 :                 bytestream2_skip(gb, 19);
     233           0 :                 extra = bytestream2_get_be32(gb);
     234           0 :                 s->is_short = !(extra & 1);
     235           0 :                 s->is_brush = extra == 2;
     236           0 :                 s->is_interlaced = !!(extra & 0x40);
     237           0 :                 data_size -= 24;
     238           0 :                 bytestream2_skip(gb, data_size + (data_size & 1));
     239           0 :             } else if (chunk_id == MKTAG('D', 'L', 'T', 'A') ||
     240             :                        chunk_id == MKTAG('B', 'O', 'D', 'Y')) {
     241           0 :                 if (chunk_id == MKTAG('B','O','D','Y'))
     242           0 :                     s->compression &= 0xFF;
     243           0 :                 break;
     244           0 :             } else if (chunk_id == MKTAG('C', 'M', 'A', 'P')) {
     245           0 :                 int count = data_size / 3;
     246           0 :                 uint32_t *pal = s->pal;
     247             : 
     248           0 :                 if (count > 256)
     249           0 :                     return AVERROR_INVALIDDATA;
     250           0 :                 if (s->ham) {
     251           0 :                     for (i = 0; i < count; i++)
     252           0 :                         pal[i] = 0xFF000000 | bytestream2_get_le24(gb);
     253             :                 } else {
     254           0 :                     for (i = 0; i < count; i++)
     255           0 :                         pal[i] = 0xFF000000 | bytestream2_get_be24(gb);
     256             :                 }
     257           0 :                 bytestream2_skip(gb, data_size & 1);
     258             :             } else {
     259           0 :                 bytestream2_skip(gb, data_size + (data_size&1));
     260             :             }
     261             :         }
     262           6 :     } else if (!avpkt) {
     263           4 :         buf = avctx->extradata;
     264           4 :         buf_size = bytestream_get_be16(&buf);
     265           4 :         if (buf_size <= 1 || palette_size < 0) {
     266           0 :             av_log(avctx, AV_LOG_ERROR,
     267             :                    "Invalid palette size received: %u -> palette data offset: %d\n",
     268             :                    buf_size, palette_size);
     269           0 :             return AVERROR_INVALIDDATA;
     270             :         }
     271             :     }
     272             : 
     273           6 :     if (buf_size >= 41) {
     274           4 :         s->compression  = bytestream_get_byte(&buf);
     275           4 :         s->bpp          = bytestream_get_byte(&buf);
     276           4 :         s->ham          = bytestream_get_byte(&buf);
     277           4 :         s->flags        = bytestream_get_byte(&buf);
     278           4 :         s->transparency = bytestream_get_be16(&buf);
     279           4 :         s->masking      = bytestream_get_byte(&buf);
     280          68 :         for (i = 0; i < 16; i++)
     281          64 :             s->tvdc[i] = bytestream_get_be16(&buf);
     282             : 
     283           4 :         if (s->masking == MASK_HAS_MASK) {
     284           0 :             if (s->bpp >= 8 && !s->ham) {
     285           0 :                 avctx->pix_fmt = AV_PIX_FMT_RGB32;
     286           0 :                 av_freep(&s->mask_buf);
     287           0 :                 av_freep(&s->mask_palbuf);
     288           0 :                 s->mask_buf = av_malloc((s->planesize * 32) + AV_INPUT_BUFFER_PADDING_SIZE);
     289           0 :                 if (!s->mask_buf)
     290           0 :                     return AVERROR(ENOMEM);
     291           0 :                 if (s->bpp > 16) {
     292           0 :                     av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
     293           0 :                     av_freep(&s->mask_buf);
     294           0 :                     return AVERROR(ENOMEM);
     295             :                 }
     296           0 :                 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
     297           0 :                 if (!s->mask_palbuf) {
     298           0 :                     av_freep(&s->mask_buf);
     299           0 :                     return AVERROR(ENOMEM);
     300             :                 }
     301             :             }
     302           0 :             s->bpp++;
     303           4 :         } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
     304           0 :             av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
     305           0 :             return AVERROR_PATCHWELCOME;
     306             :         }
     307           4 :         if (!s->bpp || s->bpp > 32) {
     308           0 :             av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
     309           0 :             return AVERROR_INVALIDDATA;
     310           4 :         } else if (s->ham >= 8) {
     311           0 :             av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
     312           0 :             return AVERROR_INVALIDDATA;
     313             :         }
     314             : 
     315           4 :         av_freep(&s->ham_buf);
     316           4 :         av_freep(&s->ham_palbuf);
     317             : 
     318           4 :         if (s->ham) {
     319           0 :             int i, count = FFMIN(palette_size / 3, 1 << s->ham);
     320             :             int ham_count;
     321           0 :             const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
     322             : 
     323           0 :             s->ham_buf = av_malloc((s->planesize * 8) + AV_INPUT_BUFFER_PADDING_SIZE);
     324           0 :             if (!s->ham_buf)
     325           0 :                 return AVERROR(ENOMEM);
     326             : 
     327           0 :             ham_count = 8 * (1 << s->ham);
     328           0 :             s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
     329           0 :             if (!s->ham_palbuf) {
     330           0 :                 av_freep(&s->ham_buf);
     331           0 :                 return AVERROR(ENOMEM);
     332             :             }
     333             : 
     334           0 :             if (count) { // HAM with color palette attached
     335             :                 // prefill with black and palette and set HAM take direct value mask to zero
     336           0 :                 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
     337           0 :                 for (i=0; i < count; i++) {
     338           0 :                     s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
     339             :                 }
     340           0 :                 count = 1 << s->ham;
     341             :             } else { // HAM with grayscale color palette
     342           0 :                 count = 1 << s->ham;
     343           0 :                 for (i=0; i < count; i++) {
     344           0 :                     s->ham_palbuf[i*2]   = 0xFF000000; // take direct color value from palette
     345           0 :                     s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
     346             :                 }
     347             :             }
     348           0 :             for (i=0; i < count; i++) {
     349           0 :                 uint32_t tmp = i << (8 - s->ham);
     350           0 :                 tmp |= tmp >> s->ham;
     351           0 :                 s->ham_palbuf[(i+count)*2]     = 0xFF00FFFF; // just modify blue color component
     352           0 :                 s->ham_palbuf[(i+count*2)*2]   = 0xFFFFFF00; // just modify red color component
     353           0 :                 s->ham_palbuf[(i+count*3)*2]   = 0xFFFF00FF; // just modify green color component
     354           0 :                 s->ham_palbuf[(i+count)*2+1]   = 0xFF000000 | tmp << 16;
     355           0 :                 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
     356           0 :                 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
     357             :             }
     358           0 :             if (s->masking == MASK_HAS_MASK) {
     359           0 :                 for (i = 0; i < ham_count; i++)
     360           0 :                     s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
     361             :             }
     362             :         }
     363             :     }
     364             : 
     365           6 :     return 0;
     366             : }
     367             : 
     368           4 : static av_cold int decode_end(AVCodecContext *avctx)
     369             : {
     370           4 :     IffContext *s = avctx->priv_data;
     371           4 :     av_freep(&s->planebuf);
     372           4 :     av_freep(&s->ham_buf);
     373           4 :     av_freep(&s->ham_palbuf);
     374           4 :     av_freep(&s->video[0]);
     375           4 :     av_freep(&s->video[1]);
     376           4 :     av_freep(&s->pal);
     377           4 :     return 0;
     378             : }
     379             : 
     380           4 : static av_cold int decode_init(AVCodecContext *avctx)
     381             : {
     382           4 :     IffContext *s = avctx->priv_data;
     383             :     int err;
     384             : 
     385           4 :     if (avctx->bits_per_coded_sample <= 8) {
     386             :         int palette_size;
     387             : 
     388           4 :         if (avctx->extradata_size >= 2)
     389           4 :             palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
     390             :         else
     391           0 :             palette_size = 0;
     392          12 :         avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
     393           8 :                          (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
     394           0 :     } else if (avctx->bits_per_coded_sample <= 32) {
     395           0 :         if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
     396           0 :             avctx->pix_fmt = AV_PIX_FMT_RGB32;
     397           0 :         } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
     398           0 :             avctx->pix_fmt = AV_PIX_FMT_RGB444;
     399           0 :         } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
     400           0 :             if (avctx->bits_per_coded_sample == 24) {
     401           0 :                 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
     402           0 :             } else if (avctx->bits_per_coded_sample == 32) {
     403           0 :                 avctx->pix_fmt = AV_PIX_FMT_BGR32;
     404             :             } else {
     405           0 :                 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
     406           0 :                 return AVERROR_PATCHWELCOME;
     407             :             }
     408             :         }
     409             :     } else {
     410           0 :         return AVERROR_INVALIDDATA;
     411             :     }
     412             : 
     413           4 :     if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
     414           0 :         return err;
     415           4 :     s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
     416           4 :     s->planebuf  = av_malloc(s->planesize * avctx->height + AV_INPUT_BUFFER_PADDING_SIZE);
     417           4 :     if (!s->planebuf)
     418           0 :         return AVERROR(ENOMEM);
     419             : 
     420           4 :     s->bpp = avctx->bits_per_coded_sample;
     421             : 
     422           4 :     if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
     423           0 :         s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
     424           0 :         s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
     425           0 :         s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
     426           0 :         s->pal = av_calloc(256, sizeof(*s->pal));
     427           0 :         if (!s->video[0] || !s->video[1] || !s->pal)
     428           0 :             return AVERROR(ENOMEM);
     429             :     }
     430             : 
     431           4 :     if ((err = extract_header(avctx, NULL)) < 0)
     432           0 :         return err;
     433             : 
     434           4 :     return 0;
     435             : }
     436             : 
     437             : /**
     438             :  * Decode interleaved plane buffer up to 8bpp
     439             :  * @param dst Destination buffer
     440             :  * @param buf Source buffer
     441             :  * @param buf_size
     442             :  * @param plane plane number to decode as
     443             :  */
     444        1920 : static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
     445             : {
     446        1920 :     const uint64_t *lut = plane8_lut[plane];
     447        1920 :     if (plane >= 8) {
     448           0 :         av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
     449           0 :         return;
     450             :     }
     451             :     do {
     452       76800 :         uint64_t v = AV_RN64A(dst) | lut[*buf++];
     453       76800 :         AV_WN64A(dst, v);
     454       76800 :         dst += 8;
     455       76800 :     } while (--buf_size);
     456             : }
     457             : 
     458             : /**
     459             :  * Decode interleaved plane buffer up to 24bpp
     460             :  * @param dst Destination buffer
     461             :  * @param buf Source buffer
     462             :  * @param buf_size
     463             :  * @param plane plane number to decode as
     464             :  */
     465           0 : static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
     466             : {
     467           0 :     const uint32_t *lut = plane32_lut[plane];
     468             :     do {
     469           0 :         unsigned mask = (*buf >> 2) & ~3;
     470           0 :         dst[0] |= lut[mask++];
     471           0 :         dst[1] |= lut[mask++];
     472           0 :         dst[2] |= lut[mask++];
     473           0 :         dst[3] |= lut[mask];
     474           0 :         mask    = (*buf++ << 2) & 0x3F;
     475           0 :         dst[4] |= lut[mask++];
     476           0 :         dst[5] |= lut[mask++];
     477           0 :         dst[6] |= lut[mask++];
     478           0 :         dst[7] |= lut[mask];
     479           0 :         dst    += 8;
     480           0 :     } while (--buf_size);
     481           0 : }
     482             : 
     483             : #define DECODE_HAM_PLANE32(x)       \
     484             :     first       = buf[x] << 1;      \
     485             :     second      = buf[(x)+1] << 1;  \
     486             :     delta      &= pal[first++];     \
     487             :     delta      |= pal[first];       \
     488             :     dst[x]      = delta;            \
     489             :     delta      &= pal[second++];    \
     490             :     delta      |= pal[second];      \
     491             :     dst[(x)+1]  = delta
     492             : 
     493             : /**
     494             :  * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
     495             :  *
     496             :  * @param dst the destination 24bpp buffer
     497             :  * @param buf the source 8bpp chunky buffer
     498             :  * @param pal the HAM decode table
     499             :  * @param buf_size the plane size in bytes
     500             :  */
     501           0 : static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
     502             :                                const uint32_t *const pal, unsigned buf_size)
     503             : {
     504           0 :     uint32_t delta = pal[1]; /* first palette entry */
     505             :     do {
     506             :         uint32_t first, second;
     507           0 :         DECODE_HAM_PLANE32(0);
     508           0 :         DECODE_HAM_PLANE32(2);
     509           0 :         DECODE_HAM_PLANE32(4);
     510           0 :         DECODE_HAM_PLANE32(6);
     511           0 :         buf += 8;
     512           0 :         dst += 8;
     513           0 :     } while (--buf_size);
     514           0 : }
     515             : 
     516           0 : static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
     517             :                          const uint32_t *const pal, unsigned width)
     518             : {
     519             :     do {
     520           0 :         *dst++ = pal[*buf++];
     521           0 :     } while (--width);
     522           0 : }
     523             : 
     524             : /**
     525             :  * Decode one complete byterun1 encoded line.
     526             :  *
     527             :  * @param dst the destination buffer where to store decompressed bitstream
     528             :  * @param dst_size the destination plane size in bytes
     529             :  * @param buf the source byterun1 compressed bitstream
     530             :  * @param buf_end the EOF of source byterun1 compressed bitstream
     531             :  * @return number of consumed bytes in byterun1 compressed bitstream
     532             :  */
     533         240 : static int decode_byterun(uint8_t *dst, int dst_size,
     534             :                           GetByteContext *gb)
     535             : {
     536             :     unsigned x;
     537       10605 :     for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
     538             :         unsigned length;
     539       10125 :         const int8_t value = bytestream2_get_byte(gb);
     540       10125 :         if (value >= 0) {
     541        4486 :             length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
     542        4486 :             bytestream2_get_buffer(gb, dst + x, length);
     543        4486 :             if (length < value + 1)
     544           0 :                 bytestream2_skip(gb, value + 1 - length);
     545        5639 :         } else if (value > -128) {
     546        5639 :             length = FFMIN(-value + 1, dst_size - x);
     547        5639 :             memset(dst + x, bytestream2_get_byte(gb), length);
     548             :         } else { // noop
     549           0 :             continue;
     550             :         }
     551       10125 :         x += length;
     552             :     }
     553         240 :     if (x < dst_size) {
     554           0 :         av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
     555           0 :         memset(dst+x, 0, dst_size - x);
     556             :     }
     557         240 :     return bytestream2_tell(gb);
     558             : }
     559             : 
     560           0 : static int decode_byterun2(uint8_t *dst, int height, int line_size,
     561             :                            GetByteContext *gb)
     562             : {
     563             :     GetByteContext cmds;
     564             :     unsigned count;
     565           0 :     int i, y_pos = 0, x_pos = 0;
     566             : 
     567           0 :     if (bytestream2_get_be32(gb) != MKBETAG('V', 'D', 'A', 'T'))
     568           0 :         return 0;
     569             : 
     570           0 :     bytestream2_skip(gb, 4);
     571           0 :     count = bytestream2_get_be16(gb) - 2;
     572           0 :     if (bytestream2_get_bytes_left(gb) < count)
     573           0 :         return 0;
     574             : 
     575           0 :     bytestream2_init(&cmds, gb->buffer, count);
     576           0 :     bytestream2_skip(gb, count);
     577             : 
     578           0 :     for (i = 0; i < count && x_pos < line_size; i++) {
     579           0 :         int8_t cmd = bytestream2_get_byte(&cmds);
     580             :         int l, r;
     581             : 
     582           0 :         if (cmd == 0) {
     583           0 :             l = bytestream2_get_be16(gb);
     584           0 :             while (l-- > 0 && x_pos < line_size) {
     585           0 :                 dst[x_pos + y_pos   * line_size    ] = bytestream2_get_byte(gb);
     586           0 :                 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
     587           0 :                 if (y_pos >= height) {
     588           0 :                     y_pos  = 0;
     589           0 :                     x_pos += 2;
     590             :                 }
     591             :             }
     592           0 :         } else if (cmd < 0) {
     593           0 :             l = -cmd;
     594           0 :             while (l-- > 0 && x_pos < line_size) {
     595           0 :                 dst[x_pos + y_pos   * line_size    ] = bytestream2_get_byte(gb);
     596           0 :                 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
     597           0 :                 if (y_pos >= height) {
     598           0 :                     y_pos  = 0;
     599           0 :                     x_pos += 2;
     600             :                 }
     601             :             }
     602           0 :         } else if (cmd == 1) {
     603           0 :             l = bytestream2_get_be16(gb);
     604           0 :             r = bytestream2_get_be16(gb);
     605           0 :             while (l-- > 0 && x_pos < line_size) {
     606           0 :                 dst[x_pos + y_pos   * line_size    ] = r >> 8;
     607           0 :                 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
     608           0 :                 if (y_pos >= height) {
     609           0 :                     y_pos  = 0;
     610           0 :                     x_pos += 2;
     611             :                 }
     612             :             }
     613             :         } else {
     614           0 :             l = cmd;
     615           0 :             r = bytestream2_get_be16(gb);
     616           0 :             while (l-- > 0 && x_pos < line_size) {
     617           0 :                 dst[x_pos + y_pos   * line_size    ] = r >> 8;
     618           0 :                 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
     619           0 :                 if (y_pos >= height) {
     620           0 :                     y_pos  = 0;
     621           0 :                     x_pos += 2;
     622             :                 }
     623             :             }
     624             :         }
     625             :     }
     626             : 
     627           0 :     return bytestream2_tell(gb);
     628             : }
     629             : 
     630             : #define DECODE_RGBX_COMMON(type) \
     631             :     if (!length) { \
     632             :         length = bytestream2_get_byte(gb); \
     633             :         if (!length) { \
     634             :             length = bytestream2_get_be16(gb); \
     635             :             if (!length) \
     636             :                 return; \
     637             :         } \
     638             :     } \
     639             :     for (i = 0; i < length; i++) { \
     640             :         *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
     641             :         x += 1; \
     642             :         if (x >= width) { \
     643             :             y += 1; \
     644             :             if (y >= height) \
     645             :                 return; \
     646             :             x = 0; \
     647             :         } \
     648             :     }
     649             : 
     650             : /**
     651             :  * Decode RGB8 buffer
     652             :  * @param[out] dst Destination buffer
     653             :  * @param width Width of destination buffer (pixels)
     654             :  * @param height Height of destination buffer (pixels)
     655             :  * @param linesize Line size of destination buffer (bytes)
     656             :  */
     657           0 : static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
     658             : {
     659           0 :     int x = 0, y = 0, i, length;
     660           0 :     while (bytestream2_get_bytes_left(gb) >= 4) {
     661           0 :         uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
     662           0 :         length = bytestream2_get_byte(gb) & 0x7F;
     663           0 :         DECODE_RGBX_COMMON(uint32_t)
     664             :     }
     665             : }
     666             : 
     667             : /**
     668             :  * Decode RGBN buffer
     669             :  * @param[out] dst Destination buffer
     670             :  * @param width Width of destination buffer (pixels)
     671             :  * @param height Height of destination buffer (pixels)
     672             :  * @param linesize Line size of destination buffer (bytes)
     673             :  */
     674           0 : static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
     675             : {
     676           0 :     int x = 0, y = 0, i, length;
     677           0 :     while (bytestream2_get_bytes_left(gb) >= 2) {
     678           0 :         uint32_t pixel = bytestream2_get_be16u(gb);
     679           0 :         length = pixel & 0x7;
     680           0 :         pixel >>= 4;
     681           0 :         DECODE_RGBX_COMMON(uint16_t)
     682             :     }
     683             : }
     684             : 
     685             : /**
     686             :  * Decode DEEP RLE 32-bit buffer
     687             :  * @param[out] dst Destination buffer
     688             :  * @param[in] src Source buffer
     689             :  * @param src_size Source buffer size (bytes)
     690             :  * @param width Width of destination buffer (pixels)
     691             :  * @param height Height of destination buffer (pixels)
     692             :  * @param linesize Line size of destination buffer (bytes)
     693             :  */
     694           0 : static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
     695             : {
     696           0 :     const uint8_t *src_end = src + src_size;
     697           0 :     int x = 0, y = 0, i;
     698           0 :     while (src + 5 <= src_end) {
     699             :         int opcode;
     700           0 :         opcode = *(int8_t *)src++;
     701           0 :         if (opcode >= 0) {
     702           0 :             int size = opcode + 1;
     703           0 :             for (i = 0; i < size; i++) {
     704           0 :                 int length = FFMIN(size - i, width);
     705           0 :                 memcpy(dst + y*linesize + x * 4, src, length * 4);
     706           0 :                 src += length * 4;
     707           0 :                 x += length;
     708           0 :                 i += length;
     709           0 :                 if (x >= width) {
     710           0 :                     x = 0;
     711           0 :                     y += 1;
     712           0 :                     if (y >= height)
     713           0 :                         return;
     714             :                 }
     715             :             }
     716             :         } else {
     717           0 :             int size = -opcode + 1;
     718           0 :             uint32_t pixel = AV_RN32(src);
     719           0 :             for (i = 0; i < size; i++) {
     720           0 :                 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
     721           0 :                 x += 1;
     722           0 :                 if (x >= width) {
     723           0 :                     x = 0;
     724           0 :                     y += 1;
     725           0 :                     if (y >= height)
     726           0 :                         return;
     727             :                 }
     728             :             }
     729           0 :             src += 4;
     730             :         }
     731             :     }
     732             : }
     733             : 
     734             : /**
     735             :  * Decode DEEP TVDC 32-bit buffer
     736             :  * @param[out] dst Destination buffer
     737             :  * @param[in] src Source buffer
     738             :  * @param src_size Source buffer size (bytes)
     739             :  * @param width Width of destination buffer (pixels)
     740             :  * @param height Height of destination buffer (pixels)
     741             :  * @param linesize Line size of destination buffer (bytes)
     742             :  * @param[int] tvdc TVDC lookup table
     743             :  */
     744           0 : static void decode_deep_tvdc32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize, const int16_t *tvdc)
     745             : {
     746           0 :     int x = 0, y = 0, plane = 0;
     747           0 :     int8_t pixel = 0;
     748             :     int i, j;
     749             : 
     750           0 :     for (i = 0; i < src_size * 2;) {
     751             : #define GETNIBBLE ((i & 1) ?  (src[i>>1] & 0xF) : (src[i>>1] >> 4))
     752           0 :         int d = tvdc[GETNIBBLE];
     753           0 :         i++;
     754           0 :         if (d) {
     755           0 :             pixel += d;
     756           0 :             dst[y * linesize + x*4 + plane] = pixel;
     757           0 :             x++;
     758             :         } else {
     759           0 :             if (i >= src_size * 2)
     760           0 :                 return;
     761           0 :             d = GETNIBBLE + 1;
     762           0 :             i++;
     763           0 :             d = FFMIN(d, width - x);
     764           0 :             for (j = 0; j < d; j++) {
     765           0 :                 dst[y * linesize + x*4 + plane] = pixel;
     766           0 :                 x++;
     767             :             }
     768             :         }
     769           0 :         if (x >= width) {
     770           0 :             plane++;
     771           0 :             if (plane >= 4) {
     772           0 :                 y++;
     773           0 :                 if (y >= height)
     774           0 :                     return;
     775           0 :                 plane = 0;
     776             :             }
     777           0 :             x = 0;
     778           0 :             pixel = 0;
     779           0 :             i = (i + 1) & ~1;
     780             :         }
     781             :     }
     782             : }
     783             : 
     784           0 : static void decode_short_horizontal_delta(uint8_t *dst,
     785             :                                           const uint8_t *buf, const uint8_t *buf_end,
     786             :                                           int w, int bpp, int dst_size)
     787             : {
     788           0 :     int planepitch = FFALIGN(w, 16) >> 3;
     789           0 :     int pitch = planepitch * bpp;
     790             :     GetByteContext ptrs, gb;
     791             :     PutByteContext pb;
     792             :     unsigned ofssrc, pos;
     793             :     int i, k;
     794             : 
     795           0 :     bytestream2_init(&ptrs, buf, buf_end - buf);
     796           0 :     bytestream2_init_writer(&pb, dst, dst_size);
     797             : 
     798           0 :     for (k = 0; k < bpp; k++) {
     799           0 :         ofssrc = bytestream2_get_be32(&ptrs);
     800           0 :         pos = 0;
     801             : 
     802           0 :         if (!ofssrc)
     803           0 :             continue;
     804             : 
     805           0 :         if (ofssrc >= buf_end - buf)
     806           0 :             continue;
     807             : 
     808           0 :         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
     809           0 :         while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
     810           0 :             int16_t offset = bytestream2_get_be16(&gb);
     811             :             unsigned noffset;
     812             : 
     813           0 :             if (offset >= 0) {
     814           0 :                 unsigned data = bytestream2_get_be16(&gb);
     815             : 
     816           0 :                 pos += offset * 2;
     817           0 :                 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
     818           0 :                 bytestream2_seek_p(&pb, noffset, SEEK_SET);
     819           0 :                 bytestream2_put_be16(&pb, data);
     820             :             } else {
     821           0 :                 uint16_t count = bytestream2_get_be16(&gb);
     822             : 
     823           0 :                 pos += 2 * -(offset + 2);
     824           0 :                 for (i = 0; i < count; i++) {
     825           0 :                     uint16_t data = bytestream2_get_be16(&gb);
     826             : 
     827           0 :                     pos += 2;
     828           0 :                     noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
     829           0 :                     bytestream2_seek_p(&pb, noffset, SEEK_SET);
     830           0 :                     bytestream2_put_be16(&pb, data);
     831             :                 }
     832             :             }
     833             :         }
     834             :     }
     835           0 : }
     836             : 
     837           0 : static void decode_byte_vertical_delta(uint8_t *dst,
     838             :                                        const uint8_t *buf, const uint8_t *buf_end,
     839             :                                        int w, int xor, int bpp, int dst_size)
     840             : {
     841           0 :     int ncolumns = ((w + 15) / 16) * 2;
     842           0 :     int dstpitch = ncolumns * bpp;
     843             :     unsigned ofsdst, ofssrc, opcode, x;
     844             :     GetByteContext ptrs, gb;
     845             :     PutByteContext pb;
     846             :     int i, j, k;
     847             : 
     848           0 :     bytestream2_init(&ptrs, buf, buf_end - buf);
     849           0 :     bytestream2_init_writer(&pb, dst, dst_size);
     850             : 
     851           0 :     for (k = 0; k < bpp; k++) {
     852           0 :         ofssrc = bytestream2_get_be32(&ptrs);
     853             : 
     854           0 :         if (!ofssrc)
     855           0 :             continue;
     856             : 
     857           0 :         if (ofssrc >= buf_end - buf)
     858           0 :             continue;
     859             : 
     860           0 :         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
     861           0 :         for (j = 0; j < ncolumns; j++) {
     862           0 :             ofsdst = j + k * ncolumns;
     863             : 
     864           0 :             i = bytestream2_get_byte(&gb);
     865           0 :             while (i > 0) {
     866           0 :                 opcode = bytestream2_get_byte(&gb);
     867             : 
     868           0 :                 if (opcode == 0) {
     869           0 :                     opcode  = bytestream2_get_byte(&gb);
     870           0 :                     x = bytestream2_get_byte(&gb);
     871             : 
     872           0 :                     while (opcode) {
     873           0 :                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
     874           0 :                         if (xor && ofsdst < dst_size) {
     875           0 :                             bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
     876             :                         } else {
     877           0 :                             bytestream2_put_byte(&pb, x);
     878             :                         }
     879           0 :                         ofsdst += dstpitch;
     880           0 :                         opcode--;
     881             :                     }
     882           0 :                 } else if (opcode < 0x80) {
     883           0 :                     ofsdst += opcode * dstpitch;
     884             :                 } else {
     885           0 :                     opcode &= 0x7f;
     886             : 
     887           0 :                     while (opcode) {
     888           0 :                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
     889           0 :                         if (xor && ofsdst < dst_size) {
     890           0 :                             bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
     891             :                         } else {
     892           0 :                             bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
     893             :                         }
     894           0 :                         ofsdst += dstpitch;
     895           0 :                         opcode--;
     896             :                     }
     897             :                 }
     898           0 :                 i--;
     899             :             }
     900             :         }
     901             :     }
     902           0 : }
     903             : 
     904           0 : static void decode_delta_j(uint8_t *dst,
     905             :                            const uint8_t *buf, const uint8_t *buf_end,
     906             :                            int w, int h, int bpp, int dst_size)
     907             : {
     908             :     int32_t pitch;
     909             :     uint8_t *ptr;
     910             :     uint32_t type, flag, cols, groups, rows, bytes;
     911             :     uint32_t offset;
     912           0 :     int planepitch_byte = (w + 7) / 8;
     913           0 :     int planepitch = ((w + 15) / 16) * 2;
     914             :     int kludge_j, b, g, r, d;
     915             :     GetByteContext gb;
     916             : 
     917           0 :     pitch = planepitch * bpp;
     918           0 :     kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
     919             : 
     920           0 :     bytestream2_init(&gb, buf, buf_end - buf);
     921             : 
     922           0 :     while (bytestream2_get_bytes_left(&gb) >= 2) {
     923           0 :         type = bytestream2_get_be16(&gb);
     924             : 
     925           0 :         switch (type) {
     926           0 :         case 0:
     927           0 :             return;
     928           0 :         case 1:
     929           0 :             flag   = bytestream2_get_be16(&gb);
     930           0 :             cols   = bytestream2_get_be16(&gb);
     931           0 :             groups = bytestream2_get_be16(&gb);
     932             : 
     933           0 :             for (g = 0; g < groups; g++) {
     934           0 :                 offset = bytestream2_get_be16(&gb);
     935             : 
     936           0 :                 if (cols * bpp == 0 || bytestream2_get_bytes_left(&gb) < cols * bpp) {
     937           0 :                     av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%"PRId32"*%d)", cols, bpp);
     938           0 :                     return;
     939             :                 }
     940             : 
     941           0 :                 if (kludge_j)
     942           0 :                     offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
     943             :                 else
     944           0 :                     offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
     945             : 
     946           0 :                 for (b = 0; b < cols; b++) {
     947           0 :                     for (d = 0; d < bpp; d++) {
     948           0 :                         uint8_t value = bytestream2_get_byte(&gb);
     949             : 
     950           0 :                         if (offset >= dst_size)
     951           0 :                             return;
     952           0 :                         ptr = dst + offset;
     953             : 
     954           0 :                         if (flag)
     955           0 :                             ptr[0] ^= value;
     956             :                         else
     957           0 :                             ptr[0]  = value;
     958             : 
     959           0 :                         offset += planepitch;
     960             :                     }
     961             :                 }
     962           0 :                 if ((cols * bpp) & 1)
     963           0 :                     bytestream2_skip(&gb, 1);
     964             :             }
     965           0 :             break;
     966           0 :         case 2:
     967           0 :             flag   = bytestream2_get_be16(&gb);
     968           0 :             rows   = bytestream2_get_be16(&gb);
     969           0 :             bytes  = bytestream2_get_be16(&gb);
     970           0 :             groups = bytestream2_get_be16(&gb);
     971             : 
     972           0 :             for (g = 0; g < groups; g++) {
     973           0 :                 offset = bytestream2_get_be16(&gb);
     974             : 
     975           0 :                 if (kludge_j)
     976           0 :                     offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
     977             :                 else
     978           0 :                     offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
     979             : 
     980           0 :                 for (r = 0; r < rows; r++) {
     981           0 :                     for (d = 0; d < bpp; d++) {
     982           0 :                         unsigned noffset = offset + (r * pitch) + d * planepitch;
     983             : 
     984           0 :                         if (!bytes || bytestream2_get_bytes_left(&gb) < bytes) {
     985           0 :                             av_log(NULL, AV_LOG_ERROR, "bytes %"PRId32" is invalid", bytes);
     986           0 :                             return;
     987             :                         }
     988             : 
     989           0 :                         for (b = 0; b < bytes; b++) {
     990           0 :                             uint8_t value = bytestream2_get_byte(&gb);
     991             : 
     992           0 :                             if (noffset >= dst_size)
     993           0 :                                 return;
     994           0 :                             ptr = dst + noffset;
     995             : 
     996           0 :                             if (flag)
     997           0 :                                 ptr[0] ^= value;
     998             :                             else
     999           0 :                                 ptr[0]  = value;
    1000             : 
    1001           0 :                             noffset++;
    1002             :                         }
    1003             :                     }
    1004             :                 }
    1005           0 :                 if ((rows * bytes * bpp) & 1)
    1006           0 :                     bytestream2_skip(&gb, 1);
    1007             :             }
    1008           0 :             break;
    1009           0 :         default:
    1010           0 :             return;
    1011             :         }
    1012             :     }
    1013             : }
    1014             : 
    1015           0 : static void decode_short_vertical_delta(uint8_t *dst,
    1016             :                                         const uint8_t *buf, const uint8_t *buf_end,
    1017             :                                         int w, int bpp, int dst_size)
    1018             : {
    1019           0 :     int ncolumns = (w + 15) >> 4;
    1020           0 :     int dstpitch = ncolumns * bpp * 2;
    1021             :     unsigned ofsdst, ofssrc, ofsdata, opcode, x;
    1022             :     GetByteContext ptrs, gb, dptrs, dgb;
    1023             :     PutByteContext pb;
    1024             :     int i, j, k;
    1025             : 
    1026           0 :     if (buf_end - buf <= 64)
    1027           0 :         return;
    1028             : 
    1029           0 :     bytestream2_init(&ptrs, buf, buf_end - buf);
    1030           0 :     bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
    1031           0 :     bytestream2_init_writer(&pb, dst, dst_size);
    1032             : 
    1033           0 :     for (k = 0; k < bpp; k++) {
    1034           0 :         ofssrc = bytestream2_get_be32(&ptrs);
    1035           0 :         ofsdata = bytestream2_get_be32(&dptrs);
    1036             : 
    1037           0 :         if (!ofssrc)
    1038           0 :             continue;
    1039             : 
    1040           0 :         if (ofssrc >= buf_end - buf)
    1041           0 :             return;
    1042             : 
    1043           0 :         if (ofsdata >= buf_end - buf)
    1044           0 :             return;
    1045             : 
    1046           0 :         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
    1047           0 :         bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
    1048           0 :         for (j = 0; j < ncolumns; j++) {
    1049           0 :             ofsdst = (j + k * ncolumns) * 2;
    1050             : 
    1051           0 :             i = bytestream2_get_byte(&gb);
    1052           0 :             while (i > 0) {
    1053           0 :                 opcode = bytestream2_get_byte(&gb);
    1054             : 
    1055           0 :                 if (opcode == 0) {
    1056           0 :                     opcode = bytestream2_get_byte(&gb);
    1057           0 :                     x = bytestream2_get_be16(&dgb);
    1058             : 
    1059           0 :                     while (opcode) {
    1060           0 :                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
    1061           0 :                         bytestream2_put_be16(&pb, x);
    1062           0 :                         ofsdst += dstpitch;
    1063           0 :                         opcode--;
    1064             :                     }
    1065           0 :                 } else if (opcode < 0x80) {
    1066           0 :                     ofsdst += opcode * dstpitch;
    1067             :                 } else {
    1068           0 :                     opcode &= 0x7f;
    1069             : 
    1070           0 :                     while (opcode) {
    1071           0 :                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
    1072           0 :                         bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
    1073           0 :                         ofsdst += dstpitch;
    1074           0 :                         opcode--;
    1075             :                     }
    1076             :                 }
    1077           0 :                 i--;
    1078             :             }
    1079             :         }
    1080             :     }
    1081             : }
    1082             : 
    1083           0 : static void decode_long_vertical_delta(uint8_t *dst,
    1084             :                                        const uint8_t *buf, const uint8_t *buf_end,
    1085             :                                        int w, int bpp, int dst_size)
    1086             : {
    1087           0 :     int ncolumns = (w + 31) >> 5;
    1088           0 :     int dstpitch = ((w + 15) / 16 * 2) * bpp;
    1089             :     unsigned ofsdst, ofssrc, ofsdata, opcode, x;
    1090             :     GetByteContext ptrs, gb, dptrs, dgb;
    1091             :     PutByteContext pb;
    1092             :     int i, j, k, h;
    1093             : 
    1094           0 :     if (buf_end - buf <= 64)
    1095           0 :         return;
    1096             : 
    1097           0 :     h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
    1098           0 :     bytestream2_init(&ptrs, buf, buf_end - buf);
    1099           0 :     bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
    1100           0 :     bytestream2_init_writer(&pb, dst, dst_size);
    1101             : 
    1102           0 :     for (k = 0; k < bpp; k++) {
    1103           0 :         ofssrc = bytestream2_get_be32(&ptrs);
    1104           0 :         ofsdata = bytestream2_get_be32(&dptrs);
    1105             : 
    1106           0 :         if (!ofssrc)
    1107           0 :             continue;
    1108             : 
    1109           0 :         if (ofssrc >= buf_end - buf)
    1110           0 :             return;
    1111             : 
    1112           0 :         if (ofsdata >= buf_end - buf)
    1113           0 :             return;
    1114             : 
    1115           0 :         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
    1116           0 :         bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
    1117           0 :         for (j = 0; j < ncolumns; j++) {
    1118           0 :             ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
    1119             : 
    1120           0 :             i = bytestream2_get_byte(&gb);
    1121           0 :             while (i > 0) {
    1122           0 :                 opcode = bytestream2_get_byte(&gb);
    1123             : 
    1124           0 :                 if (opcode == 0) {
    1125           0 :                     opcode = bytestream2_get_byte(&gb);
    1126           0 :                     if (h && (j == (ncolumns - 1))) {
    1127           0 :                         x = bytestream2_get_be16(&dgb);
    1128           0 :                         bytestream2_skip(&dgb, 2);
    1129             :                     } else {
    1130           0 :                         x = bytestream2_get_be32(&dgb);
    1131             :                     }
    1132             : 
    1133           0 :                     while (opcode) {
    1134           0 :                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
    1135           0 :                         if (h && (j == (ncolumns - 1))) {
    1136           0 :                             bytestream2_put_be16(&pb, x);
    1137             :                         } else {
    1138           0 :                             bytestream2_put_be32(&pb, x);
    1139             :                         }
    1140           0 :                         ofsdst += dstpitch;
    1141           0 :                         opcode--;
    1142             :                     }
    1143           0 :                 } else if (opcode < 0x80) {
    1144           0 :                     ofsdst += opcode * dstpitch;
    1145             :                 } else {
    1146           0 :                     opcode &= 0x7f;
    1147             : 
    1148           0 :                     while (opcode) {
    1149           0 :                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
    1150           0 :                         if (h && (j == (ncolumns - 1))) {
    1151           0 :                             bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
    1152           0 :                             bytestream2_skip(&dgb, 2);
    1153             :                         } else {
    1154           0 :                             bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
    1155             :                         }
    1156           0 :                         ofsdst += dstpitch;
    1157           0 :                         opcode--;
    1158             :                     }
    1159             :                 }
    1160           0 :                 i--;
    1161             :             }
    1162             :         }
    1163             :     }
    1164             : }
    1165             : 
    1166           0 : static void decode_short_vertical_delta2(uint8_t *dst,
    1167             :                                          const uint8_t *buf, const uint8_t *buf_end,
    1168             :                                          int w, int bpp, int dst_size)
    1169             : {
    1170           0 :     int ncolumns = (w + 15) >> 4;
    1171           0 :     int dstpitch = ncolumns * bpp * 2;
    1172             :     unsigned ofsdst, ofssrc, opcode, x;
    1173             :     GetByteContext ptrs, gb;
    1174             :     PutByteContext pb;
    1175             :     int i, j, k;
    1176             : 
    1177           0 :     bytestream2_init(&ptrs, buf, buf_end - buf);
    1178           0 :     bytestream2_init_writer(&pb, dst, dst_size);
    1179             : 
    1180           0 :     for (k = 0; k < bpp; k++) {
    1181           0 :         ofssrc = bytestream2_get_be32(&ptrs);
    1182             : 
    1183           0 :         if (!ofssrc)
    1184           0 :             continue;
    1185             : 
    1186           0 :         if (ofssrc >= buf_end - buf)
    1187           0 :             continue;
    1188             : 
    1189           0 :         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
    1190           0 :         for (j = 0; j < ncolumns; j++) {
    1191           0 :             ofsdst = (j + k * ncolumns) * 2;
    1192             : 
    1193           0 :             i = bytestream2_get_be16(&gb);
    1194           0 :             while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
    1195           0 :                 opcode = bytestream2_get_be16(&gb);
    1196             : 
    1197           0 :                 if (opcode == 0) {
    1198           0 :                     opcode = bytestream2_get_be16(&gb);
    1199           0 :                     x = bytestream2_get_be16(&gb);
    1200             : 
    1201           0 :                     while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
    1202           0 :                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
    1203           0 :                         bytestream2_put_be16(&pb, x);
    1204           0 :                         ofsdst += dstpitch;
    1205           0 :                         opcode--;
    1206             :                     }
    1207           0 :                 } else if (opcode < 0x8000) {
    1208           0 :                     ofsdst += opcode * dstpitch;
    1209             :                 } else {
    1210           0 :                     opcode &= 0x7fff;
    1211             : 
    1212           0 :                     while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
    1213           0 :                            bytestream2_get_bytes_left_p(&pb) > 1) {
    1214           0 :                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
    1215           0 :                         bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
    1216           0 :                         ofsdst += dstpitch;
    1217           0 :                         opcode--;
    1218             :                     }
    1219             :                 }
    1220           0 :                 i--;
    1221             :             }
    1222             :         }
    1223             :     }
    1224           0 : }
    1225             : 
    1226           0 : static void decode_long_vertical_delta2(uint8_t *dst,
    1227             :                                         const uint8_t *buf, const uint8_t *buf_end,
    1228             :                                         int w, int bpp, int dst_size)
    1229             : {
    1230           0 :     int ncolumns = (w + 31) >> 5;
    1231           0 :     int dstpitch = ((w + 15) / 16 * 2) * bpp;
    1232             :     unsigned ofsdst, ofssrc, opcode, x;
    1233           0 :     unsigned skip = 0x80000000, mask = skip - 1;
    1234             :     GetByteContext ptrs, gb;
    1235             :     PutByteContext pb;
    1236             :     int i, j, k, h;
    1237             : 
    1238           0 :     h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
    1239           0 :     bytestream2_init(&ptrs, buf, buf_end - buf);
    1240           0 :     bytestream2_init_writer(&pb, dst, dst_size);
    1241             : 
    1242           0 :     for (k = 0; k < bpp; k++) {
    1243           0 :         ofssrc = bytestream2_get_be32(&ptrs);
    1244             : 
    1245           0 :         if (!ofssrc)
    1246           0 :             continue;
    1247             : 
    1248           0 :         if (ofssrc >= buf_end - buf)
    1249           0 :             continue;
    1250             : 
    1251           0 :         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
    1252           0 :         for (j = 0; j < ncolumns; j++) {
    1253           0 :             ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
    1254             : 
    1255           0 :             if (h && (j == (ncolumns - 1))) {
    1256           0 :                 skip = 0x8000;
    1257           0 :                 mask = skip - 1;
    1258             :             }
    1259             : 
    1260           0 :             i = bytestream2_get_be32(&gb);
    1261           0 :             while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
    1262           0 :                 opcode = bytestream2_get_be32(&gb);
    1263             : 
    1264           0 :                 if (opcode == 0) {
    1265           0 :                     if (h && (j == ncolumns - 1)) {
    1266           0 :                         opcode = bytestream2_get_be16(&gb);
    1267           0 :                         x = bytestream2_get_be16(&gb);
    1268             :                     } else {
    1269           0 :                         opcode = bytestream2_get_be32(&gb);
    1270           0 :                         x = bytestream2_get_be32(&gb);
    1271             :                     }
    1272             : 
    1273           0 :                     while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
    1274           0 :                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
    1275           0 :                         if (h && (j == ncolumns - 1))
    1276           0 :                             bytestream2_put_be16(&pb, x);
    1277             :                         else
    1278           0 :                             bytestream2_put_be32(&pb, x);
    1279           0 :                         ofsdst += dstpitch;
    1280           0 :                         opcode--;
    1281             :                     }
    1282           0 :                 } else if (opcode < skip) {
    1283           0 :                     ofsdst += opcode * dstpitch;
    1284             :                 } else {
    1285           0 :                     opcode &= mask;
    1286             : 
    1287           0 :                     while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
    1288           0 :                            bytestream2_get_bytes_left_p(&pb) > 1) {
    1289           0 :                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
    1290           0 :                         if (h && (j == ncolumns - 1)) {
    1291           0 :                             bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
    1292             :                         } else {
    1293           0 :                             bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
    1294             :                         }
    1295           0 :                         ofsdst += dstpitch;
    1296           0 :                         opcode--;
    1297             :                     }
    1298             :                 }
    1299           0 :                 i--;
    1300             :             }
    1301             :         }
    1302             :     }
    1303           0 : }
    1304             : 
    1305           0 : static void decode_delta_d(uint8_t *dst,
    1306             :                            const uint8_t *buf, const uint8_t *buf_end,
    1307             :                            int w, int flag, int bpp, int dst_size)
    1308             : {
    1309           0 :     int planepitch = FFALIGN(w, 16) >> 3;
    1310           0 :     int pitch = planepitch * bpp;
    1311           0 :     int planepitch_byte = (w + 7) / 8;
    1312             :     unsigned entries, ofssrc;
    1313             :     GetByteContext gb, ptrs;
    1314             :     PutByteContext pb;
    1315             :     int k;
    1316             : 
    1317           0 :     if (buf_end - buf <= 4 * bpp)
    1318           0 :         return;
    1319             : 
    1320           0 :     bytestream2_init_writer(&pb, dst, dst_size);
    1321           0 :     bytestream2_init(&ptrs, buf, bpp * 4);
    1322             : 
    1323           0 :     for (k = 0; k < bpp; k++) {
    1324           0 :         ofssrc = bytestream2_get_be32(&ptrs);
    1325             : 
    1326           0 :         if (!ofssrc)
    1327           0 :             continue;
    1328             : 
    1329           0 :         if (ofssrc >= buf_end - buf)
    1330           0 :             continue;
    1331             : 
    1332           0 :         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
    1333             : 
    1334           0 :         entries = bytestream2_get_be32(&gb);
    1335           0 :         while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
    1336           0 :             int32_t opcode  = bytestream2_get_be32(&gb);
    1337           0 :             unsigned offset = bytestream2_get_be32(&gb);
    1338             : 
    1339           0 :             bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
    1340           0 :             if (opcode >= 0) {
    1341           0 :                 uint32_t x = bytestream2_get_be32(&gb);
    1342           0 :                 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
    1343           0 :                     bytestream2_put_be32(&pb, x);
    1344           0 :                     bytestream2_skip_p(&pb, pitch - 4);
    1345           0 :                     opcode--;
    1346             :                 }
    1347             :             } else {
    1348           0 :                 opcode = -opcode;
    1349           0 :                 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
    1350           0 :                     bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
    1351           0 :                     bytestream2_skip_p(&pb, pitch - 4);
    1352           0 :                     opcode--;
    1353             :                 }
    1354             :             }
    1355           0 :             entries--;
    1356             :         }
    1357             :     }
    1358             : }
    1359             : 
    1360           0 : static void decode_delta_e(uint8_t *dst,
    1361             :                            const uint8_t *buf, const uint8_t *buf_end,
    1362             :                            int w, int flag, int bpp, int dst_size)
    1363             : {
    1364           0 :     int planepitch = FFALIGN(w, 16) >> 3;
    1365           0 :     int pitch = planepitch * bpp;
    1366           0 :     int planepitch_byte = (w + 7) / 8;
    1367             :     unsigned entries, ofssrc;
    1368             :     GetByteContext gb, ptrs;
    1369             :     PutByteContext pb;
    1370             :     int k;
    1371             : 
    1372           0 :     if (buf_end - buf <= 4 * bpp)
    1373           0 :         return;
    1374             : 
    1375           0 :     bytestream2_init_writer(&pb, dst, dst_size);
    1376           0 :     bytestream2_init(&ptrs, buf, bpp * 4);
    1377             : 
    1378           0 :     for (k = 0; k < bpp; k++) {
    1379           0 :         ofssrc = bytestream2_get_be32(&ptrs);
    1380             : 
    1381           0 :         if (!ofssrc)
    1382           0 :             continue;
    1383             : 
    1384           0 :         if (ofssrc >= buf_end - buf)
    1385           0 :             continue;
    1386             : 
    1387           0 :         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
    1388             : 
    1389           0 :         entries = bytestream2_get_be16(&gb);
    1390           0 :         while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
    1391           0 :             int16_t opcode  = bytestream2_get_be16(&gb);
    1392           0 :             unsigned offset = bytestream2_get_be32(&gb);
    1393             : 
    1394           0 :             bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
    1395           0 :             if (opcode >= 0) {
    1396           0 :                 uint16_t x = bytestream2_get_be16(&gb);
    1397           0 :                 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
    1398           0 :                     bytestream2_put_be16(&pb, x);
    1399           0 :                     bytestream2_skip_p(&pb, pitch - 2);
    1400           0 :                     opcode--;
    1401             :                 }
    1402             :             } else {
    1403           0 :                 opcode = -opcode;
    1404           0 :                 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
    1405           0 :                     bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
    1406           0 :                     bytestream2_skip_p(&pb, pitch - 2);
    1407           0 :                     opcode--;
    1408             :                 }
    1409             :             }
    1410           0 :             entries--;
    1411             :         }
    1412             :     }
    1413             : }
    1414             : 
    1415           0 : static void decode_delta_l(uint8_t *dst,
    1416             :                            const uint8_t *buf, const uint8_t *buf_end,
    1417             :                            int w, int flag, int bpp, int dst_size)
    1418             : {
    1419             :     GetByteContext off0, off1, dgb, ogb;
    1420             :     PutByteContext pb;
    1421             :     unsigned poff0, poff1;
    1422             :     int i, k, dstpitch;
    1423           0 :     int planepitch_byte = (w + 7) / 8;
    1424           0 :     int planepitch = ((w + 15) / 16) * 2;
    1425           0 :     int pitch = planepitch * bpp;
    1426             : 
    1427           0 :     if (buf_end - buf <= 64)
    1428           0 :         return;
    1429             : 
    1430           0 :     bytestream2_init(&off0, buf, buf_end - buf);
    1431           0 :     bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
    1432           0 :     bytestream2_init_writer(&pb, dst, dst_size);
    1433             : 
    1434           0 :     dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
    1435             : 
    1436           0 :     for (k = 0; k < bpp; k++) {
    1437           0 :         poff0 = bytestream2_get_be32(&off0);
    1438           0 :         poff1 = bytestream2_get_be32(&off1);
    1439             : 
    1440           0 :         if (!poff0)
    1441           0 :             continue;
    1442             : 
    1443           0 :         if (2LL * poff0 >= buf_end - buf)
    1444           0 :             return;
    1445             : 
    1446           0 :         if (2LL * poff1 >= buf_end - buf)
    1447           0 :             return;
    1448             : 
    1449           0 :         bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
    1450           0 :         bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
    1451             : 
    1452           0 :         while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
    1453           0 :             uint32_t offset = bytestream2_get_be16(&ogb);
    1454           0 :             int16_t cnt = bytestream2_get_be16(&ogb);
    1455             :             uint16_t data;
    1456             : 
    1457           0 :             offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
    1458           0 :             if (cnt < 0) {
    1459           0 :                 if (bytestream2_get_bytes_left(&dgb) < 2)
    1460           0 :                     break;
    1461           0 :                 bytestream2_seek_p(&pb, offset, SEEK_SET);
    1462           0 :                 cnt = -cnt;
    1463           0 :                 data = bytestream2_get_be16(&dgb);
    1464           0 :                 for (i = 0; i < cnt; i++) {
    1465           0 :                     bytestream2_put_be16(&pb, data);
    1466           0 :                     bytestream2_skip_p(&pb, dstpitch - 2);
    1467             :                 }
    1468             :             } else {
    1469           0 :                 if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
    1470           0 :                     break;
    1471           0 :                 bytestream2_seek_p(&pb, offset, SEEK_SET);
    1472           0 :                 for (i = 0; i < cnt; i++) {
    1473           0 :                     data = bytestream2_get_be16(&dgb);
    1474           0 :                     bytestream2_put_be16(&pb, data);
    1475           0 :                     bytestream2_skip_p(&pb, dstpitch - 2);
    1476             :                 }
    1477             :             }
    1478             :         }
    1479             :     }
    1480             : }
    1481             : 
    1482           0 : static int unsupported(AVCodecContext *avctx)
    1483             : {
    1484           0 :     IffContext *s = avctx->priv_data;
    1485           0 :     avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
    1486           0 :     return AVERROR_INVALIDDATA;
    1487             : }
    1488             : 
    1489           2 : static int decode_frame(AVCodecContext *avctx,
    1490             :                         void *data, int *got_frame,
    1491             :                         AVPacket *avpkt)
    1492             : {
    1493           2 :     IffContext *s          = avctx->priv_data;
    1494           2 :     AVFrame *frame         = data;
    1495           2 :     const uint8_t *buf     = avpkt->data;
    1496           2 :     int buf_size           = avpkt->size;
    1497           2 :     const uint8_t *buf_end = buf + buf_size;
    1498             :     int y, plane, res;
    1499           2 :     GetByteContext *gb = &s->gb;
    1500             :     const AVPixFmtDescriptor *desc;
    1501             : 
    1502           2 :     bytestream2_init(gb, avpkt->data, avpkt->size);
    1503             : 
    1504           2 :     if ((res = extract_header(avctx, avpkt)) < 0)
    1505           0 :         return res;
    1506             : 
    1507           2 :     if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
    1508           0 :         return res;
    1509           2 :     s->frame = frame;
    1510             : 
    1511           2 :     buf      += bytestream2_tell(gb);
    1512           2 :     buf_size -= bytestream2_tell(gb);
    1513           2 :     desc = av_pix_fmt_desc_get(avctx->pix_fmt);
    1514             : 
    1515           4 :     if (!s->init && avctx->bits_per_coded_sample <= 8 &&
    1516           2 :         avctx->pix_fmt == AV_PIX_FMT_PAL8) {
    1517           4 :         if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
    1518           0 :             return res;
    1519           0 :     } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
    1520           0 :                avctx->pix_fmt == AV_PIX_FMT_RGB32) {
    1521           0 :         if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
    1522           0 :             return res;
    1523             :     }
    1524           2 :     s->init = 1;
    1525             : 
    1526           2 :     if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
    1527           0 :         if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
    1528           0 :             memcpy(s->pal, s->frame->data[1], 256 * 4);
    1529             :     }
    1530             : 
    1531           2 :     switch (s->compression) {
    1532           1 :     case 0x0:
    1533           1 :         if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
    1534           0 :             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
    1535           0 :                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
    1536           0 :                 for (plane = 0; plane < s->bpp; plane++) {
    1537           0 :                     for (y = 0; y < avctx->height && buf < buf_end; y++) {
    1538           0 :                         uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1539           0 :                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
    1540           0 :                         buf += s->planesize;
    1541             :                     }
    1542             :                 }
    1543           0 :             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
    1544           0 :                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
    1545           0 :                 for (y = 0; y < avctx->height; y++) {
    1546           0 :                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1547           0 :                     memset(s->ham_buf, 0, s->planesize * 8);
    1548           0 :                     for (plane = 0; plane < s->bpp; plane++) {
    1549           0 :                         const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
    1550           0 :                         if (start >= buf_end)
    1551           0 :                             break;
    1552           0 :                         decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
    1553             :                     }
    1554           0 :                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
    1555             :                 }
    1556             :             } else
    1557           0 :                 return unsupported(avctx);
    1558           1 :         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
    1559           0 :             int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
    1560             :             int x;
    1561           0 :             for (y = 0; y < avctx->height && buf < buf_end; y++) {
    1562           0 :                 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1563           0 :                 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
    1564           0 :                 buf += raw_width;
    1565           0 :                 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
    1566           0 :                     for (x = 0; x < avctx->width; x++)
    1567           0 :                         row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
    1568             :                 }
    1569             :             }
    1570           1 :         } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
    1571           0 :                    avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
    1572           1 :             if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
    1573           0 :                 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
    1574           3 :             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
    1575         241 :                 for (y = 0; y < avctx->height; y++) {
    1576         240 :                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1577         240 :                     memset(row, 0, avctx->width);
    1578        2160 :                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
    1579        1920 :                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
    1580        1920 :                         buf += s->planesize;
    1581             :                     }
    1582             :                 }
    1583           0 :             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
    1584           0 :                 for (y = 0; y < avctx->height; y++) {
    1585           0 :                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1586           0 :                     memset(s->ham_buf, 0, s->planesize * 8);
    1587           0 :                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
    1588           0 :                         decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
    1589           0 :                         buf += s->planesize;
    1590             :                     }
    1591           0 :                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
    1592             :                 }
    1593             :             } else { // AV_PIX_FMT_BGR32
    1594           0 :                 for (y = 0; y < avctx->height; y++) {
    1595           0 :                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1596           0 :                     memset(row, 0, avctx->width << 2);
    1597           0 :                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
    1598           0 :                         decodeplane32((uint32_t *)row, buf,
    1599           0 :                                       FFMIN(s->planesize, buf_end - buf), plane);
    1600           0 :                         buf += s->planesize;
    1601             :                     }
    1602             :                 }
    1603             :             }
    1604           0 :         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
    1605           0 :             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
    1606           0 :                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
    1607           0 :                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1608           0 :                     memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
    1609           0 :                     buf += avctx->width + (avctx->width % 2); // padding if odd
    1610             :                 }
    1611           0 :             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
    1612           0 :                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
    1613           0 :                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1614           0 :                     memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
    1615           0 :                     buf += avctx->width + (avctx->width & 1); // padding if odd
    1616           0 :                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
    1617             :                 }
    1618             :             } else
    1619           0 :                 return unsupported(avctx);
    1620             :         } else {
    1621           0 :             return unsupported(avctx);
    1622             :         }
    1623           1 :         break;
    1624           1 :     case 0x1:
    1625           2 :         if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
    1626           1 :             avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
    1627           0 :             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
    1628           0 :                 uint8_t *video = s->video[0];
    1629             : 
    1630           0 :                 for (y = 0; y < avctx->height; y++) {
    1631           0 :                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1632           0 :                     memset(row, 0, avctx->width);
    1633           0 :                     for (plane = 0; plane < s->bpp; plane++) {
    1634           0 :                         buf += decode_byterun(s->planebuf, s->planesize, gb);
    1635           0 :                         if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
    1636           0 :                             memcpy(video, s->planebuf, s->planesize);
    1637           0 :                             video += s->planesize;
    1638             :                         }
    1639           0 :                         decodeplane8(row, s->planebuf, s->planesize, plane);
    1640             :                     }
    1641             :                 }
    1642           0 :             } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
    1643           0 :                 for (y = 0; y < avctx->height; y++) {
    1644           0 :                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1645           0 :                     memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
    1646           0 :                     for (plane = 0; plane < s->bpp; plane++) {
    1647           0 :                         buf += decode_byterun(s->planebuf, s->planesize, gb);
    1648           0 :                         decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
    1649             :                     }
    1650           0 :                     lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
    1651             :                 }
    1652           0 :             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
    1653           0 :                 uint8_t *video = s->video[0];
    1654           0 :                 for (y = 0; y < avctx->height; y++) {
    1655           0 :                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1656           0 :                     memset(s->ham_buf, 0, s->planesize * 8);
    1657           0 :                     for (plane = 0; plane < s->bpp; plane++) {
    1658           0 :                         buf += decode_byterun(s->planebuf, s->planesize, gb);
    1659           0 :                         if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
    1660           0 :                             memcpy(video, s->planebuf, s->planesize);
    1661           0 :                             video += s->planesize;
    1662             :                         }
    1663           0 :                         decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
    1664             :                     }
    1665           0 :                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
    1666             :                 }
    1667             :             } else { // AV_PIX_FMT_BGR32
    1668           0 :                 for (y = 0; y < avctx->height; y++) {
    1669           0 :                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1670           0 :                     memset(row, 0, avctx->width << 2);
    1671           0 :                     for (plane = 0; plane < s->bpp; plane++) {
    1672           0 :                         buf += decode_byterun(s->planebuf, s->planesize, gb);
    1673           0 :                         decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
    1674             :                     }
    1675             :                 }
    1676             :             }
    1677           1 :         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
    1678           2 :             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
    1679         241 :                 for (y = 0; y < avctx->height; y++) {
    1680         240 :                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1681         240 :                     buf += decode_byterun(row, avctx->width, gb);
    1682             :                 }
    1683           0 :             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
    1684           0 :                 for (y = 0; y < avctx->height; y++) {
    1685           0 :                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1686           0 :                     buf += decode_byterun(s->ham_buf, avctx->width, gb);
    1687           0 :                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
    1688             :                 }
    1689             :             } else
    1690           0 :                 return unsupported(avctx);
    1691           0 :         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
    1692           0 :             if (av_get_bits_per_pixel(desc) == 32)
    1693           0 :                 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
    1694             :             else
    1695           0 :                 return unsupported(avctx);
    1696           0 :         } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
    1697           0 :             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
    1698           0 :                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
    1699           0 :                 for (plane = 0; plane < s->bpp; plane++) {
    1700           0 :                     for (y = 0; y < avctx->height && buf < buf_end; y++) {
    1701           0 :                         uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1702           0 :                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
    1703           0 :                         buf += s->planesize;
    1704             :                     }
    1705             :                 }
    1706           0 :             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
    1707           0 :                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
    1708           0 :                 for (y = 0; y < avctx->height; y++) {
    1709           0 :                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1710           0 :                     memset(s->ham_buf, 0, s->planesize * 8);
    1711           0 :                     for (plane = 0; plane < s->bpp; plane++) {
    1712           0 :                         const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
    1713           0 :                         if (start >= buf_end)
    1714           0 :                             break;
    1715           0 :                         decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
    1716             :                     }
    1717           0 :                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
    1718             :                 }
    1719             :             } else {
    1720           0 :                 return unsupported(avctx);
    1721             :             }
    1722             :         } else {
    1723           0 :             return unsupported(avctx);
    1724             :         }
    1725           1 :         break;
    1726           0 :     case 0x2:
    1727           0 :         if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
    1728           0 :             for (plane = 0; plane < s->bpp; plane++) {
    1729           0 :                 decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
    1730           0 :                 for (y = 0; y < avctx->height; y++) {
    1731           0 :                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1732           0 :                     decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
    1733             :                 }
    1734             :             }
    1735             :         } else {
    1736           0 :             return unsupported(avctx);
    1737             :         }
    1738           0 :         break;
    1739           0 :     case 0x4:
    1740           0 :         if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
    1741           0 :             decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
    1742           0 :         else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
    1743           0 :             decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
    1744             :         else
    1745           0 :             return unsupported(avctx);
    1746           0 :         break;
    1747           0 :     case 0x5:
    1748           0 :         if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
    1749           0 :             if (av_get_bits_per_pixel(desc) == 32)
    1750           0 :                 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
    1751             :             else
    1752           0 :                 return unsupported(avctx);
    1753             :         } else
    1754           0 :             return unsupported(avctx);
    1755           0 :         break;
    1756           0 :     case 0x300:
    1757             :     case 0x301:
    1758           0 :         decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
    1759           0 :         break;
    1760           0 :     case 0x500:
    1761             :     case 0x501:
    1762           0 :         decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
    1763           0 :         break;
    1764           0 :     case 0x700:
    1765             :     case 0x701:
    1766           0 :         if (s->is_short)
    1767           0 :             decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
    1768             :         else
    1769           0 :             decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
    1770           0 :         break;
    1771           0 :     case 0x800:
    1772             :     case 0x801:
    1773           0 :         if (s->is_short)
    1774           0 :             decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
    1775             :         else
    1776           0 :             decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
    1777           0 :         break;
    1778           0 :     case 0x4a00:
    1779             :     case 0x4a01:
    1780           0 :         decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
    1781           0 :         break;
    1782           0 :     case 0x6400:
    1783             :     case 0x6401:
    1784           0 :         if (s->is_interlaced)
    1785           0 :             return unsupported(avctx);
    1786           0 :         decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
    1787           0 :         break;
    1788           0 :     case 0x6500:
    1789             :     case 0x6501:
    1790           0 :         if (s->is_interlaced)
    1791           0 :             return unsupported(avctx);
    1792           0 :         decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
    1793           0 :         break;
    1794           0 :     case 0x6c00:
    1795             :     case 0x6c01:
    1796           0 :         decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
    1797           0 :         break;
    1798           0 :     default:
    1799           0 :         return unsupported(avctx);
    1800             :     }
    1801             : 
    1802           2 :     if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
    1803           0 :         memcpy(s->video[1], s->video[0], s->video_size);
    1804             :     }
    1805             : 
    1806           2 :     if (s->compression > 0xff) {
    1807           0 :         if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
    1808           0 :             buf = s->video[0];
    1809           0 :             for (y = 0; y < avctx->height; y++) {
    1810           0 :                 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1811           0 :                 memset(row, 0, avctx->width);
    1812           0 :                 for (plane = 0; plane < s->bpp; plane++) {
    1813           0 :                     decodeplane8(row, buf, s->planesize, plane);
    1814           0 :                     buf += s->planesize;
    1815             :                 }
    1816             :             }
    1817           0 :             memcpy(frame->data[1], s->pal, 256 * 4);
    1818           0 :         } else if (s->ham) {
    1819           0 :             int i, count = 1 << s->ham;
    1820             : 
    1821           0 :             buf = s->video[0];
    1822           0 :             memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
    1823           0 :             for (i = 0; i < count; i++) {
    1824           0 :                 s->ham_palbuf[i*2+1] = s->pal[i];
    1825             :             }
    1826           0 :             for (i = 0; i < count; i++) {
    1827           0 :                 uint32_t tmp = i << (8 - s->ham);
    1828           0 :                 tmp |= tmp >> s->ham;
    1829           0 :                 s->ham_palbuf[(i+count)*2]     = 0xFF00FFFF;
    1830           0 :                 s->ham_palbuf[(i+count*2)*2]   = 0xFFFFFF00;
    1831           0 :                 s->ham_palbuf[(i+count*3)*2]   = 0xFFFF00FF;
    1832           0 :                 s->ham_palbuf[(i+count)*2+1]   = 0xFF000000 | tmp << 16;
    1833           0 :                 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
    1834           0 :                 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
    1835             :             }
    1836           0 :             if (s->masking == MASK_HAS_MASK) {
    1837           0 :                 for (i = 0; i < 8 * (1 << s->ham); i++)
    1838           0 :                     s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
    1839             :             }
    1840           0 :             for (y = 0; y < avctx->height; y++) {
    1841           0 :                 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
    1842           0 :                 memset(s->ham_buf, 0, s->planesize * 8);
    1843           0 :                 for (plane = 0; plane < s->bpp; plane++) {
    1844           0 :                     decodeplane8(s->ham_buf, buf, s->planesize, plane);
    1845           0 :                     buf += s->planesize;
    1846             :                 }
    1847           0 :                 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
    1848             :             }
    1849             :         } else {
    1850           0 :             return unsupported(avctx);
    1851             :         }
    1852             : 
    1853           0 :         if (!s->is_brush) {
    1854           0 :             FFSWAP(uint8_t *, s->video[0], s->video[1]);
    1855             :         }
    1856             :     }
    1857             : 
    1858           2 :     if (avpkt->flags & AV_PKT_FLAG_KEY) {
    1859           2 :         frame->key_frame = 1;
    1860           2 :         frame->pict_type = AV_PICTURE_TYPE_I;
    1861             :     } else {
    1862           0 :         frame->key_frame = 0;
    1863           0 :         frame->pict_type = AV_PICTURE_TYPE_P;
    1864             :     }
    1865             : 
    1866           2 :     *got_frame = 1;
    1867             : 
    1868           2 :     return buf_size;
    1869             : }
    1870             : 
    1871             : #if CONFIG_IFF_ILBM_DECODER
    1872             : AVCodec ff_iff_ilbm_decoder = {
    1873             :     .name           = "iff",
    1874             :     .long_name      = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
    1875             :     .type           = AVMEDIA_TYPE_VIDEO,
    1876             :     .id             = AV_CODEC_ID_IFF_ILBM,
    1877             :     .priv_data_size = sizeof(IffContext),
    1878             :     .init           = decode_init,
    1879             :     .close          = decode_end,
    1880             :     .decode         = decode_frame,
    1881             :     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
    1882             :     .capabilities   = AV_CODEC_CAP_DR1,
    1883             : };
    1884             : #endif

Generated by: LCOV version 1.13