]> git.sesse.net Git - ffmpeg/blob - libavcodec/iff.c
Merge commit 'ffe04c330335add4c6d70ab0bb98e6b3f4f7abfa'
[ffmpeg] / libavcodec / iff.c
1 /*
2  * IFF ACBM/DEEP/ILBM/PBM bitmap decoder
3  * Copyright (c) 2010 Peter Ross <pross@xvid.org>
4  * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 /**
24  * @file
25  * IFF ACBM/DEEP/ILBM/PBM bitmap decoder
26  */
27
28 #include "libavutil/imgutils.h"
29 #include "bytestream.h"
30 #include "avcodec.h"
31 #include "get_bits.h"
32 #include "internal.h"
33
34 // TODO: masking bits
35 typedef enum {
36     MASK_NONE,
37     MASK_HAS_MASK,
38     MASK_HAS_TRANSPARENT_COLOR,
39     MASK_LASSO
40 } mask_type;
41
42 typedef struct {
43     AVFrame *frame;
44     int planesize;
45     uint8_t * planebuf;
46     uint8_t * ham_buf;      ///< temporary buffer for planar to chunky conversation
47     uint32_t *ham_palbuf;   ///< HAM decode table
48     uint32_t *mask_buf;     ///< temporary buffer for palette indices
49     uint32_t *mask_palbuf;  ///< masking palette table
50     unsigned  compression;  ///< delta compression method used
51     unsigned  bpp;          ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
52     unsigned  ham;          ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
53     unsigned  flags;        ///< 1 for EHB, 0 is no extra half darkening
54     unsigned  transparency; ///< TODO: transparency color index in palette
55     unsigned  masking;      ///< TODO: masking method used
56     int init; // 1 if buffer and palette data already initialized, 0 otherwise
57     int16_t   tvdc[16];     ///< TVDC lookup table
58 } IffContext;
59
60 #define LUT8_PART(plane, v)                             \
61     AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane,  \
62     AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane,  \
63     AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane,  \
64     AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane,  \
65     AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane,  \
66     AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane,  \
67     AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane,  \
68     AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane,  \
69     AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane,  \
70     AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane,  \
71     AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane,  \
72     AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane,  \
73     AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane,  \
74     AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane,  \
75     AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane,  \
76     AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
77
78 #define LUT8(plane) {                           \
79     LUT8_PART(plane, 0x0000000),                \
80     LUT8_PART(plane, 0x1000000),                \
81     LUT8_PART(plane, 0x0010000),                \
82     LUT8_PART(plane, 0x1010000),                \
83     LUT8_PART(plane, 0x0000100),                \
84     LUT8_PART(plane, 0x1000100),                \
85     LUT8_PART(plane, 0x0010100),                \
86     LUT8_PART(plane, 0x1010100),                \
87     LUT8_PART(plane, 0x0000001),                \
88     LUT8_PART(plane, 0x1000001),                \
89     LUT8_PART(plane, 0x0010001),                \
90     LUT8_PART(plane, 0x1010001),                \
91     LUT8_PART(plane, 0x0000101),                \
92     LUT8_PART(plane, 0x1000101),                \
93     LUT8_PART(plane, 0x0010101),                \
94     LUT8_PART(plane, 0x1010101),                \
95 }
96
97 // 8 planes * 8-bit mask
98 static const uint64_t plane8_lut[8][256] = {
99     LUT8(0), LUT8(1), LUT8(2), LUT8(3),
100     LUT8(4), LUT8(5), LUT8(6), LUT8(7),
101 };
102
103 #define LUT32(plane) {                                \
104              0,          0,          0,          0,   \
105              0,          0,          0, 1 << plane,   \
106              0,          0, 1 << plane,          0,   \
107              0,          0, 1 << plane, 1 << plane,   \
108              0, 1 << plane,          0,          0,   \
109              0, 1 << plane,          0, 1 << plane,   \
110              0, 1 << plane, 1 << plane,          0,   \
111              0, 1 << plane, 1 << plane, 1 << plane,   \
112     1 << plane,          0,          0,          0,   \
113     1 << plane,          0,          0, 1 << plane,   \
114     1 << plane,          0, 1 << plane,          0,   \
115     1 << plane,          0, 1 << plane, 1 << plane,   \
116     1 << plane, 1 << plane,          0,          0,   \
117     1 << plane, 1 << plane,          0, 1 << plane,   \
118     1 << plane, 1 << plane, 1 << plane,          0,   \
119     1 << plane, 1 << plane, 1 << plane, 1 << plane,   \
120 }
121
122 // 32 planes * 4-bit mask * 4 lookup tables each
123 static const uint32_t plane32_lut[32][16*4] = {
124     LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
125     LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
126     LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
127     LUT32(12), LUT32(13), LUT32(14), LUT32(15),
128     LUT32(16), LUT32(17), LUT32(18), LUT32(19),
129     LUT32(20), LUT32(21), LUT32(22), LUT32(23),
130     LUT32(24), LUT32(25), LUT32(26), LUT32(27),
131     LUT32(28), LUT32(29), LUT32(30), LUT32(31),
132 };
133
134 // Gray to RGB, required for palette table of grayscale images with bpp < 8
135 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
136     return x << 16 | x << 8 | x;
137 }
138
139 /**
140  * Convert CMAP buffer (stored in extradata) to lavc palette format
141  */
142 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
143 {
144     IffContext *s = avctx->priv_data;
145     int count, i;
146     const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
147     int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
148
149     if (avctx->bits_per_coded_sample > 8) {
150         av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
151         return AVERROR_INVALIDDATA;
152     }
153
154     count = 1 << avctx->bits_per_coded_sample;
155     // If extradata is smaller than actually needed, fill the remaining with black.
156     count = FFMIN(palette_size / 3, count);
157     if (count) {
158         for (i = 0; i < count; i++)
159             pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
160         if (s->flags && count >= 32) { // EHB
161             for (i = 0; i < 32; i++)
162                 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
163             count = FFMAX(count, 64);
164         }
165     } else { // Create gray-scale color palette for bps < 8
166         count = 1 << avctx->bits_per_coded_sample;
167
168         for (i = 0; i < count; i++)
169             pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
170     }
171     if (s->masking == MASK_HAS_MASK) {
172         memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
173         for (i = 0; i < count; i++)
174             pal[i] &= 0xFFFFFF;
175     } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
176         s->transparency < 1 << avctx->bits_per_coded_sample)
177         pal[s->transparency] &= 0xFFFFFF;
178     return 0;
179 }
180
181 /**
182  * Extracts the IFF extra context and updates internal
183  * decoder structures.
184  *
185  * @param avctx the AVCodecContext where to extract extra context to
186  * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
187  * @return >= 0 in case of success, a negative error code otherwise
188  */
189 static int extract_header(AVCodecContext *const avctx,
190                           const AVPacket *const avpkt) {
191     const uint8_t *buf;
192     unsigned buf_size;
193     IffContext *s = avctx->priv_data;
194     int i, palette_size;
195
196     if (avctx->extradata_size < 2) {
197         av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
198         return AVERROR_INVALIDDATA;
199     }
200     palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
201
202     if (avpkt) {
203         int image_size;
204         if (avpkt->size < 2)
205             return AVERROR_INVALIDDATA;
206         image_size = avpkt->size - AV_RB16(avpkt->data);
207         buf = avpkt->data;
208         buf_size = bytestream_get_be16(&buf);
209         if (buf_size <= 1 || image_size <= 1) {
210             av_log(avctx, AV_LOG_ERROR,
211                    "Invalid image size received: %u -> image data offset: %d\n",
212                    buf_size, image_size);
213             return AVERROR_INVALIDDATA;
214         }
215     } else {
216         buf = avctx->extradata;
217         buf_size = bytestream_get_be16(&buf);
218         if (buf_size <= 1 || palette_size < 0) {
219             av_log(avctx, AV_LOG_ERROR,
220                    "Invalid palette size received: %u -> palette data offset: %d\n",
221                    buf_size, palette_size);
222             return AVERROR_INVALIDDATA;
223         }
224     }
225
226     if (buf_size >= 41) {
227         s->compression  = bytestream_get_byte(&buf);
228         s->bpp          = bytestream_get_byte(&buf);
229         s->ham          = bytestream_get_byte(&buf);
230         s->flags        = bytestream_get_byte(&buf);
231         s->transparency = bytestream_get_be16(&buf);
232         s->masking      = bytestream_get_byte(&buf);
233         for (i = 0; i < 16; i++)
234             s->tvdc[i] = bytestream_get_be16(&buf);
235
236         if (s->masking == MASK_HAS_MASK) {
237             if (s->bpp >= 8 && !s->ham) {
238                 avctx->pix_fmt = AV_PIX_FMT_RGB32;
239                 av_freep(&s->mask_buf);
240                 av_freep(&s->mask_palbuf);
241                 s->mask_buf = av_malloc((s->planesize * 32) + FF_INPUT_BUFFER_PADDING_SIZE);
242                 if (!s->mask_buf)
243                     return AVERROR(ENOMEM);
244                 if (s->bpp > 16) {
245                     av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
246                     av_freep(&s->mask_buf);
247                     return AVERROR(ENOMEM);
248                 }
249                 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
250                 if (!s->mask_palbuf) {
251                     av_freep(&s->mask_buf);
252                     return AVERROR(ENOMEM);
253                 }
254             }
255             s->bpp++;
256         } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
257             av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
258             return AVERROR_PATCHWELCOME;
259         }
260         if (!s->bpp || s->bpp > 32) {
261             av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
262             return AVERROR_INVALIDDATA;
263         } else if (s->ham >= 8) {
264             av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
265             return AVERROR_INVALIDDATA;
266         }
267
268         av_freep(&s->ham_buf);
269         av_freep(&s->ham_palbuf);
270
271         if (s->ham) {
272             int i, count = FFMIN(palette_size / 3, 1 << s->ham);
273             int ham_count;
274             const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
275
276             s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
277             if (!s->ham_buf)
278                 return AVERROR(ENOMEM);
279
280             ham_count = 8 * (1 << s->ham);
281             s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
282             if (!s->ham_palbuf) {
283                 av_freep(&s->ham_buf);
284                 return AVERROR(ENOMEM);
285             }
286
287             if (count) { // HAM with color palette attached
288                 // prefill with black and palette and set HAM take direct value mask to zero
289                 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
290                 for (i=0; i < count; i++) {
291                     s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
292                 }
293                 count = 1 << s->ham;
294             } else { // HAM with grayscale color palette
295                 count = 1 << s->ham;
296                 for (i=0; i < count; i++) {
297                     s->ham_palbuf[i*2]   = 0xFF000000; // take direct color value from palette
298                     s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
299                 }
300             }
301             for (i=0; i < count; i++) {
302                 uint32_t tmp = i << (8 - s->ham);
303                 tmp |= tmp >> s->ham;
304                 s->ham_palbuf[(i+count)*2]     = 0xFF00FFFF; // just modify blue color component
305                 s->ham_palbuf[(i+count*2)*2]   = 0xFFFFFF00; // just modify red color component
306                 s->ham_palbuf[(i+count*3)*2]   = 0xFFFF00FF; // just modify green color component
307                 s->ham_palbuf[(i+count)*2+1]   = 0xFF000000 | tmp << 16;
308                 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
309                 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
310             }
311             if (s->masking == MASK_HAS_MASK) {
312                 for (i = 0; i < ham_count; i++)
313                     s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
314             }
315         }
316     }
317
318     return 0;
319 }
320
321 static av_cold int decode_end(AVCodecContext *avctx)
322 {
323     IffContext *s = avctx->priv_data;
324     av_frame_free(&s->frame);
325     av_freep(&s->planebuf);
326     av_freep(&s->ham_buf);
327     av_freep(&s->ham_palbuf);
328     return 0;
329 }
330
331 static av_cold int decode_init(AVCodecContext *avctx)
332 {
333     IffContext *s = avctx->priv_data;
334     int err;
335
336     if (avctx->bits_per_coded_sample <= 8) {
337         int palette_size;
338
339         if (avctx->extradata_size >= 2)
340             palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
341         else
342             palette_size = 0;
343         avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
344                          (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
345     } else if (avctx->bits_per_coded_sample <= 32) {
346         if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
347             avctx->pix_fmt = AV_PIX_FMT_RGB32;
348         } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
349             avctx->pix_fmt = AV_PIX_FMT_RGB444;
350         } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
351             if (avctx->bits_per_coded_sample == 24) {
352                 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
353             } else if (avctx->bits_per_coded_sample == 32) {
354                 avctx->pix_fmt = AV_PIX_FMT_BGR32;
355             } else {
356                 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
357                 return AVERROR_PATCHWELCOME;
358             }
359         }
360     } else {
361         return AVERROR_INVALIDDATA;
362     }
363
364     if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
365         return err;
366     s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
367     s->planebuf  = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
368     if (!s->planebuf)
369         return AVERROR(ENOMEM);
370
371     s->bpp = avctx->bits_per_coded_sample;
372     s->frame = av_frame_alloc();
373     if (!s->frame) {
374         decode_end(avctx);
375         return AVERROR(ENOMEM);
376     }
377
378     if ((err = extract_header(avctx, NULL)) < 0)
379         return err;
380
381     return 0;
382 }
383
384 /**
385  * Decode interleaved plane buffer up to 8bpp
386  * @param dst Destination buffer
387  * @param buf Source buffer
388  * @param buf_size
389  * @param plane plane number to decode as
390  */
391 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
392 {
393     const uint64_t *lut = plane8_lut[plane];
394     if (plane >= 8) {
395         av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
396         return;
397     }
398     do {
399         uint64_t v = AV_RN64A(dst) | lut[*buf++];
400         AV_WN64A(dst, v);
401         dst += 8;
402     } while (--buf_size);
403 }
404
405 /**
406  * Decode interleaved plane buffer up to 24bpp
407  * @param dst Destination buffer
408  * @param buf Source buffer
409  * @param buf_size
410  * @param plane plane number to decode as
411  */
412 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
413 {
414     const uint32_t *lut = plane32_lut[plane];
415     do {
416         unsigned mask = (*buf >> 2) & ~3;
417         dst[0] |= lut[mask++];
418         dst[1] |= lut[mask++];
419         dst[2] |= lut[mask++];
420         dst[3] |= lut[mask];
421         mask    = (*buf++ << 2) & 0x3F;
422         dst[4] |= lut[mask++];
423         dst[5] |= lut[mask++];
424         dst[6] |= lut[mask++];
425         dst[7] |= lut[mask];
426         dst    += 8;
427     } while (--buf_size);
428 }
429
430 #define DECODE_HAM_PLANE32(x)       \
431     first       = buf[x] << 1;      \
432     second      = buf[(x)+1] << 1;  \
433     delta      &= pal[first++];     \
434     delta      |= pal[first];       \
435     dst[x]      = delta;            \
436     delta      &= pal[second++];    \
437     delta      |= pal[second];      \
438     dst[(x)+1]  = delta
439
440 /**
441  * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
442  *
443  * @param dst the destination 24bpp buffer
444  * @param buf the source 8bpp chunky buffer
445  * @param pal the HAM decode table
446  * @param buf_size the plane size in bytes
447  */
448 static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
449                                const uint32_t *const pal, unsigned buf_size)
450 {
451     uint32_t delta = pal[1]; /* first palette entry */
452     do {
453         uint32_t first, second;
454         DECODE_HAM_PLANE32(0);
455         DECODE_HAM_PLANE32(2);
456         DECODE_HAM_PLANE32(4);
457         DECODE_HAM_PLANE32(6);
458         buf += 8;
459         dst += 8;
460     } while (--buf_size);
461 }
462
463 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
464                          const uint32_t *const pal, unsigned width)
465 {
466     do {
467         *dst++ = pal[*buf++];
468     } while (--width);
469 }
470
471 /**
472  * Decode one complete byterun1 encoded line.
473  *
474  * @param dst the destination buffer where to store decompressed bitstream
475  * @param dst_size the destination plane size in bytes
476  * @param buf the source byterun1 compressed bitstream
477  * @param buf_end the EOF of source byterun1 compressed bitstream
478  * @return number of consumed bytes in byterun1 compressed bitstream
479  */
480 static int decode_byterun(uint8_t *dst, int dst_size,
481                           const uint8_t *buf, const uint8_t *const buf_end)
482 {
483     const uint8_t *const buf_start = buf;
484     unsigned x;
485     for (x = 0; x < dst_size && buf < buf_end;) {
486         unsigned length;
487         const int8_t value = *buf++;
488         if (value >= 0) {
489             length = value + 1;
490             memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
491             buf += length;
492         } else if (value > -128) {
493             length = -value + 1;
494             memset(dst + x, *buf++, FFMIN(length, dst_size - x));
495         } else { // noop
496             continue;
497         }
498         x += length;
499     }
500     return buf - buf_start;
501 }
502
503 #define DECODE_RGBX_COMMON(type) \
504     if (!length) { \
505         length = bytestream2_get_byte(gb); \
506         if (!length) { \
507             length = bytestream2_get_be16(gb); \
508             if (!length) \
509                 return; \
510         } \
511     } \
512     for (i = 0; i < length; i++) { \
513         *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
514         x += 1; \
515         if (x >= width) { \
516             y += 1; \
517             if (y >= height) \
518                 return; \
519             x = 0; \
520         } \
521     }
522
523 /**
524  * Decode RGB8 buffer
525  * @param[out] dst Destination buffer
526  * @param width Width of destination buffer (pixels)
527  * @param height Height of destination buffer (pixels)
528  * @param linesize Line size of destination buffer (bytes)
529  */
530 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
531 {
532     int x = 0, y = 0, i, length;
533     while (bytestream2_get_bytes_left(gb) >= 4) {
534         uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
535         length = bytestream2_get_byte(gb) & 0x7F;
536         DECODE_RGBX_COMMON(uint32_t)
537     }
538 }
539
540 /**
541  * Decode RGBN buffer
542  * @param[out] dst Destination buffer
543  * @param width Width of destination buffer (pixels)
544  * @param height Height of destination buffer (pixels)
545  * @param linesize Line size of destination buffer (bytes)
546  */
547 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
548 {
549     int x = 0, y = 0, i, length;
550     while (bytestream2_get_bytes_left(gb) >= 2) {
551         uint32_t pixel = bytestream2_get_be16u(gb);
552         length = pixel & 0x7;
553         pixel >>= 4;
554         DECODE_RGBX_COMMON(uint16_t)
555     }
556 }
557
558 /**
559  * Decode DEEP RLE 32-bit buffer
560  * @param[out] dst Destination buffer
561  * @param[in] src Source buffer
562  * @param src_size Source buffer size (bytes)
563  * @param width Width of destination buffer (pixels)
564  * @param height Height of destination buffer (pixels)
565  * @param linesize Line size of destination buffer (bytes)
566  */
567 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
568 {
569     const uint8_t *src_end = src + src_size;
570     int x = 0, y = 0, i;
571     while (src + 5 <= src_end) {
572         int opcode;
573         opcode = *(int8_t *)src++;
574         if (opcode >= 0) {
575             int size = opcode + 1;
576             for (i = 0; i < size; i++) {
577                 int length = FFMIN(size - i, width);
578                 memcpy(dst + y*linesize + x * 4, src, length * 4);
579                 src += length * 4;
580                 x += length;
581                 i += length;
582                 if (x >= width) {
583                     x = 0;
584                     y += 1;
585                     if (y >= height)
586                         return;
587                 }
588             }
589         } else {
590             int size = -opcode + 1;
591             uint32_t pixel = AV_RN32(src);
592             for (i = 0; i < size; i++) {
593                 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
594                 x += 1;
595                 if (x >= width) {
596                     x = 0;
597                     y += 1;
598                     if (y >= height)
599                         return;
600                 }
601             }
602             src += 4;
603         }
604     }
605 }
606
607 /**
608  * Decode DEEP TVDC 32-bit buffer
609  * @param[out] dst Destination buffer
610  * @param[in] src Source buffer
611  * @param src_size Source buffer size (bytes)
612  * @param width Width of destination buffer (pixels)
613  * @param height Height of destination buffer (pixels)
614  * @param linesize Line size of destination buffer (bytes)
615  * @param[int] tvdc TVDC lookup table
616  */
617 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)
618 {
619     int x = 0, y = 0, plane = 0;
620     int8_t pixel = 0;
621     int i, j;
622
623     for (i = 0; i < src_size * 2;) {
624 #define GETNIBBLE ((i & 1) ?  (src[i>>1] & 0xF) : (src[i>>1] >> 4))
625         int d = tvdc[GETNIBBLE];
626         i++;
627         if (d) {
628             pixel += d;
629             dst[y * linesize + x*4 + plane] = pixel;
630             x++;
631         } else {
632             if (i >= src_size * 2)
633                 return;
634             d = GETNIBBLE + 1;
635             i++;
636             d = FFMIN(d, width - x);
637             for (j = 0; j < d; j++) {
638                 dst[y * linesize + x*4 + plane] = pixel;
639                 x++;
640             }
641         }
642         if (x >= width) {
643             plane++;
644             if (plane >= 4) {
645                 y++;
646                 if (y >= height)
647                     return;
648                 plane = 0;
649             }
650             x = 0;
651             pixel = 0;
652             i = (i + 1) & ~1;
653         }
654     }
655 }
656
657 static int unsupported(AVCodecContext *avctx)
658 {
659     IffContext *s = avctx->priv_data;
660     avpriv_request_sample(avctx, "bitmap (compression %i, bpp %i, ham %i)", s->compression, s->bpp, s->ham);
661     return AVERROR_INVALIDDATA;
662 }
663
664 static int decode_frame(AVCodecContext *avctx,
665                         void *data, int *got_frame,
666                         AVPacket *avpkt)
667 {
668     IffContext *s          = avctx->priv_data;
669     const uint8_t *buf     = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
670     const int buf_size     = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
671     const uint8_t *buf_end = buf + buf_size;
672     int y, plane, res;
673     GetByteContext gb;
674
675     if ((res = extract_header(avctx, avpkt)) < 0)
676         return res;
677     if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
678         return res;
679     if (!s->init && avctx->bits_per_coded_sample <= 8 &&
680         avctx->pix_fmt == AV_PIX_FMT_PAL8) {
681         if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame->data[1])) < 0)
682             return res;
683     } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
684                avctx->pix_fmt == AV_PIX_FMT_RGB32) {
685         if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
686             return res;
687     }
688     s->init = 1;
689
690     switch (s->compression) {
691     case 0:
692         if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
693             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
694                 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
695                 for (plane = 0; plane < s->bpp; plane++) {
696                     for (y = 0; y < avctx->height && buf < buf_end; y++) {
697                         uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
698                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
699                         buf += s->planesize;
700                     }
701                 }
702             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
703                 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
704                 for (y = 0; y < avctx->height; y++) {
705                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
706                     memset(s->ham_buf, 0, s->planesize * 8);
707                     for (plane = 0; plane < s->bpp; plane++) {
708                         const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
709                         if (start >= buf_end)
710                             break;
711                         decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
712                     }
713                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
714                 }
715             } else
716                 return unsupported(avctx);
717         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
718             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
719             int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
720             int x;
721             for (y = 0; y < avctx->height && buf < buf_end; y++) {
722                 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
723                 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
724                 buf += raw_width;
725                 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
726                     for (x = 0; x < avctx->width; x++)
727                         row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
728                 }
729             }
730         } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
731             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
732                 for (y = 0; y < avctx->height; y++) {
733                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
734                     memset(row, 0, avctx->width);
735                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
736                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
737                         buf += s->planesize;
738                     }
739                 }
740             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
741                 for (y = 0; y < avctx->height; y++) {
742                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
743                     memset(s->ham_buf, 0, s->planesize * 8);
744                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
745                         decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
746                         buf += s->planesize;
747                     }
748                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
749                 }
750             } else { // AV_PIX_FMT_BGR32
751                 for (y = 0; y < avctx->height; y++) {
752                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
753                     memset(row, 0, avctx->width << 2);
754                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
755                         decodeplane32((uint32_t *)row, buf,
756                                       FFMIN(s->planesize, buf_end - buf), plane);
757                         buf += s->planesize;
758                     }
759                 }
760             }
761         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
762             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
763                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
764                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
765                     memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
766                     buf += avctx->width + (avctx->width % 2); // padding if odd
767                 }
768             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
769                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
770                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
771                     memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
772                     buf += avctx->width + (avctx->width & 1); // padding if odd
773                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
774                 }
775             } else
776                 return unsupported(avctx);
777         }
778         break;
779     case 1:
780         if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
781             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
782                 for (y = 0; y < avctx->height; y++) {
783                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
784                     memset(row, 0, avctx->width);
785                     for (plane = 0; plane < s->bpp; plane++) {
786                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
787                         decodeplane8(row, s->planebuf, s->planesize, plane);
788                     }
789                 }
790             } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
791                 for (y = 0; y < avctx->height; y++) {
792                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
793                     memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
794                     for (plane = 0; plane < s->bpp; plane++) {
795                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
796                         decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
797                     }
798                     lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
799                 }
800             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
801                 for (y = 0; y < avctx->height; y++) {
802                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
803                     memset(s->ham_buf, 0, s->planesize * 8);
804                     for (plane = 0; plane < s->bpp; plane++) {
805                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
806                         decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
807                     }
808                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
809                 }
810             } else { // AV_PIX_FMT_BGR32
811                 for (y = 0; y < avctx->height; y++) {
812                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
813                     memset(row, 0, avctx->width << 2);
814                     for (plane = 0; plane < s->bpp; plane++) {
815                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
816                         decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
817                     }
818                 }
819             }
820         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
821             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
822                 for (y = 0; y < avctx->height; y++) {
823                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
824                     buf += decode_byterun(row, avctx->width, buf, buf_end);
825                 }
826             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
827                 for (y = 0; y < avctx->height; y++) {
828                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
829                     buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
830                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
831                 }
832             } else
833                 return unsupported(avctx);
834         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
835             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
836             if (av_get_bits_per_pixel(desc) == 32)
837                 decode_deep_rle32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0]);
838             else
839                 return unsupported(avctx);
840         }
841         break;
842     case 4:
843         bytestream2_init(&gb, buf, buf_size);
844         if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8'))
845             decode_rgb8(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
846         else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N'))
847             decode_rgbn(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
848         else
849             return unsupported(avctx);
850         break;
851     case 5:
852         if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
853             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
854             if (av_get_bits_per_pixel(desc) == 32)
855                 decode_deep_tvdc32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0], s->tvdc);
856             else
857                 return unsupported(avctx);
858         } else
859             return unsupported(avctx);
860         break;
861     default:
862         return unsupported(avctx);
863     }
864
865     if ((res = av_frame_ref(data, s->frame)) < 0)
866         return res;
867
868     *got_frame = 1;
869
870     return buf_size;
871 }
872
873 #if CONFIG_IFF_ILBM_DECODER
874 AVCodec ff_iff_ilbm_decoder = {
875     .name           = "iff",
876     .long_name      = NULL_IF_CONFIG_SMALL("IFF"),
877     .type           = AVMEDIA_TYPE_VIDEO,
878     .id             = AV_CODEC_ID_IFF_ILBM,
879     .priv_data_size = sizeof(IffContext),
880     .init           = decode_init,
881     .close          = decode_end,
882     .decode         = decode_frame,
883     .capabilities   = CODEC_CAP_DR1,
884 };
885 #endif
886 #if CONFIG_IFF_BYTERUN1_DECODER
887 AVCodec ff_iff_byterun1_decoder = {
888     .name           = "iff",
889     .long_name      = NULL_IF_CONFIG_SMALL("IFF"),
890     .type           = AVMEDIA_TYPE_VIDEO,
891     .id             = AV_CODEC_ID_IFF_BYTERUN1,
892     .priv_data_size = sizeof(IffContext),
893     .init           = decode_init,
894     .close          = decode_end,
895     .decode         = decode_frame,
896     .capabilities   = CODEC_CAP_DR1,
897 };
898 #endif