annotate 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
rev   line source
rlm@1 1 // ZlibDecoder.cpp
rlm@1 2
rlm@1 3 #include "StdAfx.h"
rlm@1 4
rlm@1 5 #include "../Common/StreamUtils.h"
rlm@1 6
rlm@1 7 #include "DeflateDecoder.h"
rlm@1 8 #include "ZlibDecoder.h"
rlm@1 9
rlm@1 10 namespace NCompress {
rlm@1 11 namespace NZlib {
rlm@1 12
rlm@1 13 #define DEFLATE_TRY_BEGIN try {
rlm@1 14 #define DEFLATE_TRY_END } \
rlm@1 15 catch(...) { return S_FALSE; }
rlm@1 16
rlm@1 17 #define ADLER_MOD 65521
rlm@1 18 #define ADLER_LOOP_MAX 5550
rlm@1 19
rlm@1 20 static UInt32 Adler32_Update(UInt32 adler, const Byte *buf, size_t size)
rlm@1 21 {
rlm@1 22 UInt32 a = adler & 0xFFFF;
rlm@1 23 UInt32 b = (adler >> 16) & 0xFFFF;
rlm@1 24 while (size > 0)
rlm@1 25 {
rlm@1 26 unsigned curSize = (size > ADLER_LOOP_MAX) ? ADLER_LOOP_MAX : (unsigned )size;
rlm@1 27 unsigned i;
rlm@1 28 for (i = 0; i < curSize; i++)
rlm@1 29 {
rlm@1 30 a += buf[i];
rlm@1 31 b += a;
rlm@1 32 }
rlm@1 33 buf += curSize;
rlm@1 34 size -= curSize;
rlm@1 35 a %= ADLER_MOD;
rlm@1 36 b %= ADLER_MOD;
rlm@1 37 }
rlm@1 38 return (b << 16) + a;
rlm@1 39 }
rlm@1 40
rlm@1 41 STDMETHODIMP COutStreamWithAdler::Write(const void *data, UInt32 size, UInt32 *processedSize)
rlm@1 42 {
rlm@1 43 HRESULT result = _stream->Write(data, size, &size);
rlm@1 44 _adler = Adler32_Update(_adler, (const Byte *)data, size);
rlm@1 45 if (processedSize != NULL)
rlm@1 46 *processedSize = size;
rlm@1 47 return result;
rlm@1 48 }
rlm@1 49
rlm@1 50 STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
rlm@1 51 const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
rlm@1 52 {
rlm@1 53 DEFLATE_TRY_BEGIN
rlm@1 54 if (!AdlerStream)
rlm@1 55 {
rlm@1 56 AdlerSpec = new COutStreamWithAdler;
rlm@1 57 AdlerStream = AdlerSpec;
rlm@1 58 }
rlm@1 59 if (!DeflateDecoder)
rlm@1 60 {
rlm@1 61 DeflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder;
rlm@1 62 DeflateDecoderSpec->ZlibMode = true;
rlm@1 63 DeflateDecoder = DeflateDecoderSpec;
rlm@1 64 }
rlm@1 65
rlm@1 66 Byte buf[2];
rlm@1 67 RINOK(ReadStream_FALSE(inStream, buf, 2));
rlm@1 68 int method = buf[0] & 0xF;
rlm@1 69 if (method != 8)
rlm@1 70 return S_FALSE;
rlm@1 71 // int dicSize = buf[0] >> 4;
rlm@1 72 if ((((UInt32)buf[0] << 8) + buf[1]) % 31 != 0)
rlm@1 73 return S_FALSE;
rlm@1 74 if ((buf[1] & 0x20) != 0) // dictPresent
rlm@1 75 return S_FALSE;
rlm@1 76 // int level = (buf[1] >> 6);
rlm@1 77
rlm@1 78 AdlerSpec->SetStream(outStream);
rlm@1 79 AdlerSpec->Init();
rlm@1 80 HRESULT res = DeflateDecoder->Code(inStream, AdlerStream, inSize, outSize, progress);
rlm@1 81 AdlerSpec->ReleaseStream();
rlm@1 82
rlm@1 83 if (res == S_OK)
rlm@1 84 {
rlm@1 85 const Byte *p = DeflateDecoderSpec->ZlibFooter;
rlm@1 86 UInt32 adler = ((UInt32)p[0] << 24) | ((UInt32)p[1] << 16) | ((UInt32)p[2] << 8) | p[3];
rlm@1 87 if (adler != AdlerSpec->GetAdler())
rlm@1 88 return S_FALSE;
rlm@1 89 }
rlm@1 90 return res;
rlm@1 91 DEFLATE_TRY_END
rlm@1 92 }
rlm@1 93
rlm@1 94 }}