The .diff file is also attached henceforth.Please have a look.
diff --git a/libavcodec/exr.c b/libavcodec/exr.c index 6251fb7..cc15a3a 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -770,6 +770,163 @@ static int piz_uncompress(EXRContext *s, const uint8_t *src, int ssize, return 0; } + +/* + +* + * @file + * OpenEXR decoder + * Digital Ltd. LLC + * All rights reserved. + * + * For more information on the OpenEXR format, visit: + * http://openexr.com/ + +implemetation of B44_uncompress method which is a lossy compression method which the following features + +compression rate 32/14 +works only on channels of HALF .It'll not work on FLOAT and UINT +the compression method is as follows: It interprets 32byte input data as 16 - 16 bit integers +It divides it into blocks of 4 by 4 pixels.Itt compresses 16 into 14 bytes. +*/ + +static +void unpack14 (const unsigned char b[14], unsigned short s[16]) +{ + // + // Unpack a 14-byte block into 4 by 4 16-bit pixels. + // + unsigned short shift,bias; + #if defined (DEBUG) + assert (b[2] != 0xfc); + #endif + s[ 0] = (b[0] << 8) | b[1]; + shift = (b[ 2] >> 2); + 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 unpack3 (const unsigned char b[3], unsigned short s[16]) +{ + // + // Unpack a 3-byte block into 4 by 4 identical 16-bit pixels. + // + #if defined (DEBUG) + assert (b[2] == 0xfc); + #endif + 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) +{ + unsigned long dest_len = uncompressed_size; + uint8_t *out; + int i, j; + //int c; + uint16_t *ptr; + uint16_t *tmp = (uint16_t *)td->tmp; + out = td->uncompressed_data; + if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK || + dest_len != uncompressed_size) + return AVERROR_INVALIDDATA; + for (i = 0; i < s->nb_channels; i++) { + EXRChannel *channel = &s->channels[i]; + int size = channel->pixel_type; + const char *inPtr=src; + int inSize = compressed_size; + ptr = tmp; + if (channel->pixel_type != EXR_HALF) { + // + // UINT or FLOAT channel. + // + int n = s->xdelta * s->ydelta * size * sizeof (unsigned short); + memcpy (ptr, inPtr, n); + inPtr += n; + inSize -= n; + continue; + } else { + // + //EXR_HALF Channel + for (int y=0; y < s->ydelta; y +=4 ) { + unsigned short *row0 = ptr + y * s->xdelta; + unsigned short *row1 = row0 + s->xdelta; + unsigned short *row2 = row1 + s->xdelta; + unsigned short *row3 = row2 + s->xdelta; + for (int x = 0; x < s->xdelta; x += 4) { + unsigned short stmp[16]; + if (((const unsigned char *)inPtr)[2] == 0xfc) { + unpack3 ((const unsigned char *)inPtr, stmp); + inPtr += 3; + inSize -= 3; + } else { + unpack14 ((const unsigned char *)inPtr, stmp); + inPtr += 14; + inSize -= 14; + } + int num = (x + 3 < s->xdelta)? 4 * sizeof (unsigned short) : (s->xdelta - x) * sizeof (unsigned short); + if (y + 3 < s->ydelta) { + memcpy (row0, &stmp[ 0], num); + memcpy (row1, &stmp[ 4], num); + memcpy (row2, &stmp[ 8], num); + memcpy (row3, &stmp[12], num); + } else { + memcpy (row0, &stmp[ 0], num); + if (y + 1 < s->ydelta) + memcpy (row1, &stmp[ 4], num); + if (y + 2 < s->ydelta) + memcpy (row2, &stmp[ 8], num); + } + row0 += 4; + row1 += 4; + row2 += 4; + row3 += 4; + } + } + } + } + for (i = 0; i < s->ysize; i++) { + for (j = 0; j < s->nb_channels; j++) { + uint16_t *in = tmp + j * s->xdelta * s->ysize + i * s->xdelta; + memcpy(out, in, s->xdelta * 2); + out += s->xdelta * 2; + } + } + return 0; +} + + static int pxr24_uncompress(EXRContext *s, const uint8_t *src, int compressed_size, int uncompressed_size, EXRThreadData *td) @@ -888,6 +1045,8 @@ static int decode_block(AVCodecContext *avctx, void *tdata, break; case EXR_RLE: ret = rle_uncompress(src, data_size, uncompressed_size, td); + case EXR_B44: + ret = b44_uncompress(s, src, data_size, uncompressed_size, td); } if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "decode_block() failed.\n"); @@ -1282,6 +1441,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, s->scan_lines_per_block = 16; break; case EXR_PIZ: + case EXR_B44: s->scan_lines_per_block = 32; break; default: Greeshma Balabhadra
diff --git a/libavcodec/exr.c b/libavcodec/exr.c index 6251fb7..cc15a3a 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -770,6 +770,163 @@ static int piz_uncompress(EXRContext *s, const uint8_t *src, int ssize, return 0; } + +/* + +* + * @file + * OpenEXR decoder + * Digital Ltd. LLC + * All rights reserved. + * + * For more information on the OpenEXR format, visit: + * http://openexr.com/ + +implemetation of B44_uncompress method which is a lossy compression method which the following features + +compression rate 32/14 +works only on channels of HALF .It'll not work on FLOAT and UINT +the compression method is as follows: It interprets 32byte input data as 16 - 16 bit integers +It divides it into blocks of 4 by 4 pixels.Itt compresses 16 into 14 bytes. +*/ + +static +void unpack14 (const unsigned char b[14], unsigned short s[16]) +{ + // + // Unpack a 14-byte block into 4 by 4 16-bit pixels. + // + unsigned short shift,bias; + #if defined (DEBUG) + assert (b[2] != 0xfc); + #endif + s[ 0] = (b[0] << 8) | b[1]; + shift = (b[ 2] >> 2); + 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 unpack3 (const unsigned char b[3], unsigned short s[16]) +{ + // + // Unpack a 3-byte block into 4 by 4 identical 16-bit pixels. + // + #if defined (DEBUG) + assert (b[2] == 0xfc); + #endif + 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) +{ + unsigned long dest_len = uncompressed_size; + uint8_t *out; + int i, j; + //int c; + uint16_t *ptr; + uint16_t *tmp = (uint16_t *)td->tmp; + out = td->uncompressed_data; + if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK || + dest_len != uncompressed_size) + return AVERROR_INVALIDDATA; + for (i = 0; i < s->nb_channels; i++) { + EXRChannel *channel = &s->channels[i]; + int size = channel->pixel_type; + const char *inPtr=src; + int inSize = compressed_size; + ptr = tmp; + if (channel->pixel_type != EXR_HALF) { + // + // UINT or FLOAT channel. + // + int n = s->xdelta * s->ydelta * size * sizeof (unsigned short); + memcpy (ptr, inPtr, n); + inPtr += n; + inSize -= n; + continue; + } else { + // + //EXR_HALF Channel + for (int y=0; y < s->ydelta; y +=4 ) { + unsigned short *row0 = ptr + y * s->xdelta; + unsigned short *row1 = row0 + s->xdelta; + unsigned short *row2 = row1 + s->xdelta; + unsigned short *row3 = row2 + s->xdelta; + for (int x = 0; x < s->xdelta; x += 4) { + unsigned short stmp[16]; + if (((const unsigned char *)inPtr)[2] == 0xfc) { + unpack3 ((const unsigned char *)inPtr, stmp); + inPtr += 3; + inSize -= 3; + } else { + unpack14 ((const unsigned char *)inPtr, stmp); + inPtr += 14; + inSize -= 14; + } + int num = (x + 3 < s->xdelta)? 4 * sizeof (unsigned short) : (s->xdelta - x) * sizeof (unsigned short); + if (y + 3 < s->ydelta) { + memcpy (row0, &stmp[ 0], num); + memcpy (row1, &stmp[ 4], num); + memcpy (row2, &stmp[ 8], num); + memcpy (row3, &stmp[12], num); + } else { + memcpy (row0, &stmp[ 0], num); + if (y + 1 < s->ydelta) + memcpy (row1, &stmp[ 4], num); + if (y + 2 < s->ydelta) + memcpy (row2, &stmp[ 8], num); + } + row0 += 4; + row1 += 4; + row2 += 4; + row3 += 4; + } + } + } + } + for (i = 0; i < s->ysize; i++) { + for (j = 0; j < s->nb_channels; j++) { + uint16_t *in = tmp + j * s->xdelta * s->ysize + i * s->xdelta; + memcpy(out, in, s->xdelta * 2); + out += s->xdelta * 2; + } + } + return 0; +} + + static int pxr24_uncompress(EXRContext *s, const uint8_t *src, int compressed_size, int uncompressed_size, EXRThreadData *td) @@ -888,6 +1045,8 @@ static int decode_block(AVCodecContext *avctx, void *tdata, break; case EXR_RLE: ret = rle_uncompress(src, data_size, uncompressed_size, td); + case EXR_B44: + ret = b44_uncompress(s, src, data_size, uncompressed_size, td); } if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "decode_block() failed.\n"); @@ -1282,6 +1441,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, s->scan_lines_per_block = 16; break; case EXR_PIZ: + case EXR_B44: s->scan_lines_per_block = 32; break; default:
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel