e32tools/e32lib/e32image/deflate/encode.cpp
author raptorbot <raptorbot@systemstesthead.symbian.intra>
Fri, 18 Dec 2009 19:57:42 +0000
branchwip
changeset 117 ecf683438dc6
parent 0 044383f39525
permissions -rw-r--r--
Don't mess around with EPOCROOT until actually entering raptor so we know what the original was Put the original epocroot back on the front of the whatcomp output. This allows what output to be either relative or absolute depending on what your epocroot is.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     1
// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     2
// All rights reserved.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     3
// This component and the accompanying materials are made available
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     4
// under the terms of "Eclipse Public License v1.0"
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     5
// which accompanies this distribution, and is available
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     7
//
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     8
// Initial Contributors:
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    10
//
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    11
// Contributors:
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    12
//
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    13
// Description:
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    14
// e32tools\petran\Szip\encode.cpp
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    15
// 
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    16
//
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    17
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    18
#include "huffman.h"
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    19
#include "panic.h"
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    20
#include <e32base.h>
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    21
#include "h_utl.h"
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    22
#include <assert.h>
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    23
#include "farray.h"
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    24
#include <stdlib.h>
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    25
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    26
void User::Invariant()
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    27
	{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    28
	fprintf(stderr, "User::Invariant() called\n");
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    29
	exit(1);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    30
	}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    31
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    32
// local definitions used for Huffman code generation
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    33
typedef TUint16 THuff;		/** @internal */
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    34
const THuff KLeaf=0x8000;	/** @internal */
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    35
struct TNode
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    36
/** @internal */
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    37
	{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    38
	TUint iCount;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    39
	THuff iLeft;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    40
	THuff iRight;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    41
	};
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    42
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    43
void HuffmanLengthsL(TUint32* aLengths,const TNode* aNodes,TInt aNode,TInt aLen)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    44
/** recursive function to calculate the code lengths from the node tree
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    45
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    46
	@internal
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    47
*/
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    48
	{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    49
	if (++aLen>Huffman::KMaxCodeLength)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    50
		Panic(EHuffmanBufferOverflow);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    51
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    52
	const TNode& node=aNodes[aNode];
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    53
	TUint x=node.iLeft;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    54
	if (x&KLeaf)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    55
		aLengths[x&~KLeaf]=aLen;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    56
	else
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    57
		HuffmanLengthsL(aLengths,aNodes,x,aLen);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    58
	x=node.iRight;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    59
	if (x&KLeaf)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    60
		aLengths[x&~KLeaf]=aLen;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    61
	else
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    62
		HuffmanLengthsL(aLengths,aNodes,x,aLen);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    63
	}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    64
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    65
void InsertInOrder(TNode* aNodes, TInt aSize, TUint aCount, TInt aVal)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    66
/**	Insert the {aCount,aValue} pair into the already sorted array of nodes
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    67
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    68
	@internal
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    69
*/
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    70
	{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    71
	// Uses Insertion sort following a binary search...
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    72
	TInt l=0, r=aSize;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    73
	while (l < r)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    74
		{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    75
		TInt m = (l+r) >> 1;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    76
		if (aNodes[m].iCount<aCount)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    77
			r=m;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    78
		else
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    79
			l=m+1;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    80
		}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    81
	HMem::Copy(aNodes+l+1,aNodes+l,sizeof(TNode)*(aSize-l));
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    82
	aNodes[l].iCount=aCount;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    83
	aNodes[l].iRight=TUint16(aVal);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    84
	}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    85
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    86
void Huffman::HuffmanL(const TUint32 aFrequency[],TInt aNumCodes,TUint32 aHuffman[])
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    87
/** Generate a Huffman code
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    88
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    89
	This generates a Huffman code for a given set of code frequencies. The output
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    90
	is a table of code lengths which can be used to build canonincal encoding tables
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    91
	or decoding trees for use with the TBitInput and TBitOutput classes.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    92
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    93
	Entries in the table with a frequency of zero will have a zero code length
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    94
	and thus no associated huffman encoding. If each such symbol should have a
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    95
	maximum length encoding, they must be given at least a frequency of 1.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    96
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    97
	For an alphabet of n symbols, this algorithm has a transient memory overhead
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    98
	of 8n, and a time complexity of O(n*log(n)).
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
    99
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   100
	@param "const TUint32 aFrequency[]" The table of code frequencies
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   101
	@param "TInt aNumCodes" The number of codes in the table
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   102
	@param "TUint32 aHuffman[]" The table for the output code-length table. This must be
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   103
		the same size as the frequency table, and can safely be the same table
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   104
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   105
	@leave "KErrNoMemory" If memory used for code generation cannot be allocated
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   106
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   107
  	@panic "USER ???" If the number of codes exceeds Huffman::KMaxCodes
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   108
*/
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   109
	{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   110
	if(TUint(aNumCodes)>TUint(KMaxCodes))
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   111
		Panic(EHuffmanTooManyCodes);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   112
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   113
	// Sort the values into decreasing order of frequency
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   114
	//
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   115
	TNode* nodes = new TNode[aNumCodes];
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   116
	if(nodes==NULL)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   117
		Panic(EHuffmanOutOfMemory);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   118
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   119
	TInt lCount=0;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   120
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   121
	for (TInt ii=0;ii<aNumCodes;++ii)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   122
		{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   123
		TInt c=aFrequency[ii];
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   124
		if (c!=0)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   125
			InsertInOrder(nodes,lCount++,c,ii|KLeaf);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   126
		}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   127
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   128
	// default code length is zero
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   129
	HMem::FillZ(aHuffman,aNumCodes*sizeof(TUint32));
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   130
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   131
	if (lCount==0)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   132
		{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   133
		// no codes with frequency>0. No code has a length
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   134
		}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   135
	else if (lCount==1)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   136
		{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   137
		// special case for a single value (always encode as "0")
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   138
		aHuffman[nodes[0].iRight&~KLeaf]=1;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   139
		}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   140
	else
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   141
		{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   142
		// Huffman algorithm: pair off least frequent nodes and reorder
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   143
		//
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   144
		do
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   145
			{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   146
			--lCount;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   147
			TUint c=nodes[lCount].iCount + nodes[lCount-1].iCount;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   148
			nodes[lCount].iLeft=nodes[lCount-1].iRight;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   149
			// re-order the leaves now to reflect new combined frequency 'c'
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   150
			InsertInOrder(nodes,lCount-1,c,lCount);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   151
			} while (lCount>1);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   152
		// generate code lengths in aHuffman[]
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   153
		HuffmanLengthsL(aHuffman,nodes,1,0);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   154
		}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   155
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   156
	delete [] nodes;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   157
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   158
	if(!IsValid(aHuffman,aNumCodes))
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   159
		Panic(EHuffmanInvalidCoding);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   160
	}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   161
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   162
TBool Huffman::IsValid(const TUint32 aHuffman[],TInt aNumCodes)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   163
/** Validate a Huffman encoding
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   164
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   165
	This verifies that a Huffman coding described by the code lengths is valid.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   166
	In particular, it ensures that no code exceeds the maximum length and
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   167
	that it is possible to generate a canonical coding for the specified lengths.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   168
	
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   169
	@param "const TUint32 aHuffman[]" The table of code lengths as generated by Huffman::HuffmanL()
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   170
	@param "TInt aNumCodes" The number of codes in the table
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   171
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   172
	@return True if the code is valid, otherwise false
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   173
*/
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   174
	{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   175
	// The code is valid if one of the following holds:
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   176
	// (a) the code exactly fills the 'code space'
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   177
	// (b) there is only a single symbol with code length 1
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   178
	// (c) there are no encoded symbols
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   179
	//
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   180
	TUint remain=1<<KMaxCodeLength;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   181
	TInt totlen=0;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   182
	for (const TUint32* p=aHuffman+aNumCodes; p>aHuffman;)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   183
		{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   184
		TInt len=*--p;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   185
		if (len>0)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   186
			{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   187
			totlen+=len;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   188
			if (len>KMaxCodeLength)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   189
				return EFalse;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   190
			TUint c=1<<(KMaxCodeLength-len);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   191
			if (c>remain)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   192
				return EFalse;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   193
			remain-=c;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   194
			}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   195
		}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   196
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   197
	return remain==0 || totlen<=1;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   198
	}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   199
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   200
void Huffman::Encoding(const TUint32 aHuffman[],TInt aNumCodes,TUint32 aEncodeTable[])
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   201
/** Create a canonical Huffman encoding table
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   202
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   203
	This generates the huffman codes used by TBitOutput::HuffmanL() to write huffman
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   204
	encoded data. The input is table of code lengths, as generated by Huffman::HuffmanL()
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   205
	and must represent a valid huffman code.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   206
	
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   207
	@param "const TUint32 aHuffman[]" The table of code lengths as generated by Huffman::HuffmanL()
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   208
	@param "TInt aNumCodes" The number of codes in the table
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   209
	@param "TUint32 aEncodeTable[]" The table for the output huffman codes. This must be
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   210
		the same size as the code-length table, and can safely be the same table
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   211
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   212
	@panic "USER ???" If the provided code is not a valid Huffman coding
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   213
	
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   214
	@see IsValid()
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   215
	@see HuffmanL()
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   216
*/
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   217
	{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   218
	__ASSERT_ALWAYS(IsValid(aHuffman,aNumCodes),Panic(EHuffmanInvalidCoding));
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   219
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   220
	TFixedArray<TInt,KMaxCodeLength> lenCount;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   221
	lenCount.Reset();
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   222
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   223
	TInt ii;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   224
	for (ii=0;ii<aNumCodes;++ii)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   225
		{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   226
		TInt len=aHuffman[ii]-1;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   227
		if (len>=0)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   228
			++lenCount[len];
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   229
		}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   230
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   231
	TFixedArray<TUint,KMaxCodeLength> nextCode;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   232
	TUint code=0;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   233
	for (ii=0;ii<KMaxCodeLength;++ii)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   234
		{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   235
		code<<=1;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   236
		nextCode[ii]=code;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   237
		code+=lenCount[ii];
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   238
		}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   239
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   240
	for (ii=0;ii<aNumCodes;++ii)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   241
		{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   242
		TInt len=aHuffman[ii];
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   243
		if (len==0)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   244
			aEncodeTable[ii]=0;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   245
		else
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   246
			{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   247
			aEncodeTable[ii] = (nextCode[len-1]<<(KMaxCodeLength-len))|(len<<KMaxCodeLength);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   248
			++nextCode[len-1];
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   249
			}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   250
		}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   251
	}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   252
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   253
/** the encoding table for the externalised code
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   254
	@internal
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   255
*/
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   256
const TUint32 HuffmanEncoding[]=
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   257
	{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   258
	0x10000000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   259
	0x1c000000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   260
	0x12000000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   261
	0x1d000000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   262
	0x26000000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   263
	0x26800000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   264
	0x2f000000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   265
	0x37400000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   266
	0x37600000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   267
	0x37800000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   268
	0x3fa00000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   269
	0x3fb00000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   270
	0x3fc00000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   271
	0x3fd00000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   272
	0x47e00000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   273
	0x47e80000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   274
	0x47f00000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   275
	0x4ff80000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   276
	0x57fc0000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   277
	0x5ffe0000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   278
	0x67ff0000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   279
	0x77ff8000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   280
	0x7fffa000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   281
	0x7fffb000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   282
	0x7fffc000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   283
	0x7fffd000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   284
	0x7fffe000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   285
	0x87fff000,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   286
	0x87fff800
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   287
	};
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   288
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   289
void EncodeRunLengthL(TBitOutput& aOutput, TInt aLength)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   290
/** encode 0a as '0' and 0b as '1', return number of symbols created
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   291
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   292
	@internal
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   293
*/
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   294
	{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   295
	if (aLength>0)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   296
		{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   297
		EncodeRunLengthL(aOutput,(aLength-1)>>1);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   298
		aOutput.HuffmanL(HuffmanEncoding[1-(aLength&1)]);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   299
		}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   300
	}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   301
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   302
void Huffman::ExternalizeL(TBitOutput& aOutput,const TUint32 aHuffman[],TInt aNumCodes)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   303
/** Store a canonical huffman encoding in compact form
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   304
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   305
	As the encoding is canonical, only the code lengths of each code needs to be saved.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   306
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   307
	Due to the nature of code length tables, these can usually be stored very compactly
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   308
	by encoding the encoding itself, hence the use of the bit output stream.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   309
	
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   310
	@param "TBitOutput& aOutput" The output stream for the encoding
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   311
	@param "const TUint32 aHuffman[]" The table of code lengths as generated by Huffman::HuffmanL()
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   312
	@param "TInt aNumCodes" The number of huffman codes in the table
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   313
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   314
	@leave "TBitOutput::HuffmanL()"
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   315
*/
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   316
	{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   317
	// We assume that the code length table is generated by the huffman generator,
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   318
	// in which case the maxmimum code length is 27 bits.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   319
	//
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   320
	// We apply three transformations to the data:
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   321
	// 1. the data goes through a move-to-front coder
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   322
	// 2. apply a rle-0 coder which replace runs of '0' with streams of '0a' and '0b'
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   323
	// 3. encode the result using a predefined (average) huffman coding
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   324
	//
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   325
	// This can be done in a single pass over the data, avoiding the need for additional
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   326
	// memory.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   327
	//
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   328
	// initialise the list for the MTF coder
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   329
	TFixedArray<TUint8,Huffman::KMetaCodes> list;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   330
	TInt i;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   331
	for (i=0;i<list.Count();++i)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   332
		list[i]=TUint8(i);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   333
	TInt last=0;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   334
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   335
	TInt rl=0;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   336
	const TUint32* p32=aHuffman;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   337
	const TUint32* e32=p32+aNumCodes;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   338
	while (p32<e32)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   339
		{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   340
		TInt c=*p32++;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   341
		if (c==last)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   342
			++rl;	// repeat of last symbol
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   343
		else
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   344
			{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   345
			// encode run-length
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   346
			EncodeRunLengthL(aOutput,rl);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   347
			rl=0;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   348
			// find code in MTF list
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   349
			TInt j;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   350
			for (j=1;list[j]!=c;++j)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   351
				;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   352
			// store this code
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   353
			aOutput.HuffmanL(HuffmanEncoding[j+1]);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   354
			// adjust list for MTF algorithm
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   355
			while (--j>0)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   356
				list[j+1]=list[j];
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   357
			list[1]=TUint8(last);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   358
			last=c;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   359
			}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   360
		}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   361
	// encod any remaining run-length
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   362
	EncodeRunLengthL(aOutput,rl);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   363
	}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   364
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   365
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   366
TBitOutput::TBitOutput()
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   367
/** Construct a bit stream output object
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   368
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   369
	Following construction the bit stream is ready for writing bits, but will first call
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   370
	OverflowL() as the output buffer is 'full'. A derived class can detect this state as
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   371
	Ptr() will return null.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   372
*/
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   373
	:iCode(0),iBits(-8),iPtr(0),iEnd(0)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   374
	{}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   375
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   376
TBitOutput::TBitOutput(TUint8* aBuf,TInt aSize)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   377
/** Construct a bit stream output object over a buffer
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   378
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   379
	Data will be written to the buffer until it is full, at which point OverflowL() will
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   380
	be called. This should handle the data and then can Set() again to reset the buffer
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   381
	for further output.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   382
	
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   383
	@param "TUint8* aBuf" The buffer for output
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   384
	@param "TInt aSize" The size of the buffer in bytes
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   385
*/
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   386
	:iCode(0),iBits(-8),iPtr(aBuf),iEnd(aBuf+aSize)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   387
	{}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   388
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   389
void TBitOutput::HuffmanL(TUint aHuffCode)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   390
/** Write a huffman code
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   391
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   392
	This expects a huffman code value as generated by Huffman::Encoding()
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   393
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   394
	@param "TUint aHuffCode" The huffman code write to the stream
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   395
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   396
	@leave "OverflowL()" If the output buffer is full, OverflowL() is called
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   397
*/
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   398
	{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   399
	DoWriteL(aHuffCode<<(32-Huffman::KMaxCodeLength),aHuffCode>>Huffman::KMaxCodeLength);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   400
	}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   401
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   402
void TBitOutput::WriteL(TUint aValue,TInt aLength)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   403
/** Write an arbitrary integer value
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   404
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   405
	Write an unsigned integer using the number of bits specified. Only
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   406
	the low order bits of the value are written to the output, most
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   407
	significant bit first.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   408
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   409
	@param "TUint aValue" The value to write to the stream
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   410
	@param "TUint aLength" The number of bits to output
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   411
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   412
	@leave "OverflowL()" If the output buffer is full, OverflowL() is called
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   413
*/
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   414
	{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   415
	if (aLength)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   416
		DoWriteL(aValue<<=32-aLength,aLength);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   417
	}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   418
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   419
void TBitOutput::PadL(TUint aPadding)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   420
/** Pad the bitstream to the next byte boundary
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   421
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   422
	Terminate the bitstream by padding the last byte with the requested value.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   423
	Following this operation the bitstream can continue to be used, the data will
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   424
	start at the next byte.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   425
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   426
	@param "TUint aPadding" The bit value to pad the final byte with
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   427
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   428
	@leave "OverflowL()" If the output buffer is full, OverflowL() is called
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   429
*/
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   430
	{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   431
	if (iBits>-8)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   432
		WriteL(aPadding?0xffffffffu:0,-iBits);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   433
	}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   434
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   435
void TBitOutput::DoWriteL(TUint aBits,TInt aSize)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   436
/** Write the higher order bits to the stream
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   437
	
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   438
	@internal
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   439
*/
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   440
	{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   441
	if (aSize>25)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   442
		{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   443
		// cannot process >25 bits in a single pass
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   444
		// so do the top 8 bits first
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   445
		ASSERT(aSize<=32);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   446
		DoWriteL(aBits&0xff000000u,8);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   447
		aBits<<=8;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   448
		aSize-=8;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   449
		}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   450
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   451
	TInt bits=iBits;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   452
	TUint code=iCode|(aBits>>(bits+8));
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   453
	bits+=aSize;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   454
	if (bits>=0)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   455
		{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   456
		TUint8* p=iPtr;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   457
		do
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   458
			{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   459
			if (p==iEnd)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   460
				{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   461
				// run out of buffer space so invoke the overflow handler
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   462
				iPtr=p;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   463
				OverflowL();
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   464
				p=iPtr;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   465
				ASSERT(p!=iEnd);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   466
				}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   467
			*p++=TUint8(code>>24);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   468
			code<<=8;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   469
			bits-=8;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   470
			} while (bits>=0);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   471
		iPtr=p;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   472
		}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   473
	iCode=code;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   474
	iBits=bits;
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   475
	}
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   476
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   477
void TBitOutput::OverflowL()
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   478
/** Handle a full output buffer
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   479
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   480
	This virtual function is called when the output buffer is full. It should deal
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   481
	with the data in the buffer before reseting the buffer using Set(), allowing
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   482
	further data to be written.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   483
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   484
	A derived class can replace this to write the data to a file (for example)
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   485
	before marking the buffer as empty.
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   486
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   487
	@leave "KErrOverflow" The default implementation leaves
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   488
*/
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   489
	{
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   490
	Panic(EHuffmanBufferOverflow);
044383f39525 Convert Build package from SFL to EPL
Alex Gilkes <alex.gilkes@nokia.com>
parents:
diff changeset
   491
	}