First public contribution.
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_decode.cpp
18 #include "e32huffman.h"
20 #include <e32base_private.h>
24 const TInt KHuffTerminate=0x0001;
25 const TUint32 KBranch1=sizeof(TUint32)<<16;
28 TUint32* HuffmanSubTree(TUint32* aPtr,const TUint32* aValue,TUint32** aLevel)
30 // write the subtree below aPtr and return the head
36 TUint32* sub0=HuffmanSubTree(aPtr,aValue,aLevel); // 0-tree first
37 aPtr=HuffmanSubTree(sub0,aValue-(aPtr-sub0)-1,aLevel); // 1-tree
38 TInt branch0=(TUint8*)sub0-(TUint8*)(aPtr-1);
39 *--aPtr=KBranch1|branch0;
43 TUint term0=*aValue--; // 0-term
44 aPtr=HuffmanSubTree(aPtr,aValue,aLevel); // 1-tree
45 *--aPtr=KBranch1|(term0>>16);
49 TUint term0=*aValue--; // 0-term
50 TUint term1=*aValue--;
51 *--aPtr=(term1>>16<<16)|(term0>>16);
56 /** Create a canonical Huffman decoding tree
58 This generates the huffman decoding tree used by TBitInput::HuffmanL() to read huffman
59 encoded data. The input is table of code lengths, as generated by Huffman::HuffmanL()
60 and must represent a valid huffman code.
62 @param aHuffman The table of code lengths as generated by Huffman::HuffmanL()
63 @param aNumCodes The number of codes in the table
64 @param aDecodeTree The space for the decoding tree. This must be the same
65 size as the code-length table, and can safely be the same memory
66 @param aSymbolBase the base value for the output 'symbols' from the decoding tree, by default
69 @panic "USER ???" If the provided code is not a valid Huffman coding
74 EXPORT_C void Huffman::Decoding(const TUint32 aHuffman[],TInt aNumCodes,TUint32 aDecodeTree[],TInt aSymbolBase)
76 __ASSERT_ALWAYS(IsValid(aHuffman,aNumCodes),User::Panic(KCat,EHuffmanInvalidCoding));
78 TFixedArray<TInt,KMaxCodeLength> counts;
82 for (ii=0;ii<aNumCodes;++ii)
84 TInt len=aHuffman[ii];
93 TFixedArray<TUint32*,KMaxCodeLength> level;
94 TUint32* lit=aDecodeTree+codes;
95 for (ii=0;ii<KMaxCodeLength;++ii)
100 aSymbolBase=(aSymbolBase<<17)+(KHuffTerminate<<16);
101 for (ii=0;ii<aNumCodes;++ii)
103 TUint len=TUint8(aDecodeTree[ii]);
105 *--level[len-1]|=(ii<<17)+aSymbolBase;
107 if (codes==1) // codes==1 special case: incomplete tree
109 TUint term=aDecodeTree[0]>>16;
110 aDecodeTree[0]=term|(term<<16); // 0- and 1-terminate at root
113 HuffmanSubTree(aDecodeTree+codes-1,aDecodeTree+codes-1,&level[0]);
116 // The decoding tree for the externalised code
117 const TUint32 HuffmanDecoding[]=
149 /** Restore a canonical huffman encoding from a bit stream
151 The encoding must have been stored using Huffman::ExternalizeL(). The resulting
152 code-length table can be used to create an encoding table using Huffman::Encoding()
153 or a decoding tree using Huffman::Decoding().
155 @param aInput The input stream with the encoding
156 @param aHuffman The internalized code-length table is placed here
157 @param aNumCodes The number of huffman codes in the table
159 @leave TBitInput::HuffmanL()
163 EXPORT_C void Huffman::InternalizeL(TBitInput& aInput,TUint32 aHuffman[],TInt aNumCodes)
164 // See ExternalizeL for a description of the format
166 // initialise move-to-front list
167 TFixedArray<TUint8,Huffman::KMetaCodes> list;
168 for (TInt i=0;i<list.Count();++i)
171 // extract codes, reverse rle-0 and mtf encoding in one pass
173 const TUint32* end=aHuffman+aNumCodes;
177 TInt c=aInput.HuffmanL(HuffmanDecoding);
181 // one of the zero codes used by RLE-0
182 // update he run-length
187 if(rl >= TUint(end-p))
188 User::Leave(KErrCorrupt);
194 --c; // c is now 1..27
195 list[0]=TUint8(last);
197 Mem::Copy(&list[1],&list[0],c);
207 // bit-stream input class
209 inline TUint reverse(TUint aVal)
211 // Reverse the byte-order of a 32 bit value
212 // This generates optimal ARM code (4 instructions)
215 TUint v=(aVal<<16)|(aVal>>16);
218 aVal=(aVal>>8)|(aVal<<24);
222 /** Construct a bit stream input object
224 Following construction the bit stream is ready for reading bits, but will
225 immediately call UnderflowL() as the input buffer is empty.
227 EXPORT_C TBitInput::TBitInput()
228 :iCount(0),iRemain(0)
231 /** Construct a bit stream input object over a buffer
233 Following construction the bit stream is ready for reading bits from
234 the specified buffer.
236 @param aPtr The address of the buffer containing the bit stream
237 @param aLength The length of the bitstream in bits
238 @param aOffset The bit offset from the start of the buffer to the bit stream (defaults to zero)
240 EXPORT_C TBitInput::TBitInput(const TUint8* aPtr, TInt aLength, TInt aOffset)
242 Set(aPtr,aLength,aOffset);
245 /** Set the memory buffer to use for input
247 Bits will be read from this buffer until it is empty, at which point
248 UnderflowL() will be called.
250 @param aPtr The address of the buffer containing the bit stream
251 @param aLength The length of the bitstream in bits
252 @param aOffset The bit offset from the start of the buffer to the bit stream (defaults to zero)
254 EXPORT_C void TBitInput::Set(const TUint8* aPtr, TInt aLength, TInt aOffset)
257 p+=aOffset>>3; // nearest byte to the specified bit offset
258 aOffset&=7; // bit offset within the byte
259 const TUint32* ptr=(const TUint32*)(p&~3); // word containing this byte
260 aOffset+=(p&3)<<3; // bit offset within the word
265 // read the first few bits of the stream
266 iBits=reverse(*ptr++)<<aOffset;
277 #ifndef __HUFFMAN_MACHINE_CODED__
279 /** Read a single bit from the input
281 Return the next bit in the input stream. This will call UnderflowL() if
282 there are no more bits available.
284 @return The next bit in the stream
286 @leave "UnderflowL()" It the bit stream is exhausted more UnderflowL is called
289 EXPORT_C TUint TBitInput::ReadL()
300 /** Read a multi-bit value from the input
302 Return the next few bits as an unsigned integer. The last bit read is
303 the least significant bit of the returned value, and the value is
304 zero extended to return a 32-bit result.
306 A read of zero bits will always reaturn zero.
308 This will call UnderflowL() if there are not enough bits available.
310 @param aSize The number of bits to read
312 @return The bits read from the stream
314 @leave "UnderflowL()" It the bit stream is exhausted more UnderflowL is called
317 EXPORT_C TUint TBitInput::ReadL(TInt aSize)
328 // X86 does not allow shift-by-32
330 val|=bits>>(32-(iCount+aSize))<<(-iCount); // scrub low order bits
332 val|=bits>>(32-(iCount+aSize))<<(-iCount); // scrub low order bits
334 aSize=-iCount; // bits still required
337 bits=reverse(*iPtr++);
351 // X86 does not allow shift-by-32
352 iBits=aSize==32?0:bits<<aSize;
356 return val|(bits>>(32-aSize));
359 /** Read and decode a Huffman Code
361 Interpret the next bits in the input as a Huffman code in the specified
362 decoding. The decoding tree should be the output from Huffman::Decoding().
364 @param aTree The huffman decoding tree
366 @return The symbol that was decoded
368 @leave "UnderflowL()" It the bit stream is exhausted more UnderflowL is called
371 EXPORT_C TUint TBitInput::HuffmanL(const TUint32* aTree)
376 aTree=PtrAdd(aTree,huff>>16);
380 } while ((huff&0x10000u)==0);
386 /** Handle an empty input buffer
388 This virtual function is called when the input buffer is empty and
389 more bits are required. It should reset the input buffer with more
392 A derived class can replace this to read the data from a file
393 (for example) before reseting the input buffer.
395 @leave KErrUnderflow The default implementation leaves
397 void TBitInput::UnderflowL()
399 User::Leave(KErrUnderflow);