1// zlib.cpp - written and placed in the public domain by Wei Dai 2 3// "zlib" is the name of a well known C language compression library 4// (http://www.zlib.org) and also the name of a compression format 5// (RFC 1950) that the library implements. This file is part of a 6// complete reimplementation of the zlib compression format. 7 8#include "pch.h" 9#include "zlib.h" 10#include "zdeflate.h" 11#include "zinflate.h" 12 13NAMESPACE_BEGIN(CryptoPP) 14 15static const byte DEFLATE_METHOD = 8; 16static const byte FDICT_FLAG = 1 << 5; 17 18// ************************************************************* 19 20void ZlibCompressor::WritePrestreamHeader() 21{ 22 m_adler32.Restart(); 23 byte cmf = DEFLATE_METHOD | ((GetLog2WindowSize()-8) << 4); 24 byte flags = GetCompressionLevel() << 6; 25 AttachedTransformation()->PutWord16(RoundUpToMultipleOf(cmf*256+flags, 31)); 26} 27 28void ZlibCompressor::ProcessUncompressedData(const byte *inString, size_t length) 29{ 30 m_adler32.Update(inString, length); 31} 32 33void ZlibCompressor::WritePoststreamTail() 34{ 35 FixedSizeSecBlock<byte, 4> adler32; 36 m_adler32.Final(adler32); 37 AttachedTransformation()->Put(adler32, 4); 38} 39 40unsigned int ZlibCompressor::GetCompressionLevel() const 41{ 42 static const unsigned int deflateToCompressionLevel[] = {0, 1, 1, 1, 2, 2, 2, 2, 2, 3}; 43 return deflateToCompressionLevel[GetDeflateLevel()]; 44} 45 46// ************************************************************* 47 48ZlibDecompressor::ZlibDecompressor(BufferedTransformation *attachment, bool repeat, int propagation) 49 : Inflator(attachment, repeat, propagation) 50{ 51} 52 53void ZlibDecompressor::ProcessPrestreamHeader() 54{ 55 m_adler32.Restart(); 56 57 byte cmf; 58 byte flags; 59 60 if (!m_inQueue.Get(cmf) || !m_inQueue.Get(flags)) 61 throw HeaderErr(); 62 63 if ((cmf*256+flags) % 31 != 0) 64 throw HeaderErr(); // if you hit this exception, you're probably trying to decompress invalid data 65 66 if ((cmf & 0xf) != DEFLATE_METHOD) 67 throw UnsupportedAlgorithm(); 68 69 if (flags & FDICT_FLAG) 70 throw UnsupportedPresetDictionary(); 71 72 m_log2WindowSize = 8 + (cmf >> 4); 73} 74 75void ZlibDecompressor::ProcessDecompressedData(const byte *inString, size_t length) 76{ 77 AttachedTransformation()->Put(inString, length); 78 m_adler32.Update(inString, length); 79} 80 81void ZlibDecompressor::ProcessPoststreamTail() 82{ 83 FixedSizeSecBlock<byte, 4> adler32; 84 if (m_inQueue.Get(adler32, 4) != 4) 85 throw Adler32Err(); 86 if (!m_adler32.Verify(adler32)) 87 throw Adler32Err(); 88} 89 90NAMESPACE_END 91