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