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 <stdint.h>
29
35
36 // TODO: masking bits
43
50 uint32_t *
mask_buf;
///< temporary buffer for palette indices
53 unsigned bpp;
///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
54 unsigned ham;
///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
55 unsigned flags;
///< 1 for EHB, 0 is no extra half darkening
56 unsigned transparency;
///< TODO: transparency color index in palette
57 unsigned masking;
///< TODO: masking method used
58 int init;
// 1 if buffer and palette data already initialized, 0 otherwise
59 int16_t
tvdc[16];
///< TVDC lookup table
61
62 #define LUT8_PART(plane, v) \
63 AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
64 AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
65 AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
66 AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
67 AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
68 AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
69 AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
70 AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
71 AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
72 AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
73 AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
74 AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
75 AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
76 AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
77 AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
78 AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
79
80 #define LUT8(plane) { \
81 LUT8_PART(plane, 0x0000000), \
82 LUT8_PART(plane, 0x1000000), \
83 LUT8_PART(plane, 0x0010000), \
84 LUT8_PART(plane, 0x1010000), \
85 LUT8_PART(plane, 0x0000100), \
86 LUT8_PART(plane, 0x1000100), \
87 LUT8_PART(plane, 0x0010100), \
88 LUT8_PART(plane, 0x1010100), \
89 LUT8_PART(plane, 0x0000001), \
90 LUT8_PART(plane, 0x1000001), \
91 LUT8_PART(plane, 0x0010001), \
92 LUT8_PART(plane, 0x1010001), \
93 LUT8_PART(plane, 0x0000101), \
94 LUT8_PART(plane, 0x1000101), \
95 LUT8_PART(plane, 0x0010101), \
96 LUT8_PART(plane, 0x1010101), \
97 }
98
99 // 8 planes * 8-bit mask
103 };
104
105 #define LUT32(plane) { \
106 0, 0, 0, 0, \
107 0, 0, 0, 1 << plane, \
108 0, 0, 1 << plane, 0, \
109 0, 0, 1 << plane, 1 << plane, \
110 0, 1 << plane, 0, 0, \
111 0, 1 << plane, 0, 1 << plane, \
112 0, 1 << plane, 1 << plane, 0, \
113 0, 1 << plane, 1 << plane, 1 << plane, \
114 1 << plane, 0, 0, 0, \
115 1 << plane, 0, 0, 1 << plane, \
116 1 << plane, 0, 1 << plane, 0, \
117 1 << plane, 0, 1 << plane, 1 << plane, \
118 1 << plane, 1 << plane, 0, 0, \
119 1 << plane, 1 << plane, 0, 1 << plane, \
120 1 << plane, 1 << plane, 1 << plane, 0, \
121 1 << plane, 1 << plane, 1 << plane, 1 << plane, \
122 }
123
124 // 32 planes * 4-bit mask * 4 lookup tables each
134 };
135
136 // Gray to RGB, required for palette table of grayscale images with bpp < 8
138 return x << 16 | x << 8 | x;
139 }
140
141 /**
142 * Convert CMAP buffer (stored in extradata) to lavc palette format
143 */
145 {
150
154 }
155
157 // If extradata is smaller than actually needed, fill the remaining with black.
158 count =
FFMIN(palette_size / 3, count);
159 if (count) {
160 for (i = 0; i <
count; i++)
161 pal[i] = 0xFF000000 |
AV_RB24(palette + i*3);
162 if (s->
flags && count >= 32) {
// EHB
163 for (i = 0; i < 32; i++)
164 pal[i + 32] = 0xFF000000 | (
AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
165 count =
FFMAX(count, 64);
166 }
167 } else { // Create gray-scale color palette for bps < 8
169
170 for (i = 0; i <
count; i++)
172 }
175 for (i = 0; i <
count; i++)
176 pal[i] &= 0xFFFFFF;
180 return 0;
181 }
182
183 /**
184 * Extracts the IFF extra context and updates internal
185 * decoder structures.
186 *
187 * @param avctx the AVCodecContext where to extract extra context to
188 * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
189 * @return >= 0 in case of success, a negative error code otherwise
190 */
194 unsigned buf_size;
196 int i, palette_size;
197
201 }
203
204 if (avpkt) {
205 int image_size;
210 buf_size = bytestream_get_be16(&buf);
211 if (buf_size <= 1 || image_size <= 1) {
213 "Invalid image size received: %u -> image data offset: %d\n",
214 buf_size, image_size);
216 }
217 } else {
219 buf_size = bytestream_get_be16(&buf);
220 if (buf_size <= 1 || palette_size < 0) {
222 "Invalid palette size received: %u -> palette data offset: %d\n",
223 buf_size, palette_size);
225 }
226 }
227
228 if (buf_size >= 41) {
230 s->
bpp = bytestream_get_byte(&buf);
231 s->
ham = bytestream_get_byte(&buf);
232 s->
flags = bytestream_get_byte(&buf);
234 s->
masking = bytestream_get_byte(&buf);
235 for (i = 0; i < 16; i++)
236 s->
tvdc[i] = bytestream_get_be16(&buf);
237
239 if (s->
bpp >= 8 && !s->
ham) {
250 }
255 }
256 }
261 }
262 if (!s->
bpp || s->
bpp > 32) {
265 }
else if (s->
ham >= 8) {
268 }
269
272
275 int ham_count;
277
281
282 ham_count = 8 * (1 << s->
ham);
287 }
288
289 if (count) { // HAM with color palette attached
290 // prefill with black and palette and set HAM take direct value mask to zero
291 memset(s->
ham_palbuf, 0, (1 << s->
ham) * 2 * sizeof (uint32_t));
292 for (i=0; i <
count; i++) {
294 }
296 } else { // HAM with grayscale color palette
298 for (i=0; i <
count; i++) {
299 s->
ham_palbuf[i*2] = 0xFF000000;
// take direct color value from palette
301 }
302 }
303 for (i=0; i <
count; i++) {
304 uint32_t tmp = i << (8 - s->
ham);
305 tmp |= tmp >> s->
ham;
306 s->
ham_palbuf[(i+
count)*2] = 0xFF00FFFF;
// just modify blue color component
307 s->
ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
// just modify red color component
308 s->
ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
// just modify green color component
310 s->
ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
311 s->
ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
312 }
314 for (i = 0; i < ham_count; i++)
316 }
317 }
318 }
319
320 return 0;
321 }
322
324 {
330 return 0;
331 }
332
334 {
336 int err;
337
339 int palette_size;
340
343 else
344 palette_size = 0;
357 } else {
360 }
361 }
362 } else {
364 }
365
367 return err;
372
378 }
379
381 return err;
382
383 return 0;
384 }
385
386 /**
387 * Decode interleaved plane buffer up to 8bpp
388 * @param dst Destination buffer
389 * @param buf Source buffer
390 * @param buf_size
391 * @param plane plane number to decode as
392 */
394 {
396 if (plane >= 8) {
398 return;
399 }
400 do {
401 uint64_t
v =
AV_RN64A(dst) | lut[*buf++];
403 dst += 8;
404 } while (--buf_size);
405 }
406
407 /**
408 * Decode interleaved plane buffer up to 24bpp
409 * @param dst Destination buffer
410 * @param buf Source buffer
411 * @param buf_size
412 * @param plane plane number to decode as
413 */
415 {
417 do {
418 unsigned mask = (*buf >> 2) & ~3;
419 dst[0] |= lut[mask++];
420 dst[1] |= lut[mask++];
421 dst[2] |= lut[mask++];
423 mask = (*buf++ << 2) & 0x3F;
424 dst[4] |= lut[mask++];
425 dst[5] |= lut[mask++];
426 dst[6] |= lut[mask++];
428 dst += 8;
429 } while (--buf_size);
430 }
431
432 #define DECODE_HAM_PLANE32(x) \
433 first = buf[x] << 1; \
434 second = buf[(x)+1] << 1; \
435 delta &= pal[first++]; \
436 delta |= pal[first]; \
437 dst[x] = delta; \
438 delta &= pal[second++]; \
439 delta |= pal[second]; \
440 dst[(x)+1] = delta
441
442 /**
443 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
444 *
445 * @param dst the destination 24bpp buffer
446 * @param buf the source 8bpp chunky buffer
447 * @param pal the HAM decode table
448 * @param buf_size the plane size in bytes
449 */
451 const uint32_t *const pal, unsigned buf_size)
452 {
453 uint32_t
delta = pal[1];
/* first palette entry */
454 do {
455 uint32_t first, second;
460 buf += 8;
461 dst += 8;
462 } while (--buf_size);
463 }
464
466 const uint32_t *
const pal,
unsigned width)
467 {
468 do {
469 *dst++ = pal[*buf++];
470 } while (--width);
471 }
472
473 /**
474 * Decode one complete byterun1 encoded line.
475 *
476 * @param dst the destination buffer where to store decompressed bitstream
477 * @param dst_size the destination plane size in bytes
478 * @param buf the source byterun1 compressed bitstream
479 * @param buf_end the EOF of source byterun1 compressed bitstream
480 * @return number of consumed bytes in byterun1 compressed bitstream
481 */
484 {
486 unsigned x;
487 for (x = 0; x < dst_size && buf < buf_end;) {
489 const int8_t
value = *buf++;
490 if (value >= 0) {
491 length =
FFMIN3(value + 1, dst_size - x, buf_end - buf);
492 memcpy(dst + x, buf, length);
494 } else if (value > -128) {
495 length =
FFMIN(-value + 1, dst_size - x);
496 memset(dst + x, *buf++, length);
497 } else { // noop
498 continue;
499 }
501 }
502 if (x < dst_size) {
504 memset(dst+x, 0, dst_size - x);
505 }
506 return buf - buf_start;
507 }
508
509 #define DECODE_RGBX_COMMON(type) \
510 if (!length) { \
511 length = bytestream2_get_byte(gb); \
512 if (!length) { \
513 length = bytestream2_get_be16(gb); \
514 if (!length) \
515 return; \
516 } \
517 } \
518 for (i = 0; i < length; i++) { \
519 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
520 x += 1; \
521 if (x >= width) { \
522 y += 1; \
523 if (y >= height) \
524 return; \
525 x = 0; \
526 } \
527 }
528
529 /**
530 * Decode RGB8 buffer
531 * @param[out] dst Destination buffer
532 * @param width Width of destination buffer (pixels)
533 * @param height Height of destination buffer (pixels)
534 * @param linesize Line size of destination buffer (bytes)
535 */
537 {
540 uint32_t
pixel = 0xFF000000 | bytestream2_get_be24(gb);
541 length = bytestream2_get_byte(gb) & 0x7F;
543 }
544 }
545
546 /**
547 * Decode RGBN buffer
548 * @param[out] dst Destination buffer
549 * @param width Width of destination buffer (pixels)
550 * @param height Height of destination buffer (pixels)
551 * @param linesize Line size of destination buffer (bytes)
552 */
554 {
557 uint32_t
pixel = bytestream2_get_be16u(gb);
558 length = pixel & 0x7;
559 pixel >>= 4;
561 }
562 }
563
564 /**
565 * Decode DEEP RLE 32-bit buffer
566 * @param[out] dst Destination buffer
567 * @param[in] src Source buffer
568 * @param src_size Source buffer size (bytes)
569 * @param width Width of destination buffer (pixels)
570 * @param height Height of destination buffer (pixels)
571 * @param linesize Line size of destination buffer (bytes)
572 */
574 {
575 const uint8_t *src_end = src + src_size;
577 while (src + 5 <= src_end) {
578 int opcode;
579 opcode = *(int8_t *)src++;
580 if (opcode >= 0) {
581 int size = opcode + 1;
582 for (i = 0; i <
size; i++) {
584 memcpy(dst +
y*linesize + x * 4, src, length * 4);
585 src += length * 4;
588 if (x >= width) {
589 x = 0;
592 return;
593 }
594 }
595 } else {
596 int size = -opcode + 1;
598 for (i = 0; i <
size; i++) {
599 *(uint32_t *)(dst +
y*linesize + x * 4) =
pixel;
600 x += 1;
601 if (x >= width) {
602 x = 0;
605 return;
606 }
607 }
608 src += 4;
609 }
610 }
611 }
612
613 /**
614 * Decode DEEP TVDC 32-bit buffer
615 * @param[out] dst Destination buffer
616 * @param[in] src Source buffer
617 * @param src_size Source buffer size (bytes)
618 * @param width Width of destination buffer (pixels)
619 * @param height Height of destination buffer (pixels)
620 * @param linesize Line size of destination buffer (bytes)
621 * @param[int] tvdc TVDC lookup table
622 */
624 {
625 int x = 0,
y = 0, plane = 0;
627 int i, j;
628
629 for (i = 0; i < src_size * 2;) {
630 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
632 i++;
633 if (d) {
634 pixel += d;
635 dst[
y * linesize + x*4 + plane] =
pixel;
636 x++;
637 } else {
638 if (i >= src_size * 2)
639 return;
641 i++;
642 d =
FFMIN(d, width - x);
643 for (j = 0; j < d; j++) {
644 dst[
y * linesize + x*4 + plane] =
pixel;
645 x++;
646 }
647 }
648 if (x >= width) {
649 plane++;
650 if (plane >= 4) {
653 return;
654 plane = 0;
655 }
656 x = 0;
657 pixel = 0;
658 i = (i + 1) & ~1;
659 }
660 }
661 }
662
664 {
668 }
669
671 void *
data,
int *got_frame,
673 {
677 const uint8_t *buf_end = buf + buf_size;
681
683 return res;
685 return res;
686
688
692 return res;
696 return res;
697 }
699
701 case 0:
705 for (plane = 0; plane < s->
bpp; plane++) {
706 for (y = 0; y < avctx->
height && buf < buf_end; y++) {
710 }
711 }
712 }
else if (s->
ham) {
// HAM to AV_PIX_FMT_BGR32
714 for (y = 0; y < avctx->
height; y++) {
717 for (plane = 0; plane < s->
bpp; plane++) {
719 if (start >= buf_end)
720 break;
722 }
724 }
725 } else
729 int x;
730 for (y = 0; y < avctx->
height && buf < buf_end; y++) {
732 memcpy(row, buf,
FFMIN(raw_width, buf_end - buf));
733 buf += raw_width;
735 for (x = 0; x < avctx->
width; x++)
736 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
737 }
738 }
739 }
else if (avctx->
codec_tag ==
MKTAG(
'I',
'L',
'B',
'M')) {
// interleaved
741 for (y = 0; y < avctx->
height; y++) {
743 memset(row, 0, avctx->
width);
744 for (plane = 0; plane < s->
bpp && buf < buf_end; plane++) {
747 }
748 }
749 }
else if (s->
ham) {
// HAM to AV_PIX_FMT_BGR32
750 for (y = 0; y < avctx->
height; y++) {
753 for (plane = 0; plane < s->
bpp && buf < buf_end; plane++) {
756 }
758 }
759 } else { // AV_PIX_FMT_BGR32
760 for (y = 0; y < avctx->
height; y++) {
762 memset(row, 0, avctx->
width << 2);
763 for (plane = 0; plane < s->
bpp && buf < buf_end; plane++) {
767 }
768 }
769 }
770 }
else if (avctx->
codec_tag ==
MKTAG(
'P',
'B',
'M',
' ')) {
// IFF-PBM
772 for (y = 0; y < avctx->
height && buf_end >
buf; y++) {
774 memcpy(row, buf,
FFMIN(avctx->
width, buf_end - buf));
775 buf += avctx->
width + (avctx->
width % 2);
// padding if odd
776 }
777 }
else if (s->
ham) {
// IFF-PBM: HAM to AV_PIX_FMT_BGR32
778 for (y = 0; y < avctx->
height && buf_end >
buf; y++) {
781 buf += avctx->
width + (avctx->
width & 1);
// padding if odd
783 }
784 } else
786 }
787 break;
788 case 1:
789 if (avctx->
codec_tag ==
MKTAG(
'I',
'L',
'B',
'M')) {
// interleaved
791 for (y = 0; y < avctx->
height; y++) {
793 memset(row, 0, avctx->
width);
794 for (plane = 0; plane < s->
bpp; plane++) {
797 }
798 }
800 for (y = 0; y < avctx->
height; y++) {
803 for (plane = 0; plane < s->
bpp; plane++) {
806 }
808 }
809 }
else if (s->
ham) {
// HAM to AV_PIX_FMT_BGR32
810 for (y = 0; y < avctx->
height; y++) {
813 for (plane = 0; plane < s->
bpp; plane++) {
816 }
818 }
819 } else { // AV_PIX_FMT_BGR32
820 for (y = 0; y < avctx->
height; y++) {
822 memset(row, 0, avctx->
width << 2);
823 for (plane = 0; plane < s->
bpp; plane++) {
826 }
827 }
828 }
829 }
else if (avctx->
codec_tag ==
MKTAG(
'P',
'B',
'M',
' ')) {
// IFF-PBM
831 for (y = 0; y < avctx->
height; y++) {
834 }
835 }
else if (s->
ham) {
// IFF-PBM: HAM to AV_PIX_FMT_BGR32
836 for (y = 0; y < avctx->
height; y++) {
840 }
841 } else
843 }
else if (avctx->
codec_tag ==
MKTAG(
'D',
'E',
'E',
'P')) {
// IFF-DEEP
846 else
848 }
849 break;
850 case 4:
856 else
858 break;
859 case 5:
863 else
865 } else
867 break;
868 default:
870 }
871
873 return res;
874
875 *got_frame = 1;
876
877 return buf_size;
878 }
879
880 #if CONFIG_IFF_ILBM_DECODER
881 AVCodec ff_iff_ilbm_decoder = {
891 };
892 #endif
893 #if CONFIG_IFF_BYTERUN1_DECODER
894 AVCodec ff_iff_byterun1_decoder = {
904 };
905 #endif