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 Libav.
00007  *
00008  * Libav 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  * Libav 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 Libav; 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 "internal.h"
00032 #include "get_bits.h"
00033 
00034 typedef struct {
00035     AVFrame frame;
00036     int planesize;
00037     uint8_t * planebuf;
00038     int init; // 1 if buffer and palette data already initialized, 0 otherwise
00039 } IffContext;
00040 
00041 #define LUT8_PART(plane, v)                             \
00042     AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane,  \
00043     AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane,  \
00044     AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane,  \
00045     AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane,  \
00046     AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane,  \
00047     AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane,  \
00048     AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane,  \
00049     AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane,  \
00050     AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane,  \
00051     AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane,  \
00052     AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane,  \
00053     AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane,  \
00054     AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane,  \
00055     AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane,  \
00056     AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane,  \
00057     AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
00058 
00059 #define LUT8(plane) {                           \
00060     LUT8_PART(plane, 0x0000000),                \
00061     LUT8_PART(plane, 0x1000000),                \
00062     LUT8_PART(plane, 0x0010000),                \
00063     LUT8_PART(plane, 0x1010000),                \
00064     LUT8_PART(plane, 0x0000100),                \
00065     LUT8_PART(plane, 0x1000100),                \
00066     LUT8_PART(plane, 0x0010100),                \
00067     LUT8_PART(plane, 0x1010100),                \
00068     LUT8_PART(plane, 0x0000001),                \
00069     LUT8_PART(plane, 0x1000001),                \
00070     LUT8_PART(plane, 0x0010001),                \
00071     LUT8_PART(plane, 0x1010001),                \
00072     LUT8_PART(plane, 0x0000101),                \
00073     LUT8_PART(plane, 0x1000101),                \
00074     LUT8_PART(plane, 0x0010101),                \
00075     LUT8_PART(plane, 0x1010101),                \
00076 }
00077 
00078 // 8 planes * 8-bit mask
00079 static const uint64_t plane8_lut[8][256] = {
00080     LUT8(0), LUT8(1), LUT8(2), LUT8(3),
00081     LUT8(4), LUT8(5), LUT8(6), LUT8(7),
00082 };
00083 
00084 #define LUT32(plane) {                                \
00085              0,          0,          0,          0,   \
00086              0,          0,          0, 1 << plane,   \
00087              0,          0, 1 << plane,          0,   \
00088              0,          0, 1 << plane, 1 << plane,   \
00089              0, 1 << plane,          0,          0,   \
00090              0, 1 << plane,          0, 1 << plane,   \
00091              0, 1 << plane, 1 << plane,          0,   \
00092              0, 1 << plane, 1 << plane, 1 << plane,   \
00093     1 << plane,          0,          0,          0,   \
00094     1 << plane,          0,          0, 1 << plane,   \
00095     1 << plane,          0, 1 << plane,          0,   \
00096     1 << plane,          0, 1 << plane, 1 << plane,   \
00097     1 << plane, 1 << plane,          0,          0,   \
00098     1 << plane, 1 << plane,          0, 1 << plane,   \
00099     1 << plane, 1 << plane, 1 << plane,          0,   \
00100     1 << plane, 1 << plane, 1 << plane, 1 << plane,   \
00101 }
00102 
00103 // 32 planes * 4-bit mask * 4 lookup tables each
00104 static const uint32_t plane32_lut[32][16*4] = {
00105     LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
00106     LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
00107     LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
00108     LUT32(12), LUT32(13), LUT32(14), LUT32(15),
00109     LUT32(16), LUT32(17), LUT32(18), LUT32(19),
00110     LUT32(20), LUT32(21), LUT32(22), LUT32(23),
00111     LUT32(24), LUT32(25), LUT32(26), LUT32(27),
00112     LUT32(28), LUT32(29), LUT32(30), LUT32(31),
00113 };
00114 
00115 // Gray to RGB, required for palette table of grayscale images with bpp < 8
00116 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
00117     return x << 16 | x << 8 | x;
00118 }
00119 
00123 static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
00124 {
00125     int count, i;
00126 
00127     if (avctx->bits_per_coded_sample > 8) {
00128         av_log(avctx, AV_LOG_ERROR, "bit_per_coded_sample > 8 not supported\n");
00129         return AVERROR_INVALIDDATA;
00130     }
00131 
00132     count = 1 << avctx->bits_per_coded_sample;
00133     // If extradata is smaller than actually needed, fill the remaining with black.
00134     count = FFMIN(avctx->extradata_size / 3, count);
00135     if (count) {
00136         for (i=0; i < count; i++) {
00137             pal[i] = 0xFF000000 | AV_RB24( avctx->extradata + i*3 );
00138         }
00139     } else { // Create gray-scale color palette for bps < 8
00140         count = 1 << avctx->bits_per_coded_sample;
00141 
00142         for (i=0; i < count; i++) {
00143             pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
00144         }
00145     }
00146     return 0;
00147 }
00148 
00149 static av_cold int decode_init(AVCodecContext *avctx)
00150 {
00151     IffContext *s = avctx->priv_data;
00152     int err;
00153 
00154     if (avctx->bits_per_coded_sample <= 8) {
00155         avctx->pix_fmt = (avctx->bits_per_coded_sample < 8 ||
00156                           avctx->extradata_size) ? PIX_FMT_PAL8
00157                                                  : PIX_FMT_GRAY8;
00158     } else if (avctx->bits_per_coded_sample <= 32) {
00159         avctx->pix_fmt = PIX_FMT_BGR32;
00160     } else {
00161         return AVERROR_INVALIDDATA;
00162     }
00163 
00164     if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
00165         return err;
00166     s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
00167     s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
00168     if (!s->planebuf)
00169         return AVERROR(ENOMEM);
00170 
00171     s->frame.reference = 1;
00172 
00173     return 0;
00174 }
00175 
00183 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
00184 {
00185     const uint64_t *lut = plane8_lut[plane];
00186     do {
00187         uint64_t v = AV_RN64A(dst) | lut[*buf++];
00188         AV_WN64A(dst, v);
00189         dst += 8;
00190     } while (--buf_size);
00191 }
00192 
00200 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
00201 {
00202     const uint32_t *lut = plane32_lut[plane];
00203     do {
00204         unsigned mask = (*buf >> 2) & ~3;
00205         dst[0] |= lut[mask++];
00206         dst[1] |= lut[mask++];
00207         dst[2] |= lut[mask++];
00208         dst[3] |= lut[mask];
00209         mask = (*buf++ << 2) & 0x3F;
00210         dst[4] |= lut[mask++];
00211         dst[5] |= lut[mask++];
00212         dst[6] |= lut[mask++];
00213         dst[7] |= lut[mask];
00214         dst += 8;
00215     } while (--buf_size);
00216 }
00217 
00227 static int decode_byterun(uint8_t *dst, int dst_size,
00228                           const uint8_t *buf, const uint8_t *const buf_end) {
00229     const uint8_t *const buf_start = buf;
00230     unsigned x;
00231     for (x = 0; x < dst_size && buf < buf_end;) {
00232         unsigned length;
00233         const int8_t value = *buf++;
00234         if (value >= 0) {
00235             length = value + 1;
00236             memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
00237             buf += length;
00238         } else if (value > -128) {
00239             length = -value + 1;
00240             memset(dst + x, *buf++, FFMIN(length, dst_size - x));
00241         } else { // noop
00242             continue;
00243         }
00244         x += length;
00245     }
00246     return buf - buf_start;
00247 }
00248 
00249 static int decode_frame_ilbm(AVCodecContext *avctx,
00250                             void *data, int *data_size,
00251                             AVPacket *avpkt)
00252 {
00253     IffContext *s = avctx->priv_data;
00254     const uint8_t *buf = avpkt->data;
00255     int buf_size = avpkt->size;
00256     const uint8_t *buf_end = buf+buf_size;
00257     int y, plane, res;
00258 
00259     if (s->init) {
00260         if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
00261             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00262             return res;
00263         }
00264     } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
00265         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00266         return res;
00267     } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != PIX_FMT_GRAY8) {
00268         if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
00269             return res;
00270     }
00271     s->init = 1;
00272 
00273     if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
00274         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00275             for (y = 0; y < avctx->height && buf < buf_end; y++ ) {
00276                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00277                 memset(row, 0, avctx->width);
00278                 for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
00279                     decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00280                     buf += s->planesize;
00281                 }
00282             }
00283         } else { // PIX_FMT_BGR32
00284             for(y = 0; y < avctx->height; y++ ) {
00285                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00286                 memset(row, 0, avctx->width << 2);
00287                 for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
00288                     decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
00289                     buf += s->planesize;
00290                 }
00291             }
00292         }
00293     } else if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { // IFF-PBM
00294         for(y = 0; y < avctx->height; y++ ) {
00295             uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
00296             memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
00297             buf += avctx->width + (avctx->width % 2); // padding if odd
00298         }
00299     }
00300 
00301     *data_size = sizeof(AVFrame);
00302     *(AVFrame*)data = s->frame;
00303     return buf_size;
00304 }
00305 
00306 static int decode_frame_byterun1(AVCodecContext *avctx,
00307                             void *data, int *data_size,
00308                             AVPacket *avpkt)
00309 {
00310     IffContext *s = avctx->priv_data;
00311     const uint8_t *buf = avpkt->data;
00312     int buf_size = avpkt->size;
00313     const uint8_t *buf_end = buf+buf_size;
00314     int y, plane, res;
00315 
00316     if (s->init) {
00317         if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
00318             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00319             return res;
00320         }
00321     } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
00322         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00323         return res;
00324     } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != PIX_FMT_GRAY8) {
00325         if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
00326             return res;
00327     }
00328     s->init = 1;
00329 
00330     if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
00331         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
00332             for(y = 0; y < avctx->height ; y++ ) {
00333                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
00334                 memset(row, 0, avctx->width);
00335                 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
00336                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00337                     decodeplane8(row, s->planebuf, s->planesize, plane);
00338                 }
00339             }
00340         } else { //PIX_FMT_BGR32
00341             for(y = 0; y < avctx->height ; y++ ) {
00342                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00343                 memset(row, 0, avctx->width << 2);
00344                 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
00345                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
00346                     decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
00347                 }
00348             }
00349         }
00350     } else {
00351         for(y = 0; y < avctx->height ; y++ ) {
00352             uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
00353             buf += decode_byterun(row, avctx->width, buf, buf_end);
00354         }
00355     }
00356 
00357     *data_size = sizeof(AVFrame);
00358     *(AVFrame*)data = s->frame;
00359     return buf_size;
00360 }
00361 
00362 static av_cold int decode_end(AVCodecContext *avctx)
00363 {
00364     IffContext *s = avctx->priv_data;
00365     if (s->frame.data[0])
00366         avctx->release_buffer(avctx, &s->frame);
00367     av_freep(&s->planebuf);
00368     return 0;
00369 }
00370 
00371 AVCodec ff_iff_ilbm_decoder = {
00372     .name           = "iff_ilbm",
00373     .type           = AVMEDIA_TYPE_VIDEO,
00374     .id             = CODEC_ID_IFF_ILBM,
00375     .priv_data_size = sizeof(IffContext),
00376     .init           = decode_init,
00377     .close          = decode_end,
00378     .decode         = decode_frame_ilbm,
00379     .capabilities   = CODEC_CAP_DR1,
00380     .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
00381 };
00382 
00383 AVCodec ff_iff_byterun1_decoder = {
00384     .name           = "iff_byterun1",
00385     .type           = AVMEDIA_TYPE_VIDEO,
00386     .id             = CODEC_ID_IFF_BYTERUN1,
00387     .priv_data_size = sizeof(IffContext),
00388     .init           = decode_init,
00389     .close          = decode_end,
00390     .decode         = decode_frame_byterun1,
00391     .capabilities   = CODEC_CAP_DR1,
00392     .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
00393 };