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)
30void LowFirstBitWriter::StartCounting()
37unsigned long LowFirstBitWriter::FinishCounting()
44void LowFirstBitWriter::PutBits(
unsigned long value,
unsigned int length)
50 m_buffer |= value << m_bitsBuffered;
51 m_bitsBuffered += length;
53 while (m_bitsBuffered >= 8)
55 m_outputBuffer[m_bytesBuffered++] = (
byte)m_buffer;
56 if (m_bytesBuffered == m_outputBuffer.
size())
67void LowFirstBitWriter::FlushBitBuffer()
70 m_bitCount += 8*(m_bitsBuffered > 0);
73 if (m_bytesBuffered > 0)
78 if (m_bitsBuffered > 0)
87void LowFirstBitWriter::ClearBitBuffer()
102 : symbol(0), parent(0) {}
104 : symbol(rhs.symbol), parent(rhs.parent) {}
114 union {
size_t parent;
unsigned depth, freq;};
119 inline bool operator()(
unsigned int lhs,
const HuffmanNode &rhs) {
return lhs < rhs.freq;}
120 inline bool operator()(
const HuffmanNode &lhs,
const HuffmanNode &rhs)
const {
return lhs.freq < rhs.freq;}
122 inline bool operator()(
const HuffmanNode &lhs,
unsigned int rhs) {
return lhs.freq < rhs;}
125void HuffmanEncoder::GenerateCodeLengths(
unsigned int *codeBits,
unsigned int maxCodeBits,
const unsigned int *codeCounts,
size_t nCodes)
132 for (i=0; i<nCodes; i++)
135 tree[i].freq = codeCounts[i];
138 size_t treeBegin = std::upper_bound(tree.begin(), tree.end(), 0,
FreqLessThan()) - tree.begin();
139 if (treeBegin == nCodes)
141 std::fill(codeBits, codeBits+nCodes, 0);
144 tree.resize(nCodes + nCodes - treeBegin - 1);
146 size_t leastLeaf = treeBegin, leastInterior = nCodes;
147 for (i=nCodes; i<tree.size(); i++)
150 least = (leastLeaf == nCodes || (leastInterior < i && tree[leastInterior].freq < tree[leastLeaf].freq)) ? leastInterior++ : leastLeaf++;
151 tree[i].freq = tree[least].freq;
152 tree[least].parent = i;
153 least = (leastLeaf == nCodes || (leastInterior < i && tree[leastInterior].freq < tree[leastLeaf].freq)) ? leastInterior++ : leastLeaf++;
154 tree[i].freq += tree[least].freq;
155 tree[least].parent = i;
158 tree[tree.size()-1].depth = 0;
159 if (tree.size() >= 2)
160 for (i=tree.size()-2; i>=nCodes; i--)
161 tree[i].depth = tree[tree[i].parent].depth + 1;
162 unsigned int sum = 0;
164 std::fill(blCount.begin(), blCount.end(), 0);
165 for (i=treeBegin; i<nCodes; i++)
167 const size_t n = tree[i].parent;
168 const size_t depth =
STDMIN(maxCodeBits, tree[n].depth + 1);
170 sum += 1 << (maxCodeBits - depth);
173 unsigned int overflow = sum > (
unsigned int)(1 << maxCodeBits) ? sum - (1 << maxCodeBits) : 0;
177 unsigned int bits = maxCodeBits-1;
178 while (blCount[bits] == 0)
181 blCount[bits+1] += 2;
183 blCount[maxCodeBits]--;
186 for (i=0; i<treeBegin; i++)
187 codeBits[tree[i].symbol] = 0;
188 unsigned int bits = maxCodeBits;
189 for (i=treeBegin; i<nCodes; i++)
191 while (blCount[bits] == 0)
193 codeBits[tree[i].symbol] = bits;
202 unsigned int maxCodeBits = *std::max_element(codeBits, codeBits+nCodes);
203 if (maxCodeBits == 0)
207 std::fill(blCount.
begin(), blCount.
end(), 0);
209 for (i=0; i<nCodes; i++)
210 blCount[codeBits[i]]++;
215 for (i=2; i<=maxCodeBits; i++)
217 code = (code + blCount[i-1]) << 1;
220 CRYPTOPP_ASSERT(maxCodeBits == 1 || code == (1 << maxCodeBits) - blCount[maxCodeBits]);
222 m_valueToCode.resize(nCodes);
223 for (i=0; i<nCodes; i++)
225 unsigned int len = m_valueToCode[i].len = codeBits[i];
227 m_valueToCode[i].code =
BitReverse(nextCode[len]++) >> (8*
sizeof(code_t)-len);
231inline void HuffmanEncoder::Encode(
LowFirstBitWriter &writer, value_t value)
const
234 writer.PutBits(m_valueToCode[value].code, m_valueToCode[value].len);
241 InitializeStaticEncoders();
249 InitializeStaticEncoders();
253void Deflator::InitializeStaticEncoders()
255 unsigned int codeLengths[288];
256 std::fill(codeLengths + 0, codeLengths + 144, 8);
257 std::fill(codeLengths + 144, codeLengths + 256, 9);
258 std::fill(codeLengths + 256, codeLengths + 280, 7);
259 std::fill(codeLengths + 280, codeLengths + 288, 8);
260 m_staticLiteralEncoder.
Initialize(codeLengths, 288);
261 std::fill(codeLengths + 0, codeLengths + 32, 5);
262 m_staticDistanceEncoder.
Initialize(codeLengths, 32);
271 m_log2WindowSize = log2WindowSize;
272 DSIZE = 1 << m_log2WindowSize;
274 HSIZE = 1 << m_log2WindowSize;
276 m_byteBuffer.
New(2*DSIZE);
279 m_matchBuffer.
New(DSIZE/2);
286 m_compressibleDeflateLevel = detectUncompressible ? m_deflateLevel : 0;
289void Deflator::Reset(
bool forceReset)
296 m_headerWritten =
false;
297 m_matchAvailable =
false;
301 m_minLookahead = MAX_MATCH;
302 m_matchBufferEnd = 0;
310 std::fill(m_head.
begin(), m_head.
end(),
byte(0));
312 std::fill(m_literalCounts.
begin(), m_literalCounts.
end(),
byte(0));
313 std::fill(m_distanceCounts.
begin(), m_distanceCounts.
end(),
byte(0));
321 if (deflateLevel == m_deflateLevel)
326 static const unsigned int configurationTable[10][4] = {
336 {32, 128, 258, 1024},
337 {32, 258, 258, 4096}};
339 GOOD_MATCH = configurationTable[deflateLevel][0];
340 MAX_LAZYLENGTH = configurationTable[deflateLevel][1];
341 MAX_CHAIN_LENGTH = configurationTable[deflateLevel][3];
343 m_deflateLevel = deflateLevel;
346unsigned int Deflator::FillWindow(
const byte *str,
size_t length)
348 unsigned int maxBlockSize = (
unsigned int)
STDMIN(2UL*DSIZE, 0xffffUL);
350 if (m_stringStart >= maxBlockSize - MAX_MATCH)
352 if (m_blockStart < DSIZE)
355 memcpy(m_byteBuffer, m_byteBuffer + DSIZE, DSIZE);
357 m_dictionaryEnd = m_dictionaryEnd < DSIZE ? 0 : m_dictionaryEnd-DSIZE;
359 m_stringStart -= DSIZE;
361 m_previousMatch -= DSIZE;
363 m_blockStart -= DSIZE;
370 for (i=0; i<HSIZE; i++)
373 for (i=0; i<DSIZE; i++)
378 unsigned int accepted =
UnsignedMin(maxBlockSize-(m_stringStart+m_lookahead), length);
380 memcpy(m_byteBuffer + m_stringStart + m_lookahead, str, accepted);
381 m_lookahead += accepted;
385inline unsigned int Deflator::ComputeHash(
const byte *str)
const
388 return ((str[0] << 10) ^ (str[1] << 5) ^ str[2]) & HMASK;
391unsigned int Deflator::LongestMatch(
unsigned int &bestMatch)
const
396 unsigned int bestLength =
STDMAX(m_previousLength, (
unsigned int)MIN_MATCH-1);
397 if (m_lookahead <= bestLength)
400 const byte *scan = m_byteBuffer + m_stringStart, *scanEnd = scan +
STDMIN((
unsigned int)MAX_MATCH, m_lookahead);
401 unsigned int limit = m_stringStart > (DSIZE-MAX_MATCH) ? m_stringStart - (DSIZE-MAX_MATCH) : 0;
402 unsigned int current = m_head[ComputeHash(scan)];
404 unsigned int chainLength = MAX_CHAIN_LENGTH;
405 if (m_previousLength >= GOOD_MATCH)
408 while (current > limit && --chainLength > 0)
410 const byte *match = m_byteBuffer + current;
411 CRYPTOPP_ASSERT(scan + bestLength < m_byteBuffer + m_stringStart + m_lookahead);
412 if (scan[bestLength-1] == match[bestLength-1] && scan[bestLength] == match[bestLength] && scan[0] == match[0] && scan[1] == match[1])
415 unsigned int len = (
unsigned int)(
416#
if defined(_STDEXT_BEGIN) && !(defined(_MSC_VER) && (_MSC_VER < 1400 || _MSC_VER >= 1600)) && !defined(_STLPORT_VERSION)
417 stdext::unchecked_mismatch
422 (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));
424 (scan+3, scanEnd, match+3).first - scan);
427 if (len > bestLength)
433 if (len == (
unsigned int)(scanEnd - scan))
437 current = m_prev[current & DMASK];
439 return (bestMatch > 0) ? bestLength : 0;
442inline void Deflator::InsertString(
unsigned int start)
445 unsigned int hash = ComputeHash(m_byteBuffer + start);
446 m_prev[start & DMASK] = m_head[hash];
447 m_head[hash] =
word16(start);
450void Deflator::ProcessBuffer()
452 if (!m_headerWritten)
454 WritePrestreamHeader();
455 m_headerWritten =
true;
458 if (m_deflateLevel == 0)
460 m_stringStart += m_lookahead;
462 m_blockLength = m_stringStart - m_blockStart;
463 m_matchAvailable =
false;
467 while (m_lookahead > m_minLookahead)
469 while (m_dictionaryEnd < m_stringStart && m_dictionaryEnd+3 <= m_stringStart+m_lookahead)
470 InsertString(m_dictionaryEnd++);
472 if (m_matchAvailable)
474 unsigned int matchPosition = 0, matchLength = 0;
475 bool usePreviousMatch;
476 if (m_previousLength >= MAX_LAZYLENGTH)
477 usePreviousMatch =
true;
480 matchLength = LongestMatch(matchPosition);
481 usePreviousMatch = (matchLength == 0);
483 if (usePreviousMatch)
485 MatchFound(m_stringStart-1-m_previousMatch, m_previousLength);
486 m_stringStart += m_previousLength-1;
487 m_lookahead -= m_previousLength-1;
488 m_matchAvailable =
false;
492 m_previousLength = matchLength;
493 m_previousMatch = matchPosition;
494 LiteralByte(m_byteBuffer[m_stringStart-1]);
501 m_previousLength = 0;
502 m_previousLength = LongestMatch(m_previousMatch);
503 if (m_previousLength)
504 m_matchAvailable =
true;
506 LiteralByte(m_byteBuffer[m_stringStart]);
511 CRYPTOPP_ASSERT(m_stringStart - (m_blockStart+m_blockLength) == (
unsigned int)m_matchAvailable);
514 if (m_minLookahead == 0 && m_matchAvailable)
516 LiteralByte(m_byteBuffer[m_stringStart-1]);
517 m_matchAvailable =
false;
521size_t Deflator::Put2(
const byte *str,
size_t length,
int messageEnd,
bool blocking)
527 while (accepted < length)
529 unsigned int newAccepted = FillWindow(str+accepted, length-accepted);
532 ProcessUncompressedData(str+accepted, newAccepted);
533 accepted += newAccepted;
543 WritePoststreamTail();
547 Output(0, NULLPTR, 0, messageEnd, blocking);
558 m_minLookahead = MAX_MATCH;
561 EncodeBlock(
false, STORED);
565void Deflator::LiteralByte(
byte b)
567 if (m_matchBufferEnd == m_matchBuffer.
size())
570 m_matchBuffer[m_matchBufferEnd++].literalCode = b;
571 m_literalCounts[b]++;
575void Deflator::MatchFound(
unsigned int distance,
unsigned int length)
577 if (m_matchBufferEnd == m_matchBuffer.
size())
580 static const unsigned int lengthCodes[] = {
581 257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268, 268,
582 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 272,
583 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274,
584 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276, 276, 276, 276, 276,
585 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
586 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
587 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279,
588 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280,
589 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281,
590 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281,
591 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282,
592 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282,
593 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
594 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
595 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
596 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 285};
597 static const unsigned int lengthBases[] =
598 {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,
600 static const unsigned int distanceBases[30] =
601 {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,
602 4097,6145,8193,12289,16385,24577};
605 EncodedMatch &m = m_matchBuffer[m_matchBufferEnd++];
607 unsigned int lengthCode = lengthCodes[length-3];
608 m.literalCode = lengthCode;
609 m.literalExtra = length - lengthBases[lengthCode-257];
610 unsigned int distanceCode = (
unsigned int)(std::upper_bound(distanceBases, distanceBases+30, distance) - distanceBases - 1);
611 m.distanceCode = distanceCode;
612 m.distanceExtra = distance - distanceBases[distanceCode];
614 m_literalCounts[lengthCode]++;
615 m_distanceCounts[distanceCode]++;
616 m_blockLength += length;
619inline unsigned int CodeLengthEncode(
const unsigned int *begin,
620 const unsigned int *end,
621 const unsigned int *& p,
622 unsigned int &extraBits,
623 unsigned int &extraBitsLength)
628 const unsigned int *oldp = p;
629 if (v==0 && p[1]==0 && p[2]==0)
631 for (p=p+3; p!=end && *p==0 && p!=oldp+138; p++) {}
632 unsigned int repeat = (
unsigned int)(p - oldp);
635 extraBits = repeat-3;
641 extraBits = repeat-11;
646 else if (p!=begin && v==p[-1] && v==p[1] && v==p[2])
648 for (p=p+3; p!=end && *p==v && p!=oldp+6; p++) {}
649 unsigned int repeat = (
unsigned int)(p - oldp);
650 extraBits = repeat-3;
661void Deflator::EncodeBlock(
bool eof,
unsigned int blockType)
664 PutBits(blockType, 2);
666 if (blockType == STORED)
677 if (blockType == DYNAMIC)
682 m_literalCounts[256] = 1;
683 HuffmanEncoder::GenerateCodeLengths(literalCodeLengths, 15, m_literalCounts, 286);
684 m_dynamicLiteralEncoder.
Initialize(literalCodeLengths, 286);
685 unsigned int hlit = (
unsigned int)(
FindIfNot(RevIt(literalCodeLengths.
end()), RevIt(literalCodeLengths.
begin()+257), 0).base() - (literalCodeLengths.
begin()+257));
687 HuffmanEncoder::GenerateCodeLengths(distanceCodeLengths, 15, m_distanceCounts, 30);
688 m_dynamicDistanceEncoder.
Initialize(distanceCodeLengths, 30);
689 unsigned int hdist = (
unsigned int)(
FindIfNot(RevIt(distanceCodeLengths.
end()), RevIt(distanceCodeLengths.
begin()+1), 0).base() - (distanceCodeLengths.
begin()+1));
692 memcpy(combinedLengths, literalCodeLengths, (hlit+257)*
sizeof(
unsigned int));
693 memcpy(combinedLengths+hlit+257, distanceCodeLengths, (hdist+1)*
sizeof(
unsigned int));
696 std::fill(codeLengthCodeCounts.
begin(), codeLengthCodeCounts.
end(), 0);
697 const unsigned int *p = combinedLengths.begin(), *begin = combinedLengths.begin(), *end = combinedLengths.end();
700 unsigned int code=0, extraBits=0, extraBitsLength=0;
701 code = CodeLengthEncode(begin, end, p, extraBits, extraBitsLength);
702 codeLengthCodeCounts[code]++;
704 HuffmanEncoder::GenerateCodeLengths(codeLengthCodeLengths, 7, codeLengthCodeCounts, 19);
706 static const unsigned int border[] = {
707 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
708 unsigned int hclen = 19;
709 while (hclen > 4 && codeLengthCodeLengths[border[hclen-1]] == 0)
717 for (
unsigned int i=0; i<hclen+4; i++)
718 PutBits(codeLengthCodeLengths[border[i]], 3);
720 p = combinedLengths.begin();
723 unsigned int code=0, extraBits=0, extraBitsLength=0;
724 code = CodeLengthEncode(begin, end, p, extraBits, extraBitsLength);
725 codeLengthEncoder.Encode(*
this, code);
726 PutBits(extraBits, extraBitsLength);
730 static const unsigned int lengthExtraBits[] = {
731 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
732 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
733 static const unsigned int distanceExtraBits[] = {
734 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
735 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
738 const HuffmanEncoder &literalEncoder = (blockType == STATIC) ? m_staticLiteralEncoder : m_dynamicLiteralEncoder;
739 const HuffmanEncoder &distanceEncoder = (blockType == STATIC) ? m_staticDistanceEncoder : m_dynamicDistanceEncoder;
741 for (
unsigned int i=0; i<m_matchBufferEnd; i++)
743 unsigned int literalCode = m_matchBuffer[i].literalCode;
744 literalEncoder.Encode(*
this, literalCode);
745 if (literalCode >= 257)
748 PutBits(m_matchBuffer[i].literalExtra, lengthExtraBits[literalCode-257]);
749 unsigned int distanceCode = m_matchBuffer[i].distanceCode;
750 distanceEncoder.Encode(*
this, distanceCode);
751 PutBits(m_matchBuffer[i].distanceExtra, distanceExtraBits[distanceCode]);
754 literalEncoder.Encode(*
this, 256);
758void Deflator::EndBlock(
bool eof)
760 if (m_blockLength == 0 && !eof)
763 if (m_deflateLevel == 0)
765 EncodeBlock(eof, STORED);
767 if (m_compressibleDeflateLevel > 0 && ++m_detectCount == m_detectSkip)
769 m_deflateLevel = m_compressibleDeflateLevel;
775 unsigned long storedLen = 8*((
unsigned long)m_blockLength+4) +
RoundUpToMultipleOf(m_bitsBuffered+3, 8U)-m_bitsBuffered;
778 EncodeBlock(eof, STATIC);
779 unsigned long staticLen = FinishCounting();
781 unsigned long dynamicLen;
782 if (m_blockLength < 128 && m_deflateLevel < 8)
783 dynamicLen = ULONG_MAX;
787 EncodeBlock(eof, DYNAMIC);
788 dynamicLen = FinishCounting();
791 if (storedLen <= staticLen && storedLen <= dynamicLen)
793 EncodeBlock(eof, STORED);
795 if (m_compressibleDeflateLevel > 0)
799 m_detectSkip = m_detectSkip ?
STDMIN(2*m_detectSkip, 128U) : 1;
804 if (staticLen <= dynamicLen)
805 EncodeBlock(eof, STATIC);
807 EncodeBlock(eof, DYNAMIC);
809 if (m_compressibleDeflateLevel > 0)
814 m_matchBufferEnd = 0;
815 m_blockStart += m_blockLength;
817 std::fill(m_literalCounts.
begin(), m_literalCounts.
end(), 0);
818 std::fill(m_distanceCounts.
begin(), m_distanceCounts.
end(), 0);
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
bool IsolatedFlush(bool hardFlush, bool blocking)
Flushes data buffered by this object, without signal propagation.
void SetDeflateLevel(int deflateLevel)
Sets the deflation level.
@ DEFAULT_LOG2_WINDOW_SIZE
Default window size (15)
@ MAX_LOG2_WINDOW_SIZE
Maximum window size, largest table (15)
@ MIN_LOG2_WINDOW_SIZE
Minimum window size, smallest table (9)
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
@ MIN_DEFLATE_LEVEL
Minimum deflation level, fastest speed (0)
@ DEFAULT_DEFLATE_LEVEL
Default deflation level, compromise between speed (6)
@ MAX_DEFLATE_LEVEL
Minimum deflation level, slowest speed (9)
void IsolatedInitialize(const NameValuePairs ¶meters)
Initialize or reinitialize this object, without signal propagation.
Deflator(BufferedTransformation *attachment=NULL, int deflateLevel=DEFAULT_DEFLATE_LEVEL, int log2WindowSize=DEFAULT_LOG2_WINDOW_SIZE, bool detectUncompressible=true)
Construct a Deflator compressor.
Implementation of BufferedTransformation's attachment interface.
BufferedTransformation * AttachedTransformation()
Retrieve attached transformation.
void Initialize(const unsigned int *codeBits, unsigned int nCodes)
Initialize or reinitialize this object.
HuffmanEncoder()
Construct a HuffmanEncoder.
An invalid argument was detected.
LowFirstBitWriter(BufferedTransformation *attachment)
Construct a LowFirstBitWriter.
Interface for retrieving values given their names.
T GetValueWithDefault(const char *name, T defaultValue) const
Get a named value.
CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
iterator begin()
Provides an iterator pointing to the first element in the memory block.
iterator end()
Provides an iterator pointing beyond the last element in the memory block.
void New(size_type newSize)
Change size without preserving contents.
size_type size() const
Provides the count of elements in the SecBlock.
Stack-based SecBlock that grows into the heap.
unsigned char byte
8-bit unsigned datatype
unsigned short word16
16-bit unsigned datatype
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
Utility functions for the Crypto++ library.
byte BitReverse(byte value)
Reverses bits in a 8-bit value.
#define COUNTOF(arr)
Counts elements in an array.
T1 SaturatingSubtract(const T1 &a, const T2 &b)
Performs a saturating subtract clamped at 0.
const T & STDMAX(const T &a, const T &b)
Replacement function for std::max.
T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
Rounds a value up to a multiple of a second value.
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
InputIt FindIfNot(InputIt first, InputIt last, const T &value)
Finds first element not in a range.
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be negative and incorrectly promoted.
Crypto++ library namespace.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
DEFLATE compression and decompression (RFC 1951)