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