Mercurial > vba-linux
view src/win32/7zip/7z/CPP/7zip/Compress/ZlibDecoder.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line source
1 // ZlibDecoder.cpp3 #include "StdAfx.h"5 #include "../Common/StreamUtils.h"7 #include "DeflateDecoder.h"8 #include "ZlibDecoder.h"10 namespace NCompress {11 namespace NZlib {13 #define DEFLATE_TRY_BEGIN try {14 #define DEFLATE_TRY_END } \15 catch(...) { return S_FALSE; }17 #define ADLER_MOD 6552118 #define ADLER_LOOP_MAX 555020 static UInt32 Adler32_Update(UInt32 adler, const Byte *buf, size_t size)21 {22 UInt32 a = adler & 0xFFFF;23 UInt32 b = (adler >> 16) & 0xFFFF;24 while (size > 0)25 {26 unsigned curSize = (size > ADLER_LOOP_MAX) ? ADLER_LOOP_MAX : (unsigned )size;27 unsigned i;28 for (i = 0; i < curSize; i++)29 {30 a += buf[i];31 b += a;32 }33 buf += curSize;34 size -= curSize;35 a %= ADLER_MOD;36 b %= ADLER_MOD;37 }38 return (b << 16) + a;39 }41 STDMETHODIMP COutStreamWithAdler::Write(const void *data, UInt32 size, UInt32 *processedSize)42 {43 HRESULT result = _stream->Write(data, size, &size);44 _adler = Adler32_Update(_adler, (const Byte *)data, size);45 if (processedSize != NULL)46 *processedSize = size;47 return result;48 }50 STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,51 const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)52 {53 DEFLATE_TRY_BEGIN54 if (!AdlerStream)55 {56 AdlerSpec = new COutStreamWithAdler;57 AdlerStream = AdlerSpec;58 }59 if (!DeflateDecoder)60 {61 DeflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder;62 DeflateDecoderSpec->ZlibMode = true;63 DeflateDecoder = DeflateDecoderSpec;64 }66 Byte buf[2];67 RINOK(ReadStream_FALSE(inStream, buf, 2));68 int method = buf[0] & 0xF;69 if (method != 8)70 return S_FALSE;71 // int dicSize = buf[0] >> 4;72 if ((((UInt32)buf[0] << 8) + buf[1]) % 31 != 0)73 return S_FALSE;74 if ((buf[1] & 0x20) != 0) // dictPresent75 return S_FALSE;76 // int level = (buf[1] >> 6);78 AdlerSpec->SetStream(outStream);79 AdlerSpec->Init();80 HRESULT res = DeflateDecoder->Code(inStream, AdlerStream, inSize, outSize, progress);81 AdlerSpec->ReleaseStream();83 if (res == S_OK)84 {85 const Byte *p = DeflateDecoderSpec->ZlibFooter;86 UInt32 adler = ((UInt32)p[0] << 24) | ((UInt32)p[1] << 16) | ((UInt32)p[2] << 8) | p[3];87 if (adler != AdlerSpec->GetAdler())88 return S_FALSE;89 }90 return res;91 DEFLATE_TRY_END92 }94 }}