]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/ivi_dsp.c
ffv1: split decoder and encoder
[ffmpeg] / libavcodec / ivi_dsp.c
index a58fcc52da3cba3d67243ebcbd241bd05da24594..3ffe84ab9eae87560ca7fea56dfe73b9013f0718 100644 (file)
@@ -1,45 +1,47 @@
 /*
  * DSP functions for Indeo Video Interactive codecs (Indeo4 and Indeo5)
  *
- * Copyright (c) 2009 Maxim Poliakovski
+ * Copyright (c) 2009-2011 Maxim Poliakovski
  *
- * This file is part of FFmpeg.
+ * This file is part of Libav.
  *
- * FFmpeg is free software; you can redistribute it and/or
+ * Libav is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * FFmpeg is distributed in the hope that it will be useful,
+ * Libav is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
+ * License along with Libav; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
- * @file libavcodec/ivi_dsp.c
+ * @file
  * DSP functions (inverse transforms, motion compensation, wavelet recompostions)
  * for Indeo Video Interactive codecs.
  */
 
 #include "avcodec.h"
 #include "dsputil.h"
+#include "dwt.h"
 #include "ivi_common.h"
 #include "ivi_dsp.h"
 
 void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst,
-                        const int dst_pitch, const int num_bands)
+                        const int dst_pitch)
 {
     int             x, y, indx;
     int32_t         p0, p1, p2, p3, tmp0, tmp1, tmp2;
     int32_t         b0_1, b0_2, b1_1, b1_2, b1_3, b2_1, b2_2, b2_3, b2_4, b2_5, b2_6;
     int32_t         b3_1, b3_2, b3_3, b3_4, b3_5, b3_6, b3_7, b3_8, b3_9;
-    uint32_t        pitch, back_pitch;
+    int32_t         pitch, back_pitch;
     const IDWTELEM *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
+    const int       num_bands = 4;
 
     /* all bands should have the same pitch */
     pitch = plane->bands[0].pitch;
@@ -177,6 +179,153 @@ void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst,
     }
 }
 
