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

Reply via email to