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 if (avctx->codec_tag != MKTAG('D','E','E','P'))
00329 avctx->pix_fmt = PIX_FMT_BGR32;
00330 } else {
00331 return AVERROR_INVALIDDATA;
00332 }
00333
00334 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
00335 return err;
00336 s->planesize = FFALIGN(avctx->width, 16) >> 3;
00337 s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
00338 if (!s->planebuf)
00339 return AVERROR(ENOMEM);
00340
00341 s->bpp = avctx->bits_per_coded_sample;
00342 avcodec_get_frame_defaults(&s->frame);
00343
00344 if ((err = extract_header(avctx, NULL)) < 0)
00345 return err;
00346 s->frame.reference = 3;
00347
00348 return 0;
00349 }
00350
00358 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
00359 {
00360 const uint64_t *lut = plane8_lut[plane];
00361 do {
00362 uint64_t v = AV_RN64A(dst) | lut[*buf++];
00363 AV_WN64A(dst, v);
00364 dst += 8;
00365 } while (--buf_size);
00366 }
00367
00375 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
00376 {
00377 const uint32_t *lut = plane32_lut[plane];
00378 do {
00379 unsigned mask = (*buf >> 2) & ~3;
00380 dst[0] |= lut[mask++];
00381 dst[1] |= lut[mask++];
00382 dst[2] |= lut[mask++];
00383 dst[3] |= lut[mask];
00384 mask = (*buf++ << 2) & 0x3F;
00385 dst[4] |= lut[mask++];
00386 dst[5] |= lut[mask++];
00387 dst[6] |= lut[mask++];
00388 dst[7] |= lut[mask];
00389 dst += 8;
00390 } while (--buf_size);
00391 }
00392
00393 #define DECODE_HAM_PLANE32(x) \
00394 first = buf[x] << 1; \
00395 second = buf[(x)+1] << 1; \
00396 delta &= pal[first++]; \
00397 delta |= pal[first]; \
00398 dst[x] = delta; \
00399 delta &= pal[second++]; \
00400 delta |= pal[second]; \
00401 dst[(x)+1] = delta
00402
00411 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
00412 const uint32_t *const pal, unsigned buf_size)
00413 {
00414 uint32_t delta = 0;
00415 do {
00416 uint32_t first, second;
00417 DECODE_HAM_PLANE32(0);
00418 DECODE_HAM_PLANE32(2);
00419 DECODE_HAM_PLANE32(4);
00420 DECODE_HAM_PLANE32(6);
00421 buf += 8;
00422 dst += 8;
00423 } while (--buf_size);
00424 }
00425
00426 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
00427 const uint32_t *const pal, unsigned width)
00428 {
00429 do {
00430 *dst++ = pal[*buf++];
00431 } while (--width);
00432 }
00433
00443 static int decode_byterun(uint8_t *dst, int dst_size,
00444 const uint8_t *buf, const uint8_t *const buf_end) {
00445 const uint8_t *const buf_start = buf;
00446 unsigned x;
00447 for (x = 0; x < dst_size && buf < buf_end;) {
00448 unsigned length;
00449 const int8_t value = *buf++;
00450 if (value >= 0) {
00451 length = value + 1;
00452 memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
00453 buf += length;
00454 } else if (value > -128) {
00455 length = -value + 1;
00456 memset(dst + x, *buf++, FFMIN(length, dst_size - x));
00457 } else {
00458 continue;
00459 }
00460 x += length;
00461 }
00462 return buf - buf_start;
00463 }
00464
00465 static int decode_frame_ilbm(AVCodecContext *avctx,
00466 void *data, int *data_size,
00467 AVPacket *avpkt)
00468 {
00469 IffContext *s = avctx->priv_data;
00470 const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
00471 const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
00472 const uint8_t *buf_end = buf+buf_size;
00473 int y, plane, res;
00474
00475 if ((res = extract_header(avctx, avpkt)) < 0)
00476 return res;
00477
00478 if (s->init) {
00479 if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
00480 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00481 return res;
00482 }
00483 } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
00484 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00485 return res;
00486 } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt == PIX_FMT_PAL8) {
00487 if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
00488 return res;
00489 }
00490 s->init = 1;
00491
00492 if (avctx->codec_tag == MKTAG('A','C','B','M')) {
00493 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00494 memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
00495 for (plane = 0; plane < s->bpp; plane++) {
00496 for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
00497 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00498 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00499 buf += s->planesize;
00500 }
00501 }
00502 } else if (s->ham) {
00503 memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
00504 for(y = 0; y < avctx->height; y++) {
00505 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00506 memset(s->ham_buf, 0, s->planesize * 8);
00507 for (plane = 0; plane < s->bpp; plane++) {
00508 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
00509 if (start >= buf_end)
00510 break;
00511 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
00512 }
00513 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00514 }
00515 }
00516 } else if (avctx->codec_tag == MKTAG('D','E','E','P')) {
00517 int raw_width = avctx->width * (av_get_bits_per_pixel(&av_pix_fmt_descriptors[avctx->pix_fmt]) >> 3);
00518 int x;
00519 for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
00520 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00521 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
00522 buf += raw_width;
00523 if (avctx->pix_fmt == PIX_FMT_BGR32) {
00524 for(x = 0; x < avctx->width; x++)
00525 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
00526 }
00527 }
00528 } else if (avctx->codec_tag == MKTAG('I','L','B','M')) {
00529 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00530 for(y = 0; y < avctx->height; y++ ) {
00531 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00532 memset(row, 0, avctx->width);
00533 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00534 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00535 buf += s->planesize;
00536 }
00537 }
00538 } else if (s->ham) {
00539 for (y = 0; y < avctx->height; y++) {
00540 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00541 memset(s->ham_buf, 0, s->planesize * 8);
00542 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00543 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
00544 buf += s->planesize;
00545 }
00546 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00547 }
00548 } else {
00549 for(y = 0; y < avctx->height; y++ ) {
00550 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00551 memset(row, 0, avctx->width << 2);
00552 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00553 decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00554 buf += s->planesize;
00555 }
00556 }
00557 }
00558 } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) {
00559 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00560 for(y = 0; y < avctx->height; y++ ) {
00561 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00562 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
00563 buf += avctx->width + (avctx->width % 2);
00564 }
00565 } else if (s->ham) {
00566 for (y = 0; y < avctx->height; y++) {
00567 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00568 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
00569 buf += avctx->width + (avctx->width & 1);
00570 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00571 }
00572 } else {
00573 av_log_ask_for_sample(avctx, "unsupported bpp\n");
00574 return AVERROR_INVALIDDATA;
00575 }
00576 }
00577
00578 *data_size = sizeof(AVFrame);
00579 *(AVFrame*)data = s->frame;
00580 return buf_size;
00581 }
00582
00583 static int decode_frame_byterun1(AVCodecContext *avctx,
00584 void *data, int *data_size,
00585 AVPacket *avpkt)
00586 {
00587 IffContext *s = avctx->priv_data;
00588 const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
00589 const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
00590 const uint8_t *buf_end = buf+buf_size;
00591 int y, plane, res;
00592
00593 if ((res = extract_header(avctx, avpkt)) < 0)
00594 return res;
00595 if (s->init) {
00596 if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
00597 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00598 return res;
00599 }
00600 } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
00601 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00602 return res;
00603 } else if (avctx->pix_fmt == PIX_FMT_PAL8) {
00604 if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
00605 return res;
00606 } else if (avctx->pix_fmt == PIX_FMT_RGB32 && avctx->bits_per_coded_sample <= 8) {
00607 if ((res = ff_cmap_read_palette(avctx, s->mask_palbuf)) < 0)
00608 return res;
00609 }
00610 s->init = 1;
00611
00612 if (avctx->codec_tag == MKTAG('I','L','B','M')) {
00613 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00614 for(y = 0; y < avctx->height ; y++ ) {
00615 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00616 memset(row, 0, avctx->width);
00617 for (plane = 0; plane < s->bpp; plane++) {
00618 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00619 decodeplane8(row, s->planebuf, s->planesize, plane);
00620 }
00621 }
00622 } else if (avctx->bits_per_coded_sample <= 8) {
00623 for (y = 0; y < avctx->height ; y++ ) {
00624 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00625 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
00626 for (plane = 0; plane < s->bpp; plane++) {
00627 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00628 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
00629 }
00630 lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width);
00631 }
00632 } else if (s->ham) {
00633 for (y = 0; y < avctx->height ; y++) {
00634 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00635 memset(s->ham_buf, 0, s->planesize * 8);
00636 for (plane = 0; plane < s->bpp; plane++) {
00637 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00638 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
00639 }
00640 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00641 }
00642 } else {
00643 for(y = 0; y < avctx->height ; y++ ) {
00644 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00645 memset(row, 0, avctx->width << 2);
00646 for (plane = 0; plane < s->bpp; plane++) {
00647 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00648 decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
00649 }
00650 }
00651 }
00652 } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) {
00653 if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00654 for(y = 0; y < avctx->height ; y++ ) {
00655 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00656 buf += decode_byterun(row, avctx->width, buf, buf_end);
00657 }
00658 } else if (s->ham) {
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(s->ham_buf, avctx->width, buf, buf_end);
00662 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00663 }
00664 } else {
00665 av_log_ask_for_sample(avctx, "unsupported bpp\n");
00666 return AVERROR_INVALIDDATA;
00667 }
00668 }
00669
00670 *data_size = sizeof(AVFrame);
00671 *(AVFrame*)data = s->frame;
00672 return buf_size;
00673 }
00674
00675 static av_cold int decode_end(AVCodecContext *avctx)
00676 {
00677 IffContext *s = avctx->priv_data;
00678 if (s->frame.data[0])
00679 avctx->release_buffer(avctx, &s->frame);
00680 av_freep(&s->planebuf);
00681 av_freep(&s->ham_buf);
00682 av_freep(&s->ham_palbuf);
00683 return 0;
00684 }
00685
00686 AVCodec ff_iff_ilbm_decoder = {
00687 .name = "iff_ilbm",
00688 .type = AVMEDIA_TYPE_VIDEO,
00689 .id = CODEC_ID_IFF_ILBM,
00690 .priv_data_size = sizeof(IffContext),
00691 .init = decode_init,
00692 .close = decode_end,
00693 .decode = decode_frame_ilbm,
00694 .capabilities = CODEC_CAP_DR1,
00695 .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
00696 };
00697
00698 AVCodec ff_iff_byterun1_decoder = {
00699 .name = "iff_byterun1",
00700 .type = AVMEDIA_TYPE_VIDEO,
00701 .id = CODEC_ID_IFF_BYTERUN1,
00702 .priv_data_size = sizeof(IffContext),
00703 .init = decode_init,
00704 .close = decode_end,
00705 .decode = decode_frame_byterun1,
00706 .capabilities = CODEC_CAP_DR1,
00707 .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
00708 };