Home | History | Annotate | Download | only in IlmImf
      1 ///////////////////////////////////////////////////////////////////////////
      2 //
      3 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
      4 // Digital Ltd. LLC
      5 //
      6 // All rights reserved.
      7 //
      8 // Redistribution and use in source and binary forms, with or without
      9 // modification, are permitted provided that the following conditions are
     10 // met:
     11 // *       Redistributions of source code must retain the above copyright
     12 // notice, this list of conditions and the following disclaimer.
     13 // *       Redistributions in binary form must reproduce the above
     14 // copyright notice, this list of conditions and the following disclaimer
     15 // in the documentation and/or other materials provided with the
     16 // distribution.
     17 // *       Neither the name of Industrial Light & Magic nor the names of
     18 // its contributors may be used to endorse or promote products derived
     19 // from this software without specific prior written permission.
     20 //
     21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32 //
     33 ///////////////////////////////////////////////////////////////////////////
     34 
     35 
     36 
     37 //-----------------------------------------------------------------------------
     38 //
     39 //	16-bit Haar Wavelet encoding and decoding
     40 //
     41 //	The source code in this file is derived from the encoding
     42 //	and decoding routines written by Christian Rouet for his
     43 //	PIZ image file format.
     44 //
     45 //-----------------------------------------------------------------------------
     46 
     47 
     48 #include <ImfWav.h>
     49 
     50 namespace Imf {
     51 namespace {
     52 
     53 
     54 //
     55 // Wavelet basis functions without modulo arithmetic; they produce
     56 // the best compression ratios when the wavelet-transformed data are
     57 // Huffman-encoded, but the wavelet transform works only for 14-bit
     58 // data (untransformed data values must be less than (1 << 14)).
     59 //
     60 
     61 inline void
     62 wenc14 (unsigned short  a, unsigned short  b,
     63         unsigned short &l, unsigned short &h)
     64 {
     65     short as = a;
     66     short bs = b;
     67 
     68     short ms = (as + bs) >> 1;
     69     short ds = as - bs;
     70 
     71     l = ms;
     72     h = ds;
     73 }
     74 
     75 
     76 inline void
     77 wdec14 (unsigned short  l, unsigned short  h,
     78         unsigned short &a, unsigned short &b)
     79 {
     80     short ls = l;
     81     short hs = h;
     82 
     83     int hi = hs;
     84     int ai = ls + (hi & 1) + (hi >> 1);
     85 
     86     short as = ai;
     87     short bs = ai - hi;
     88 
     89     a = as;
     90     b = bs;
     91 }
     92 
     93 
     94 //
     95 // Wavelet basis functions with modulo arithmetic; they work with full
     96 // 16-bit data, but Huffman-encoding the wavelet-transformed data doesn't
     97 // compress the data quite as well.
     98 //
     99 
    100 const int NBITS = 16;
    101 const int A_OFFSET =  1 << (NBITS  - 1);
    102 const int M_OFFSET =  1 << (NBITS  - 1);
    103 const int MOD_MASK = (1 <<  NBITS) - 1;
    104 
    105 
    106 inline void
    107 wenc16 (unsigned short  a, unsigned short  b,
    108         unsigned short &l, unsigned short &h)
    109 {
    110     int ao =  (a + A_OFFSET) & MOD_MASK;
    111     int m  = ((ao + b) >> 1);
    112     int d  =   ao - b;
    113 
    114     if (d < 0)
    115     m = (m + M_OFFSET) & MOD_MASK;
    116 
    117     d &= MOD_MASK;
    118 
    119     l = m;
    120     h = d;
    121 }
    122 
    123 
    124 inline void
    125 wdec16 (unsigned short  l, unsigned short  h,
    126         unsigned short &a, unsigned short &b)
    127 {
    128     int m = l;
    129     int d = h;
    130     int bb = (m - (d >> 1)) & MOD_MASK;
    131     int aa = (d + bb - A_OFFSET) & MOD_MASK;
    132     b = bb;
    133     a = aa;
    134 }
    135 
    136 } // namespace
    137 
    138 
    139 //
    140 // 2D Wavelet encoding:
    141 //
    142 
    143 void
    144 wav2Encode
    145     (unsigned short*	in,	// io: values are transformed in place
    146      int		nx,	// i : x size
    147      int		ox,	// i : x offset
    148      int		ny,	// i : y size
    149      int		oy,	// i : y offset
    150      unsigned short	mx)	// i : maximum in[x][y] value
    151 {
    152     bool w14 = (mx < (1 << 14));
    153     int	n  = (nx > ny)? ny: nx;
    154     int	p  = 1;			// == 1 <<  level
    155     int p2 = 2;			// == 1 << (level+1)
    156 
    157     //
    158     // Hierachical loop on smaller dimension n
    159     //
    160 
    161     while (p2 <= n)
    162     {
    163     unsigned short *py = in;
    164     unsigned short *ey = in + oy * (ny - p2);
    165     int oy1 = oy * p;
    166     int oy2 = oy * p2;
    167     int ox1 = ox * p;
    168     int ox2 = ox * p2;
    169     unsigned short i00,i01,i10,i11;
    170 
    171     //
    172     // Y loop
    173     //
    174 
    175     for (; py <= ey; py += oy2)
    176     {
    177         unsigned short *px = py;
    178         unsigned short *ex = py + ox * (nx - p2);
    179 
    180         //
    181         // X loop
    182         //
    183 
    184         for (; px <= ex; px += ox2)
    185         {
    186         unsigned short *p01 = px  + ox1;
    187         unsigned short *p10 = px  + oy1;
    188         unsigned short *p11 = p10 + ox1;
    189 
    190         //
    191         // 2D wavelet encoding
    192         //
    193 
    194         if (w14)
    195         {
    196             wenc14 (*px,  *p01, i00, i01);
    197             wenc14 (*p10, *p11, i10, i11);
    198             wenc14 (i00, i10, *px,  *p10);
    199             wenc14 (i01, i11, *p01, *p11);
    200         }
    201         else
    202         {
    203             wenc16 (*px,  *p01, i00, i01);
    204             wenc16 (*p10, *p11, i10, i11);
    205             wenc16 (i00, i10, *px,  *p10);
    206             wenc16 (i01, i11, *p01, *p11);
    207         }
    208         }
    209 
    210         //
    211         // Encode (1D) odd column (still in Y loop)
    212         //
    213 
    214         if (nx & p)
    215         {
    216         unsigned short *p10 = px + oy1;
    217 
    218         if (w14)
    219             wenc14 (*px, *p10, i00, *p10);
    220         else
    221             wenc16 (*px, *p10, i00, *p10);
    222 
    223         *px= i00;
    224         }
    225     }
    226 
    227     //
    228     // Encode (1D) odd line (must loop in X)
    229     //
    230 
    231     if (ny & p)
    232     {
    233         unsigned short *px = py;
    234         unsigned short *ex = py + ox * (nx - p2);
    235 
    236         for (; px <= ex; px += ox2)
    237         {
    238         unsigned short *p01 = px + ox1;
    239 
    240         if (w14)
    241             wenc14 (*px, *p01, i00, *p01);
    242         else
    243             wenc16 (*px, *p01, i00, *p01);
    244 
    245         *px= i00;
    246         }
    247     }
    248 
    249     //
    250     // Next level
    251     //
    252 
    253     p = p2;
    254     p2 <<= 1;
    255     }
    256 }
    257 
    258 
    259 //
    260 // 2D Wavelet decoding:
    261 //
    262 
    263 void
    264 wav2Decode
    265     (unsigned short*	in,	// io: values are transformed in place
    266      int		nx,	// i : x size
    267      int		ox,	// i : x offset
    268      int		ny,	// i : y size
    269      int		oy,	// i : y offset
    270      unsigned short	mx)	// i : maximum in[x][y] value
    271 {
    272     bool w14 = (mx < (1 << 14));
    273     int	n = (nx > ny)? ny: nx;
    274     int	p = 1;
    275     int p2;
    276 
    277     //
    278     // Search max level
    279     //
    280 
    281     while (p <= n)
    282     p <<= 1;
    283 
    284     p >>= 1;
    285     p2 = p;
    286     p >>= 1;
    287 
    288     //
    289     // Hierarchical loop on smaller dimension n
    290     //
    291 
    292     while (p >= 1)
    293     {
    294     unsigned short *py = in;
    295     unsigned short *ey = in + oy * (ny - p2);
    296     int oy1 = oy * p;
    297     int oy2 = oy * p2;
    298     int ox1 = ox * p;
    299     int ox2 = ox * p2;
    300     unsigned short i00,i01,i10,i11;
    301 
    302     //
    303     // Y loop
    304     //
    305 
    306     for (; py <= ey; py += oy2)
    307     {
    308         unsigned short *px = py;
    309         unsigned short *ex = py + ox * (nx - p2);
    310 
    311         //
    312         // X loop
    313         //
    314 
    315         for (; px <= ex; px += ox2)
    316         {
    317         unsigned short *p01 = px  + ox1;
    318         unsigned short *p10 = px  + oy1;
    319         unsigned short *p11 = p10 + ox1;
    320 
    321         //
    322         // 2D wavelet decoding
    323         //
    324 
    325         if (w14)
    326         {
    327             wdec14 (*px,  *p10, i00, i10);
    328             wdec14 (*p01, *p11, i01, i11);
    329             wdec14 (i00, i01, *px,  *p01);
    330             wdec14 (i10, i11, *p10, *p11);
    331         }
    332         else
    333         {
    334             wdec16 (*px,  *p10, i00, i10);
    335             wdec16 (*p01, *p11, i01, i11);
    336             wdec16 (i00, i01, *px,  *p01);
    337             wdec16 (i10, i11, *p10, *p11);
    338         }
    339         }
    340 
    341         //
    342         // Decode (1D) odd column (still in Y loop)
    343         //
    344 
    345         if (nx & p)
    346         {
    347         unsigned short *p10 = px + oy1;
    348 
    349         if (w14)
    350             wdec14 (*px, *p10, i00, *p10);
    351         else
    352             wdec16 (*px, *p10, i00, *p10);
    353 
    354         *px= i00;
    355         }
    356     }
    357 
    358     //
    359     // Decode (1D) odd line (must loop in X)
    360     //
    361 
    362     if (ny & p)
    363     {
    364         unsigned short *px = py;
    365         unsigned short *ex = py + ox * (nx - p2);
    366 
    367         for (; px <= ex; px += ox2)
    368         {
    369         unsigned short *p01 = px + ox1;
    370 
    371         if (w14)
    372             wdec14 (*px, *p01, i00, *p01);
    373         else
    374             wdec16 (*px, *p01, i00, *p01);
    375 
    376         *px= i00;
    377         }
    378     }
    379 
    380     //
    381     // Next level
    382     //
    383 
    384     p2 = p;
    385     p >>= 1;
    386     }
    387 }
    388 
    389 
    390 } // namespace Imf
    391