• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

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

Generated on Wed Apr 11 2012 07:31:33 for FFmpeg by  doxygen 1.7.1