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
00033
00034 typedef enum {
00035 MASK_NONE,
00036 MASK_HAS_MASK,
00037 MASK_HAS_TRANSPARENT_COLOR,
00038 MASK_LASSO
00039 } mask_type;
00040
00041 typedef struct {
00042 AVFrame frame;
00043 int planesize;
00044 uint8_t * planebuf;
00045 uint8_t * ham_buf;
00046 uint32_t *ham_palbuf;
00047 uint32_t *mask_buf;
00048 uint32_t *mask_palbuf;
00049 unsigned compression;
00050 unsigned bpp;
00051 unsigned ham;
00052 unsigned flags;
00053 unsigned transparency;
00054 unsigned masking;
00055 int init;
00056 } IffContext;
00057
00058 #define LUT8_PART(plane, v) \
00059 AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
00060 AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
00061 AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
00062 AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
00063 AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
00064 AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
00065 AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
00066 AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
00067 AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
00068 AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
00069 AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
00070 AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
00071 AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
00072 AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
00073 AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
00074 AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
00075
00076 #define LUT8(plane) { \
00077 LUT8_PART(plane, 0x0000000), \
00078 LUT8_PART(plane, 0x1000000), \
00079 LUT8_PART(plane, 0x0010000), \
00080 LUT8_PART(plane, 0x1010000), \
00081 LUT8_PART(plane, 0x0000100), \
00082 LUT8_PART(plane, 0x1000100), \
00083 LUT8_PART(plane, 0x0010100), \
00084 LUT8_PART(plane, 0x1010100), \
00085 LUT8_PART(plane, 0x0000001), \
00086 LUT8_PART(plane, 0x1000001), \
00087 LUT8_PART(plane, 0x0010001), \
00088 LUT8_PART(plane, 0x1010001), \
00089 LUT8_PART(plane, 0x0000101), \
00090 LUT8_PART(plane, 0x1000101), \
00091 LUT8_PART(plane, 0x0010101), \
00092 LUT8_PART(plane, 0x1010101), \
00093 }
00094
00095
00096 static const uint64_t plane8_lut[8][256] = {
00097 LUT8(0), LUT8(1), LUT8(2), LUT8(3),
00098 LUT8(4), LUT8(5), LUT8(6), LUT8(7),
00099 };
00100
00101 #define LUT32(plane) { \
00102 0, 0, 0, 0, \
00103 0, 0, 0, 1 << plane, \
00104 0, 0, 1 << plane, 0, \
00105 0, 0, 1 << plane, 1 << plane, \
00106 0, 1 << plane, 0, 0, \
00107 0, 1 << plane, 0, 1 << plane, \
00108 0, 1 << plane, 1 << plane, 0, \
00109 0, 1 << plane, 1 << plane, 1 << plane, \
00110 1 << plane, 0, 0, 0, \
00111 1 << plane, 0, 0, 1 << plane, \
00112 1 << plane, 0, 1 << plane, 0, \
00113 1 << plane, 0, 1 << plane, 1 << plane, \
00114 1 << plane, 1 << plane, 0, 0, \
00115 1 << plane, 1 << plane, 0, 1 << plane, \
00116 1 << plane, 1 << plane, 1 << plane, 0, \
00117 1 << plane, 1 << plane, 1 << plane, 1 << plane, \
00118 }
00119
00120
00121 static const uint32_t plane32_lut[32][16*4] = {
00122 LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
00123 LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
00124 LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
00125 LUT32(12), LUT32(13), LUT32(14), LUT32(15),
00126 LUT32(16), LUT32(17), LUT32(18), LUT32(19),
00127 LUT32(20), LUT32(21), LUT32(22), LUT32(23),
00128 LUT32(24), LUT32(25), LUT32(26), LUT32(27),
00129 LUT32(28), LUT32(29), LUT32(30), LUT32(31),
00130 };
00131
00132
00133 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
00134 return x << 16 | x << 8 | x;
00135 }
00136
00140 static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
00141 {
00142 IffContext *s = avctx->priv_data;
00143 int count, i;
00144 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
00145 int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
00146
00147 if (avctx->bits_per_coded_sample > 8) {
00148 av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
00149 return AVERROR_INVALIDDATA;
00150 }
00151
00152 count = 1 << avctx->bits_per_coded_sample;
00153
00154 count = FFMIN(palette_size / 3, count);
00155 if (count) {
00156 for (i=0; i < count; i++) {
00157 pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
00158 }
00159 if (s->flags && count >= 32) {
00160 for (i = 0; i < 32; i++)
00161 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
00162 count = FFMAX(count, 64);
00163 }
00164 } else {
00165 count = 1 << avctx->bits_per_coded_sample;
00166
00167 for (i=0; i < count; i++) {
00168 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
00169 }
00170 }
00171 if (s->masking == MASK_HAS_MASK) {
00172 memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
00173 for (i = 0; i < count; i++)
00174 pal[i] &= 0xFFFFFF;
00175 } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
00176 s->transparency < 1 << avctx->bits_per_coded_sample)
00177 pal[s->transparency] &= 0xFFFFFF;
00178 return 0;
00179 }
00180
00189 static int extract_header(AVCodecContext *const avctx,
00190 const AVPacket *const avpkt) {
00191 const uint8_t *buf;
00192 unsigned buf_size;
00193 IffContext *s = avctx->priv_data;
00194 int palette_size;
00195
00196 if (avctx->extradata_size < 2) {
00197 av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
00198 return AVERROR_INVALIDDATA;
00199 }
00200 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
00201
00202 if (avpkt) {
00203 int image_size;
00204 if (avpkt->size < 2)
00205 return AVERROR_INVALIDDATA;
00206 image_size = avpkt->size - AV_RB16(avpkt->data);
00207 buf = avpkt->data;
00208 buf_size = bytestream_get_be16(&buf);
00209 if (buf_size <= 1 || image_size <= 1) {
00210 av_log(avctx, AV_LOG_ERROR,
00211 "Invalid image size received: %u -> image data offset: %d\n",
00212 buf_size, image_size);
00213 return AVERROR_INVALIDDATA;
00214 }
00215 } else {
00216 buf = avctx->extradata;
00217 buf_size = bytestream_get_be16(&buf);
00218 if (buf_size <= 1 || palette_size < 0) {
00219 av_log(avctx, AV_LOG_ERROR,
00220 "Invalid palette size received: %u -> palette data offset: %d\n",
00221 buf_size, palette_size);
00222 return AVERROR_INVALIDDATA;
00223 }
00224 }
00225
00226 if (buf_size > 8) {
00227 s->compression = bytestream_get_byte(&buf);
00228 s->bpp = bytestream_get_byte(&buf);
00229 s->ham = bytestream_get_byte(&buf);
00230 s->flags = bytestream_get_byte(&buf);
00231 s->transparency = bytestream_get_be16(&buf);
00232 s->masking = bytestream_get_byte(&buf);
00233 if (s->masking == MASK_HAS_MASK) {
00234 if (s->bpp >= 8) {
00235 avctx->pix_fmt = PIX_FMT_RGB32;
00236 av_freep(&s->mask_buf);
00237 av_freep(&s->mask_palbuf);
00238 s->mask_buf = av_malloc((s->planesize * 32) + FF_INPUT_BUFFER_PADDING_SIZE);
00239 if (!s->mask_buf)
00240 return AVERROR(ENOMEM);
00241 if (s->bpp > 16) {
00242 av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
00243 av_freep(&s->mask_buf);
00244 return AVERROR(ENOMEM);
00245 }
00246 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
00247 if (!s->mask_palbuf) {
00248 av_freep(&s->mask_buf);
00249 return AVERROR(ENOMEM);
00250 }
00251 }
00252 s->bpp++;
00253 } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
00254 av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
00255 return AVERROR_PATCHWELCOME;
00256 }
00257 if (!s->bpp || s->bpp > 32) {
00258 av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
00259 return AVERROR_INVALIDDATA;
00260 } else if (s->ham >= 8) {
00261 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
00262 return AVERROR_INVALIDDATA;
00263 }
00264
00265 av_freep(&s->ham_buf);
00266 av_freep(&s->ham_palbuf);
00267
00268 if (s->ham) {
00269 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
00270 int ham_count;
00271 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
00272
00273 s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
00274 if (!s->ham_buf)
00275 return AVERROR(ENOMEM);
00276
00277 ham_count = 8 * (1 << s->ham);
00278 s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
00279 if (!s->ham_palbuf) {
00280 av_freep(&s->ham_buf);
00281 return AVERROR(ENOMEM);
00282 }
00283
00284 if (count) {
00285
00286 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
00287 for (i=0; i < count; i++) {
00288 s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
00289 }
00290 count = 1 << s->ham;
00291 } else {
00292 count = 1 << s->ham;
00293 for (i=0; i < count; i++) {
00294 s->ham_palbuf[i*2] = 0xFF000000;
00295 s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
00296 }
00297 }
00298 for (i=0; i < count; i++) {
00299 uint32_t tmp = i << (8 - s->ham);
00300 tmp |= tmp >> s->ham;
00301 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
00302 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
00303 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
00304 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
00305 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
00306 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
00307 }
00308 if (s->masking == MASK_HAS_MASK) {
00309 for (i = 0; i < ham_count; i++)
00310 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
00311 }
00312 }
00313 }
00314
00315 return 0;
00316 }
00317
00318 static av_cold int decode_init(AVCodecContext *avctx)
00319 {
00320 IffContext *s = avctx->priv_data;
00321 int err;
00322
00323 if (avctx->bits_per_coded_sample <= 8) {
00324 int palette_size;
00325
00326 if (avctx->extradata_size >= 2)
00327 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
00328 else
00329 palette_size = 0;
00330 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
00331 (avctx->extradata_size >= 2 && palette_size) ? PIX_FMT_PAL8 : PIX_FMT_GRAY8;
00332 } else if (avctx->bits_per_coded_sample <= 32) {
00333 if (avctx->codec_tag != MKTAG('D','E','E','P'))
00334 avctx->pix_fmt = PIX_FMT_BGR32;
00335 } else {
00336 return AVERROR_INVALIDDATA;
00337 }
00338
00339 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
00340 return err;
00341 s->planesize = FFALIGN(avctx->width, 16) >> 3;
00342 s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
00343 if (!s->planebuf)
00344 return AVERROR(ENOMEM);
00345
00346 s->bpp = avctx->bits_per_coded_sample;
00347 avcodec_get_frame_defaults(&s->frame);
00348
00349 if ((err = extract_header(avctx, NULL)) < 0)
00350 return err;
00351 s->frame.reference = 3;
00352
00353 return 0;
00354 }
00355
00363 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
00364 {
00365 const uint64_t *lut = plane8_lut[plane];
00366 do {
00367 uint64_t v = AV_RN64A(dst) | lut[*buf++];
00368 AV_WN64A(dst, v);
00369 dst += 8;
00370 } while (--buf_size);
00371 }
00372
00380 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
00381 {
00382 const uint32_t *lut = plane32_lut[plane];
00383 do {
00384 unsigned mask = (*buf >> 2) & ~3;
00385 dst[0] |= lut[mask++];
00386 dst[1] |= lut[mask++];
00387 dst[2] |= lut[mask++];
00388 dst[3] |= lut[mask];
00389 mask = (*buf++ << 2) & 0x3F;
00390 dst[4] |= lut[mask++];
00391 dst[5] |= lut[mask++];
00392 dst[6] |= lut[mask++];
00393 dst[7] |= lut[mask];
00394 dst += 8;
00395 } while (--buf_size);
00396 }
00397
00398 #define DECODE_HAM_PLANE32(x) \
00399 first = buf[x] << 1; \
00400 second = buf[(x)+1] << 1; \
00401 delta &= pal[first++]; \
00402 delta |= pal[first]; \
00403 dst[x] = delta; \
00404 delta &= pal[second++]; \
00405 delta |= pal[second]; \
00406 dst[(x)+1] = delta
00407
00416 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
00417 const uint32_t *const pal, unsigned buf_size)
00418 {
00419 uint32_t delta = 0;
00420 do {
00421 uint32_t first, second;
00422 DECODE_HAM_PLANE32(0);
00423 DECODE_HAM_PLANE32(2);
00424 DECODE_HAM_PLANE32(4);
00425 DECODE_HAM_PLANE32(6);
00426 buf += 8;
00427 dst += 8;
00428 } while (--buf_size);
00429 }
00430
00431 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
00432 const uint32_t *const pal, unsigned width)
00433 {
00434 do {
00435 *dst++ = pal[*buf++];
00436 } while (--width);
00437 }
00438
00448 static int decode_byterun(uint8_t *dst, int dst_size,
00449 const uint8_t *buf, const uint8_t *const buf_end) {
00450 const uint8_t *const buf_start = buf;
00451 unsigned x;
00452 for (x = 0; x < dst_size && buf < buf_end;) {
00453 unsigned length;
00454 const int8_t value = *buf++;
00455 if (value >= 0) {
00456 length = value + 1;
00457 memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
00458 buf += length;
00459 } else if (value > -128) {
00460 length = -value + 1;
00461 memset(dst + x, *buf++, FFMIN(length, dst_size - x));
00462 } else {
00463 continue;
00464 }
00465 x += length;
00466 }
00467 return buf - buf_start;
00468 }
00469
00470 static int decode_frame_ilbm(AVCodecContext *avctx,
00471 void *data, int *data_size,
00472 AVPacket *avpkt)
00473 {
00474 IffContext *s = avctx->priv_data;
00475 const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
00476 const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
00477 const uint8_t *buf_end = buf+buf_size;
00478 int y, plane, res;
00479
00480 if ((res = extract_header(avctx, avpkt)) < 0)
00481 return res;
00482
00483 if (s->init) {
00484 if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
00485 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00486 return res;
00487 }
00488 } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
00489 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00490 return res;
00491 } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt == PIX_FMT_PAL8) {
00492 if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
00493 return res;
00494 }
00495 s->init = 1;
00496
00497 if (avctx->codec_tag == MKTAG('A','C','B','M')) {
00498 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00499 memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
00500 for (plane = 0; plane < s->bpp; plane++) {
00501 for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
00502 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00503 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00504 buf += s->planesize;
00505 }
00506 }
00507 } else if (s->ham) {
00508 memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
00509 for(y = 0; y < avctx->height; y++) {
00510 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00511 memset(s->ham_buf, 0, s->planesize * 8);
00512 for (plane = 0; plane < s->bpp; plane++) {
00513 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
00514 if (start >= buf_end)
00515 break;
00516 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
00517 }
00518 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00519 }
00520 }
00521 } else if (avctx->codec_tag == MKTAG('D','E','E','P')) {
00522 int raw_width = avctx->width * (av_get_bits_per_pixel(&av_pix_fmt_descriptors[avctx->pix_fmt]) >> 3);
00523 int x;
00524 for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
00525 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00526 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
00527 buf += raw_width;
00528 if (avctx->pix_fmt == PIX_FMT_BGR32) {
00529 for(x = 0; x < avctx->width; x++)
00530 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
00531 }
00532 }
00533 } else if (avctx->codec_tag == MKTAG('I','L','B','M')) {
00534 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00535 for(y = 0; y < avctx->height; y++ ) {
00536 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00537 memset(row, 0, avctx->width);
00538 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00539 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00540 buf += s->planesize;
00541 }
00542 }
00543 } else if (s->ham) {
00544 for (y = 0; y < avctx->height; y++) {
00545 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00546 memset(s->ham_buf, 0, s->planesize * 8);
00547 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00548 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
00549 buf += s->planesize;
00550 }
00551 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00552 }
00553 } else {
00554 for(y = 0; y < avctx->height; y++ ) {
00555 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00556 memset(row, 0, avctx->width << 2);
00557 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00558 decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00559 buf += s->planesize;
00560 }
00561 }
00562 }
00563 } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) {
00564 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00565 for(y = 0; y < avctx->height; y++ ) {
00566 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00567 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
00568 buf += avctx->width + (avctx->width % 2);
00569 }
00570 } else if (s->ham) {
00571 for (y = 0; y < avctx->height; y++) {
00572 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00573 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
00574 buf += avctx->width + (avctx->width & 1);
00575 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00576 }
00577 } else {
00578 av_log_ask_for_sample(avctx, "unsupported bpp\n");
00579 return AVERROR_INVALIDDATA;
00580 }
00581 }
00582
00583 *data_size = sizeof(AVFrame);
00584 *(AVFrame*)data = s->frame;
00585 return buf_size;
00586 }
00587
00588 static int decode_frame_byterun1(AVCodecContext *avctx,
00589 void *data, int *data_size,
00590 AVPacket *avpkt)
00591 {
00592 IffContext *s = avctx->priv_data;
00593 const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
00594 const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
00595 const uint8_t *buf_end = buf+buf_size;
00596 int y, plane, res;
00597
00598 if ((res = extract_header(avctx, avpkt)) < 0)
00599 return res;
00600 if (s->init) {
00601 if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
00602 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00603 return res;
00604 }
00605 } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
00606 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00607 return res;
00608 } else if (avctx->pix_fmt == PIX_FMT_PAL8) {
00609 if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
00610 return res;
00611 } else if (avctx->pix_fmt == PIX_FMT_RGB32 && avctx->bits_per_coded_sample <= 8) {
00612 if ((res = ff_cmap_read_palette(avctx, s->mask_palbuf)) < 0)
00613 return res;
00614 }
00615 s->init = 1;
00616
00617 if (avctx->codec_tag == MKTAG('I','L','B','M')) {
00618 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00619 for(y = 0; y < avctx->height ; y++ ) {
00620 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00621 memset(row, 0, avctx->width);
00622 for (plane = 0; plane < s->bpp; plane++) {
00623 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00624 decodeplane8(row, s->planebuf, s->planesize, plane);
00625 }
00626 }
00627 } else if (avctx->bits_per_coded_sample <= 8) {
00628 for (y = 0; y < avctx->height ; y++ ) {
00629 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00630 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
00631 for (plane = 0; plane < s->bpp; plane++) {
00632 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00633 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
00634 }
00635 lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width);
00636 }
00637 } else if (s->ham) {
00638 for (y = 0; y < avctx->height ; y++) {
00639 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00640 memset(s->ham_buf, 0, s->planesize * 8);
00641 for (plane = 0; plane < s->bpp; plane++) {
00642 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00643 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
00644 }
00645 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00646 }
00647 } else {
00648 for(y = 0; y < avctx->height ; y++ ) {
00649 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00650 memset(row, 0, avctx->width << 2);
00651 for (plane = 0; plane < s->bpp; plane++) {
00652 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00653 decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
00654 }
00655 }
00656 }
00657 } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) {
00658 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00659 for(y = 0; y < avctx->height ; y++ ) {
00660 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00661 buf += decode_byterun(row, avctx->width, buf, buf_end);
00662 }
00663 } else if (s->ham) {
00664 for (y = 0; y < avctx->height ; y++) {
00665 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00666 buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
00667 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00668 }
00669 } else {
00670 av_log_ask_for_sample(avctx, "unsupported bpp\n");
00671 return AVERROR_INVALIDDATA;
00672 }
00673 }
00674
00675 *data_size = sizeof(AVFrame);
00676 *(AVFrame*)data = s->frame;
00677 return buf_size;
00678 }
00679
00680 static av_cold int decode_end(AVCodecContext *avctx)
00681 {
00682 IffContext *s = avctx->priv_data;
00683 if (s->frame.data[0])
00684 avctx->release_buffer(avctx, &s->frame);
00685 av_freep(&s->planebuf);
00686 av_freep(&s->ham_buf);
00687 av_freep(&s->ham_palbuf);
00688 return 0;
00689 }
00690
00691 #if CONFIG_IFF_ILBM_DECODER
00692 AVCodec ff_iff_ilbm_decoder = {
00693 .name = "iff_ilbm",
00694 .type = AVMEDIA_TYPE_VIDEO,
00695 .id = AV_CODEC_ID_IFF_ILBM,
00696 .priv_data_size = sizeof(IffContext),
00697 .init = decode_init,
00698 .close = decode_end,
00699 .decode = decode_frame_ilbm,
00700 .capabilities = CODEC_CAP_DR1,
00701 .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
00702 };
00703 #endif
00704 #if CONFIG_IFF_BYTERUN1_DECODER
00705 AVCodec ff_iff_byterun1_decoder = {
00706 .name = "iff_byterun1",
00707 .type = AVMEDIA_TYPE_VIDEO,
00708 .id = AV_CODEC_ID_IFF_BYTERUN1,
00709 .priv_data_size = sizeof(IffContext),
00710 .init = decode_init,
00711 .close = decode_end,
00712 .decode = decode_frame_byterun1,
00713 .capabilities = CODEC_CAP_DR1,
00714 .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
00715 };
00716 #endif