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