Update contrib.
1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\euser\us_encode.cpp
18 #include "e32huffman.h"
20 #include <e32base_private.h>
24 // local definitions used for Huffman code generation
25 typedef TUint16 THuff; /** @internal */
26 const THuff KLeaf=0x8000; /** @internal */
35 /** recursive function to calculate the code lengths from the node tree
39 void HuffmanLengthsL(TUint32* aLengths,const TNode* aNodes,TInt aNode,TInt aLen)
41 if (++aLen>Huffman::KMaxCodeLength)
42 User::Leave(KErrOverflow);
44 const TNode& node=aNodes[aNode];
47 aLengths[x&~KLeaf]=aLen;
49 HuffmanLengthsL(aLengths,aNodes,x,aLen);
52 aLengths[x&~KLeaf]=aLen;
54 HuffmanLengthsL(aLengths,aNodes,x,aLen);
57 /** Insert the {aCount,aValue} pair into the already sorted array of nodes
61 void InsertInOrder(TNode* aNodes, TInt aSize, TUint aCount, TInt aVal)
63 // Uses Insertion sort following a binary search...
68 if (aNodes[m].iCount<aCount)
73 Mem::Copy(aNodes+l+1,aNodes+l,sizeof(TNode)*(aSize-l));
74 aNodes[l].iCount=aCount;
75 aNodes[l].iRight=TUint16(aVal);
78 /** Generate a Huffman code
80 This generates a Huffman code for a given set of code frequencies. The output
81 is a table of code lengths which can be used to build canonincal encoding tables
82 or decoding trees for use with the TBitInput and TBitOutput classes.
84 Entries in the table with a frequency of zero will have a zero code length
85 and thus no associated huffman encoding. If each such symbol should have a
86 maximum length encoding, they must be given at least a frequency of 1.
88 For an alphabet of n symbols, this algorithm has a transient memory overhead
89 of 8n, and a time complexity of O(n*log(n)).
91 @param aFrequency The table of code frequencies
92 @param aNumCodes The number of codes in the table
93 @param aHuffman The table for the output code-length table. This must be
94 the same size as the frequency table, and can safely be the same table
96 @leave KErrNoMemory If memory used for code generation cannot be allocated
98 @panic "USER ???" If the number of codes exceeds Huffman::KMaxCodes
100 EXPORT_C void Huffman::HuffmanL(const TUint32 aFrequency[],TInt aNumCodes,TUint32 aHuffman[])
102 __ASSERT_ALWAYS(TUint(aNumCodes)<=TUint(KMaxCodes),User::Panic(KCat,EHuffmanTooManyCodes));
104 // Sort the values into decreasing order of frequency
106 TNode* nodes = new(ELeave) TNode[aNumCodes];
107 CleanupArrayDeletePushL(nodes);
110 for (TInt ii=0;ii<aNumCodes;++ii)
112 TInt c=aFrequency[ii];
114 InsertInOrder(nodes,lCount++,c,ii|KLeaf);
117 // default code length is zero
118 Mem::FillZ(aHuffman,aNumCodes*sizeof(TUint32));
122 // no codes with frequency>0. No code has a length
126 // special case for a single value (always encode as "0")
127 aHuffman[nodes[0].iRight&~KLeaf]=1;
131 // Huffman algorithm: pair off least frequent nodes and reorder
136 TUint c=nodes[lCount].iCount + nodes[lCount-1].iCount;
137 nodes[lCount].iLeft=nodes[lCount-1].iRight;
138 // re-order the leaves now to reflect new combined frequency 'c'
139 InsertInOrder(nodes,lCount-1,c,lCount);
141 // generate code lengths in aHuffman[]
142 HuffmanLengthsL(aHuffman,nodes,1,0);
144 CleanupStack::PopAndDestroy(nodes);
146 __ASSERT_DEBUG(IsValid(aHuffman,aNumCodes),User::Panic(KCat,EHuffmanInvalidCoding));
149 /** Validate a Huffman encoding
151 This verifies that a Huffman coding described by the code lengths is valid.
152 In particular, it ensures that no code exceeds the maximum length and
153 that it is possible to generate a canonical coding for the specified lengths.
155 @param aHuffman The table of code lengths as generated by Huffman::HuffmanL()
156 @param aNumCodes The number of codes in the table
158 @return True if the code is valid, otherwise false
160 EXPORT_C TBool Huffman::IsValid(const TUint32 aHuffman[],TInt aNumCodes)
162 // The code is valid if one of the following holds:
163 // (a) the code exactly fills the 'code space'
164 // (b) there is only a single symbol with code length 1
165 // (c) there are no encoded symbols
167 TUint remain=1<<KMaxCodeLength;
169 for (const TUint32* p=aHuffman+aNumCodes; p>aHuffman;)
175 if (len>KMaxCodeLength)
177 TUint c=1<<(KMaxCodeLength-len);
184 return remain==0 || totlen<=1;
187 /** Create a canonical Huffman encoding table
189 This generates the huffman codes used by TBitOutput::HuffmanL() to write huffman
190 encoded data. The input is table of code lengths, as generated by Huffman::HuffmanL()
191 and must represent a valid huffman code.
193 @param aHuffman The table of code lengths as generated by Huffman::HuffmanL()
194 @param aNumCodes The number of codes in the table
195 @param aEncodeTable The table for the output huffman codes. This must be
196 the same size as the code-length table, and can safely be the same table
198 @panic "USER ???" If the provided code is not a valid Huffman coding
203 EXPORT_C void Huffman::Encoding(const TUint32 aHuffman[],TInt aNumCodes,TUint32 aEncodeTable[])
205 __ASSERT_ALWAYS(IsValid(aHuffman,aNumCodes),User::Panic(KCat,EHuffmanInvalidCoding));
207 TFixedArray<TInt,KMaxCodeLength> lenCount;
211 for (ii=0;ii<aNumCodes;++ii)
213 TInt len=aHuffman[ii]-1;
218 TFixedArray<TUint,KMaxCodeLength> nextCode;
220 for (ii=0;ii<KMaxCodeLength;++ii)
227 for (ii=0;ii<aNumCodes;++ii)
229 TInt len=aHuffman[ii];
234 aEncodeTable[ii] = (nextCode[len-1]<<(KMaxCodeLength-len))|(len<<KMaxCodeLength);
240 /** the encoding table for the externalised code
243 const TUint32 HuffmanEncoding[]=
276 /** encode 0a as '0' and 0b as '1', return number of symbols created
280 void EncodeRunLengthL(TBitOutput& aOutput, TInt aLength)
284 EncodeRunLengthL(aOutput,(aLength-1)>>1);
285 aOutput.HuffmanL(HuffmanEncoding[1-(aLength&1)]);
289 /** Store a canonical huffman encoding in compact form
291 As the encoding is canonical, only the code lengths of each code needs to be saved.
293 Due to the nature of code length tables, these can usually be stored very compactly
294 by encoding the encoding itself, hence the use of the bit output stream.
296 @param aOutput The output stream for the encoding
297 @param aHuffman The table of code lengths as generated by Huffman::HuffmanL()
298 @param aNumCodes The number of huffman codes in the table
300 @leave TBitOutput::HuffmanL()
302 EXPORT_C void Huffman::ExternalizeL(TBitOutput& aOutput,const TUint32 aHuffman[],TInt aNumCodes)
304 // We assume that the code length table is generated by the huffman generator,
305 // in which case the maxmimum code length is 27 bits.
307 // We apply three transformations to the data:
308 // 1. the data goes through a move-to-front coder
309 // 2. apply a rle-0 coder which replace runs of '0' with streams of '0a' and '0b'
310 // 3. encode the result using a predefined (average) huffman coding
312 // This can be done in a single pass over the data, avoiding the need for additional
315 // initialise the list for the MTF coder
316 TFixedArray<TUint8,Huffman::KMetaCodes> list;
318 for (i=0;i<list.Count();++i)
323 const TUint32* p32=aHuffman;
324 const TUint32* e32=p32+aNumCodes;
329 ++rl; // repeat of last symbol
333 EncodeRunLengthL(aOutput,rl);
335 // find code in MTF list
337 for (j=1;list[j]!=c;++j)
340 aOutput.HuffmanL(HuffmanEncoding[j+1]);
341 // adjust list for MTF algorithm
344 list[1]=TUint8(last);
348 // encod any remaining run-length
349 EncodeRunLengthL(aOutput,rl);
353 /** Construct a bit stream output object
355 Following construction the bit stream is ready for writing bits, but will first call
356 OverflowL() as the output buffer is 'full'. A derived class can detect this state as
357 Ptr() will return null.
359 EXPORT_C TBitOutput::TBitOutput()
360 :iCode(0),iBits(-8),iPtr(0),iEnd(0)
363 /** Construct a bit stream output object over a buffer
365 Data will be written to the buffer until it is full, at which point OverflowL() will
366 be called. This should handle the data and then can Set() again to reset the buffer
369 @param aBuf The buffer for output
370 @param aSize The size of the buffer in bytes
372 EXPORT_C TBitOutput::TBitOutput(TUint8* aBuf,TInt aSize)
373 :iCode(0),iBits(-8),iPtr(aBuf),iEnd(aBuf+aSize)
376 /** Write a huffman code
378 This expects a huffman code value as generated by Huffman::Encoding()
380 @param aHuffCode The huffman code write to the stream
382 @leave OverflowL() If the output buffer is full, OverflowL() is called
384 EXPORT_C void TBitOutput::HuffmanL(TUint aHuffCode)
386 DoWriteL(aHuffCode<<(32-Huffman::KMaxCodeLength),aHuffCode>>Huffman::KMaxCodeLength);
389 /** Write an arbitrary integer value
391 Write an unsigned integer using the number of bits specified. Only
392 the low order bits of the value are written to the output, most
393 significant bit first.
395 @param aValue The value to write to the stream
396 @param aLength The number of bits to output
398 @leave OverflowL() If the output buffer is full, OverflowL() is called
400 EXPORT_C void TBitOutput::WriteL(TUint aValue,TInt aLength)
403 DoWriteL(aValue<<=32-aLength,aLength);
406 /** Pad the bitstream to the next byte boundary
408 Terminate the bitstream by padding the last byte with the requested value.
409 Following this operation the bitstream can continue to be used, the data will
410 start at the next byte.
412 @param aPadding The bit value to pad the final byte with
414 @leave OverflowL() If the output buffer is full, OverflowL() is called
416 EXPORT_C void TBitOutput::PadL(TUint aPadding)
419 WriteL(aPadding?0xffffffffu:0,-iBits);
422 /** Write the higher order bits to the stream
426 void TBitOutput::DoWriteL(TUint aBits,TInt aSize)
430 // cannot process >25 bits in a single pass
431 // so do the top 8 bits first
433 DoWriteL(aBits&0xff000000u,8);
439 TUint code=iCode|(aBits>>(bits+8));
448 // run out of buffer space so invoke the overflow handler
454 *p++=TUint8(code>>24);
464 /** Handle a full output buffer
466 This virtual function is called when the output buffer is full. It should deal
467 with the data in the buffer before reseting the buffer using Set(), allowing
468 further data to be written.
470 A derived class can replace this to write the data to a file (for example)
471 before marking the buffer as empty.
473 @leave KErrOverflow The default implementation leaves
475 void TBitOutput::OverflowL()
477 User::Leave(KErrOverflow);