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