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 49namespace Imf { 50 51 52ZipCompressor::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 79ZipCompressor::~ZipCompressor () 80{ 81 delete [] _tmpBuffer; 82 delete [] _outBuffer; 83} 84 85 86int 87ZipCompressor::numScanLines () const 88{ 89 return _numScanLines; 90} 91 92 93int 94ZipCompressor::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 167int 168ZipCompressor::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