Mercurial > vba-linux
comparison 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 |
comparison
equal
deleted
inserted
replaced
0:8ced16adf2e1 | 1:f9f4f1b99eed |
---|---|
1 // ZlibDecoder.cpp | |
2 | |
3 #include "StdAfx.h" | |
4 | |
5 #include "../Common/StreamUtils.h" | |
6 | |
7 #include "DeflateDecoder.h" | |
8 #include "ZlibDecoder.h" | |
9 | |
10 namespace NCompress { | |
11 namespace NZlib { | |
12 | |
13 #define DEFLATE_TRY_BEGIN try { | |
14 #define DEFLATE_TRY_END } \ | |
15 catch(...) { return S_FALSE; } | |
16 | |
17 #define ADLER_MOD 65521 | |
18 #define ADLER_LOOP_MAX 5550 | |
19 | |
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 } | |
40 | |
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 } | |
49 | |
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 } | |
65 | |
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); | |
77 | |
78 AdlerSpec->SetStream(outStream); | |
79 AdlerSpec->Init(); | |
80 HRESULT res = DeflateDecoder->Code(inStream, AdlerStream, inSize, outSize, progress); | |
81 AdlerSpec->ReleaseStream(); | |
82 | |
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 } | |
93 | |
94 }} |