libavcodec/iff.c
Go to the documentation of this file.
00001 /*
00002  * IFF PBM/ILBM bitmap decoder
00003  * Copyright (c) 2010 Peter Ross <pross@xvid.org>
00004  * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
00005  *
00006  * This file is part of FFmpeg.
00007  *
00008  * FFmpeg is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * FFmpeg is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with FFmpeg; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00028 #include "libavutil/imgutils.h"
00029 #include "bytestream.h"
00030 #include "avcodec.h"
00031 #include "get_bits.h"
00032 
00033 // TODO: masking bits
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; // 1 if buffer and palette data already initialized, 0 otherwise
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 // 8 planes * 8-bit mask
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 // 32 planes * 4-bit mask * 4 lookup tables each
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 // Gray to RGB, required for palette table of grayscale images with bpp < 8
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     // If extradata is smaller than actually needed, fill the remaining with black.
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) { // EHB
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 { // Create gray-scale color palette for bps < 8
00165         count = 1 << avctx->bits_per_coded_sample;
00166 
00167         for (i=0; i < count; i++) {
00168             pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
00169         }
00170     }
00171     if (s->masking == MASK_HAS_MASK) {
00172         memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
00173         for (i = 0; i < count; i++)
00174             pal[i] &= 0xFFFFFF;
00175     } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
00176         s->transparency < 1 << avctx->bits_per_coded_sample)
00177         pal[s->transparency] &= 0xFFFFFF;
00178     return 0;
00179 }
00180 
00189 static int extract_header(AVCodecContext *const avctx,
00190                           const AVPacket *const avpkt) {
00191     const uint8_t *buf;
00192     unsigned buf_size;
00193     IffContext *s = avctx->priv_data;
00194     int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
00195 
00196     if (avpkt) {
00197         int image_size;
00198         if (avpkt->size < 2)
00199             return AVERROR_INVALIDDATA;
00200         image_size = avpkt->size - AV_RB16(avpkt->data);
00201         buf = avpkt->data;
00202         buf_size = bytestream_get_be16(&buf);
00203         if (buf_size <= 1 || image_size <= 1) {
00204             av_log(avctx, AV_LOG_ERROR,
00205                    "Invalid image size received: %u -> image data offset: %d\n",
00206                    buf_size, image_size);
00207             return AVERROR_INVALIDDATA;
00208         }
00209     } else {
00210         if (avctx->extradata_size < 2)
00211             return AVERROR_INVALIDDATA;
00212         buf = avctx->extradata;
00213         buf_size = bytestream_get_be16(&buf);
00214         if (buf_size <= 1 || palette_size < 0) {
00215             av_log(avctx, AV_LOG_ERROR,
00216                    "Invalid palette size received: %u -> palette data offset: %d\n",
00217                    buf_size, palette_size);
00218             return AVERROR_INVALIDDATA;
00219         }
00220     }
00221 
00222     if (buf_size > 8) {
00223         s->compression  = bytestream_get_byte(&buf);
00224         s->bpp          = bytestream_get_byte(&buf);
00225         s->ham          = bytestream_get_byte(&buf);
00226         s->flags        = bytestream_get_byte(&buf);
00227         s->transparency = bytestream_get_be16(&buf);
00228         s->masking      = bytestream_get_byte(&buf);
00229         if (s->masking == MASK_HAS_MASK) {
00230             if (s->bpp >= 8) {
00231                 avctx->pix_fmt = PIX_FMT_RGB32;
00232                 av_freep(&s->mask_buf);
00233                 av_freep(&s->mask_palbuf);
00234                 s->mask_buf = av_malloc((s->planesize * 32) + FF_INPUT_BUFFER_PADDING_SIZE);
00235                 if (!s->mask_buf)
00236                     return AVERROR(ENOMEM);
00237                 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
00238                 if (!s->mask_palbuf) {
00239                     av_freep(&s->mask_buf);
00240                     return AVERROR(ENOMEM);
00241                 }
00242             }
00243             s->bpp++;
00244         } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
00245             av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
00246             return AVERROR_PATCHWELCOME;
00247         }
00248         if (!s->bpp || s->bpp > 32) {
00249             av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
00250             return AVERROR_INVALIDDATA;
00251         } else if (s->ham >= 8) {
00252             av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
00253             return AVERROR_INVALIDDATA;
00254         }
00255 
00256         av_freep(&s->ham_buf);
00257         av_freep(&s->ham_palbuf);
00258 
00259         if (s->ham) {
00260             int i, count = FFMIN(palette_size / 3, 1 << s->ham);
00261             int ham_count;
00262             const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
00263 
00264             s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
00265             if (!s->ham_buf)
00266                 return AVERROR(ENOMEM);
00267 
00268             ham_count = 8 * (1 << s->ham);
00269             s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
00270             if (!s->ham_palbuf) {
00271                 av_freep(&s->ham_buf);
00272                 return AVERROR(ENOMEM);
00273             }
00274 
00275             if (count) { // HAM with color palette attached
00276                 // prefill with black and palette and set HAM take direct value mask to zero
00277                 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
00278                 for (i=0; i < count; i++) {
00279                     s->ham_palbuf[i*2+1] = AV_RL24(palette + i*3);
00280                 }
00281                 count = 1 << s->ham;
00282             } else { // HAM with grayscale color palette
00283                 count = 1 << s->ham;
00284                 for (i=0; i < count; i++) {
00285                     s->ham_palbuf[i*2]   = 0; // take direct color value from palette
00286                     s->ham_palbuf[i*2+1] = av_le2ne32(gray2rgb((i * 255) >> s->ham));
00287                 }
00288             }
00289             for (i=0; i < count; i++) {
00290                 uint32_t tmp = i << (8 - s->ham);
00291                 tmp |= tmp >> s->ham;
00292                 s->ham_palbuf[(i+count)*2]     = 0x00FFFF; // just modify blue color component
00293                 s->ham_palbuf[(i+count*2)*2]   = 0xFFFF00; // just modify red color component
00294                 s->ham_palbuf[(i+count*3)*2]   = 0xFF00FF; // just modify green color component
00295                 s->ham_palbuf[(i+count)*2+1]   = tmp << 16;
00296                 s->ham_palbuf[(i+count*2)*2+1] = tmp;
00297                 s->ham_palbuf[(i+count*3)*2+1] = tmp << 8;
00298             }
00299             if (s->masking == MASK_HAS_MASK) {
00300                 for (i = 0; i < ham_count; i++)
00301                     s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
00302             }
00303         }
00304     }
00305 
00306     return 0;
00307 }
00308 
00309 static av_cold int decode_init(AVCodecContext *avctx)
00310 {
00311     IffContext *s = avctx->priv_data;
00312     int err;
00313 
00314     if (avctx->bits_per_coded_sample <= 8) {
00315         int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
00316         avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
00317                          (avctx->extradata_size >= 2 && palette_size) ? PIX_FMT_PAL8 : PIX_FMT_GRAY8;
00318     } else if (avctx->bits_per_coded_sample <= 32) {
00319         avctx->pix_fmt = PIX_FMT_BGR32;
00320     } else {
00321         return AVERROR_INVALIDDATA;
00322     }
00323 
00324     if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
00325         return err;
00326     s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
00327     s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
00328     if (!s->planebuf)
00329         return AVERROR(ENOMEM);
00330 
00331     s->bpp = avctx->bits_per_coded_sample;
00332     avcodec_get_frame_defaults(&s->frame);
00333 
00334     if ((err = extract_header(avctx, NULL)) < 0)
00335         return err;
00336     s->frame.reference = 3;
00337 
00338     return 0;
00339 }
00340 
00348 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
00349 {
00350     const uint64_t *lut = plane8_lut[plane];
00351     do {
00352         uint64_t v = AV_RN64A(dst) | lut[*buf++];
00353         AV_WN64A(dst, v);
00354         dst += 8;
00355     } while (--buf_size);
00356 }
00357 
00365 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
00366 {
00367     const uint32_t *lut = plane32_lut[plane];
00368     do {
00369         unsigned mask = (*buf >> 2) & ~3;
00370         dst[0] |= lut[mask++];
00371         dst[1] |= lut[mask++];
00372         dst[2] |= lut[mask++];
00373         dst[3] |= lut[mask];
00374         mask = (*buf++ << 2) & 0x3F;
00375         dst[4] |= lut[mask++];
00376         dst[5] |= lut[mask++];
00377         dst[6] |= lut[mask++];
00378         dst[7] |= lut[mask];
00379         dst += 8;
00380     } while (--buf_size);
00381 }
00382 
00383 #define DECODE_HAM_PLANE32(x)       \
00384     first       = buf[x] << 1;      \
00385     second      = buf[(x)+1] << 1;  \
00386     delta      &= pal[first++];     \
00387     delta      |= pal[first];       \
00388     dst[x]      = delta;            \
00389     delta      &= pal[second++];    \
00390     delta      |= pal[second];      \
00391     dst[(x)+1]  = delta
00392 
00401 static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
00402                                const uint32_t *const pal, unsigned buf_size)
00403 {
00404     uint32_t delta = 0;
00405     do {
00406         uint32_t first, second;
00407         DECODE_HAM_PLANE32(0);
00408         DECODE_HAM_PLANE32(2);
00409         DECODE_HAM_PLANE32(4);
00410         DECODE_HAM_PLANE32(6);
00411         buf += 8;
00412         dst += 8;
00413     } while (--buf_size);
00414 }
00415 
00416 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
00417                          const uint32_t *const pal, unsigned width)
00418 {
00419     do {
00420         *dst++ = pal[*buf++];
00421     } while (--width);
00422 }
00423 
00433 static int decode_byterun(uint8_t *dst, int dst_size,
00434                           const uint8_t *buf, const uint8_t *const buf_end) {
00435     const uint8_t *const buf_start = buf;
00436     unsigned x;
00437     for (x = 0; x < dst_size && buf < buf_end;) {
00438         unsigned length;
00439         const int8_t value = *buf++;
00440         if (value >= 0) {
00441             length = value + 1;
00442             memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
00443             buf += length;
00444         } else if (value > -128) {
00445             length = -value + 1;
00446             memset(dst + x, *buf++, FFMIN(length, dst_size - x));
00447         } else { // noop
00448             continue;
00449         }
00450         x += length;
00451     }
00452     return buf - buf_start;
00453 }
00454 
00455 static int decode_frame_ilbm(AVCodecContext *avctx,
00456                             void *data, int *data_size,
00457                             AVPacket *avpkt)
00458 {
00459     IffContext *s = avctx->priv_data;
00460     const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
00461     const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
00462     const uint8_t *buf_end = buf+buf_size;
00463     int y, plane, res;
00464 
00465     if ((res = extract_header(avctx, avpkt)) < 0)
00466         return res;
00467 
00468     if (s->init) {
00469         if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
00470             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00471             return res;
00472         }
00473     } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
00474         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00475         return res;
00476     } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != PIX_FMT_GRAY8) {
00477         if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
00478             return res;
00479     }
00480     s->init = 1;
00481 
00482     if (avctx->codec_tag == MKTAG('A','C','B','M')) {
00483         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00484             memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
00485             for (plane = 0; plane < s->bpp; plane++) {
00486                 for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
00487                     uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00488                     decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00489                     buf += s->planesize;
00490                 }
00491             }
00492         } else if (s->ham) { // HAM to PIX_FMT_BGR32
00493             memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
00494             for(y = 0; y < avctx->height; y++) {
00495                 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00496                 memset(s->ham_buf, 0, s->planesize * 8);
00497                 for (plane = 0; plane < s->bpp; plane++) {
00498                     const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
00499                     if (start >= buf_end)
00500                         break;
00501                     decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
00502                 }
00503                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00504             }
00505         }
00506     } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
00507         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00508             for(y = 0; y < avctx->height; y++ ) {
00509                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00510                 memset(row, 0, avctx->width);
00511                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00512                     decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00513                     buf += s->planesize;
00514                 }
00515             }
00516         } else if (s->ham) { // HAM to PIX_FMT_BGR32
00517             for (y = 0; y < avctx->height; y++) {
00518                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00519                 memset(s->ham_buf, 0, s->planesize * 8);
00520                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00521                     decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
00522                     buf += s->planesize;
00523                 }
00524                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00525             }
00526         } else { // PIX_FMT_BGR32
00527             for(y = 0; y < avctx->height; y++ ) {
00528                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00529                 memset(row, 0, avctx->width << 2);
00530                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00531                     decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00532                     buf += s->planesize;
00533                 }
00534             }
00535         }
00536     } else if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { // IFF-PBM
00537         for(y = 0; y < avctx->height; y++ ) {
00538             uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00539             memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
00540             buf += avctx->width + (avctx->width % 2); // padding if odd
00541         }
00542     } else { // IFF-PBM: HAM to PIX_FMT_BGR32
00543         for (y = 0; y < avctx->height; y++) {
00544             uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00545             memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
00546             buf += avctx->width + (avctx->width & 1); // padding if odd
00547             decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, avctx->width);
00548         }
00549     }
00550 
00551     *data_size = sizeof(AVFrame);
00552     *(AVFrame*)data = s->frame;
00553     return buf_size;
00554 }
00555 
00556 static int decode_frame_byterun1(AVCodecContext *avctx,
00557                             void *data, int *data_size,
00558                             AVPacket *avpkt)
00559 {
00560     IffContext *s = avctx->priv_data;
00561     const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
00562     const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
00563     const uint8_t *buf_end = buf+buf_size;
00564     int y, plane, res;
00565 
00566     if ((res = extract_header(avctx, avpkt)) < 0)
00567         return res;
00568     if (s->init) {
00569         if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
00570             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00571             return res;
00572         }
00573     } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
00574         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00575         return res;
00576     } else if (avctx->pix_fmt == PIX_FMT_PAL8) {
00577         if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
00578             return res;
00579     } else if (avctx->pix_fmt == PIX_FMT_RGB32 && avctx->bits_per_coded_sample <= 8) {
00580         if ((res = ff_cmap_read_palette(avctx, s->mask_palbuf)) < 0)
00581             return res;
00582     }
00583     s->init = 1;
00584 
00585     if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
00586         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00587             for(y = 0; y < avctx->height ; y++ ) {
00588                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00589                 memset(row, 0, avctx->width);
00590                 for (plane = 0; plane < s->bpp; plane++) {
00591                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00592                     decodeplane8(row, s->planebuf, s->planesize, plane);
00593                 }
00594             }
00595         } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to PIX_FMT_BGR32
00596             for (y = 0; y < avctx->height ; y++ ) {
00597                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00598                 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
00599                 for (plane = 0; plane < s->bpp; plane++) {
00600                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00601                     decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
00602                 }
00603                 lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width);
00604             }
00605         } else if (s->ham) { // HAM to PIX_FMT_BGR32
00606             for (y = 0; y < avctx->height ; y++) {
00607                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00608                 memset(s->ham_buf, 0, s->planesize * 8);
00609                 for (plane = 0; plane < s->bpp; plane++) {
00610                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00611                     decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
00612                 }
00613                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00614             }
00615         } else { //PIX_FMT_BGR32
00616             for(y = 0; y < avctx->height ; y++ ) {
00617                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00618                 memset(row, 0, avctx->width << 2);
00619                 for (plane = 0; plane < s->bpp; plane++) {
00620                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00621                     decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
00622                 }
00623             }
00624         }
00625     } else if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { // IFF-PBM
00626         for(y = 0; y < avctx->height ; y++ ) {
00627             uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00628             buf += decode_byterun(row, avctx->width, buf, buf_end);
00629         }
00630     } else { // IFF-PBM: HAM to PIX_FMT_BGR32
00631         for (y = 0; y < avctx->height ; y++) {
00632             uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00633             buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
00634             decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, avctx->width);
00635         }
00636     }
00637 
00638     *data_size = sizeof(AVFrame);
00639     *(AVFrame*)data = s->frame;
00640     return buf_size;
00641 }
00642 
00643 static av_cold int decode_end(AVCodecContext *avctx)
00644 {
00645     IffContext *s = avctx->priv_data;
00646     if (s->frame.data[0])
00647         avctx->release_buffer(avctx, &s->frame);
00648     av_freep(&s->planebuf);
00649     av_freep(&s->ham_buf);
00650     av_freep(&s->ham_palbuf);
00651     return 0;
00652 }
00653 
00654 AVCodec ff_iff_ilbm_decoder = {
00655     .name           = "iff_ilbm",
00656     .type           = AVMEDIA_TYPE_VIDEO,
00657     .id             = CODEC_ID_IFF_ILBM,
00658     .priv_data_size = sizeof(IffContext),
00659     .init           = decode_init,
00660     .close          = decode_end,
00661     .decode         = decode_frame_ilbm,
00662     .capabilities   = CODEC_CAP_DR1,
00663     .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
00664 };
00665 
00666 AVCodec ff_iff_byterun1_decoder = {
00667     .name           = "iff_byterun1",
00668     .type           = AVMEDIA_TYPE_VIDEO,
00669     .id             = CODEC_ID_IFF_BYTERUN1,
00670     .priv_data_size = sizeof(IffContext),
00671     .init           = decode_init,
00672     .close          = decode_end,
00673     .decode         = decode_frame_byterun1,
00674     .capabilities   = CODEC_CAP_DR1,
00675     .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
00676 };