annotate ffmpeg/libavcodec/iff.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * IFF ACBM/DEEP/ILBM/PBM bitmap decoder
yading@10 3 * Copyright (c) 2010 Peter Ross <pross@xvid.org>
yading@10 4 * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
yading@10 5 *
yading@10 6 * This file is part of FFmpeg.
yading@10 7 *
yading@10 8 * FFmpeg is free software; you can redistribute it and/or
yading@10 9 * modify it under the terms of the GNU Lesser General Public
yading@10 10 * License as published by the Free Software Foundation; either
yading@10 11 * version 2.1 of the License, or (at your option) any later version.
yading@10 12 *
yading@10 13 * FFmpeg is distributed in the hope that it will be useful,
yading@10 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 16 * Lesser General Public License for more details.
yading@10 17 *
yading@10 18 * You should have received a copy of the GNU Lesser General Public
yading@10 19 * License along with FFmpeg; if not, write to the Free Software
yading@10 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 21 */
yading@10 22
yading@10 23 /**
yading@10 24 * @file
yading@10 25 * IFF ACBM/DEEP/ILBM/PBM bitmap decoder
yading@10 26 */
yading@10 27
yading@10 28 #include "libavutil/imgutils.h"
yading@10 29 #include "bytestream.h"
yading@10 30 #include "avcodec.h"
yading@10 31 #include "get_bits.h"
yading@10 32 #include "internal.h"
yading@10 33
yading@10 34 // TODO: masking bits
yading@10 35 typedef enum {
yading@10 36 MASK_NONE,
yading@10 37 MASK_HAS_MASK,
yading@10 38 MASK_HAS_TRANSPARENT_COLOR,
yading@10 39 MASK_LASSO
yading@10 40 } mask_type;
yading@10 41
yading@10 42 typedef struct {
yading@10 43 AVFrame *frame;
yading@10 44 int planesize;
yading@10 45 uint8_t * planebuf;
yading@10 46 uint8_t * ham_buf; ///< temporary buffer for planar to chunky conversation
yading@10 47 uint32_t *ham_palbuf; ///< HAM decode table
yading@10 48 uint32_t *mask_buf; ///< temporary buffer for palette indices
yading@10 49 uint32_t *mask_palbuf; ///< masking palette table
yading@10 50 unsigned compression; ///< delta compression method used
yading@10 51 unsigned bpp; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
yading@10 52 unsigned ham; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
yading@10 53 unsigned flags; ///< 1 for EHB, 0 is no extra half darkening
yading@10 54 unsigned transparency; ///< TODO: transparency color index in palette
yading@10 55 unsigned masking; ///< TODO: masking method used
yading@10 56 int init; // 1 if buffer and palette data already initialized, 0 otherwise
yading@10 57 int16_t tvdc[16]; ///< TVDC lookup table
yading@10 58 } IffContext;
yading@10 59
yading@10 60 #define LUT8_PART(plane, v) \
yading@10 61 AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
yading@10 62 AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
yading@10 63 AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
yading@10 64 AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
yading@10 65 AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
yading@10 66 AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
yading@10 67 AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
yading@10 68 AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
yading@10 69 AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
yading@10 70 AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
yading@10 71 AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
yading@10 72 AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
yading@10 73 AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
yading@10 74 AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
yading@10 75 AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
yading@10 76 AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
yading@10 77
yading@10 78 #define LUT8(plane) { \
yading@10 79 LUT8_PART(plane, 0x0000000), \
yading@10 80 LUT8_PART(plane, 0x1000000), \
yading@10 81 LUT8_PART(plane, 0x0010000), \
yading@10 82 LUT8_PART(plane, 0x1010000), \
yading@10 83 LUT8_PART(plane, 0x0000100), \
yading@10 84 LUT8_PART(plane, 0x1000100), \
yading@10 85 LUT8_PART(plane, 0x0010100), \
yading@10 86 LUT8_PART(plane, 0x1010100), \
yading@10 87 LUT8_PART(plane, 0x0000001), \
yading@10 88 LUT8_PART(plane, 0x1000001), \
yading@10 89 LUT8_PART(plane, 0x0010001), \
yading@10 90 LUT8_PART(plane, 0x1010001), \
yading@10 91 LUT8_PART(plane, 0x0000101), \
yading@10 92 LUT8_PART(plane, 0x1000101), \
yading@10 93 LUT8_PART(plane, 0x0010101), \
yading@10 94 LUT8_PART(plane, 0x1010101), \
yading@10 95 }
yading@10 96
yading@10 97 // 8 planes * 8-bit mask
yading@10 98 static const uint64_t plane8_lut[8][256] = {
yading@10 99 LUT8(0), LUT8(1), LUT8(2), LUT8(3),
yading@10 100 LUT8(4), LUT8(5), LUT8(6), LUT8(7),
yading@10 101 };
yading@10 102
yading@10 103 #define LUT32(plane) { \
yading@10 104 0, 0, 0, 0, \
yading@10 105 0, 0, 0, 1 << plane, \
yading@10 106 0, 0, 1 << plane, 0, \
yading@10 107 0, 0, 1 << plane, 1 << plane, \
yading@10 108 0, 1 << plane, 0, 0, \
yading@10 109 0, 1 << plane, 0, 1 << plane, \
yading@10 110 0, 1 << plane, 1 << plane, 0, \
yading@10 111 0, 1 << plane, 1 << plane, 1 << plane, \
yading@10 112 1 << plane, 0, 0, 0, \
yading@10 113 1 << plane, 0, 0, 1 << plane, \
yading@10 114 1 << plane, 0, 1 << plane, 0, \
yading@10 115 1 << plane, 0, 1 << plane, 1 << plane, \
yading@10 116 1 << plane, 1 << plane, 0, 0, \
yading@10 117 1 << plane, 1 << plane, 0, 1 << plane, \
yading@10 118 1 << plane, 1 << plane, 1 << plane, 0, \
yading@10 119 1 << plane, 1 << plane, 1 << plane, 1 << plane, \
yading@10 120 }
yading@10 121
yading@10 122 // 32 planes * 4-bit mask * 4 lookup tables each
yading@10 123 static const uint32_t plane32_lut[32][16*4] = {
yading@10 124 LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
yading@10 125 LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
yading@10 126 LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
yading@10 127 LUT32(12), LUT32(13), LUT32(14), LUT32(15),
yading@10 128 LUT32(16), LUT32(17), LUT32(18), LUT32(19),
yading@10 129 LUT32(20), LUT32(21), LUT32(22), LUT32(23),
yading@10 130 LUT32(24), LUT32(25), LUT32(26), LUT32(27),
yading@10 131 LUT32(28), LUT32(29), LUT32(30), LUT32(31),
yading@10 132 };
yading@10 133
yading@10 134 // Gray to RGB, required for palette table of grayscale images with bpp < 8
yading@10 135 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
yading@10 136 return x << 16 | x << 8 | x;
yading@10 137 }
yading@10 138
yading@10 139 /**
yading@10 140 * Convert CMAP buffer (stored in extradata) to lavc palette format
yading@10 141 */
yading@10 142 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
yading@10 143 {
yading@10 144 IffContext *s = avctx->priv_data;
yading@10 145 int count, i;
yading@10 146 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
yading@10 147 int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
yading@10 148
yading@10 149 if (avctx->bits_per_coded_sample > 8) {
yading@10 150 av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
yading@10 151 return AVERROR_INVALIDDATA;
yading@10 152 }
yading@10 153
yading@10 154 count = 1 << avctx->bits_per_coded_sample;
yading@10 155 // If extradata is smaller than actually needed, fill the remaining with black.
yading@10 156 count = FFMIN(palette_size / 3, count);
yading@10 157 if (count) {
yading@10 158 for (i=0; i < count; i++) {
yading@10 159 pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
yading@10 160 }
yading@10 161 if (s->flags && count >= 32) { // EHB
yading@10 162 for (i = 0; i < 32; i++)
yading@10 163 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
yading@10 164 count = FFMAX(count, 64);
yading@10 165 }
yading@10 166 } else { // Create gray-scale color palette for bps < 8
yading@10 167 count = 1 << avctx->bits_per_coded_sample;
yading@10 168
yading@10 169 for (i=0; i < count; i++) {
yading@10 170 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
yading@10 171 }
yading@10 172 }
yading@10 173 if (s->masking == MASK_HAS_MASK) {
yading@10 174 memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
yading@10 175 for (i = 0; i < count; i++)
yading@10 176 pal[i] &= 0xFFFFFF;
yading@10 177 } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
yading@10 178 s->transparency < 1 << avctx->bits_per_coded_sample)
yading@10 179 pal[s->transparency] &= 0xFFFFFF;
yading@10 180 return 0;
yading@10 181 }
yading@10 182
yading@10 183 /**
yading@10 184 * Extracts the IFF extra context and updates internal
yading@10 185 * decoder structures.
yading@10 186 *
yading@10 187 * @param avctx the AVCodecContext where to extract extra context to
yading@10 188 * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
yading@10 189 * @return 0 in case of success, a negative error code otherwise
yading@10 190 */
yading@10 191 static int extract_header(AVCodecContext *const avctx,
yading@10 192 const AVPacket *const avpkt) {
yading@10 193 const uint8_t *buf;
yading@10 194 unsigned buf_size;
yading@10 195 IffContext *s = avctx->priv_data;
yading@10 196 int i, palette_size;
yading@10 197
yading@10 198 if (avctx->extradata_size < 2) {
yading@10 199 av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
yading@10 200 return AVERROR_INVALIDDATA;
yading@10 201 }
yading@10 202 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
yading@10 203
yading@10 204 if (avpkt) {
yading@10 205 int image_size;
yading@10 206 if (avpkt->size < 2)
yading@10 207 return AVERROR_INVALIDDATA;
yading@10 208 image_size = avpkt->size - AV_RB16(avpkt->data);
yading@10 209 buf = avpkt->data;
yading@10 210 buf_size = bytestream_get_be16(&buf);
yading@10 211 if (buf_size <= 1 || image_size <= 1) {
yading@10 212 av_log(avctx, AV_LOG_ERROR,
yading@10 213 "Invalid image size received: %u -> image data offset: %d\n",
yading@10 214 buf_size, image_size);
yading@10 215 return AVERROR_INVALIDDATA;
yading@10 216 }
yading@10 217 } else {
yading@10 218 buf = avctx->extradata;
yading@10 219 buf_size = bytestream_get_be16(&buf);
yading@10 220 if (buf_size <= 1 || palette_size < 0) {
yading@10 221 av_log(avctx, AV_LOG_ERROR,
yading@10 222 "Invalid palette size received: %u -> palette data offset: %d\n",
yading@10 223 buf_size, palette_size);
yading@10 224 return AVERROR_INVALIDDATA;
yading@10 225 }
yading@10 226 }
yading@10 227
yading@10 228 if (buf_size >= 41) {
yading@10 229 s->compression = bytestream_get_byte(&buf);
yading@10 230 s->bpp = bytestream_get_byte(&buf);
yading@10 231 s->ham = bytestream_get_byte(&buf);
yading@10 232 s->flags = bytestream_get_byte(&buf);
yading@10 233 s->transparency = bytestream_get_be16(&buf);
yading@10 234 s->masking = bytestream_get_byte(&buf);
yading@10 235 for (i = 0; i < 16; i++)
yading@10 236 s->tvdc[i] = bytestream_get_be16(&buf);
yading@10 237
yading@10 238 if (s->masking == MASK_HAS_MASK) {
yading@10 239 if (s->bpp >= 8 && !s->ham) {
yading@10 240 avctx->pix_fmt = AV_PIX_FMT_RGB32;
yading@10 241 av_freep(&s->mask_buf);
yading@10 242 av_freep(&s->mask_palbuf);
yading@10 243 s->mask_buf = av_malloc((s->planesize * 32) + FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 244 if (!s->mask_buf)
yading@10 245 return AVERROR(ENOMEM);
yading@10 246 if (s->bpp > 16) {
yading@10 247 av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
yading@10 248 av_freep(&s->mask_buf);
yading@10 249 return AVERROR(ENOMEM);
yading@10 250 }
yading@10 251 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 252 if (!s->mask_palbuf) {
yading@10 253 av_freep(&s->mask_buf);
yading@10 254 return AVERROR(ENOMEM);
yading@10 255 }
yading@10 256 }
yading@10 257 s->bpp++;
yading@10 258 } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
yading@10 259 av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
yading@10 260 return AVERROR_PATCHWELCOME;
yading@10 261 }
yading@10 262 if (!s->bpp || s->bpp > 32) {
yading@10 263 av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
yading@10 264 return AVERROR_INVALIDDATA;
yading@10 265 } else if (s->ham >= 8) {
yading@10 266 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
yading@10 267 return AVERROR_INVALIDDATA;
yading@10 268 }
yading@10 269
yading@10 270 av_freep(&s->ham_buf);
yading@10 271 av_freep(&s->ham_palbuf);
yading@10 272
yading@10 273 if (s->ham) {
yading@10 274 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
yading@10 275 int ham_count;
yading@10 276 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
yading@10 277
yading@10 278 s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 279 if (!s->ham_buf)
yading@10 280 return AVERROR(ENOMEM);
yading@10 281
yading@10 282 ham_count = 8 * (1 << s->ham);
yading@10 283 s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 284 if (!s->ham_palbuf) {
yading@10 285 av_freep(&s->ham_buf);
yading@10 286 return AVERROR(ENOMEM);
yading@10 287 }
yading@10 288
yading@10 289 if (count) { // HAM with color palette attached
yading@10 290 // prefill with black and palette and set HAM take direct value mask to zero
yading@10 291 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
yading@10 292 for (i=0; i < count; i++) {
yading@10 293 s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
yading@10 294 }
yading@10 295 count = 1 << s->ham;
yading@10 296 } else { // HAM with grayscale color palette
yading@10 297 count = 1 << s->ham;
yading@10 298 for (i=0; i < count; i++) {
yading@10 299 s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
yading@10 300 s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
yading@10 301 }
yading@10 302 }
yading@10 303 for (i=0; i < count; i++) {
yading@10 304 uint32_t tmp = i << (8 - s->ham);
yading@10 305 tmp |= tmp >> s->ham;
yading@10 306 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
yading@10 307 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
yading@10 308 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
yading@10 309 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
yading@10 310 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
yading@10 311 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
yading@10 312 }
yading@10 313 if (s->masking == MASK_HAS_MASK) {
yading@10 314 for (i = 0; i < ham_count; i++)
yading@10 315 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
yading@10 316 }
yading@10 317 }
yading@10 318 }
yading@10 319
yading@10 320 return 0;
yading@10 321 }
yading@10 322
yading@10 323 static av_cold int decode_init(AVCodecContext *avctx)
yading@10 324 {
yading@10 325 IffContext *s = avctx->priv_data;
yading@10 326 int err;
yading@10 327
yading@10 328 if (avctx->bits_per_coded_sample <= 8) {
yading@10 329 int palette_size;
yading@10 330
yading@10 331 if (avctx->extradata_size >= 2)
yading@10 332 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
yading@10 333 else
yading@10 334 palette_size = 0;
yading@10 335 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
yading@10 336 (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
yading@10 337 } else if (avctx->bits_per_coded_sample <= 32) {
yading@10 338 if (avctx->codec_tag == MKTAG('R','G','B','8')) {
yading@10 339 avctx->pix_fmt = AV_PIX_FMT_RGB32;
yading@10 340 } else if (avctx->codec_tag == MKTAG('R','G','B','N')) {
yading@10 341 avctx->pix_fmt = AV_PIX_FMT_RGB444;
yading@10 342 } else if (avctx->codec_tag != MKTAG('D','E','E','P')) {
yading@10 343 if (avctx->bits_per_coded_sample == 24) {
yading@10 344 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
yading@10 345 } else if (avctx->bits_per_coded_sample == 32) {
yading@10 346 avctx->pix_fmt = AV_PIX_FMT_BGR32;
yading@10 347 } else {
yading@10 348 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
yading@10 349 return AVERROR_PATCHWELCOME;
yading@10 350 }
yading@10 351 }
yading@10 352 } else {
yading@10 353 return AVERROR_INVALIDDATA;
yading@10 354 }
yading@10 355
yading@10 356 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
yading@10 357 return err;
yading@10 358 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
yading@10 359 s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
yading@10 360 if (!s->planebuf)
yading@10 361 return AVERROR(ENOMEM);
yading@10 362
yading@10 363 s->bpp = avctx->bits_per_coded_sample;
yading@10 364 s->frame = av_frame_alloc();
yading@10 365 if (!s->frame)
yading@10 366 return AVERROR(ENOMEM);
yading@10 367
yading@10 368 if ((err = extract_header(avctx, NULL)) < 0)
yading@10 369 return err;
yading@10 370
yading@10 371 return 0;
yading@10 372 }
yading@10 373
yading@10 374 /**
yading@10 375 * Decode interleaved plane buffer up to 8bpp
yading@10 376 * @param dst Destination buffer
yading@10 377 * @param buf Source buffer
yading@10 378 * @param buf_size
yading@10 379 * @param plane plane number to decode as
yading@10 380 */
yading@10 381 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
yading@10 382 {
yading@10 383 const uint64_t *lut = plane8_lut[plane];
yading@10 384 if (plane >= 8) {
yading@10 385 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
yading@10 386 return;
yading@10 387 }
yading@10 388 do {
yading@10 389 uint64_t v = AV_RN64A(dst) | lut[*buf++];
yading@10 390 AV_WN64A(dst, v);
yading@10 391 dst += 8;
yading@10 392 } while (--buf_size);
yading@10 393 }
yading@10 394
yading@10 395 /**
yading@10 396 * Decode interleaved plane buffer up to 24bpp
yading@10 397 * @param dst Destination buffer
yading@10 398 * @param buf Source buffer
yading@10 399 * @param buf_size
yading@10 400 * @param plane plane number to decode as
yading@10 401 */
yading@10 402 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
yading@10 403 {
yading@10 404 const uint32_t *lut = plane32_lut[plane];
yading@10 405 do {
yading@10 406 unsigned mask = (*buf >> 2) & ~3;
yading@10 407 dst[0] |= lut[mask++];
yading@10 408 dst[1] |= lut[mask++];
yading@10 409 dst[2] |= lut[mask++];
yading@10 410 dst[3] |= lut[mask];
yading@10 411 mask = (*buf++ << 2) & 0x3F;
yading@10 412 dst[4] |= lut[mask++];
yading@10 413 dst[5] |= lut[mask++];
yading@10 414 dst[6] |= lut[mask++];
yading@10 415 dst[7] |= lut[mask];
yading@10 416 dst += 8;
yading@10 417 } while (--buf_size);
yading@10 418 }
yading@10 419
yading@10 420 #define DECODE_HAM_PLANE32(x) \
yading@10 421 first = buf[x] << 1; \
yading@10 422 second = buf[(x)+1] << 1; \
yading@10 423 delta &= pal[first++]; \
yading@10 424 delta |= pal[first]; \
yading@10 425 dst[x] = delta; \
yading@10 426 delta &= pal[second++]; \
yading@10 427 delta |= pal[second]; \
yading@10 428 dst[(x)+1] = delta
yading@10 429
yading@10 430 /**
yading@10 431 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
yading@10 432 *
yading@10 433 * @param dst the destination 24bpp buffer
yading@10 434 * @param buf the source 8bpp chunky buffer
yading@10 435 * @param pal the HAM decode table
yading@10 436 * @param buf_size the plane size in bytes
yading@10 437 */
yading@10 438 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
yading@10 439 const uint32_t *const pal, unsigned buf_size)
yading@10 440 {
yading@10 441 uint32_t delta = pal[1]; /* first palette entry */
yading@10 442 do {
yading@10 443 uint32_t first, second;
yading@10 444 DECODE_HAM_PLANE32(0);
yading@10 445 DECODE_HAM_PLANE32(2);
yading@10 446 DECODE_HAM_PLANE32(4);
yading@10 447 DECODE_HAM_PLANE32(6);
yading@10 448 buf += 8;
yading@10 449 dst += 8;
yading@10 450 } while (--buf_size);
yading@10 451 }
yading@10 452
yading@10 453 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
yading@10 454 const uint32_t *const pal, unsigned width)
yading@10 455 {
yading@10 456 do {
yading@10 457 *dst++ = pal[*buf++];
yading@10 458 } while (--width);
yading@10 459 }
yading@10 460
yading@10 461 /**
yading@10 462 * Decode one complete byterun1 encoded line.
yading@10 463 *
yading@10 464 * @param dst the destination buffer where to store decompressed bitstream
yading@10 465 * @param dst_size the destination plane size in bytes
yading@10 466 * @param buf the source byterun1 compressed bitstream
yading@10 467 * @param buf_end the EOF of source byterun1 compressed bitstream
yading@10 468 * @return number of consumed bytes in byterun1 compressed bitstream
yading@10 469 */
yading@10 470 static int decode_byterun(uint8_t *dst, int dst_size,
yading@10 471 const uint8_t *buf, const uint8_t *const buf_end) {
yading@10 472 const uint8_t *const buf_start = buf;
yading@10 473 unsigned x;
yading@10 474 for (x = 0; x < dst_size && buf < buf_end;) {
yading@10 475 unsigned length;
yading@10 476 const int8_t value = *buf++;
yading@10 477 if (value >= 0) {
yading@10 478 length = value + 1;
yading@10 479 memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
yading@10 480 buf += length;
yading@10 481 } else if (value > -128) {
yading@10 482 length = -value + 1;
yading@10 483 memset(dst + x, *buf++, FFMIN(length, dst_size - x));
yading@10 484 } else { // noop
yading@10 485 continue;
yading@10 486 }
yading@10 487 x += length;
yading@10 488 }
yading@10 489 return buf - buf_start;
yading@10 490 }
yading@10 491
yading@10 492 #define DECODE_RGBX_COMMON(type) \
yading@10 493 if (!length) { \
yading@10 494 length = bytestream2_get_byte(gb); \
yading@10 495 if (!length) { \
yading@10 496 length = bytestream2_get_be16(gb); \
yading@10 497 if (!length) \
yading@10 498 return; \
yading@10 499 } \
yading@10 500 } \
yading@10 501 for (i = 0; i < length; i++) { \
yading@10 502 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
yading@10 503 x += 1; \
yading@10 504 if (x >= width) { \
yading@10 505 y += 1; \
yading@10 506 if (y >= height) \
yading@10 507 return; \
yading@10 508 x = 0; \
yading@10 509 } \
yading@10 510 }
yading@10 511
yading@10 512 /**
yading@10 513 * Decode RGB8 buffer
yading@10 514 * @param[out] dst Destination buffer
yading@10 515 * @param width Width of destination buffer (pixels)
yading@10 516 * @param height Height of destination buffer (pixels)
yading@10 517 * @param linesize Line size of destination buffer (bytes)
yading@10 518 */
yading@10 519 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
yading@10 520 {
yading@10 521 int x = 0, y = 0, i, length;
yading@10 522 while (bytestream2_get_bytes_left(gb) >= 4) {
yading@10 523 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
yading@10 524 length = bytestream2_get_byte(gb) & 0x7F;
yading@10 525 DECODE_RGBX_COMMON(uint32_t)
yading@10 526 }
yading@10 527 }
yading@10 528
yading@10 529 /**
yading@10 530 * Decode RGBN buffer
yading@10 531 * @param[out] dst Destination buffer
yading@10 532 * @param width Width of destination buffer (pixels)
yading@10 533 * @param height Height of destination buffer (pixels)
yading@10 534 * @param linesize Line size of destination buffer (bytes)
yading@10 535 */
yading@10 536 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
yading@10 537 {
yading@10 538 int x = 0, y = 0, i, length;
yading@10 539 while (bytestream2_get_bytes_left(gb) >= 2) {
yading@10 540 uint32_t pixel = bytestream2_get_be16u(gb);
yading@10 541 length = pixel & 0x7;
yading@10 542 pixel >>= 4;
yading@10 543 DECODE_RGBX_COMMON(uint16_t)
yading@10 544 }
yading@10 545 }
yading@10 546
yading@10 547 /**
yading@10 548 * Decode DEEP RLE 32-bit buffer
yading@10 549 * @param[out] dst Destination buffer
yading@10 550 * @param[in] src Source buffer
yading@10 551 * @param src_size Source buffer size (bytes)
yading@10 552 * @param width Width of destination buffer (pixels)
yading@10 553 * @param height Height of destination buffer (pixels)
yading@10 554 * @param linesize Line size of destination buffer (bytes)
yading@10 555 */
yading@10 556 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
yading@10 557 {
yading@10 558 const uint8_t *src_end = src + src_size;
yading@10 559 int x = 0, y = 0, i;
yading@10 560 while (src + 5 <= src_end) {
yading@10 561 int opcode;
yading@10 562 opcode = *(int8_t *)src++;
yading@10 563 if (opcode >= 0) {
yading@10 564 int size = opcode + 1;
yading@10 565 for (i = 0; i < size; i++) {
yading@10 566 int length = FFMIN(size - i, width);
yading@10 567 memcpy(dst + y*linesize + x * 4, src, length * 4);
yading@10 568 src += length * 4;
yading@10 569 x += length;
yading@10 570 i += length;
yading@10 571 if (x >= width) {
yading@10 572 x = 0;
yading@10 573 y += 1;
yading@10 574 if (y >= height)
yading@10 575 return;
yading@10 576 }
yading@10 577 }
yading@10 578 } else {
yading@10 579 int size = -opcode + 1;
yading@10 580 uint32_t pixel = AV_RN32(src);
yading@10 581 for (i = 0; i < size; i++) {
yading@10 582 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
yading@10 583 x += 1;
yading@10 584 if (x >= width) {
yading@10 585 x = 0;
yading@10 586 y += 1;
yading@10 587 if (y >= height)
yading@10 588 return;
yading@10 589 }
yading@10 590 }
yading@10 591 src += 4;
yading@10 592 }
yading@10 593 }
yading@10 594 }
yading@10 595
yading@10 596 /**
yading@10 597 * Decode DEEP TVDC 32-bit buffer
yading@10 598 * @param[out] dst Destination buffer
yading@10 599 * @param[in] src Source buffer
yading@10 600 * @param src_size Source buffer size (bytes)
yading@10 601 * @param width Width of destination buffer (pixels)
yading@10 602 * @param height Height of destination buffer (pixels)
yading@10 603 * @param linesize Line size of destination buffer (bytes)
yading@10 604 * @param[int] tvdc TVDC lookup table
yading@10 605 */
yading@10 606 static void decode_deep_tvdc32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize, const int16_t *tvdc)
yading@10 607 {
yading@10 608 int x = 0, y = 0, plane = 0;
yading@10 609 int8_t pixel = 0;
yading@10 610 int i, j;
yading@10 611
yading@10 612 for (i = 0; i < src_size * 2;) {
yading@10 613 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
yading@10 614 int d = tvdc[GETNIBBLE];
yading@10 615 i++;
yading@10 616 if (d) {
yading@10 617 pixel += d;
yading@10 618 dst[y * linesize + x*4 + plane] = pixel;
yading@10 619 x++;
yading@10 620 } else {
yading@10 621 if (i >= src_size * 2)
yading@10 622 return;
yading@10 623 d = GETNIBBLE + 1;
yading@10 624 i++;
yading@10 625 d = FFMIN(d, width - x);
yading@10 626 for (j = 0; j < d; j++) {
yading@10 627 dst[y * linesize + x*4 + plane] = pixel;
yading@10 628 x++;
yading@10 629 }
yading@10 630 }
yading@10 631 if (x >= width) {
yading@10 632 plane++;
yading@10 633 if (plane >= 4) {
yading@10 634 y++;
yading@10 635 if (y >= height)
yading@10 636 return;
yading@10 637 plane = 0;
yading@10 638 }
yading@10 639 x = 0;
yading@10 640 pixel = 0;
yading@10 641 i = (i + 1) & ~1;
yading@10 642 }
yading@10 643 }
yading@10 644 }
yading@10 645
yading@10 646 static int unsupported(AVCodecContext *avctx)
yading@10 647 {
yading@10 648 IffContext *s = avctx->priv_data;
yading@10 649 avpriv_request_sample(avctx, "bitmap (compression %i, bpp %i, ham %i)", s->compression, s->bpp, s->ham);
yading@10 650 return AVERROR_INVALIDDATA;
yading@10 651 }
yading@10 652
yading@10 653 static int decode_frame(AVCodecContext *avctx,
yading@10 654 void *data, int *got_frame,
yading@10 655 AVPacket *avpkt)
yading@10 656 {
yading@10 657 IffContext *s = avctx->priv_data;
yading@10 658 const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
yading@10 659 const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
yading@10 660 const uint8_t *buf_end = buf+buf_size;
yading@10 661 int y, plane, res;
yading@10 662 GetByteContext gb;
yading@10 663
yading@10 664 if ((res = extract_header(avctx, avpkt)) < 0)
yading@10 665 return res;
yading@10 666 if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
yading@10 667 return res;
yading@10 668 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
yading@10 669 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
yading@10 670 if ((res = cmap_read_palette(avctx, (uint32_t*)s->frame->data[1])) < 0)
yading@10 671 return res;
yading@10 672 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
yading@10 673 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
yading@10 674 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
yading@10 675 return res;
yading@10 676 }
yading@10 677 s->init = 1;
yading@10 678
yading@10 679 switch (s->compression) {
yading@10 680 case 0:
yading@10 681 if (avctx->codec_tag == MKTAG('A','C','B','M')) {
yading@10 682 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
yading@10 683 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
yading@10 684 for (plane = 0; plane < s->bpp; plane++) {
yading@10 685 for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
yading@10 686 uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
yading@10 687 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
yading@10 688 buf += s->planesize;
yading@10 689 }
yading@10 690 }
yading@10 691 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
yading@10 692 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
yading@10 693 for(y = 0; y < avctx->height; y++) {
yading@10 694 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
yading@10 695 memset(s->ham_buf, 0, s->planesize * 8);
yading@10 696 for (plane = 0; plane < s->bpp; plane++) {
yading@10 697 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
yading@10 698 if (start >= buf_end)
yading@10 699 break;
yading@10 700 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
yading@10 701 }
yading@10 702 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
yading@10 703 }
yading@10 704 } else
yading@10 705 return unsupported(avctx);
yading@10 706 } else if (avctx->codec_tag == MKTAG('D','E','E','P')) {
yading@10 707 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
yading@10 708 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
yading@10 709 int x;
yading@10 710 for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
yading@10 711 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
yading@10 712 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
yading@10 713 buf += raw_width;
yading@10 714 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
yading@10 715 for(x = 0; x < avctx->width; x++)
yading@10 716 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
yading@10 717 }
yading@10 718 }
yading@10 719 } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
yading@10 720 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
yading@10 721 for(y = 0; y < avctx->height; y++ ) {
yading@10 722 uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
yading@10 723 memset(row, 0, avctx->width);
yading@10 724 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
yading@10 725 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
yading@10 726 buf += s->planesize;
yading@10 727 }
yading@10 728 }
yading@10 729 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
yading@10 730 for (y = 0; y < avctx->height; y++) {
yading@10 731 uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
yading@10 732 memset(s->ham_buf, 0, s->planesize * 8);
yading@10 733 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
yading@10 734 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
yading@10 735 buf += s->planesize;
yading@10 736 }
yading@10 737 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
yading@10 738 }
yading@10 739 } else { // AV_PIX_FMT_BGR32
yading@10 740 for(y = 0; y < avctx->height; y++ ) {
yading@10 741 uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
yading@10 742 memset(row, 0, avctx->width << 2);
yading@10 743 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
yading@10 744 decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
yading@10 745 buf += s->planesize;
yading@10 746 }
yading@10 747 }
yading@10 748 }
yading@10 749 } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
yading@10 750 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
yading@10 751 for(y = 0; y < avctx->height && buf_end > buf; y++ ) {
yading@10 752 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
yading@10 753 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
yading@10 754 buf += avctx->width + (avctx->width % 2); // padding if odd
yading@10 755 }
yading@10 756 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
yading@10 757 for (y = 0; y < avctx->height && buf_end > buf; y++) {
yading@10 758 uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
yading@10 759 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
yading@10 760 buf += avctx->width + (avctx->width & 1); // padding if odd
yading@10 761 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
yading@10 762 }
yading@10 763 } else
yading@10 764 return unsupported(avctx);
yading@10 765 }
yading@10 766 break;
yading@10 767 case 1:
yading@10 768 if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
yading@10 769 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
yading@10 770 for(y = 0; y < avctx->height ; y++ ) {
yading@10 771 uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
yading@10 772 memset(row, 0, avctx->width);
yading@10 773 for (plane = 0; plane < s->bpp; plane++) {
yading@10 774 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
yading@10 775 decodeplane8(row, s->planebuf, s->planesize, plane);
yading@10 776 }
yading@10 777 }
yading@10 778 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
yading@10 779 for (y = 0; y < avctx->height ; y++ ) {
yading@10 780 uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
yading@10 781 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
yading@10 782 for (plane = 0; plane < s->bpp; plane++) {
yading@10 783 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
yading@10 784 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
yading@10 785 }
yading@10 786 lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width);
yading@10 787 }
yading@10 788 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
yading@10 789 for (y = 0; y < avctx->height ; y++) {
yading@10 790 uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
yading@10 791 memset(s->ham_buf, 0, s->planesize * 8);
yading@10 792 for (plane = 0; plane < s->bpp; plane++) {
yading@10 793 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
yading@10 794 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
yading@10 795 }
yading@10 796 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
yading@10 797 }
yading@10 798 } else { //AV_PIX_FMT_BGR32
yading@10 799 for(y = 0; y < avctx->height ; y++ ) {
yading@10 800 uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
yading@10 801 memset(row, 0, avctx->width << 2);
yading@10 802 for (plane = 0; plane < s->bpp; plane++) {
yading@10 803 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
yading@10 804 decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
yading@10 805 }
yading@10 806 }
yading@10 807 }
yading@10 808 } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
yading@10 809 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
yading@10 810 for(y = 0; y < avctx->height ; y++ ) {
yading@10 811 uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
yading@10 812 buf += decode_byterun(row, avctx->width, buf, buf_end);
yading@10 813 }
yading@10 814 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
yading@10 815 for (y = 0; y < avctx->height ; y++) {
yading@10 816 uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
yading@10 817 buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
yading@10 818 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
yading@10 819 }
yading@10 820 } else
yading@10 821 return unsupported(avctx);
yading@10 822 } else if (avctx->codec_tag == MKTAG('D','E','E','P')) { // IFF-DEEP
yading@10 823 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
yading@10 824 if (av_get_bits_per_pixel(desc) == 32)
yading@10 825 decode_deep_rle32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0]);
yading@10 826 else
yading@10 827 return unsupported(avctx);
yading@10 828 }
yading@10 829 break;
yading@10 830 case 4:
yading@10 831 bytestream2_init(&gb, buf, buf_size);
yading@10 832 if (avctx->codec_tag == MKTAG('R','G','B','8'))
yading@10 833 decode_rgb8(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
yading@10 834 else if (avctx->codec_tag == MKTAG('R','G','B','N'))
yading@10 835 decode_rgbn(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
yading@10 836 else
yading@10 837 return unsupported(avctx);
yading@10 838 break;
yading@10 839 case 5:
yading@10 840 if (avctx->codec_tag == MKTAG('D','E','E','P')) {
yading@10 841 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
yading@10 842 if (av_get_bits_per_pixel(desc) == 32)
yading@10 843 decode_deep_tvdc32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0], s->tvdc);
yading@10 844 else
yading@10 845 return unsupported(avctx);
yading@10 846 } else
yading@10 847 return unsupported(avctx);
yading@10 848 break;
yading@10 849 default:
yading@10 850 return unsupported(avctx);
yading@10 851 }
yading@10 852
yading@10 853 if ((res = av_frame_ref(data, s->frame)) < 0)
yading@10 854 return res;
yading@10 855
yading@10 856 *got_frame = 1;
yading@10 857
yading@10 858 return buf_size;
yading@10 859 }
yading@10 860
yading@10 861 static av_cold int decode_end(AVCodecContext *avctx)
yading@10 862 {
yading@10 863 IffContext *s = avctx->priv_data;
yading@10 864 av_frame_free(&s->frame);
yading@10 865 av_freep(&s->planebuf);
yading@10 866 av_freep(&s->ham_buf);
yading@10 867 av_freep(&s->ham_palbuf);
yading@10 868 return 0;
yading@10 869 }
yading@10 870
yading@10 871 #if CONFIG_IFF_ILBM_DECODER
yading@10 872 AVCodec ff_iff_ilbm_decoder = {
yading@10 873 .name = "iff",
yading@10 874 .type = AVMEDIA_TYPE_VIDEO,
yading@10 875 .id = AV_CODEC_ID_IFF_ILBM,
yading@10 876 .priv_data_size = sizeof(IffContext),
yading@10 877 .init = decode_init,
yading@10 878 .close = decode_end,
yading@10 879 .decode = decode_frame,
yading@10 880 .capabilities = CODEC_CAP_DR1,
yading@10 881 .long_name = NULL_IF_CONFIG_SMALL("IFF"),
yading@10 882 };
yading@10 883 #endif
yading@10 884 #if CONFIG_IFF_BYTERUN1_DECODER
yading@10 885 AVCodec ff_iff_byterun1_decoder = {
yading@10 886 .name = "iff",
yading@10 887 .type = AVMEDIA_TYPE_VIDEO,
yading@10 888 .id = AV_CODEC_ID_IFF_BYTERUN1,
yading@10 889 .priv_data_size = sizeof(IffContext),
yading@10 890 .init = decode_init,
yading@10 891 .close = decode_end,
yading@10 892 .decode = decode_frame,
yading@10 893 .capabilities = CODEC_CAP_DR1,
yading@10 894 .long_name = NULL_IF_CONFIG_SMALL("IFF"),
yading@10 895 };
yading@10 896 #endif