00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00028 #include "libavutil/imgutils.h"
00029 #include "bytestream.h"
00030 #include "avcodec.h"
00031 #include "get_bits.h"
00032 #include "internal.h"
00033
00034
00035 typedef enum {
00036 MASK_NONE,
00037 MASK_HAS_MASK,
00038 MASK_HAS_TRANSPARENT_COLOR,
00039 MASK_LASSO
00040 } mask_type;
00041
00042 typedef struct {
00043 AVFrame frame;
00044 int planesize;
00045 uint8_t * planebuf;
00046 uint8_t * ham_buf;
00047 uint32_t *ham_palbuf;
00048 uint32_t *mask_buf;
00049 uint32_t *mask_palbuf;
00050 unsigned compression;
00051 unsigned bpp;
00052 unsigned ham;
00053 unsigned flags;
00054 unsigned transparency;
00055 unsigned masking;
00056 int init;
00057 int16_t tvdc[16];
00058 } IffContext;
00059
00060 #define LUT8_PART(plane, v) \
00061 AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
00062 AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
00063 AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
00064 AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
00065 AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
00066 AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
00067 AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
00068 AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
00069 AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
00070 AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
00071 AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
00072 AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
00073 AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
00074 AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
00075 AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
00076 AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
00077
00078 #define LUT8(plane) { \
00079 LUT8_PART(plane, 0x0000000), \
00080 LUT8_PART(plane, 0x1000000), \
00081 LUT8_PART(plane, 0x0010000), \
00082 LUT8_PART(plane, 0x1010000), \
00083 LUT8_PART(plane, 0x0000100), \
00084 LUT8_PART(plane, 0x1000100), \
00085 LUT8_PART(plane, 0x0010100), \
00086 LUT8_PART(plane, 0x1010100), \
00087 LUT8_PART(plane, 0x0000001), \
00088 LUT8_PART(plane, 0x1000001), \
00089 LUT8_PART(plane, 0x0010001), \
00090 LUT8_PART(plane, 0x1010001), \
00091 LUT8_PART(plane, 0x0000101), \
00092 LUT8_PART(plane, 0x1000101), \
00093 LUT8_PART(plane, 0x0010101), \
00094 LUT8_PART(plane, 0x1010101), \
00095 }
00096
00097
00098 static const uint64_t plane8_lut[8][256] = {
00099 LUT8(0), LUT8(1), LUT8(2), LUT8(3),
00100 LUT8(4), LUT8(5), LUT8(6), LUT8(7),
00101 };
00102
00103 #define LUT32(plane) { \
00104 0, 0, 0, 0, \
00105 0, 0, 0, 1 << plane, \
00106 0, 0, 1 << plane, 0, \
00107 0, 0, 1 << plane, 1 << plane, \
00108 0, 1 << plane, 0, 0, \
00109 0, 1 << plane, 0, 1 << plane, \
00110 0, 1 << plane, 1 << plane, 0, \
00111 0, 1 << plane, 1 << plane, 1 << plane, \
00112 1 << plane, 0, 0, 0, \
00113 1 << plane, 0, 0, 1 << plane, \
00114 1 << plane, 0, 1 << plane, 0, \
00115 1 << plane, 0, 1 << plane, 1 << plane, \
00116 1 << plane, 1 << plane, 0, 0, \
00117 1 << plane, 1 << plane, 0, 1 << plane, \
00118 1 << plane, 1 << plane, 1 << plane, 0, \
00119 1 << plane, 1 << plane, 1 << plane, 1 << plane, \
00120 }
00121
00122
00123 static const uint32_t plane32_lut[32][16*4] = {
00124 LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
00125 LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
00126 LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
00127 LUT32(12), LUT32(13), LUT32(14), LUT32(15),
00128 LUT32(16), LUT32(17), LUT32(18), LUT32(19),
00129 LUT32(20), LUT32(21), LUT32(22), LUT32(23),
00130 LUT32(24), LUT32(25), LUT32(26), LUT32(27),
00131 LUT32(28), LUT32(29), LUT32(30), LUT32(31),
00132 };
00133
00134
00135 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
00136 return x << 16 | x << 8 | x;
00137 }
00138
00142 static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
00143 {
00144 IffContext *s = avctx->priv_data;
00145 int count, i;
00146 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
00147 int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
00148
00149 if (avctx->bits_per_coded_sample > 8) {
00150 av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
00151 return AVERROR_INVALIDDATA;
00152 }
00153
00154 count = 1 << avctx->bits_per_coded_sample;
00155
00156 count = FFMIN(palette_size / 3, count);
00157 if (count) {
00158 for (i=0; i < count; i++) {
00159 pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
00160 }
00161 if (s->flags && count >= 32) {
00162 for (i = 0; i < 32; i++)
00163 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
00164 count = FFMAX(count, 64);
00165 }
00166 } else {
00167 count = 1 << avctx->bits_per_coded_sample;
00168
00169 for (i=0; i < count; i++) {
00170 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
00171 }
00172 }
00173 if (s->masking == MASK_HAS_MASK) {
00174 memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
00175 for (i = 0; i < count; i++)
00176 pal[i] &= 0xFFFFFF;
00177 } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
00178 s->transparency < 1 << avctx->bits_per_coded_sample)
00179 pal[s->transparency] &= 0xFFFFFF;
00180 return 0;
00181 }
00182
00191 static int extract_header(AVCodecContext *const avctx,
00192 const AVPacket *const avpkt) {
00193 const uint8_t *buf;
00194 unsigned buf_size;
00195 IffContext *s = avctx->priv_data;
00196 int i, palette_size;
00197
00198 if (avctx->extradata_size < 2) {
00199 av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
00200 return AVERROR_INVALIDDATA;
00201 }
00202 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
00203
00204 if (avpkt) {
00205 int image_size;
00206 if (avpkt->size < 2)
00207 return AVERROR_INVALIDDATA;
00208 image_size = avpkt->size - AV_RB16(avpkt->data);
00209 buf = avpkt->data;
00210 buf_size = bytestream_get_be16(&buf);
00211 if (buf_size <= 1 || image_size <= 1) {
00212 av_log(avctx, AV_LOG_ERROR,
00213 "Invalid image size received: %u -> image data offset: %d\n",
00214 buf_size, image_size);
00215 return AVERROR_INVALIDDATA;
00216 }
00217 } else {
00218 buf = avctx->extradata;
00219 buf_size = bytestream_get_be16(&buf);
00220 if (buf_size <= 1 || palette_size < 0) {
00221 av_log(avctx, AV_LOG_ERROR,
00222 "Invalid palette size received: %u -> palette data offset: %d\n",
00223 buf_size, palette_size);
00224 return AVERROR_INVALIDDATA;
00225 }
00226 }
00227
00228 if (buf_size >= 41) {
00229 s->compression = bytestream_get_byte(&buf);
00230 s->bpp = bytestream_get_byte(&buf);
00231 s->ham = bytestream_get_byte(&buf);
00232 s->flags = bytestream_get_byte(&buf);
00233 s->transparency = bytestream_get_be16(&buf);
00234 s->masking = bytestream_get_byte(&buf);
00235 for (i = 0; i < 16; i++)
00236 s->tvdc[i] = bytestream_get_be16(&buf);
00237
00238 if (s->masking == MASK_HAS_MASK) {
00239 if (s->bpp >= 8 && !s->ham) {
00240 avctx->pix_fmt = AV_PIX_FMT_RGB32;
00241 av_freep(&s->mask_buf);
00242 av_freep(&s->mask_palbuf);
00243 s->mask_buf = av_malloc((s->planesize * 32) + FF_INPUT_BUFFER_PADDING_SIZE);
00244 if (!s->mask_buf)
00245 return AVERROR(ENOMEM);
00246 if (s->bpp > 16) {
00247 av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
00248 av_freep(&s->mask_buf);
00249 return AVERROR(ENOMEM);
00250 }
00251 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
00252 if (!s->mask_palbuf) {
00253 av_freep(&s->mask_buf);
00254 return AVERROR(ENOMEM);
00255 }
00256 }
00257 s->bpp++;
00258 } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
00259 av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
00260 return AVERROR_PATCHWELCOME;
00261 }
00262 if (!s->bpp || s->bpp > 32) {
00263 av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
00264 return AVERROR_INVALIDDATA;
00265 } else if (s->ham >= 8) {
00266 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
00267 return AVERROR_INVALIDDATA;
00268 }
00269
00270 av_freep(&s->ham_buf);
00271 av_freep(&s->ham_palbuf);
00272
00273 if (s->ham) {
00274 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
00275 int ham_count;
00276 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
00277
00278 s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
00279 if (!s->ham_buf)
00280 return AVERROR(ENOMEM);
00281
00282 ham_count = 8 * (1 << s->ham);
00283 s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
00284 if (!s->ham_palbuf) {
00285 av_freep(&s->ham_buf);
00286 return AVERROR(ENOMEM);
00287 }
00288
00289 if (count) {
00290
00291 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
00292 for (i=0; i < count; i++) {
00293 s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
00294 }
00295 count = 1 << s->ham;
00296 } else {
00297 count = 1 << s->ham;
00298 for (i=0; i < count; i++) {
00299 s->ham_palbuf[i*2] = 0xFF000000;
00300 s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
00301 }
00302 }
00303 for (i=0; i < count; i++) {
00304 uint32_t tmp = i << (8 - s->ham);
00305 tmp |= tmp >> s->ham;
00306 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
00307 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
00308 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
00309 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
00310 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
00311 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
00312 }
00313 if (s->masking == MASK_HAS_MASK) {
00314 for (i = 0; i < ham_count; i++)
00315 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
00316 }
00317 }
00318 }
00319
00320 return 0;
00321 }
00322
00323 static av_cold int decode_init(AVCodecContext *avctx)
00324 {
00325 IffContext *s = avctx->priv_data;
00326 int err;
00327
00328 if (avctx->bits_per_coded_sample <= 8) {
00329 int palette_size;
00330
00331 if (avctx->extradata_size >= 2)
00332 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
00333 else
00334 palette_size = 0;
00335 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
00336 (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
00337 } else if (avctx->bits_per_coded_sample <= 32) {
00338 if (avctx->codec_tag == MKTAG('R','G','B','8')) {
00339 avctx->pix_fmt = AV_PIX_FMT_RGB32;
00340 } else if (avctx->codec_tag == MKTAG('R','G','B','N')) {
00341 avctx->pix_fmt = AV_PIX_FMT_RGB444;
00342 } else if (avctx->codec_tag != MKTAG('D','E','E','P')) {
00343 if (avctx->bits_per_coded_sample == 24) {
00344 avctx->pix_fmt = AV_PIX_FMT_RGB0;
00345 } else if (avctx->bits_per_coded_sample == 32) {
00346 avctx->pix_fmt = AV_PIX_FMT_BGR32;
00347 } else {
00348 av_log_ask_for_sample(avctx, "unknown bits_per_coded_sample\n");
00349 return AVERROR_PATCHWELCOME;
00350 }
00351 }
00352 } else {
00353 return AVERROR_INVALIDDATA;
00354 }
00355
00356 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
00357 return err;
00358 s->planesize = FFALIGN(avctx->width, 16) >> 3;
00359 s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
00360 if (!s->planebuf)
00361 return AVERROR(ENOMEM);
00362
00363 s->bpp = avctx->bits_per_coded_sample;
00364 avcodec_get_frame_defaults(&s->frame);
00365
00366 if ((err = extract_header(avctx, NULL)) < 0)
00367 return err;
00368 s->frame.reference = 3;
00369
00370 return 0;
00371 }
00372
00380 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
00381 {
00382 const uint64_t *lut = plane8_lut[plane];
00383 if (plane >= 8) {
00384 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
00385 return;
00386 }
00387 do {
00388 uint64_t v = AV_RN64A(dst) | lut[*buf++];
00389 AV_WN64A(dst, v);
00390 dst += 8;
00391 } while (--buf_size);
00392 }
00393
00401 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
00402 {
00403 const uint32_t *lut = plane32_lut[plane];
00404 do {
00405 unsigned mask = (*buf >> 2) & ~3;
00406 dst[0] |= lut[mask++];
00407 dst[1] |= lut[mask++];
00408 dst[2] |= lut[mask++];
00409 dst[3] |= lut[mask];
00410 mask = (*buf++ << 2) & 0x3F;
00411 dst[4] |= lut[mask++];
00412 dst[5] |= lut[mask++];
00413 dst[6] |= lut[mask++];
00414 dst[7] |= lut[mask];
00415 dst += 8;
00416 } while (--buf_size);
00417 }
00418
00419 #define DECODE_HAM_PLANE32(x) \
00420 first = buf[x] << 1; \
00421 second = buf[(x)+1] << 1; \
00422 delta &= pal[first++]; \
00423 delta |= pal[first]; \
00424 dst[x] = delta; \
00425 delta &= pal[second++]; \
00426 delta |= pal[second]; \
00427 dst[(x)+1] = delta
00428
00437 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
00438 const uint32_t *const pal, unsigned buf_size)
00439 {
00440 uint32_t delta = pal[1];
00441 do {
00442 uint32_t first, second;
00443 DECODE_HAM_PLANE32(0);
00444 DECODE_HAM_PLANE32(2);
00445 DECODE_HAM_PLANE32(4);
00446 DECODE_HAM_PLANE32(6);
00447 buf += 8;
00448 dst += 8;
00449 } while (--buf_size);
00450 }
00451
00452 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
00453 const uint32_t *const pal, unsigned width)
00454 {
00455 do {
00456 *dst++ = pal[*buf++];
00457 } while (--width);
00458 }
00459
00469 static int decode_byterun(uint8_t *dst, int dst_size,
00470 const uint8_t *buf, const uint8_t *const buf_end) {
00471 const uint8_t *const buf_start = buf;
00472 unsigned x;
00473 for (x = 0; x < dst_size && buf < buf_end;) {
00474 unsigned length;
00475 const int8_t value = *buf++;
00476 if (value >= 0) {
00477 length = value + 1;
00478 memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
00479 buf += length;
00480 } else if (value > -128) {
00481 length = -value + 1;
00482 memset(dst + x, *buf++, FFMIN(length, dst_size - x));
00483 } else {
00484 continue;
00485 }
00486 x += length;
00487 }
00488 return buf - buf_start;
00489 }
00490
00491 #define DECODE_RGBX_COMMON(pixel_size) \
00492 if (!length) { \
00493 length = bytestream2_get_byte(gb); \
00494 if (!length) { \
00495 length = bytestream2_get_be16(gb); \
00496 if (!length) \
00497 return; \
00498 } \
00499 } \
00500 for (i = 0; i < length; i++) { \
00501 *(uint32_t *)(dst + y*linesize + x * pixel_size) = pixel; \
00502 x += 1; \
00503 if (x >= width) { \
00504 y += 1; \
00505 if (y >= height) \
00506 return; \
00507 x = 0; \
00508 } \
00509 }
00510
00518 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
00519 {
00520 int x = 0, y = 0, i, length;
00521 while (bytestream2_get_bytes_left(gb) >= 4) {
00522 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
00523 length = bytestream2_get_byte(gb) & 0x7F;
00524 DECODE_RGBX_COMMON(4)
00525 }
00526 }
00527
00535 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
00536 {
00537 int x = 0, y = 0, i, length;
00538 while (bytestream2_get_bytes_left(gb) >= 2) {
00539 uint32_t pixel = bytestream2_get_be16u(gb);
00540 length = pixel & 0x7;
00541 pixel >>= 4;
00542 DECODE_RGBX_COMMON(2)
00543 }
00544 }
00545
00555 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
00556 {
00557 const uint8_t *src_end = src + src_size;
00558 int x = 0, y = 0, i;
00559 while (src + 5 <= src_end) {
00560 int opcode;
00561 opcode = *(int8_t *)src++;
00562 if (opcode >= 0) {
00563 int size = opcode + 1;
00564 for (i = 0; i < size; i++) {
00565 int length = FFMIN(size - i, width);
00566 memcpy(dst + y*linesize + x * 4, src, length * 4);
00567 src += length * 4;
00568 x += length;
00569 i += length;
00570 if (x >= width) {
00571 x = 0;
00572 y += 1;
00573 if (y >= height)
00574 return;
00575 }
00576 }
00577 } else {
00578 int size = -opcode + 1;
00579 uint32_t pixel = AV_RL32(src);
00580 for (i = 0; i < size; i++) {
00581 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
00582 x += 1;
00583 if (x >= width) {
00584 x = 0;
00585 y += 1;
00586 if (y >= height)
00587 return;
00588 }
00589 }
00590 src += 4;
00591 }
00592 }
00593 }
00594
00605 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)
00606 {
00607 int x = 0, y = 0, plane = 0;
00608 int8_t pixel = 0;
00609 int i, j;
00610
00611 for (i = 0; i < src_size * 2;) {
00612 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
00613 int d = tvdc[GETNIBBLE];
00614 i++;
00615 if (d) {
00616 pixel += d;
00617 dst[y * linesize + x*4 + plane] = pixel;
00618 x++;
00619 } else {
00620 if (i >= src_size * 2)
00621 return;
00622 d = GETNIBBLE + 1;
00623 i++;
00624 d = FFMIN(d, width - x);
00625 for (j = 0; j < d; j++) {
00626 dst[y * linesize + x*4 + plane] = pixel;
00627 x++;
00628 }
00629 }
00630 if (x >= width) {
00631 plane++;
00632 if (plane >= 4) {
00633 y++;
00634 if (y >= height)
00635 return;
00636 plane = 0;
00637 }
00638 x = 0;
00639 pixel = 0;
00640 i = (i + 1) & ~1;
00641 }
00642 }
00643 }
00644
00645 static int unsupported(AVCodecContext *avctx)
00646 {
00647 IffContext *s = avctx->priv_data;
00648 av_log_ask_for_sample(avctx, "unsupported bitmap (compression %i, bpp %i, ham %i)\n", s->compression, s->bpp, s->ham);
00649 return AVERROR_INVALIDDATA;
00650 }
00651
00652 static int decode_frame(AVCodecContext *avctx,
00653 void *data, int *got_frame,
00654 AVPacket *avpkt)
00655 {
00656 IffContext *s = avctx->priv_data;
00657 const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
00658 const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
00659 const uint8_t *buf_end = buf+buf_size;
00660 int y, plane, res;
00661 GetByteContext gb;
00662
00663 if ((res = extract_header(avctx, avpkt)) < 0)
00664 return res;
00665 if (s->init) {
00666 if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
00667 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00668 return res;
00669 }
00670 } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
00671 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00672 return res;
00673 } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
00674 if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
00675 return res;
00676 } else if (avctx->pix_fmt == AV_PIX_FMT_RGB32 && avctx->bits_per_coded_sample <= 8) {
00677 if ((res = ff_cmap_read_palette(avctx, s->mask_palbuf)) < 0)
00678 return res;
00679 }
00680 s->init = 1;
00681
00682 switch (s->compression) {
00683 case 0:
00684 if (avctx->codec_tag == MKTAG('A','C','B','M')) {
00685 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
00686 memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
00687 for (plane = 0; plane < s->bpp; plane++) {
00688 for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
00689 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00690 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00691 buf += s->planesize;
00692 }
00693 }
00694 } else if (s->ham) {
00695 memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
00696 for(y = 0; y < avctx->height; y++) {
00697 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00698 memset(s->ham_buf, 0, s->planesize * 8);
00699 for (plane = 0; plane < s->bpp; plane++) {
00700 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
00701 if (start >= buf_end)
00702 break;
00703 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
00704 }
00705 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00706 }
00707 } else
00708 return unsupported(avctx);
00709 } else if (avctx->codec_tag == MKTAG('D','E','E','P')) {
00710 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
00711 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
00712 int x;
00713 for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
00714 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00715 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
00716 buf += raw_width;
00717 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
00718 for(x = 0; x < avctx->width; x++)
00719 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
00720 }
00721 }
00722 } else if (avctx->codec_tag == MKTAG('I','L','B','M')) {
00723 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
00724 for(y = 0; y < avctx->height; y++ ) {
00725 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00726 memset(row, 0, avctx->width);
00727 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00728 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00729 buf += s->planesize;
00730 }
00731 }
00732 } else if (s->ham) {
00733 for (y = 0; y < avctx->height; y++) {
00734 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00735 memset(s->ham_buf, 0, s->planesize * 8);
00736 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00737 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
00738 buf += s->planesize;
00739 }
00740 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00741 }
00742 } else {
00743 for(y = 0; y < avctx->height; y++ ) {
00744 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00745 memset(row, 0, avctx->width << 2);
00746 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00747 decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00748 buf += s->planesize;
00749 }
00750 }
00751 }
00752 } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) {
00753 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
00754 for(y = 0; y < avctx->height && buf_end > buf; y++ ) {
00755 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00756 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
00757 buf += avctx->width + (avctx->width % 2);
00758 }
00759 } else if (s->ham) {
00760 for (y = 0; y < avctx->height && buf_end > buf; y++) {
00761 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00762 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
00763 buf += avctx->width + (avctx->width & 1);
00764 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00765 }
00766 } else
00767 return unsupported(avctx);
00768 }
00769 break;
00770 case 1:
00771 if (avctx->codec_tag == MKTAG('I','L','B','M')) {
00772 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
00773 for(y = 0; y < avctx->height ; y++ ) {
00774 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00775 memset(row, 0, avctx->width);
00776 for (plane = 0; plane < s->bpp; plane++) {
00777 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00778 decodeplane8(row, s->planebuf, s->planesize, plane);
00779 }
00780 }
00781 } else if (avctx->bits_per_coded_sample <= 8) {
00782 for (y = 0; y < avctx->height ; y++ ) {
00783 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00784 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
00785 for (plane = 0; plane < s->bpp; plane++) {
00786 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00787 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
00788 }
00789 lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width);
00790 }
00791 } else if (s->ham) {
00792 for (y = 0; y < avctx->height ; y++) {
00793 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00794 memset(s->ham_buf, 0, s->planesize * 8);
00795 for (plane = 0; plane < s->bpp; plane++) {
00796 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00797 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
00798 }
00799 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00800 }
00801 } else {
00802 for(y = 0; y < avctx->height ; y++ ) {
00803 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00804 memset(row, 0, avctx->width << 2);
00805 for (plane = 0; plane < s->bpp; plane++) {
00806 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00807 decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
00808 }
00809 }
00810 }
00811 } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) {
00812 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
00813 for(y = 0; y < avctx->height ; y++ ) {
00814 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00815 buf += decode_byterun(row, avctx->width, buf, buf_end);
00816 }
00817 } else if (s->ham) {
00818 for (y = 0; y < avctx->height ; y++) {
00819 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00820 buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
00821 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00822 }
00823 } else
00824 return unsupported(avctx);
00825 } else if (avctx->codec_tag == MKTAG('D','E','E','P')) {
00826 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
00827 if (av_get_bits_per_pixel(desc) == 32)
00828 decode_deep_rle32(s->frame.data[0], buf, buf_size, avctx->width, avctx->height, s->frame.linesize[0]);
00829 else
00830 return unsupported(avctx);
00831 }
00832 break;
00833 case 4:
00834 bytestream2_init(&gb, buf, buf_size);
00835 if (avctx->codec_tag == MKTAG('R','G','B','8'))
00836 decode_rgb8(&gb, s->frame.data[0], avctx->width, avctx->height, s->frame.linesize[0]);
00837 else if (avctx->codec_tag == MKTAG('R','G','B','N'))
00838 decode_rgbn(&gb, s->frame.data[0], avctx->width, avctx->height, s->frame.linesize[0]);
00839 else
00840 return unsupported(avctx);
00841 break;
00842 case 5:
00843 if (avctx->codec_tag == MKTAG('D','E','E','P')) {
00844 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
00845 if (av_get_bits_per_pixel(desc) == 32)
00846 decode_deep_tvdc32(s->frame.data[0], buf, buf_size, avctx->width, avctx->height, s->frame.linesize[0], s->tvdc);
00847 else
00848 return unsupported(avctx);
00849 } else
00850 return unsupported(avctx);
00851 break;
00852 default:
00853 return unsupported(avctx);
00854 }
00855
00856 *got_frame = 1;
00857 *(AVFrame*)data = s->frame;
00858 return buf_size;
00859 }
00860
00861 static av_cold int decode_end(AVCodecContext *avctx)
00862 {
00863 IffContext *s = avctx->priv_data;
00864 if (s->frame.data[0])
00865 avctx->release_buffer(avctx, &s->frame);
00866 av_freep(&s->planebuf);
00867 av_freep(&s->ham_buf);
00868 av_freep(&s->ham_palbuf);
00869 return 0;
00870 }
00871
00872 #if CONFIG_IFF_ILBM_DECODER
00873 AVCodec ff_iff_ilbm_decoder = {
00874 .name = "iff",
00875 .type = AVMEDIA_TYPE_VIDEO,
00876 .id = AV_CODEC_ID_IFF_ILBM,
00877 .priv_data_size = sizeof(IffContext),
00878 .init = decode_init,
00879 .close = decode_end,
00880 .decode = decode_frame,
00881 .capabilities = CODEC_CAP_DR1,
00882 .long_name = NULL_IF_CONFIG_SMALL("IFF"),
00883 };
00884 #endif
00885 #if CONFIG_IFF_BYTERUN1_DECODER
00886 AVCodec ff_iff_byterun1_decoder = {
00887 .name = "iff",
00888 .type = AVMEDIA_TYPE_VIDEO,
00889 .id = AV_CODEC_ID_IFF_BYTERUN1,
00890 .priv_data_size = sizeof(IffContext),
00891 .init = decode_init,
00892 .close = decode_end,
00893 .decode = decode_frame,
00894 .capabilities = CODEC_CAP_DR1,
00895 .long_name = NULL_IF_CONFIG_SMALL("IFF"),
00896 };
00897 #endif