2016-03-20 9:31 GMT+01:00 Carl Eugen Hoyos <ceho...@ag.or.at>: > Martin Vignali <martin.vignali <at> gmail.com> writes: > > > > > The B44/B44A block decoding function (unpack_14 and unpack_3) > > > > come from the official library. > > > > > > Then please add an appropriate copyright notice to your patch. > > > What form the copyright need to have ? and where i need to put it ? > > The easy way is to add "Copyright (c) 2006, Industrial Light & Magic, > a division of Lucas Digital Ltd. LLC" to the file header. > > Carl Eugen > > New patch attached, with ILM copyright at the top of the file And remove some comments line.
Ping Martin Vignali Jokyo Images
From c2017a0897eed5e9231d259fab4d36456a6e29e9 Mon Sep 17 00:00:00 2001 From: Martin Vignali <martin.vign...@gmail.com> Date: Sun, 20 Mar 2016 11:53:27 +0100 Subject: [PATCH] libavcodec/exr : add support for B44 and B44A compression --- libavcodec/exr.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/libavcodec/exr.c b/libavcodec/exr.c index 9ec99d6..cf758be 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -1,5 +1,6 @@ /* * OpenEXR (.exr) image decoder + * Copyright (c) 2006 Industrial Light & Magic, a division of Lucas Digital Ltd. LLC * Copyright (c) 2009 Jimmy Christensen * * This file is part of FFmpeg. @@ -34,6 +35,7 @@ #include <float.h> #include <zlib.h> +#include "libavutil/common.h" #include "libavutil/imgutils.h" #include "libavutil/intfloat.h" #include "libavutil/opt.h" @@ -826,6 +828,115 @@ static int pxr24_uncompress(EXRContext *s, const uint8_t *src, return 0; } +static void unpack_14(const uint8_t b[14], uint16_t s[16]){ + /* From openExr library */ + s[ 0] = (b[0] << 8) | b[1]; + + unsigned short shift = (b[ 2] >> 2); + unsigned short bias = (0x20 << shift); + + s[ 4] = s[ 0] + ((((b[ 2] << 4) | (b[ 3] >> 4)) & 0x3f) << shift) - bias; + s[ 8] = s[ 4] + ((((b[ 3] << 2) | (b[ 4] >> 6)) & 0x3f) << shift) - bias; + s[12] = s[ 8] + ((b[ 4] & 0x3f) << shift) - bias; + + s[ 1] = s[ 0] + ((b[ 5] >> 2) << shift) - bias; + s[ 5] = s[ 4] + ((((b[ 5] << 4) | (b[ 6] >> 4)) & 0x3f) << shift) - bias; + s[ 9] = s[ 8] + ((((b[ 6] << 2) | (b[ 7] >> 6)) & 0x3f) << shift) - bias; + s[13] = s[12] + ((b[ 7] & 0x3f) << shift) - bias; + + s[ 2] = s[ 1] + ((b[ 8] >> 2) << shift) - bias; + s[ 6] = s[ 5] + ((((b[ 8] << 4) | (b[ 9] >> 4)) & 0x3f) << shift) - bias; + s[10] = s[ 9] + ((((b[ 9] << 2) | (b[10] >> 6)) & 0x3f) << shift) - bias; + s[14] = s[13] + ((b[10] & 0x3f) << shift) - bias; + + s[ 3] = s[ 2] + ((b[11] >> 2) << shift) - bias; + s[ 7] = s[ 6] + ((((b[11] << 4) | (b[12] >> 4)) & 0x3f) << shift) - bias; + s[11] = s[10] + ((((b[12] << 2) | (b[13] >> 6)) & 0x3f) << shift) - bias; + s[15] = s[14] + ((b[13] & 0x3f) << shift) - bias; + + for (int i = 0; i < 16; ++i) + { + if (s[i] & 0x8000) + s[i] &= 0x7fff; + else + s[i] = ~s[i]; + } +} + +static void unpack_3(const uint8_t b[3], uint16_t s[16]){ + /* From openExr library */ + s[0] = (b[0] << 8) | b[1]; + + if (s[0] & 0x8000) + s[0] &= 0x7fff; + else + s[0] = ~s[0]; + + for (int i = 1; i < 16; ++i) + s[i] = s[0]; +} + + +static int b44_uncompress(EXRContext *s, const uint8_t *src, int compressed_size, + int uncompressed_size, EXRThreadData *td){ + const int8_t *sr = src; + int stayToUncompress = compressed_size; + int nbB44BlockW, nbB44BlockH; + int indexHgX, indexHgY, indexOut, indexTmp; + int c, iY, iX, y, x; + + /* calc B44 block count */ + nbB44BlockW = s->xdelta / 4; + if ((s->xdelta % 4) != 0) + nbB44BlockW++; + + nbB44BlockH = s->ysize / 4; + if ((s->ysize % 4) != 0) + nbB44BlockH++; + + uint16_t tmpBuffer[16];/* B44 use 4x4 half float pixel */ + + for (c = 0; c < s->nb_channels; c++) { + for (iY = 0; iY < nbB44BlockH; iY++) { + for (iX = 0; iX < nbB44BlockW; iX++) {/* For each B44 bloc */ + if (stayToUncompress < 3){ + av_log(s, AV_LOG_ERROR, "Not enough data for B44A bloc : %d", stayToUncompress); + return AVERROR_INVALIDDATA; + } + + if (src[compressed_size - stayToUncompress + 2] == 0xfc) {/* B44A bloc */ + unpack_3(sr, tmpBuffer); + sr += 3; + stayToUncompress -= 3; + } + else{/* B44 Bloc */ + if (stayToUncompress < 14) { + av_log(s, AV_LOG_ERROR, "Not enough data for B44 bloc : %d", stayToUncompress); + return AVERROR_INVALIDDATA; + } + unpack_14(sr, tmpBuffer); + sr += 14; + stayToUncompress -= 14; + } + + /* copy data to uncompress buffer (B44 bloc can exceed target resolution)*/ + indexHgX = iX * 4; + indexHgY = iY * 4; + + for (y = indexHgY; y < FFMIN(indexHgY + 4, s->ysize); y++) { + for (x = indexHgX; x < FFMIN(indexHgX + 4, s->xdelta); x++) { + indexOut = (c * s->xdelta + y * s->xdelta * s->nb_channels + x) * 2; + indexTmp = (y-indexHgY) * 4 + (x-indexHgX); + td->uncompressed_data[indexOut] = tmpBuffer[indexTmp] & 0xff; + td->uncompressed_data[indexOut + 1] = tmpBuffer[indexTmp] >> 8; + } + } + } + } + } + return 0; +} + static int decode_block(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr) { @@ -891,6 +1002,10 @@ static int decode_block(AVCodecContext *avctx, void *tdata, break; case EXR_RLE: ret = rle_uncompress(src, data_size, uncompressed_size, td); + break; + case EXR_B44: + case EXR_B44A: + ret = b44_uncompress(s, src, data_size, uncompressed_size, td); } if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "decode_block() failed.\n"); @@ -1323,6 +1438,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, s->scan_lines_per_block = 16; break; case EXR_PIZ: + case EXR_B44: + case EXR_B44A: s->scan_lines_per_block = 32; break; default: -- 1.9.3 (Apple Git-50)
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel