Home | History | Annotate | Download | only in IlmImf
      1 ///////////////////////////////////////////////////////////////////////////
      2 //
      3 // Copyright (c) 2004, 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 //	class ZipCompressor
     40 //
     41 //-----------------------------------------------------------------------------
     42 //#define ZLIB_WINAPI
     43 
     44 #include <ImfZipCompressor.h>
     45 #include <ImfCheckedArithmetic.h>
     46 #include "Iex.h"
     47 #include <zlib.h>
     48 
     49 namespace Imf {
     50 
     51 
     52 ZipCompressor::ZipCompressor
     53     (const Header &hdr,
     54      size_t maxScanLineSize,
     55      size_t numScanLines)
     56 :
     57     Compressor (hdr),
     58     _maxScanLineSize (maxScanLineSize),
     59     _numScanLines (numScanLines),
     60     _tmpBuffer (0),
     61     _outBuffer (0)
     62 {
     63     size_t maxInBytes =
     64         uiMult (maxScanLineSize, numScanLines);
     65 
     66     size_t maxOutBytes =
     67         uiAdd (uiAdd (maxInBytes,
     68                       size_t (ceil (maxInBytes * 0.01))),
     69                size_t (100));
     70 
     71     _tmpBuffer =
     72     new char [maxInBytes];
     73 
     74     _outBuffer =
     75     new char [maxOutBytes];
     76 }
     77 
     78 
     79 ZipCompressor::~ZipCompressor ()
     80 {
     81     delete [] _tmpBuffer;
     82     delete [] _outBuffer;
     83 }
     84 
     85 
     86 int
     87 ZipCompressor::numScanLines () const
     88 {
     89     return _numScanLines;
     90 }
     91 
     92 
     93 int
     94 ZipCompressor::compress (const char *inPtr,
     95              int inSize,
     96              int /*minY*/,
     97              const char *&outPtr)
     98 {
     99     //
    100     // Special case - empty input buffer
    101     //
    102 
    103     if (inSize == 0)
    104     {
    105     outPtr = _outBuffer;
    106     return 0;
    107     }
    108 
    109     //
    110     // Reorder the pixel data.
    111     //
    112 
    113     {
    114     char *t1 = _tmpBuffer;
    115     char *t2 = _tmpBuffer + (inSize + 1) / 2;
    116     const char *stop = inPtr + inSize;
    117 
    118     while (true)
    119     {
    120         if (inPtr < stop)
    121         *(t1++) = *(inPtr++);
    122         else
    123         break;
    124 
    125         if (inPtr < stop)
    126         *(t2++) = *(inPtr++);
    127         else
    128         break;
    129     }
    130     }
    131 
    132     //
    133     // Predictor.
    134     //
    135 
    136     {
    137     unsigned char *t = (unsigned char *) _tmpBuffer + 1;
    138     unsigned char *stop = (unsigned char *) _tmpBuffer + inSize;
    139     int p = t[-1];
    140 
    141     while (t < stop)
    142     {
    143         int d = int (t[0]) - p + (128 + 256);
    144         p = t[0];
    145         t[0] = d;
    146         ++t;
    147     }
    148     }
    149 
    150     //
    151     // Compress the data using zlib
    152     //
    153 
    154     uLongf outSize = int(ceil(inSize * 1.01)) + 100;
    155 
    156     if (Z_OK != ::compress ((Bytef *)_outBuffer, &outSize,
    157                 (const Bytef *) _tmpBuffer, inSize))
    158     {
    159     throw Iex::BaseExc ("Data compression (zlib) failed.");
    160     }
    161 
    162     outPtr = _outBuffer;
    163     return outSize;
    164 }
    165 
    166 
    167 int
    168 ZipCompressor::uncompress (const char *inPtr,
    169                int inSize,
    170                int /*minY*/,
    171                const char *&outPtr)
    172 {
    173     //
    174     // Special case - empty input buffer
    175     //
    176 
    177     if (inSize == 0)
    178     {
    179     outPtr = _outBuffer;
    180     return 0;
    181     }
    182 
    183     //
    184     // Decompress the data using zlib
    185     //
    186 
    187     uLongf outSize = _maxScanLineSize * _numScanLines;
    188 
    189     if (Z_OK != ::uncompress ((Bytef *)_tmpBuffer, &outSize,
    190                   (const Bytef *) inPtr, inSize))
    191     {
    192     throw Iex::InputExc ("Data decompression (zlib) failed.");
    193     }
    194 
    195     //
    196     // Predictor.
    197     //
    198 
    199     {
    200     unsigned char *t = (unsigned char *) _tmpBuffer + 1;
    201     unsigned char *stop = (unsigned char *) _tmpBuffer + outSize;
    202 
    203     while (t < stop)
    204     {
    205         int d = int (t[-1]) + int (t[0]) - 128;
    206         t[0] = d;
    207         ++t;
    208     }
    209     }
    210 
    211     //
    212     // Reorder the pixel data.
    213     //
    214 
    215     {
    216     const char *t1 = _tmpBuffer;
    217     const char *t2 = _tmpBuffer + (outSize + 1) / 2;
    218     char *s = _outBuffer;
    219     char *stop = s + outSize;
    220 
    221     while (true)
    222     {
    223         if (s < stop)
    224         *(s++) = *(t1++);
    225         else
    226         break;
    227 
    228         if (s < stop)
    229         *(s++) = *(t2++);
    230         else
    231         break;
    232     }
    233     }
    234 
    235     outPtr = _outBuffer;
    236     return outSize;
    237 }
    238 
    239 
    240 } // namespace Imf
    241