>From 8ecf3c3e15929b64efed883c1c2a5bdb8620de3b Mon Sep 17 00:00:00 2001
From: Jean First <jeanfirst@gmail.com>
Date: Fri, 23 Sep 2011 22:55:19 +0200
Subject: [PATCH] Enable 16-bit encoding and decoding for tiff files

---
 libavcodec/tiff.c    |   14 ++++++++++++++
 libavcodec/tiffenc.c |   20 +++++++++++++-------
 2 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index e2c80ef..06b5b8e 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -601,11 +601,25 @@ static int decode_frame(AVCodecContext *avctx,
         dst = p->data[0];
         soff = s->bpp >> 3;
         ssize = s->width * soff;
+        if (s->avctx->pix_fmt == PIX_FMT_RGB48LE) {
+            for (i = 0; i < s->height; i++) {
+                for (j = soff; j < ssize; j += 2)
+                    AV_WL16(dst + j, AV_RL16(dst + j) + AV_RL16(dst + j - soff));
+                dst += stride;
+            }
+        } else if (s->avctx->pix_fmt == PIX_FMT_RGB48BE) {
+            for (i = 0; i < s->height; i++) {
+                for (j = soff; j < ssize; j += 2)
+                    AV_WB16(dst + j, AV_RB16(dst + j) + AV_RB16(dst + j - soff));
+                dst += stride;
+            }
+        } else {
         for(i = 0; i < s->height; i++) {
             for(j = soff; j < ssize; j++)
                 dst[j] += dst[j - soff];
             dst += stride;
         }
+        }
     }
 
     if(s->invert){
diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c
index eaa777a..eb1622d 100644
--- a/libavcodec/tiffenc.c
+++ b/libavcodec/tiffenc.c
@@ -44,6 +44,7 @@ static const uint8_t type_sizes2[6] = {
 };
 
 typedef struct TiffEncoderContext {
+    AVClass *avclass;
     AVCodecContext *avctx;
     AVFrame picture;
 
@@ -219,6 +220,7 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf,
     uint8_t *yuv_line = NULL;
     int shift_h, shift_v;
 
+    s->avctx = avctx;
     s->buf_start = buf;
     s->buf = &ptr;
     s->buf_size = buf_size;
@@ -245,6 +247,14 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf,
     s->subsampling[1] = 1;
 
     switch (avctx->pix_fmt) {
+    case PIX_FMT_RGB48LE:
+        s->bpp = 48;
+        s->photometric_interpretation = 2;
+        bpp_tab[0] = 16;
+        bpp_tab[1] = 16;
+        bpp_tab[2] = 16;
+        bpp_tab[3] = 16;
+        break;
     case PIX_FMT_RGB24:
         s->bpp = 24;
         s->photometric_interpretation = 2;
@@ -283,13 +293,9 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf,
         return -1;
     }
     if (!is_yuv)
-        s->bpp_tab_size = ((s->bpp + 7) >> 3);
+        s->bpp_tab_size = (s->bpp >= 48) ? ((s->bpp + 7) >> 4):((s->bpp + 7) >> 3);
 
-    if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE || s->compr == TIFF_LZW)
-        //best choose for DEFLATE
-        s->rps = s->height;
-    else
-        s->rps = FFMAX(8192 / (((s->width * s->bpp) >> 3) + 1), 1);     // suggest size of strip
+    s->rps = s->height;
     s->rps = ((s->rps - 1) / s->subsampling[1] + 1) * s->subsampling[1]; // round rps up
 
     strips = (s->height - 1) / s->rps + 1;
@@ -460,7 +466,7 @@ AVCodec ff_tiff_encoder = {
                               PIX_FMT_MONOBLACK, PIX_FMT_MONOWHITE,
                               PIX_FMT_YUV420P, PIX_FMT_YUV422P,
                               PIX_FMT_YUV444P, PIX_FMT_YUV410P,
-                              PIX_FMT_YUV411P,
+                              PIX_FMT_YUV411P, PIX_FMT_RGB48LE,
                               PIX_FMT_NONE},
     .long_name = NULL_IF_CONFIG_SMALL("TIFF image"),
     .priv_class= &class,
-- 
1.7.4.2

