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.cpp
3 #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 65521
18 #define ADLER_LOOP_MAX 5550
20 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_BEGIN
54 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) // dictPresent
75 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_END
92 }
94 }}