15 #if (defined(_MSC_VER) && (_MSC_VER < 1400)) && !defined(__MWERKS__) 17 typedef std::reverse_bidirectional_iterator<unsigned int *, unsigned int>
RevIt;
18 #elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) 19 typedef std::reverse_iterator<unsigned int *, std::random_access_iterator_tag, unsigned int>
RevIt;
21 typedef std::reverse_iterator<unsigned int *>
RevIt;
25 :
Filter(attachment), m_counting(false), m_bitCount(0), m_buffer(0)
26 , m_bitsBuffered(0), m_bytesBuffered(0)
51 m_bitsBuffered += length;
53 while (m_bitsBuffered >= 8)
103 : symbol(0), parent(0) {}
105 : symbol(rhs.symbol), parent(rhs.parent) {}
108 union {
size_t parent;
unsigned depth, freq;};
126 for (i=0; i<nCodes; i++)
129 tree[i].freq = codeCounts[i];
133 if (treeBegin == nCodes)
135 std::fill(codeBits, codeBits+nCodes, 0);
138 tree.
resize(nCodes + nCodes - treeBegin - 1);
140 size_t leastLeaf = treeBegin, leastInterior = nCodes;
141 for (i=nCodes; i<tree.
size(); i++)
144 least = (leastLeaf == nCodes || (leastInterior < i && tree[leastInterior].freq < tree[leastLeaf].freq)) ? leastInterior++ : leastLeaf++;
145 tree[i].freq = tree[least].freq;
146 tree[least].parent = i;
147 least = (leastLeaf == nCodes || (leastInterior < i && tree[leastInterior].freq < tree[leastLeaf].freq)) ? leastInterior++ : leastLeaf++;
148 tree[i].freq += tree[least].freq;
149 tree[least].parent = i;
152 tree[tree.
size()-1].depth = 0;
153 if (tree.
size() >= 2)
154 for (i=tree.
size()-2; i>=nCodes; i--)
155 tree[i].depth = tree[tree[i].parent].depth + 1;
156 unsigned int sum = 0;
158 std::fill(blCount.
begin(), blCount.
end(), 0);
159 for (i=treeBegin; i<nCodes; i++)
161 const size_t n = tree[i].parent;
162 const size_t depth =
STDMIN(maxCodeBits, tree[n].depth + 1);
164 sum += 1 << (maxCodeBits - depth);
167 unsigned int overflow = sum > (
unsigned int)(1 << maxCodeBits) ? sum - (1 << maxCodeBits) : 0;
171 unsigned int bits = maxCodeBits-1;
172 while (blCount[bits] == 0)
175 blCount[bits+1] += 2;
177 blCount[maxCodeBits]--;
180 for (i=0; i<treeBegin; i++)
181 codeBits[tree[i].symbol] = 0;
182 unsigned int bits = maxCodeBits;
183 for (i=treeBegin; i<nCodes; i++)
185 while (blCount[bits] == 0)
187 codeBits[tree[i].symbol] = bits;
196 unsigned int maxCodeBits = *std::max_element(codeBits, codeBits+nCodes);
197 if (maxCodeBits == 0)
201 std::fill(blCount.
begin(), blCount.
end(), 0);
203 for (i=0; i<nCodes; i++)
204 blCount[codeBits[i]]++;
209 for (i=2; i<=maxCodeBits; i++)
211 code = (code + blCount[i-1]) << 1;
214 CRYPTOPP_ASSERT(maxCodeBits == 1 || code == (1 << maxCodeBits) - blCount[maxCodeBits]);
216 m_valueToCode.resize(nCodes);
217 for (i=0; i<nCodes; i++)
219 unsigned int len = m_valueToCode[i].len = codeBits[i];
221 m_valueToCode[i].code =
BitReverse(nextCode[len]++) >> (8*
sizeof(
code_t)-len);
228 writer.
PutBits(m_valueToCode[value].
code, m_valueToCode[value].len);
249 unsigned int codeLengths[288];
250 std::fill(codeLengths + 0, codeLengths + 144, 8);
251 std::fill(codeLengths + 144, codeLengths + 256, 9);
252 std::fill(codeLengths + 256, codeLengths + 280, 7);
253 std::fill(codeLengths + 280, codeLengths + 288, 8);
255 std::fill(codeLengths + 0, codeLengths + 32, 5);
320 static const unsigned int configurationTable[10][4] = {
330 {32, 128, 258, 1024},
331 {32, 258, 258, 4096}};
333 GOOD_MATCH = configurationTable[deflateLevel][0];
342 unsigned int maxBlockSize = (
unsigned int)
STDMIN(2
UL*
DSIZE, 0xffffUL);
364 for (i=0; i<
HSIZE; i++)
367 for (i=0; i<
DSIZE; i++)
382 return ((str[0] << 10) ^ (str[1] << 5) ^ str[2]) &
HMASK;
395 unsigned int limit = m_stringStart > (
DSIZE-
MAX_MATCH) ? m_stringStart - (
DSIZE-MAX_MATCH) : 0;
402 while (current > limit && --chainLength > 0)
406 if (scan[bestLength-1] == match[bestLength-1] && scan[bestLength] == match[bestLength] && scan[0] == match[0] && scan[1] == match[1])
409 unsigned int len = (
unsigned int)(
410 #
if defined(_STDEXT_BEGIN) && !(defined(_MSC_VER) && (_MSC_VER < 1400 || _MSC_VER >= 1600)) && !defined(_STLPORT_VERSION)
411 stdext::unchecked_mismatch
416 (stdext::make_unchecked_array_iterator(scan)+3, stdext::make_unchecked_array_iterator(scanEnd), stdext::make_unchecked_array_iterator(match)+3).first - stdext::make_unchecked_array_iterator(scan));
418 (scan+3, scanEnd, match+3).first - scan);
421 if (len > bestLength)
427 if (len == (
unsigned int)(scanEnd - scan))
433 return (bestMatch > 0) ? bestLength : 0;
468 unsigned int matchPosition = 0, matchLength = 0;
469 bool usePreviousMatch;
471 usePreviousMatch =
true;
475 usePreviousMatch = (matchLength == 0);
477 if (usePreviousMatch)
521 while (accepted < length)
523 unsigned int newAccepted =
FillWindow(str+accepted, length-accepted);
527 accepted += newAccepted;
541 Output(0, NULL, 0, messageEnd, blocking);
574 static const unsigned int lengthCodes[] = {
575 257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268, 268,
576 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 272,
577 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274,
578 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276, 276, 276, 276, 276,
579 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
580 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
581 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
582 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280,
583 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281,
584 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281,
585 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282,
586 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282,
587 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
588 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
589 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
590 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 285};
591 static const unsigned int lengthBases[] =
592 {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,
594 static const unsigned int distanceBases[30] =
595 {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,
596 4097,6145,8193,12289,16385,24577};
601 unsigned int lengthCode = lengthCodes[length-3];
602 m.literalCode = lengthCode;
603 m.literalExtra = length - lengthBases[lengthCode-257];
604 unsigned int distanceCode = (
unsigned int)(std::upper_bound(distanceBases, distanceBases+30, distance) - distanceBases - 1);
605 m.distanceCode = distanceCode;
606 m.distanceExtra = distance - distanceBases[distanceCode];
614 const unsigned int *end,
615 const unsigned int *& p,
616 unsigned int &extraBits,
617 unsigned int &extraBitsLength)
622 const unsigned int *oldp = p;
623 if (v==0 && p[1]==0 && p[2]==0)
625 for (p=p+3; p!=end && *p==0 && p!=oldp+138; p++) {}
626 unsigned int repeat = (
unsigned int)(p - oldp);
629 extraBits = repeat-3;
635 extraBits = repeat-11;
640 else if (p!=begin && v==p[-1] && v==p[1] && v==p[2])
642 for (p=p+3; p!=end && *p==v && p!=oldp+6; p++) {}
643 unsigned int repeat = (
unsigned int)(p - oldp);
644 extraBits = repeat-3;
679 unsigned int hlit = (
unsigned int)(std::find_if(
RevIt(literalCodeLengths.
end()),
RevIt(literalCodeLengths.
begin()+257), std::bind2nd(std::not_equal_to<unsigned int>(), 0)).base() - (literalCodeLengths.
begin()+257));
683 unsigned int hdist = (
unsigned int)(std::find_if(
RevIt(distanceCodeLengths.
end()),
RevIt(distanceCodeLengths.
begin()+1), std::bind2nd(std::not_equal_to<unsigned int>(), 0)).base() - (distanceCodeLengths.
begin()+1));
686 memcpy(combinedLengths, literalCodeLengths, (hlit+257)*
sizeof(
unsigned int));
687 memcpy(combinedLengths+hlit+257, distanceCodeLengths, (hdist+1)*
sizeof(
unsigned int));
690 std::fill(codeLengthCodeCounts.
begin(), codeLengthCodeCounts.
end(), 0);
691 const unsigned int *p = combinedLengths.
begin(), *begin = combinedLengths.
begin(), *end = combinedLengths.
end();
694 unsigned int code=0, extraBits=0, extraBitsLength=0;
696 codeLengthCodeCounts[
code]++;
700 static const unsigned int border[] = {
701 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
702 unsigned int hclen = 19;
703 while (hclen > 4 && codeLengthCodeLengths[border[hclen-1]] == 0)
711 for (
unsigned int i=0; i<hclen+4; i++)
712 PutBits(codeLengthCodeLengths[border[i]], 3);
714 p = combinedLengths.
begin();
717 unsigned int code=0, extraBits=0, extraBitsLength=0;
719 codeLengthEncoder.
Encode(*
this, code);
720 PutBits(extraBits, extraBitsLength);
724 static const unsigned int lengthExtraBits[] = {
725 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
726 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
727 static const unsigned int distanceExtraBits[] = {
728 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
729 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
738 literalEncoder.
Encode(*
this, literalCode);
739 if (literalCode >= 257)
744 distanceEncoder.
Encode(*
this, distanceCode);
748 literalEncoder.
Encode(*
this, 256);
775 unsigned long dynamicLen;
777 dynamicLen = ULONG_MAX;
785 if (storedLen <= staticLen && storedLen <= dynamicLen)
798 if (staticLen <= dynamicLen)
unsigned int m_previousMatch
iterator end()
Provides an iterator pointing beyond the last element in the memory block.
unsigned int m_previousLength
An invalid argument was detected.
void PutBits(unsigned long value, unsigned int length)
Stack-based SecBlock that grows into the heap.
unsigned int m_dictionaryEnd
Utility functions for the Crypto++ library.
unsigned int m_minLookahead
T GetValueWithDefault(const char *name, T defaultValue) const
Get a named value.
bool operator()(const HuffmanNode &lhs, unsigned int rhs)
void resize(size_type newSize)
Change size and preserve contents.
#define NAMESPACE_BEGIN(x)
SecByteBlock m_byteBuffer
int m_compressibleDeflateLevel
size_type size() const
Provides the count of elements in the SecBlock.
SecBlock< EncodedMatch > m_matchBuffer
virtual void ProcessUncompressedData(const byte *string, size_t length)
void New(size_type newSize)
Change size without preserving contents.
bool IsolatedFlush(bool hardFlush, bool blocking)
Flushes data buffered by this object, without signal propagation.
HuffmanEncoder m_staticDistanceEncoder
DEFLATE compression and decompression (RFC 1951)
HuffmanEncoder m_dynamicDistanceEncoder
unsigned int m_matchBufferEnd
byte BitReverse(byte value)
Reverses bits in a 8-bit value.
SecBlock< word16 > m_head
byte order is little-endian
HuffmanNode(const HuffmanNode &rhs)
size_t Output(int outputSite, const byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=DEFAULT_CHANNEL)
Forward processed data on to attached transformation.
HuffmanEncoder m_dynamicLiteralEncoder
Default deflation level, compromise between speed (6)
void Encode(LowFirstBitWriter &writer, value_t value) const
FixedSizeSecBlock< unsigned int, 30 > m_distanceCounts
unsigned long FinishCounting()
unsigned int FillWindow(const byte *str, size_t length)
static void GenerateCodeLengths(unsigned int *codeBits, unsigned int maxCodeBits, const unsigned int *codeCounts, size_t nCodes)
unsigned int m_bitsBuffered
void MatchFound(unsigned int distance, unsigned int length)
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
bool operator()(const HuffmanNode &lhs, const HuffmanNode &rhs) const
CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
BufferedTransformation * AttachedTransformation()
Retrieve attached transformation.
Minimum window size, smallest table (9)
unsigned int m_bytesBuffered
unsigned int MAX_CHAIN_LENGTH
T1 SaturatingSubtract(const T1 &a, const T2 &b)
Performs a saturating subtract clamped at 0.
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be neagtive and incorrectly promoted.
unsigned int ComputeHash(const byte *str) const
unsigned int LongestMatch(unsigned int &bestMatch) const
unsigned int m_detectSkip
bool operator()(unsigned int lhs, const HuffmanNode &rhs)
Minimum deflation level, fastest speed (0)
void InitializeStaticEncoders()
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
#define CRYPTOPP_ASSERT(exp)
HuffmanEncoder()
Construct a HuffmanEncoder.
void SetDeflateLevel(int deflateLevel)
Sets the deflation level.
unsigned int MAX_LAZYLENGTH
Minimum deflation level, slowest speed (9)
unsigned int CodeLengthEncode(const unsigned int *begin, const unsigned int *end, const unsigned int *&p, unsigned int &extraBits, unsigned int &extraBitsLength)
unsigned int m_blockStart
iterator begin()
Provides an iterator pointing to the first element in the memory block.
virtual void WritePrestreamHeader()
Maximum window size, largest table (15)
std::reverse_iterator< unsigned int * > RevIt
FixedSizeSecBlock< unsigned int, 286 > m_literalCounts
void * memcpy(void *a, const void *b, size_t c)
Deflator(BufferedTransformation *attachment=NULL, int deflateLevel=DEFAULT_DEFLATE_LEVEL, int log2WindowSize=DEFAULT_LOG2_WINDOW_SIZE, bool detectUncompressible=true)
Construct a Deflator compressor.
LowFirstBitWriter(BufferedTransformation *attachment)
Construct a LowFirstBitWriter.
void Initialize(const unsigned int *codeBits, unsigned int nCodes)
Initialize or reinitialize this object.
void EncodeBlock(bool eof, unsigned int blockType)
Implementation of BufferedTransformation's attachment interface.
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
Rounds a value up to a multiple of a second value.
const T & STDMAX(const T &a, const T &b)
Replacement function for std::max.
SecBlock< word16 > m_prev
unsigned int m_stringStart
std::vector< char * > parameters
void InsertString(unsigned int start)
void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1)
Initialize or reinitialize this object, with signal propagation.
FixedSizeSecBlock< byte, 256 > m_outputBuffer
virtual void WritePoststreamTail()
unsigned int m_blockLength
HuffmanEncoder m_staticLiteralEncoder
void IsolatedInitialize(const NameValuePairs ¶meters)
Initialize or reinitialize this object, without signal propagation.
unsigned int m_detectCount
void Reset(bool forceReset=false)
Interface for retrieving values given their names.