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, "bit_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 = avctx->extradata_size - AV_RB16(avctx->extradata);
00195
00196 if (avpkt) {
00197 int image_size;
00198 if (avpkt->size < 2)
00199 return AVERROR_INVALIDDATA;
00200 image_size = avpkt->size - AV_RB16(avpkt->data);
00201 buf = avpkt->data;
00202 buf_size = bytestream_get_be16(&buf);
00203 if (buf_size <= 1 || image_size <= 1) {
00204 av_log(avctx, AV_LOG_ERROR,
00205 "Invalid image size received: %u -> image data offset: %d\n",
00206 buf_size, image_size);
00207 return AVERROR_INVALIDDATA;
00208 }
00209 } else {
00210 if (avctx->extradata_size < 2)
00211 return AVERROR_INVALIDDATA;
00212 buf = avctx->extradata;
00213 buf_size = bytestream_get_be16(&buf);
00214 if (buf_size <= 1 || palette_size < 0) {
00215 av_log(avctx, AV_LOG_ERROR,
00216 "Invalid palette size received: %u -> palette data offset: %d\n",
00217 buf_size, palette_size);
00218 return AVERROR_INVALIDDATA;
00219 }
00220 }
00221
00222 if (buf_size > 8) {
00223 s->compression = bytestream_get_byte(&buf);
00224 s->bpp = bytestream_get_byte(&buf);
00225 s->ham = bytestream_get_byte(&buf);
00226 s->flags = bytestream_get_byte(&buf);
00227 s->transparency = bytestream_get_be16(&buf);
00228 s->masking = bytestream_get_byte(&buf);
00229 if (s->masking == MASK_HAS_MASK) {
00230 if (s->bpp >= 8) {
00231 avctx->pix_fmt = PIX_FMT_RGB32;
00232 av_freep(&s->mask_buf);
00233 av_freep(&s->mask_palbuf);
00234 s->mask_buf = av_malloc((s->planesize * 32) + FF_INPUT_BUFFER_PADDING_SIZE);
00235 if (!s->mask_buf)
00236 return AVERROR(ENOMEM);
00237 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
00238 if (!s->mask_palbuf) {
00239 av_freep(&s->mask_buf);
00240 return AVERROR(ENOMEM);
00241 }
00242 }
00243 s->bpp++;
00244 } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
00245 av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
00246 return AVERROR_PATCHWELCOME;
00247 }
00248 if (!s->bpp || s->bpp > 32) {
00249 av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
00250 return AVERROR_INVALIDDATA;
00251 } else if (s->ham >= 8) {
00252 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
00253 return AVERROR_INVALIDDATA;
00254 }
00255
00256 av_freep(&s->ham_buf);
00257 av_freep(&s->ham_palbuf);
00258
00259 if (s->ham) {
00260 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
00261 int ham_count;
00262 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
00263
00264 s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
00265 if (!s->ham_buf)
00266 return AVERROR(ENOMEM);
00267
00268 ham_count = 8 * (1 << s->ham);
00269 s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
00270 if (!s->ham_palbuf) {
00271 av_freep(&s->ham_buf);
00272 return AVERROR(ENOMEM);
00273 }
00274
00275 if (count) {
00276
00277 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
00278 for (i=0; i < count; i++) {
00279 s->ham_palbuf[i*2+1] = AV_RL24(palette + i*3);
00280 }
00281 count = 1 << s->ham;
00282 } else {
00283 count = 1 << s->ham;
00284 for (i=0; i < count; i++) {
00285 s->ham_palbuf[i*2] = 0;
00286 s->ham_palbuf[i*2+1] = av_le2ne32(gray2rgb((i * 255) >> s->ham));
00287 }
00288 }
00289 for (i=0; i < count; i++) {
00290 uint32_t tmp = i << (8 - s->ham);
00291 tmp |= tmp >> s->ham;
00292 s->ham_palbuf[(i+count)*2] = 0x00FFFF;
00293 s->ham_palbuf[(i+count*2)*2] = 0xFFFF00;
00294 s->ham_palbuf[(i+count*3)*2] = 0xFF00FF;
00295 s->ham_palbuf[(i+count)*2+1] = tmp << 16;
00296 s->ham_palbuf[(i+count*2)*2+1] = tmp;
00297 s->ham_palbuf[(i+count*3)*2+1] = tmp << 8;
00298 }
00299 if (s->masking == MASK_HAS_MASK) {
00300 for (i = 0; i < ham_count; i++)
00301 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
00302 }
00303 }
00304 }
00305
00306 return 0;
00307 }
00308
00309 static av_cold int decode_init(AVCodecContext *avctx)
00310 {
00311 IffContext *s = avctx->priv_data;
00312 int err;
00313
00314 if (avctx->bits_per_coded_sample <= 8) {
00315 int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
00316 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
00317 (avctx->extradata_size >= 2 && palette_size) ? PIX_FMT_PAL8 : PIX_FMT_GRAY8;
00318 } else if (avctx->bits_per_coded_sample <= 32) {
00319 avctx->pix_fmt = PIX_FMT_BGR32;
00320 } else {
00321 return AVERROR_INVALIDDATA;
00322 }
00323
00324 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
00325 return err;
00326 s->planesize = FFALIGN(avctx->width, 16) >> 3;
00327 s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
00328 if (!s->planebuf)
00329 return AVERROR(ENOMEM);
00330
00331 s->bpp = avctx->bits_per_coded_sample;
00332 avcodec_get_frame_defaults(&s->frame);
00333
00334 if ((err = extract_header(avctx, NULL)) < 0)
00335 return err;
00336 s->frame.reference = 3;
00337
00338 return 0;
00339 }
00340
00348 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
00349 {
00350 const uint64_t *lut = plane8_lut[plane];
00351 do {
00352 uint64_t v = AV_RN64A(dst) | lut[*buf++];
00353 AV_WN64A(dst, v);
00354 dst += 8;
00355 } while (--buf_size);
00356 }
00357
00365 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
00366 {
00367 const uint32_t *lut = plane32_lut[plane];
00368 do {
00369 unsigned mask = (*buf >> 2) & ~3;
00370 dst[0] |= lut[mask++];
00371 dst[1] |= lut[mask++];
00372 dst[2] |= lut[mask++];
00373 dst[3] |= lut[mask];
00374 mask = (*buf++ << 2) & 0x3F;
00375 dst[4] |= lut[mask++];
00376 dst[5] |= lut[mask++];
00377 dst[6] |= lut[mask++];
00378 dst[7] |= lut[mask];
00379 dst += 8;
00380 } while (--buf_size);
00381 }
00382
00383 #define DECODE_HAM_PLANE32(x) \
00384 first = buf[x] << 1; \
00385 second = buf[(x)+1] << 1; \
00386 delta &= pal[first++]; \
00387 delta |= pal[first]; \
00388 dst[x] = delta; \
00389 delta &= pal[second++]; \
00390 delta |= pal[second]; \
00391 dst[(x)+1] = delta
00392
00401 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
00402 const uint32_t *const pal, unsigned buf_size)
00403 {
00404 uint32_t delta = 0;
00405 do {
00406 uint32_t first, second;
00407 DECODE_HAM_PLANE32(0);
00408 DECODE_HAM_PLANE32(2);
00409 DECODE_HAM_PLANE32(4);
00410 DECODE_HAM_PLANE32(6);
00411 buf += 8;
00412 dst += 8;
00413 } while (--buf_size);
00414 }
00415
00416 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
00417 const uint32_t *const pal, unsigned width)
00418 {
00419 do {
00420 *dst++ = pal[*buf++];
00421 } while (--width);
00422 }
00423
00433 static int decode_byterun(uint8_t *dst, int dst_size,
00434 const uint8_t *buf, const uint8_t *const buf_end) {
00435 const uint8_t *const buf_start = buf;
00436 unsigned x;
00437 for (x = 0; x < dst_size && buf < buf_end;) {
00438 unsigned length;
00439 const int8_t value = *buf++;
00440 if (value >= 0) {
00441 length = value + 1;
00442 memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
00443 buf += length;
00444 } else if (value > -128) {
00445 length = -value + 1;
00446 memset(dst + x, *buf++, FFMIN(length, dst_size - x));
00447 } else {
00448 continue;
00449 }
00450 x += length;
00451 }
00452 return buf - buf_start;
00453 }
00454
00455 static int decode_frame_ilbm(AVCodecContext *avctx,
00456 void *data, int *data_size,
00457 AVPacket *avpkt)
00458 {
00459 IffContext *s = avctx->priv_data;
00460 const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
00461 const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
00462 const uint8_t *buf_end = buf+buf_size;
00463 int y, plane, res;
00464
00465 if ((res = extract_header(avctx, avpkt)) < 0)
00466 return res;
00467
00468 if (s->init) {
00469 if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
00470 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00471 return res;
00472 }
00473 } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
00474 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00475 return res;
00476 } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt == PIX_FMT_PAL8) {
00477 if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
00478 return res;
00479 }
00480 s->init = 1;
00481
00482 if (avctx->codec_tag == MKTAG('A','C','B','M')) {
00483 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00484 memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
00485 for (plane = 0; plane < s->bpp; plane++) {
00486 for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
00487 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00488 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00489 buf += s->planesize;
00490 }
00491 }
00492 } else if (s->ham) {
00493 memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
00494 for(y = 0; y < avctx->height; y++) {
00495 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00496 memset(s->ham_buf, 0, s->planesize * 8);
00497 for (plane = 0; plane < s->bpp; plane++) {
00498 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
00499 if (start >= buf_end)
00500 break;
00501 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
00502 }
00503 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00504 }
00505 }
00506 } else if (avctx->codec_tag == MKTAG('I','L','B','M')) {
00507 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00508 for(y = 0; y < avctx->height; y++ ) {
00509 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00510 memset(row, 0, avctx->width);
00511 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00512 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00513 buf += s->planesize;
00514 }
00515 }
00516 } else if (s->ham) {
00517 for (y = 0; y < avctx->height; y++) {
00518 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00519 memset(s->ham_buf, 0, s->planesize * 8);
00520 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00521 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
00522 buf += s->planesize;
00523 }
00524 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00525 }
00526 } else {
00527 for(y = 0; y < avctx->height; y++ ) {
00528 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00529 memset(row, 0, avctx->width << 2);
00530 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00531 decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00532 buf += s->planesize;
00533 }
00534 }
00535 }
00536 } else if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00537 for(y = 0; y < avctx->height; y++ ) {
00538 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00539 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
00540 buf += avctx->width + (avctx->width % 2);
00541 }
00542 } else {
00543 for (y = 0; y < avctx->height; y++) {
00544 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00545 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
00546 buf += avctx->width + (avctx->width & 1);
00547 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, avctx->width);
00548 }
00549 }
00550
00551 *data_size = sizeof(AVFrame);
00552 *(AVFrame*)data = s->frame;
00553 return buf_size;
00554 }
00555
00556 static int decode_frame_byterun1(AVCodecContext *avctx,
00557 void *data, int *data_size,
00558 AVPacket *avpkt)
00559 {
00560 IffContext *s = avctx->priv_data;
00561 const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
00562 const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
00563 const uint8_t *buf_end = buf+buf_size;
00564 int y, plane, res;
00565
00566 if ((res = extract_header(avctx, avpkt)) < 0)
00567 return res;
00568 if (s->init) {
00569 if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
00570 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00571 return res;
00572 }
00573 } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
00574 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00575 return res;
00576 } else if (avctx->pix_fmt == PIX_FMT_PAL8) {
00577 if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
00578 return res;
00579 } else if (avctx->pix_fmt == PIX_FMT_RGB32 && avctx->bits_per_coded_sample <= 8) {
00580 if ((res = ff_cmap_read_palette(avctx, s->mask_palbuf)) < 0)
00581 return res;
00582 }
00583 s->init = 1;
00584
00585 if (avctx->codec_tag == MKTAG('I','L','B','M')) {
00586 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00587 for(y = 0; y < avctx->height ; y++ ) {
00588 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00589 memset(row, 0, avctx->width);
00590 for (plane = 0; plane < s->bpp; plane++) {
00591 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00592 decodeplane8(row, s->planebuf, s->planesize, plane);
00593 }
00594 }
00595 } else if (avctx->bits_per_coded_sample <= 8) {
00596 for (y = 0; y < avctx->height ; y++ ) {
00597 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00598 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
00599 for (plane = 0; plane < s->bpp; plane++) {
00600 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00601 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
00602 }
00603 lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width);
00604 }
00605 } else if (s->ham) {
00606 for (y = 0; y < avctx->height ; y++) {
00607 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00608 memset(s->ham_buf, 0, s->planesize * 8);
00609 for (plane = 0; plane < s->bpp; plane++) {
00610 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00611 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
00612 }
00613 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00614 }
00615 } else {
00616 for(y = 0; y < avctx->height ; y++ ) {
00617 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00618 memset(row, 0, avctx->width << 2);
00619 for (plane = 0; plane < s->bpp; plane++) {
00620 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00621 decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
00622 }
00623 }
00624 }
00625 } else if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00626 for(y = 0; y < avctx->height ; y++ ) {
00627 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00628 buf += decode_byterun(row, avctx->width, buf, buf_end);
00629 }
00630 } else {
00631 for (y = 0; y < avctx->height ; y++) {
00632 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00633 buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
00634 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, avctx->width);
00635 }
00636 }
00637
00638 *data_size = sizeof(AVFrame);
00639 *(AVFrame*)data = s->frame;
00640 return buf_size;
00641 }
00642
00643 static av_cold int decode_end(AVCodecContext *avctx)
00644 {
00645 IffContext *s = avctx->priv_data;
00646 if (s->frame.data[0])
00647 avctx->release_buffer(avctx, &s->frame);
00648 av_freep(&s->planebuf);
00649 av_freep(&s->ham_buf);
00650 av_freep(&s->ham_palbuf);
00651 return 0;
00652 }
00653
00654 AVCodec ff_iff_ilbm_decoder = {
00655 .name = "iff_ilbm",
00656 .type = AVMEDIA_TYPE_VIDEO,
00657 .id = CODEC_ID_IFF_ILBM,
00658 .priv_data_size = sizeof(IffContext),
00659 .init = decode_init,
00660 .close = decode_end,
00661 .decode = decode_frame_ilbm,
00662 .capabilities = CODEC_CAP_DR1,
00663 .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
00664 };
00665
00666 AVCodec ff_iff_byterun1_decoder = {
00667 .name = "iff_byterun1",
00668 .type = AVMEDIA_TYPE_VIDEO,
00669 .id = CODEC_ID_IFF_BYTERUN1,
00670 .priv_data_size = sizeof(IffContext),
00671 .init = decode_init,
00672 .close = decode_end,
00673 .decode = decode_frame_byterun1,
00674 .capabilities = CODEC_CAP_DR1,
00675 .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
00676 };