diff 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 diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/win32/7zip/7z/CPP/7zip/Compress/ZlibDecoder.cpp	Sat Mar 03 10:31:27 2012 -0600
     1.3 @@ -0,0 +1,94 @@
     1.4 +// ZlibDecoder.cpp
     1.5 +
     1.6 +#include "StdAfx.h"
     1.7 +
     1.8 +#include "../Common/StreamUtils.h"
     1.9 +
    1.10 +#include "DeflateDecoder.h"
    1.11 +#include "ZlibDecoder.h"
    1.12 +
    1.13 +namespace NCompress {
    1.14 +namespace NZlib {
    1.15 +
    1.16 +#define DEFLATE_TRY_BEGIN try {
    1.17 +#define DEFLATE_TRY_END } \
    1.18 +  catch(...) { return S_FALSE; }
    1.19 +
    1.20 +#define ADLER_MOD 65521
    1.21 +#define ADLER_LOOP_MAX 5550
    1.22 +
    1.23 +static UInt32 Adler32_Update(UInt32 adler, const Byte *buf, size_t size)
    1.24 +{
    1.25 +  UInt32 a = adler & 0xFFFF;
    1.26 +  UInt32 b = (adler >> 16) & 0xFFFF;
    1.27 +  while (size > 0)
    1.28 +  {
    1.29 +    unsigned curSize = (size > ADLER_LOOP_MAX) ? ADLER_LOOP_MAX : (unsigned )size;
    1.30 +    unsigned i;
    1.31 +    for (i = 0; i < curSize; i++)
    1.32 +    {
    1.33 +      a += buf[i];
    1.34 +      b += a;
    1.35 +    }
    1.36 +    buf += curSize;
    1.37 +    size -= curSize;
    1.38 +    a %= ADLER_MOD;
    1.39 +    b %= ADLER_MOD;
    1.40 +  }
    1.41 +  return (b << 16) + a;
    1.42 +}
    1.43 +
    1.44 +STDMETHODIMP COutStreamWithAdler::Write(const void *data, UInt32 size, UInt32 *processedSize)
    1.45 +{
    1.46 +  HRESULT result = _stream->Write(data, size, &size);
    1.47 +  _adler = Adler32_Update(_adler, (const Byte *)data, size);
    1.48 +  if (processedSize != NULL)
    1.49 +    *processedSize = size;
    1.50 +  return result;
    1.51 +}
    1.52 +
    1.53 +STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
    1.54 +    const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
    1.55 +{
    1.56 +  DEFLATE_TRY_BEGIN
    1.57 +  if (!AdlerStream)
    1.58 +  {
    1.59 +    AdlerSpec = new COutStreamWithAdler;
    1.60 +    AdlerStream = AdlerSpec;
    1.61 +  }
    1.62 +  if (!DeflateDecoder)
    1.63 +  {
    1.64 +    DeflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder;
    1.65 +    DeflateDecoderSpec->ZlibMode = true;
    1.66 +    DeflateDecoder = DeflateDecoderSpec;
    1.67 +  }
    1.68 +
    1.69 +  Byte buf[2];
    1.70 +  RINOK(ReadStream_FALSE(inStream, buf, 2));
    1.71 +  int method = buf[0] & 0xF;
    1.72 +  if (method != 8)
    1.73 +    return S_FALSE;
    1.74 +  // int dicSize = buf[0] >> 4;
    1.75 +  if ((((UInt32)buf[0] << 8) + buf[1]) % 31 != 0)
    1.76 +    return S_FALSE;
    1.77 +  if ((buf[1] & 0x20) != 0) // dictPresent
    1.78 +    return S_FALSE;
    1.79 +  // int level = (buf[1] >> 6);
    1.80 +
    1.81 +  AdlerSpec->SetStream(outStream);
    1.82 +  AdlerSpec->Init();
    1.83 +  HRESULT res = DeflateDecoder->Code(inStream, AdlerStream, inSize, outSize, progress);
    1.84 +  AdlerSpec->ReleaseStream();
    1.85 +
    1.86 +  if (res == S_OK)
    1.87 +  {
    1.88 +    const Byte *p = DeflateDecoderSpec->ZlibFooter;
    1.89 +    UInt32 adler = ((UInt32)p[0] << 24) | ((UInt32)p[1] << 16) | ((UInt32)p[2] << 8) | p[3];
    1.90 +    if (adler != AdlerSpec->GetAdler())
    1.91 +      return S_FALSE;
    1.92 +  }
    1.93 +  return res;
    1.94 +  DEFLATE_TRY_END
    1.95 +}
    1.96 +
    1.97 +}}