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