+void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst,
+                           const int dst_pitch)
+{
+    int             x, y, indx, b0, b1, b2, b3, p0, p1, p2, p3;
+    const IDWTELEM *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
+    int32_t         pitch;
+
+    /* all bands should have the same pitch */
+    pitch = plane->bands[0].pitch;
+
+    /* get pointers to the wavelet bands */
+    b0_ptr = plane->bands[0].buf;
+    b1_ptr = plane->bands[1].buf;
+    b2_ptr = plane->bands[2].buf;
+    b3_ptr = plane->bands[3].buf;
+
+    for (y = 0; y < plane->height; y += 2) {
+        for (x = 0, indx = 0; x < plane->width; x += 2, indx++) {
+            /* load coefficients */
+            b0 = b0_ptr[indx]; //should be: b0 = (num_bands > 0) ? b0_ptr[indx] : 0;
+            b1 = b1_ptr[indx]; //should be: b1 = (num_bands > 1) ? b1_ptr[indx] : 0;
+            b2 = b2_ptr[indx]; //should be: b2 = (num_bands > 2) ? b2_ptr[indx] : 0;
+            b3 = b3_ptr[indx]; //should be: b3 = (num_bands > 3) ? b3_ptr[indx] : 0;
+
+            /* haar wavelet recomposition */
+            p0 = (b0 + b1 + b2 + b3 + 2) >> 2;
+            p1 = (b0 + b1 - b2 - b3 + 2) >> 2;
+            p2 = (b0 - b1 + b2 - b3 + 2) >> 2;
+            p3 = (b0 - b1 - b2 + b3 + 2) >> 2;
+
+            /* bias, convert and output four pixels */
+            dst[x]                 = av_clip_uint8(p0 + 128);
+            dst[x + 1]             = av_clip_uint8(p1 + 128);
+            dst[dst_pitch + x]     = av_clip_uint8(p2 + 128);
+            dst[dst_pitch + x + 1] = av_clip_uint8(p3 + 128);
+        }// for x
+
+        dst += dst_pitch << 1;
+
+        b0_ptr += pitch;
+        b1_ptr += pitch;
+        b2_ptr += pitch;
+        b3_ptr += pitch;
+    }// for y
+}
+
+/** butterfly operation for the inverse Haar transform */
+#define IVI_HAAR_BFLY(s1, s2, o1, o2, t) \
+    t  = (s1 - s2) >> 1;\
+    o1 = (s1 + s2) >> 1;\
+    o2 = t;\
+
+/** inverse 8-point Haar transform */
+#define INV_HAAR8(s1, s5, s3, s7, s2, s4, s6, s8,\
+                  d1, d2, d3, d4, d5, d6, d7, d8,\
+                  t0, t1, t2, t3, t4, t5, t6, t7, t8) {\
+    t1 = s1 << 1; t5 = s5 << 1;\
+    IVI_HAAR_BFLY(t1, t5, t1, t5, t0); IVI_HAAR_BFLY(t1, s3, t1, t3, t0);\
+    IVI_HAAR_BFLY(t5, s7, t5, t7, t0); IVI_HAAR_BFLY(t1, s2, t1, t2, t0);\
+    IVI_HAAR_BFLY(t3, s4, t3, t4, t0); IVI_HAAR_BFLY(t5, s6, t5, t6, t0);\
+    IVI_HAAR_BFLY(t7, s8, t7, t8, t0);\
+    d1 = COMPENSATE(t1);\
+    d2 = COMPENSATE(t2);\
+    d3 = COMPENSATE(t3);\
+    d4 = COMPENSATE(t4);\
+    d5 = COMPENSATE(t5);\
+    d6 = COMPENSATE(t6);\
+    d7 = COMPENSATE(t7);\
+    d8 = COMPENSATE(t8); }
+
+/** inverse 4-point Haar transform */
+#define INV_HAAR4(s1, s3, s5, s7) {\
+    HAAR_BFLY(s1, s5);  HAAR_BFLY(s1, s3);  HAAR_BFLY(s5, s7);\
+    s1 = COMPENSATE(s1);\
+    s3 = COMPENSATE(s3);\
+    s5 = COMPENSATE(s5);\
+    s7 = COMPENSATE(s7); }
+
+void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
+                             const uint8_t *flags)
+{
+    int     i, shift, sp1, sp2, sp3, sp4;
+    const int32_t *src;
+    int32_t *dst;
+    int     tmp[64];
+    int     t0, t1, t2, t3, t4, t5, t6, t7, t8;
+
+    /* apply the InvHaar8 to all columns */
+#define COMPENSATE(x) (x)
+    src = in;
+    dst = tmp;
+    for (i = 0; i < 8; i++) {
+        if (flags[i]) {
+            /* pre-scaling */
+            shift = !(i & 4);
+            sp1 = src[ 0] << shift;
+            sp2 = src[ 8] << shift;
+            sp3 = src[16] << shift;
+            sp4 = src[24] << shift;
+            INV_HAAR8(    sp1,     sp2,     sp3,     sp4,
+                      src[32], src[40], src[48], src[56],
+                      dst[ 0], dst[ 8], dst[16], dst[24],
+                      dst[32], dst[40], dst[48], dst[56],
+                      t0, t1, t2, t3, t4, t5, t6, t7, t8);
+        } else
+            dst[ 0] = dst[ 8] = dst[16] = dst[24] =
+            dst[32] = dst[40] = dst[48] = dst[56] = 0;
+
+        src++;
+        dst++;
+    }
+#undef  COMPENSATE
+
+    /* apply the InvHaar8 to all rows */
+#define COMPENSATE(x) (x)
+    src = tmp;
+    for (i = 0; i < 8; i++) {
+        if (   !src[0] && !src[1] && !src[2] && !src[3]
+            && !src[4] && !src[5] && !src[6] && !src[7]) {
+            memset(out, 0, 8 * sizeof(out[0]));
+        } else {
+            INV_HAAR8(src[0], src[1], src[2], src[3],
+                      src[4], src[5], src[6], src[7],
+                      out[0], out[1], out[2], out[3],
+                      out[4], out[5], out[6], out[7],
+                      t0, t1, t2, t3, t4, t5, t6, t7, t8);
+        }
+        src += 8;
+        out += pitch;
+    }
+#undef  COMPENSATE
+}
+
+void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch,
+                       int blk_size)
+{
+    int     x, y;
+    int16_t dc_coeff;
+
+    dc_coeff = (*in + 0) >> 3;
+
+    for (y = 0; y < blk_size; out += pitch, y++) {
+        for (x = 0; x < blk_size; x++)
+            out[x] = dc_coeff;
+    }
+}
+
 /** butterfly operation for the inverse slant transform */
 #define IVI_SLANT_BFLY(s1, s2, o1, o2, t) \
     t  = s1 - s2;\
@@ -460,7 +609,7 @@ void ff_ivi_mc_ ## size ##x## size ## suffix (int16_t *buf, const int16_t *ref_b
 #define OP_PUT(a, b)  (a) = (b)
 #define OP_ADD(a, b)  (a) += (b)
 
-IVI_MC_TEMPLATE(8, _no_delta, OP_PUT);
-IVI_MC_TEMPLATE(8, _delta,    OP_ADD);
-IVI_MC_TEMPLATE(4, _no_delta, OP_PUT);
-IVI_MC_TEMPLATE(4, _delta,    OP_ADD);
+IVI_MC_TEMPLATE(8, _no_delta, OP_PUT)
+IVI_MC_TEMPLATE(8, _delta,    OP_ADD)
+IVI_MC_TEMPLATE(4, _no_delta, OP_PUT)
+IVI_MC_TEMPLATE(4, _delta,    OP_ADD)