• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ZipCompressor(const Header & hdr,size_t maxScanLineSize,size_t numScanLines)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 
~ZipCompressor()79 ZipCompressor::~ZipCompressor ()
80 {
81     delete [] _tmpBuffer;
82     delete [] _outBuffer;
83 }
84 
85 
86 int
numScanLines() const87 ZipCompressor::numScanLines () const
88 {
89     return _numScanLines;
90 }
91 
92 
93 int
compress(const char * inPtr,int inSize,int,const char * & outPtr)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
uncompress(const char * inPtr,int inSize,int,const char * & outPtr)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