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 unsigned compression;
00048 unsigned bpp;
00049 unsigned ham;
00050 unsigned flags;
00051 unsigned transparency;
00052 unsigned masking;
00053 int init;
00054 } IffContext;
00055
00056 #define LUT8_PART(plane, v) \
00057 AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
00058 AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
00059 AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
00060 AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
00061 AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
00062 AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
00063 AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
00064 AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
00065 AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
00066 AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
00067 AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
00068 AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
00069 AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
00070 AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
00071 AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
00072 AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
00073
00074 #define LUT8(plane) { \
00075 LUT8_PART(plane, 0x0000000), \
00076 LUT8_PART(plane, 0x1000000), \
00077 LUT8_PART(plane, 0x0010000), \
00078 LUT8_PART(plane, 0x1010000), \
00079 LUT8_PART(plane, 0x0000100), \
00080 LUT8_PART(plane, 0x1000100), \
00081 LUT8_PART(plane, 0x0010100), \
00082 LUT8_PART(plane, 0x1010100), \
00083 LUT8_PART(plane, 0x0000001), \
00084 LUT8_PART(plane, 0x1000001), \
00085 LUT8_PART(plane, 0x0010001), \
00086 LUT8_PART(plane, 0x1010001), \
00087 LUT8_PART(plane, 0x0000101), \
00088 LUT8_PART(plane, 0x1000101), \
00089 LUT8_PART(plane, 0x0010101), \
00090 LUT8_PART(plane, 0x1010101), \
00091 }
00092
00093
00094 static const uint64_t plane8_lut[8][256] = {
00095 LUT8(0), LUT8(1), LUT8(2), LUT8(3),
00096 LUT8(4), LUT8(5), LUT8(6), LUT8(7),
00097 };
00098
00099 #define LUT32(plane) { \
00100 0, 0, 0, 0, \
00101 0, 0, 0, 1 << plane, \
00102 0, 0, 1 << plane, 0, \
00103 0, 0, 1 << plane, 1 << plane, \
00104 0, 1 << plane, 0, 0, \
00105 0, 1 << plane, 0, 1 << plane, \
00106 0, 1 << plane, 1 << plane, 0, \
00107 0, 1 << plane, 1 << plane, 1 << plane, \
00108 1 << plane, 0, 0, 0, \
00109 1 << plane, 0, 0, 1 << plane, \
00110 1 << plane, 0, 1 << plane, 0, \
00111 1 << plane, 0, 1 << plane, 1 << plane, \
00112 1 << plane, 1 << plane, 0, 0, \
00113 1 << plane, 1 << plane, 0, 1 << plane, \
00114 1 << plane, 1 << plane, 1 << plane, 0, \
00115 1 << plane, 1 << plane, 1 << plane, 1 << plane, \
00116 }
00117
00118
00119 static const uint32_t plane32_lut[32][16*4] = {
00120 LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
00121 LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
00122 LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
00123 LUT32(12), LUT32(13), LUT32(14), LUT32(15),
00124 LUT32(16), LUT32(17), LUT32(18), LUT32(19),
00125 LUT32(20), LUT32(21), LUT32(22), LUT32(23),
00126 LUT32(24), LUT32(25), LUT32(26), LUT32(27),
00127 LUT32(28), LUT32(29), LUT32(30), LUT32(31),
00128 };
00129
00130
00131 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
00132 return x << 16 | x << 8 | x;
00133 }
00134
00138 static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
00139 {
00140 IffContext *s = avctx->priv_data;
00141 int count, i;
00142 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
00143 int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
00144
00145 if (avctx->bits_per_coded_sample > 8) {
00146 av_log(avctx, AV_LOG_ERROR, "bit_per_coded_sample > 8 not supported\n");
00147 return AVERROR_INVALIDDATA;
00148 }
00149
00150 count = 1 << avctx->bits_per_coded_sample;
00151
00152 count = FFMIN(palette_size / 3, count);
00153 if (count) {
00154 for (i=0; i < count; i++) {
00155 pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
00156 }
00157 if (s->flags && count >= 32) {
00158 for (i = 0; i < 32; i++)
00159 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
00160 }
00161 } else {
00162 count = 1 << avctx->bits_per_coded_sample;
00163
00164 for (i=0; i < count; i++) {
00165 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
00166 }
00167 }
00168 return 0;
00169 }
00170
00179 static int extract_header(AVCodecContext *const avctx,
00180 const AVPacket *const avpkt) {
00181 const uint8_t *buf;
00182 unsigned buf_size;
00183 IffContext *s = avctx->priv_data;
00184 int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
00185
00186 if (avpkt) {
00187 int image_size;
00188 if (avpkt->size < 2)
00189 return AVERROR_INVALIDDATA;
00190 image_size = avpkt->size - AV_RB16(avpkt->data);
00191 buf = avpkt->data;
00192 buf_size = bytestream_get_be16(&buf);
00193 if (buf_size <= 1 || image_size <= 1) {
00194 av_log(avctx, AV_LOG_ERROR,
00195 "Invalid image size received: %u -> image data offset: %d\n",
00196 buf_size, image_size);
00197 return AVERROR_INVALIDDATA;
00198 }
00199 } else {
00200 if (avctx->extradata_size < 2)
00201 return AVERROR_INVALIDDATA;
00202 buf = avctx->extradata;
00203 buf_size = bytestream_get_be16(&buf);
00204 if (buf_size <= 1 || palette_size < 0) {
00205 av_log(avctx, AV_LOG_ERROR,
00206 "Invalid palette size received: %u -> palette data offset: %d\n",
00207 buf_size, palette_size);
00208 return AVERROR_INVALIDDATA;
00209 }
00210 }
00211
00212 if (buf_size > 8) {
00213 s->compression = bytestream_get_byte(&buf);
00214 s->bpp = bytestream_get_byte(&buf);
00215 s->ham = bytestream_get_byte(&buf);
00216 s->flags = bytestream_get_byte(&buf);
00217 s->transparency = bytestream_get_be16(&buf);
00218 s->masking = bytestream_get_byte(&buf);
00219 if (s->masking == MASK_HAS_TRANSPARENT_COLOR) {
00220 av_log(avctx, AV_LOG_ERROR, "Transparency not supported\n");
00221 return AVERROR_PATCHWELCOME;
00222 } else if (s->masking != MASK_NONE) {
00223 av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
00224 return AVERROR_PATCHWELCOME;
00225 }
00226 if (!s->bpp || s->bpp > 32) {
00227 av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
00228 return AVERROR_INVALIDDATA;
00229 } else if (s->ham >= 8) {
00230 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
00231 return AVERROR_INVALIDDATA;
00232 }
00233
00234 av_freep(&s->ham_buf);
00235 av_freep(&s->ham_palbuf);
00236
00237 if (s->ham) {
00238 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
00239 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
00240 s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
00241 if (!s->ham_buf)
00242 return AVERROR(ENOMEM);
00243
00244 s->ham_palbuf = av_malloc((8 * (1 << s->ham) * sizeof (uint32_t)) + FF_INPUT_BUFFER_PADDING_SIZE);
00245 if (!s->ham_palbuf) {
00246 av_freep(&s->ham_buf);
00247 return AVERROR(ENOMEM);
00248 }
00249
00250 if (count) {
00251
00252 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
00253 for (i=0; i < count; i++) {
00254 s->ham_palbuf[i*2+1] = AV_RL24(palette + i*3);
00255 }
00256 count = 1 << s->ham;
00257 } else {
00258 count = 1 << s->ham;
00259 for (i=0; i < count; i++) {
00260 s->ham_palbuf[i*2] = 0;
00261 s->ham_palbuf[i*2+1] = av_le2ne32(gray2rgb((i * 255) >> s->ham));
00262 }
00263 }
00264 for (i=0; i < count; i++) {
00265 uint32_t tmp = i << (8 - s->ham);
00266 tmp |= tmp >> s->ham;
00267 s->ham_palbuf[(i+count)*2] = 0x00FFFF;
00268 s->ham_palbuf[(i+count*2)*2] = 0xFFFF00;
00269 s->ham_palbuf[(i+count*3)*2] = 0xFF00FF;
00270 s->ham_palbuf[(i+count)*2+1] = tmp << 16;
00271 s->ham_palbuf[(i+count*2)*2+1] = tmp;
00272 s->ham_palbuf[(i+count*3)*2+1] = tmp << 8;
00273 }
00274 }
00275 }
00276
00277 return 0;
00278 }
00279
00280 static av_cold int decode_init(AVCodecContext *avctx)
00281 {
00282 IffContext *s = avctx->priv_data;
00283 int err;
00284
00285 if (avctx->bits_per_coded_sample <= 8) {
00286 int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
00287 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
00288 (avctx->extradata_size >= 2 && palette_size) ? PIX_FMT_PAL8 : PIX_FMT_GRAY8;
00289 } else if (avctx->bits_per_coded_sample <= 32) {
00290 avctx->pix_fmt = PIX_FMT_BGR32;
00291 } else {
00292 return AVERROR_INVALIDDATA;
00293 }
00294
00295 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
00296 return err;
00297 s->planesize = FFALIGN(avctx->width, 16) >> 3;
00298 s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
00299 if (!s->planebuf)
00300 return AVERROR(ENOMEM);
00301
00302 s->bpp = avctx->bits_per_coded_sample;
00303 avcodec_get_frame_defaults(&s->frame);
00304
00305 if ((err = extract_header(avctx, NULL)) < 0)
00306 return err;
00307 s->frame.reference = 3;
00308
00309 return 0;
00310 }
00311
00319 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
00320 {
00321 const uint64_t *lut = plane8_lut[plane];
00322 do {
00323 uint64_t v = AV_RN64A(dst) | lut[*buf++];
00324 AV_WN64A(dst, v);
00325 dst += 8;
00326 } while (--buf_size);
00327 }
00328
00336 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
00337 {
00338 const uint32_t *lut = plane32_lut[plane];
00339 do {
00340 unsigned mask = (*buf >> 2) & ~3;
00341 dst[0] |= lut[mask++];
00342 dst[1] |= lut[mask++];
00343 dst[2] |= lut[mask++];
00344 dst[3] |= lut[mask];
00345 mask = (*buf++ << 2) & 0x3F;
00346 dst[4] |= lut[mask++];
00347 dst[5] |= lut[mask++];
00348 dst[6] |= lut[mask++];
00349 dst[7] |= lut[mask];
00350 dst += 8;
00351 } while (--buf_size);
00352 }
00353
00354 #define DECODE_HAM_PLANE32(x) \
00355 first = buf[x] << 1; \
00356 second = buf[(x)+1] << 1; \
00357 delta &= pal[first++]; \
00358 delta |= pal[first]; \
00359 dst[x] = delta; \
00360 delta &= pal[second++]; \
00361 delta |= pal[second]; \
00362 dst[(x)+1] = delta
00363
00372 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
00373 const uint32_t *const pal, unsigned buf_size)
00374 {
00375 uint32_t delta = 0;
00376 do {
00377 uint32_t first, second;
00378 DECODE_HAM_PLANE32(0);
00379 DECODE_HAM_PLANE32(2);
00380 DECODE_HAM_PLANE32(4);
00381 DECODE_HAM_PLANE32(6);
00382 buf += 8;
00383 dst += 8;
00384 } while (--buf_size);
00385 }
00386
00396 static int decode_byterun(uint8_t *dst, int dst_size,
00397 const uint8_t *buf, const uint8_t *const buf_end) {
00398 const uint8_t *const buf_start = buf;
00399 unsigned x;
00400 for (x = 0; x < dst_size && buf < buf_end;) {
00401 unsigned length;
00402 const int8_t value = *buf++;
00403 if (value >= 0) {
00404 length = value + 1;
00405 memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
00406 buf += length;
00407 } else if (value > -128) {
00408 length = -value + 1;
00409 memset(dst + x, *buf++, FFMIN(length, dst_size - x));
00410 } else {
00411 continue;
00412 }
00413 x += length;
00414 }
00415 return buf - buf_start;
00416 }
00417
00418 static int decode_frame_ilbm(AVCodecContext *avctx,
00419 void *data, int *data_size,
00420 AVPacket *avpkt)
00421 {
00422 IffContext *s = avctx->priv_data;
00423 const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
00424 const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
00425 const uint8_t *buf_end = buf+buf_size;
00426 int y, plane, res;
00427
00428 if ((res = extract_header(avctx, avpkt)) < 0)
00429 return res;
00430
00431 if (s->init) {
00432 if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
00433 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00434 return res;
00435 }
00436 } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
00437 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00438 return res;
00439 } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != PIX_FMT_GRAY8) {
00440 if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
00441 return res;
00442 }
00443 s->init = 1;
00444
00445 if (avctx->codec_tag == MKTAG('A','C','B','M')) {
00446 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00447 memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
00448 for (plane = 0; plane < s->bpp; plane++) {
00449 for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
00450 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00451 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00452 buf += s->planesize;
00453 }
00454 }
00455 } else if (s->ham) {
00456 memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
00457 for(y = 0; y < avctx->height; y++) {
00458 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00459 memset(s->ham_buf, 0, s->planesize * 8);
00460 for (plane = 0; plane < s->bpp; plane++) {
00461 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
00462 if (start >= buf_end)
00463 break;
00464 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
00465 }
00466 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00467 }
00468 }
00469 } else if (avctx->codec_tag == MKTAG('I','L','B','M')) {
00470 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00471 for(y = 0; y < avctx->height; y++ ) {
00472 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00473 memset(row, 0, avctx->width);
00474 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00475 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00476 buf += s->planesize;
00477 }
00478 }
00479 } else if (s->ham) {
00480 for (y = 0; y < avctx->height; y++) {
00481 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00482 memset(s->ham_buf, 0, s->planesize * 8);
00483 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00484 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
00485 buf += s->planesize;
00486 }
00487 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00488 }
00489 } else {
00490 for(y = 0; y < avctx->height; y++ ) {
00491 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00492 memset(row, 0, avctx->width << 2);
00493 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00494 decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00495 buf += s->planesize;
00496 }
00497 }
00498 }
00499 } else if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00500 for(y = 0; y < avctx->height; y++ ) {
00501 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00502 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
00503 buf += avctx->width + (avctx->width % 2);
00504 }
00505 } else {
00506 for (y = 0; y < avctx->height; y++) {
00507 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00508 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
00509 buf += avctx->width + (avctx->width & 1);
00510 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, avctx->width);
00511 }
00512 }
00513
00514 *data_size = sizeof(AVFrame);
00515 *(AVFrame*)data = s->frame;
00516 return buf_size;
00517 }
00518
00519 static int decode_frame_byterun1(AVCodecContext *avctx,
00520 void *data, int *data_size,
00521 AVPacket *avpkt)
00522 {
00523 IffContext *s = avctx->priv_data;
00524 const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
00525 const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
00526 const uint8_t *buf_end = buf+buf_size;
00527 int y, plane, res;
00528
00529 if ((res = extract_header(avctx, avpkt)) < 0)
00530 return res;
00531 if (s->init) {
00532 if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
00533 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00534 return res;
00535 }
00536 } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
00537 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00538 return res;
00539 } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != PIX_FMT_GRAY8) {
00540 if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
00541 return res;
00542 }
00543 s->init = 1;
00544
00545 if (avctx->codec_tag == MKTAG('I','L','B','M')) {
00546 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00547 for(y = 0; y < avctx->height ; y++ ) {
00548 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00549 memset(row, 0, avctx->width);
00550 for (plane = 0; plane < s->bpp; plane++) {
00551 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00552 decodeplane8(row, s->planebuf, s->planesize, plane);
00553 }
00554 }
00555 } else if (s->ham) {
00556 for (y = 0; y < avctx->height ; y++) {
00557 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00558 memset(s->ham_buf, 0, s->planesize * 8);
00559 for (plane = 0; plane < s->bpp; plane++) {
00560 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00561 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
00562 }
00563 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00564 }
00565 } else {
00566 for(y = 0; y < avctx->height ; y++ ) {
00567 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00568 memset(row, 0, avctx->width << 2);
00569 for (plane = 0; plane < s->bpp; plane++) {
00570 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00571 decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
00572 }
00573 }
00574 }
00575 } else if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00576 for(y = 0; y < avctx->height ; y++ ) {
00577 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00578 buf += decode_byterun(row, avctx->width, buf, buf_end);
00579 }
00580 } else {
00581 for (y = 0; y < avctx->height ; y++) {
00582 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00583 buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
00584 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, avctx->width);
00585 }
00586 }
00587
00588 *data_size = sizeof(AVFrame);
00589 *(AVFrame*)data = s->frame;
00590 return buf_size;
00591 }
00592
00593 static av_cold int decode_end(AVCodecContext *avctx)
00594 {
00595 IffContext *s = avctx->priv_data;
00596 if (s->frame.data[0])
00597 avctx->release_buffer(avctx, &s->frame);
00598 av_freep(&s->planebuf);
00599 av_freep(&s->ham_buf);
00600 av_freep(&s->ham_palbuf);
00601 return 0;
00602 }
00603
00604 AVCodec ff_iff_ilbm_decoder = {
00605 .name = "iff_ilbm",
00606 .type = AVMEDIA_TYPE_VIDEO,
00607 .id = CODEC_ID_IFF_ILBM,
00608 .priv_data_size = sizeof(IffContext),
00609 .init = decode_init,
00610 .close = decode_end,
00611 .decode = decode_frame_ilbm,
00612 .capabilities = CODEC_CAP_DR1,
00613 .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
00614 };
00615
00616 AVCodec ff_iff_byterun1_decoder = {
00617 .name = "iff_byterun1",
00618 .type = AVMEDIA_TYPE_VIDEO,
00619 .id = CODEC_ID_IFF_BYTERUN1,
00620 .priv_data_size = sizeof(IffContext),
00621 .init = decode_init,
00622 .close = decode_end,
00623 .decode = decode_frame_byterun1,
00624 .capabilities = CODEC_CAP_DR1,
00625 .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
00626 };