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_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);