• 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;
00180 
00181     if (avctx->extradata_size < 2) {
00182         av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
00183         return AVERROR_INVALIDDATA;
00184     }
00185     palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
00186 
00187     if (avpkt) {
00188         int image_size;
00189         if (avpkt->size < 2)
00190             return AVERROR_INVALIDDATA;
00191         image_size = avpkt->size - AV_RB16(avpkt->data);
00192         buf = avpkt->data;
00193         buf_size = bytestream_get_be16(&buf);
00194         if (buf_size <= 1 || image_size <= 1) {
00195             av_log(avctx, AV_LOG_ERROR,
00196                    "Invalid image size received: %u -> image data offset: %d\n",
00197                    buf_size, image_size);
00198             return AVERROR_INVALIDDATA;
00199         }
00200     } else {
00201         buf = avctx->extradata;
00202         buf_size = bytestream_get_be16(&buf);
00203         if (buf_size <= 1 || palette_size < 0) {
00204             av_log(avctx, AV_LOG_ERROR,
00205                    "Invalid palette size received: %u -> palette data offset: %d\n",
00206                    buf_size, palette_size);
00207             return AVERROR_INVALIDDATA;
00208         }
00209     }
00210 
00211     if (buf_size > 8) {
00212         s->compression  = bytestream_get_byte(&buf);
00213         s->bpp          = bytestream_get_byte(&buf);
00214         s->ham          = bytestream_get_byte(&buf);
00215         s->flags        = bytestream_get_byte(&buf);
00216         s->transparency = bytestream_get_be16(&buf);
00217         s->masking      = bytestream_get_byte(&buf);
00218         if (s->masking == MASK_HAS_TRANSPARENT_COLOR) {
00219             av_log(avctx, AV_LOG_ERROR, "Transparency not supported\n");
00220             return AVERROR_PATCHWELCOME;
00221         } else if (s->masking != MASK_NONE) {
00222             av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
00223             return AVERROR_PATCHWELCOME;
00224         }
00225         if (!s->bpp || s->bpp > 32) {
00226             av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
00227             return AVERROR_INVALIDDATA;
00228         } else if (s->ham >= 8) {
00229             av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
00230             return AVERROR_INVALIDDATA;
00231         }
00232 
00233         av_freep(&s->ham_buf);
00234         av_freep(&s->ham_palbuf);
00235 
00236         if (s->ham) {
00237             int i, count = FFMIN(palette_size / 3, 1 << s->ham);
00238             const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
00239             s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
00240             if (!s->ham_buf)
00241                 return AVERROR(ENOMEM);
00242 
00243             s->ham_palbuf = av_malloc((8 * (1 << s->ham) * sizeof (uint32_t)) + FF_INPUT_BUFFER_PADDING_SIZE);
00244             if (!s->ham_palbuf) {
00245                 av_freep(&s->ham_buf);
00246                 return AVERROR(ENOMEM);
00247             }
00248 
00249             if (count) { // HAM with color palette attached
00250                 // prefill with black and palette and set HAM take direct value mask to zero
00251                 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
00252                 for (i=0; i < count; i++) {
00253                     s->ham_palbuf[i*2+1] = AV_RL24(palette + i*3);
00254                 }
00255                 count = 1 << s->ham;
00256             } else { // HAM with grayscale color palette
00257                 count = 1 << s->ham;
00258                 for (i=0; i < count; i++) {
00259                     s->ham_palbuf[i*2]   = 0; // take direct color value from palette
00260                     s->ham_palbuf[i*2+1] = av_le2ne32(gray2rgb((i * 255) >> s->ham));
00261                 }
00262             }
00263             for (i=0; i < count; i++) {
00264                 uint32_t tmp = i << (8 - s->ham);
00265                 tmp |= tmp >> s->ham;
00266                 s->ham_palbuf[(i+count)*2]     = 0x00FFFF; // just modify blue color component
00267                 s->ham_palbuf[(i+count*2)*2]   = 0xFFFF00; // just modify red color component
00268                 s->ham_palbuf[(i+count*3)*2]   = 0xFF00FF; // just modify green color component
00269                 s->ham_palbuf[(i+count)*2+1]   = tmp << 16;
00270                 s->ham_palbuf[(i+count*2)*2+1] = tmp;
00271                 s->ham_palbuf[(i+count*3)*2+1] = tmp << 8;
00272             }
00273         } else if (s->flags & 1) { // EHB (ExtraHalfBrite) color palette
00274             av_log(avctx, AV_LOG_ERROR, "ExtraHalfBrite (EHB) mode not supported\n");
00275             return AVERROR_PATCHWELCOME;
00276         }
00277     }
00278 
00279     return 0;
00280 }
00281 
00282 static av_cold int decode_init(AVCodecContext *avctx)
00283 {
00284     IffContext *s = avctx->priv_data;
00285     int err;
00286 
00287     if (avctx->bits_per_coded_sample <= 8) {
00288         int palette_size;
00289 
00290         if (avctx->extradata_size >= 2)
00291             palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
00292         else
00293             palette_size = 0;
00294         avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
00295                          (avctx->extradata_size >= 2 && palette_size) ? PIX_FMT_PAL8 : PIX_FMT_GRAY8;
00296     } else if (avctx->bits_per_coded_sample <= 32) {
00297         avctx->pix_fmt = PIX_FMT_BGR32;
00298     } else {
00299         return AVERROR_INVALIDDATA;
00300     }
00301 
00302     if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
00303         return err;
00304     s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
00305     s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
00306     if (!s->planebuf)
00307         return AVERROR(ENOMEM);
00308 
00309     s->bpp = avctx->bits_per_coded_sample;
00310     avcodec_get_frame_defaults(&s->frame);
00311 
00312     if ((err = extract_header(avctx, NULL)) < 0)
00313         return err;
00314     s->frame.reference = 1;
00315 
00316     return 0;
00317 }
00318 
00326 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
00327 {
00328     const uint64_t *lut = plane8_lut[plane];
00329     do {
00330         uint64_t v = AV_RN64A(dst) | lut[*buf++];
00331         AV_WN64A(dst, v);
00332         dst += 8;
00333     } while (--buf_size);
00334 }
00335 
00343 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
00344 {
00345     const uint32_t *lut = plane32_lut[plane];
00346     do {
00347         unsigned mask = (*buf >> 2) & ~3;
00348         dst[0] |= lut[mask++];
00349         dst[1] |= lut[mask++];
00350         dst[2] |= lut[mask++];
00351         dst[3] |= lut[mask];
00352         mask = (*buf++ << 2) & 0x3F;
00353         dst[4] |= lut[mask++];
00354         dst[5] |= lut[mask++];
00355         dst[6] |= lut[mask++];
00356         dst[7] |= lut[mask];
00357         dst += 8;
00358     } while (--buf_size);
00359 }
00360 
00361 #define DECODE_HAM_PLANE32(x)       \
00362     first       = buf[x] << 1;      \
00363     second      = buf[(x)+1] << 1;  \
00364     delta      &= pal[first++];     \
00365     delta      |= pal[first];       \
00366     dst[x]      = delta;            \
00367     delta      &= pal[second++];    \
00368     delta      |= pal[second];      \
00369     dst[(x)+1]  = delta
00370 
00379 static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
00380                                const uint32_t *const pal, unsigned buf_size)
00381 {
00382     uint32_t delta = 0;
00383     do {
00384         uint32_t first, second;
00385         DECODE_HAM_PLANE32(0);
00386         DECODE_HAM_PLANE32(2);
00387         DECODE_HAM_PLANE32(4);
00388         DECODE_HAM_PLANE32(6);
00389         buf += 8;
00390         dst += 8;
00391     } while (--buf_size);
00392 }
00393 
00403 static int decode_byterun(uint8_t *dst, int dst_size,
00404                           const uint8_t *buf, const uint8_t *const buf_end) {
00405     const uint8_t *const buf_start = buf;
00406     unsigned x;
00407     for (x = 0; x < dst_size && buf < buf_end;) {
00408         unsigned length;
00409         const int8_t value = *buf++;
00410         if (value >= 0) {
00411             length = value + 1;
00412             memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
00413             buf += length;
00414         } else if (value > -128) {
00415             length = -value + 1;
00416             memset(dst + x, *buf++, FFMIN(length, dst_size - x));
00417         } else { // noop
00418             continue;
00419         }
00420         x += length;
00421     }
00422     return buf - buf_start;
00423 }
00424 
00425 static int decode_frame_ilbm(AVCodecContext *avctx,
00426                             void *data, int *data_size,
00427                             AVPacket *avpkt)
00428 {
00429     IffContext *s = avctx->priv_data;
00430     const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
00431     const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
00432     const uint8_t *buf_end = buf+buf_size;
00433     int y, plane, res;
00434 
00435     if ((res = extract_header(avctx, avpkt)) < 0)
00436         return res;
00437 
00438     if (s->init) {
00439         if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
00440             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00441             return res;
00442         }
00443     } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
00444         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00445         return res;
00446     } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != PIX_FMT_GRAY8) {
00447         if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
00448             return res;
00449     }
00450     s->init = 1;
00451 
00452     if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
00453         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00454             for(y = 0; y < avctx->height; y++ ) {
00455                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00456                 memset(row, 0, avctx->width);
00457                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00458                     decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00459                     buf += s->planesize;
00460                 }
00461             }
00462         } else if (s->ham) { // HAM to PIX_FMT_BGR32
00463             for (y = 0; y < avctx->height; y++) {
00464                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00465                 memset(s->ham_buf, 0, avctx->width);
00466                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00467                     decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
00468                     buf += s->planesize;
00469                 }
00470                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00471             }
00472         } else { // PIX_FMT_BGR32
00473             for(y = 0; y < avctx->height; y++ ) {
00474                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00475                 memset(row, 0, avctx->width << 2);
00476                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
00477                     decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00478                     buf += s->planesize;
00479                 }
00480             }
00481         }
00482     } else if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { // IFF-PBM
00483         for(y = 0; y < avctx->height; y++ ) {
00484             uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00485             memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
00486             buf += avctx->width + (avctx->width % 2); // padding if odd
00487         }
00488     } else { // IFF-PBM: HAM to PIX_FMT_BGR32
00489         for (y = 0; y < avctx->height; y++) {
00490             uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00491             memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
00492             buf += avctx->width + (avctx->width & 1); // padding if odd
00493             decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, avctx->width);
00494         }
00495     }
00496 
00497     *data_size = sizeof(AVFrame);
00498     *(AVFrame*)data = s->frame;
00499     return buf_size;
00500 }
00501 
00502 static int decode_frame_byterun1(AVCodecContext *avctx,
00503                             void *data, int *data_size,
00504                             AVPacket *avpkt)
00505 {
00506     IffContext *s = avctx->priv_data;
00507     const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
00508     const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
00509     const uint8_t *buf_end = buf+buf_size;
00510     int y, plane, res;
00511 
00512     if ((res = extract_header(avctx, avpkt)) < 0)
00513         return res;
00514     if (s->init) {
00515         if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
00516             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00517             return res;
00518         }
00519     } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
00520         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00521         return res;
00522     } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != PIX_FMT_GRAY8) {
00523         if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
00524             return res;
00525     }
00526     s->init = 1;
00527 
00528     if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
00529         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00530             for(y = 0; y < avctx->height ; y++ ) {
00531                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00532                 memset(row, 0, avctx->width);
00533                 for (plane = 0; plane < s->bpp; plane++) {
00534                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00535                     decodeplane8(row, s->planebuf, s->planesize, plane);
00536                 }
00537             }
00538         } else if (s->ham) { // HAM to PIX_FMT_BGR32
00539             for (y = 0; y < avctx->height ; y++) {
00540                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00541                 memset(s->ham_buf, 0, avctx->width);
00542                 for (plane = 0; plane < s->bpp; plane++) {
00543                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00544                     decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
00545                 }
00546                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
00547             }
00548         } else { //PIX_FMT_BGR32
00549             for(y = 0; y < avctx->height ; y++ ) {
00550                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00551                 memset(row, 0, avctx->width << 2);
00552                 for (plane = 0; plane < s->bpp; plane++) {
00553                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00554                     decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
00555                 }
00556             }
00557         }
00558     } else if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { // IFF-PBM
00559         for(y = 0; y < avctx->height ; y++ ) {
00560             uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00561             buf += decode_byterun(row, avctx->width, buf, buf_end);
00562         }
00563     } else { // IFF-PBM: HAM to PIX_FMT_BGR32
00564         for (y = 0; y < avctx->height ; y++) {
00565             uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00566             buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
00567             decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, avctx->width);
00568         }
00569     }
00570 
00571     *data_size = sizeof(AVFrame);
00572     *(AVFrame*)data = s->frame;
00573     return buf_size;
00574 }
00575 
00576 static av_cold int decode_end(AVCodecContext *avctx)
00577 {
00578     IffContext *s = avctx->priv_data;
00579     if (s->frame.data[0])
00580         avctx->release_buffer(avctx, &s->frame);
00581     av_freep(&s->planebuf);
00582     av_freep(&s->ham_buf);
00583     av_freep(&s->ham_palbuf);
00584     return 0;
00585 }
00586 
00587 AVCodec ff_iff_ilbm_decoder = {
00588     "iff_ilbm",
00589     AVMEDIA_TYPE_VIDEO,
00590     CODEC_ID_IFF_ILBM,
00591     sizeof(IffContext),
00592     decode_init,
00593     NULL,
00594     decode_end,
00595     decode_frame_ilbm,
00596     CODEC_CAP_DR1,
00597     .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
00598 };
00599 
00600 AVCodec ff_iff_byterun1_decoder = {
00601     "iff_byterun1",
00602     AVMEDIA_TYPE_VIDEO,
00603     CODEC_ID_IFF_BYTERUN1,
00604     sizeof(IffContext),
00605     decode_init,
00606     NULL,
00607     decode_end,
00608     decode_frame_byterun1,
00609     CODEC_CAP_DR1,
00610     .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
00611 };

Generated on Fri Feb 22 2013 07:24:27 for FFmpeg by  doxygen 1.7.1