toolsandutils/e32tools/elf2e32/source/huffman.cpp
author Mike Kinghan <mikek@symbian.org>
Wed, 24 Nov 2010 09:17:29 +0000
branchGCC_SURGE
changeset 80 d82e43335b24
parent 60 5a90ee674b42
permissions -rw-r--r--
Add the portable rombuild wrapper romnibus.pl to make it available for Windows as well as Linux
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
60
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
     1
// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
     2
// All rights reserved.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
     3
// This component and the accompanying materials are made available
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
     4
// under the terms of "Eclipse Public License v1.0"
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
     5
// which accompanies this distribution, and is available
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
     7
//
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
     8
// Initial Contributors:
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    10
//
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    11
// Contributors:
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    12
//
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    13
// Description:
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    14
// Implementation of the Huffman technique for the elf2e32 tool
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    15
// @internalComponent
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    16
// @released
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    17
// 
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    18
//
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    19
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    20
#ifdef _MSC_VER
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    21
	#pragma warning(disable: 4710) // function not inlined
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    22
#endif
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    23
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    24
#include <cassert>
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    25
#include "huffman.h"
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    26
#include "errorhandler.h"
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    27
#include "farray.h"
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    28
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    29
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    30
Function for overflow
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    31
@internalComponent
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    32
@released
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    33
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    34
void TBitOutput::OverflowL()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    35
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    36
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    37
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    38
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    39
Construct a bit stream output object
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    40
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    41
Following construction the bit stream is ready for writing bits, but will first call
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    42
OverflowL() as the output buffer is 'full'. A derived class can detect this state as
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    43
Ptr() will return null.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    44
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    45
TBitOutput::TBitOutput():iCode(0),iBits(-8),iPtr(0),iEnd(0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    46
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    47
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    48
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    49
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    50
Construct a bit stream output object over a buffer
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    51
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    52
Data will be written to the buffer until it is full, at which point OverflowL() will
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    53
be called. This should handle the data and then can Set() again to reset the buffer
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    54
for further output.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    55
	
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    56
@param "TUint8* aBuf" The buffer for output
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    57
@param "TInt aSize" The size of the buffer in bytes
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    58
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    59
TBitOutput::TBitOutput(TUint8* aBuf,TInt aSize):iCode(0),iBits(-8),iPtr(aBuf),iEnd(aBuf+aSize)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    60
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    61
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    62
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    63
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    64
Write a huffman code
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    65
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    66
This expects a huffman code value as generated by Huffman::Encoding()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    67
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    68
@param "TUint aHuffCode" The huffman code write to the stream
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    69
@leave "OverflowL()" If the output buffer is full, OverflowL() is called
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    70
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    71
void TBitOutput::HuffmanL(TUint aHuffCode)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    72
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    73
	DoWriteL(aHuffCode<<(32-Huffman::KMaxCodeLength),aHuffCode>>Huffman::KMaxCodeLength);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    74
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    75
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    76
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    77
Write an arbitrary integer value
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    78
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    79
Write an unsigned integer using the number of bits specified. Only the low order bits of the
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    80
value are written to the output, most significant bit first.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    81
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    82
@param "TUint aValue" The value to write to the stream
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    83
@param "TUint aLength" The number of bits to output
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    84
@leave "OverflowL()" If the output buffer is full, OverflowL() is called
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    85
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    86
void TBitOutput::WriteL(TUint aValue,TInt aLength)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    87
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    88
	if (aLength)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    89
		DoWriteL(aValue<<=32-aLength,aLength);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    90
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    91
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    92
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    93
Pad the bitstream to the next byte boundary
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    94
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    95
Terminate the bitstream by padding the last byte with the requested value.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    96
Following this operation the bitstream can continue to be used, the data will start at the
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    97
next byte.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    98
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
    99
@param "TUint aPadding" The bit value to pad the final byte with
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   100
@leave "OverflowL()" If the output buffer is full, OverflowL() is called
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   101
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   102
void TBitOutput::PadL(TUint aPadding)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   103
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   104
	if (iBits>-8)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   105
		WriteL(aPadding?0xffffffffu:0,-iBits);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   106
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   107
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   108
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   109
Write the higher order bits to the stream
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   110
@internalComponent
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   111
@released
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   112
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   113
void TBitOutput::DoWriteL(TUint aBits,TInt aSize)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   114
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   115
	if (aSize>25)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   116
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   117
		// cannot process >25 bits in a single pass so do the top 8 bits first
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   118
		assert(aSize<=32);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   119
		DoWriteL(aBits&0xff000000u,8);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   120
		aBits<<=8;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   121
		aSize-=8;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   122
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   123
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   124
	TInt bits=iBits;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   125
	TUint code=iCode|(aBits>>(bits+8));
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   126
	bits+=aSize;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   127
	if (bits>=0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   128
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   129
		TUint8* p=iPtr;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   130
		do
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   131
		{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   132
			if (p==iEnd)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   133
			{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   134
				// run out of buffer space so invoke the overflow handler
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   135
				iPtr=p;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   136
				OverflowL();
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   137
				p=iPtr;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   138
				assert(p!=iEnd);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   139
			}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   140
			*p++=TUint8(code>>24);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   141
			code<<=8;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   142
			bits-=8;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   143
		} while (bits>=0);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   144
		iPtr=p;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   145
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   146
	iCode=code;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   147
	iBits=bits;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   148
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   149
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   150
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   151
Constructor for class TFileOutput
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   152
@internalComponent
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   153
@released
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   154
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   155
TFileOutput::TFileOutput(std::ofstream & os):iOutStream(os)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   156
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   157
	Set(iBuf,KBufSize);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   158
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   159
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   160
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   161
Function to empty the buffer and reset the pointers
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   162
@internalComponent
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   163
@released
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   164
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   165
void TFileOutput::OverflowL()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   166
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   167
	FlushL();
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   168
	Set(iBuf,KBufSize);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   169
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   170
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   171
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   172
Function to write out the contents of the buffer
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   173
@internalComponent
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   174
@released
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   175
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   176
void TFileOutput::FlushL()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   177
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   178
	TInt len=Ptr()-iBuf;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   179
	if (len)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   180
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   181
		iOutStream.write(reinterpret_cast<char *>(iBuf), len); // write extended header
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   182
		iDataCount += len;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   183
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   184
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   185
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   186
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   187
Recursive function to calculate the code lengths from the node tree
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   188
@internalComponent
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   189
@released
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   190
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   191
void HuffmanLengthsL(TUint32* aLengths,const TNode* aNodes,TInt aNode,TInt aLen)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   192
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   193
	if (++aLen>Huffman::KMaxCodeLength)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   194
		throw E32ImageCompressionError(HUFFMANBUFFEROVERFLOWERROR);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   195
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   196
	const TNode& node=aNodes[aNode];
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   197
	TUint x=node.iLeft;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   198
	if (x&KLeaf)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   199
		aLengths[x&~KLeaf]=aLen;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   200
	else
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   201
		HuffmanLengthsL(aLengths,aNodes,x,aLen);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   202
	x=node.iRight;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   203
	if (x&KLeaf)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   204
		aLengths[x&~KLeaf]=aLen;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   205
	else
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   206
		HuffmanLengthsL(aLengths,aNodes,x,aLen);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   207
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   208
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   209
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   210
Function to Insert the {aCount,aValue} pair into the already sorted array of nodes
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   211
@internalComponent
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   212
@released
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   213
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   214
void InsertInOrder(TNode* aNodes, TInt aSize, TUint aCount, TInt aVal)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   215
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   216
	// Uses Insertion sort following a binary search...
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   217
	TInt l=0, r=aSize;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   218
	while (l < r)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   219
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   220
		TInt m = (l+r) >> 1;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   221
		if (aNodes[m].iCount<aCount)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   222
			r=m;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   223
		else
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   224
			l=m+1;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   225
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   226
	memmove(aNodes+l+1,aNodes+l,sizeof(TNode)*(aSize-l));
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   227
	aNodes[l].iCount=aCount;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   228
	aNodes[l].iRight=TUint16(aVal);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   229
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   230
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   231
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   232
Generate a Huffman code.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   233
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   234
This generates a Huffman code for a given set of code frequencies. The output is a table of
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   235
code lengths which can be used to build canonincal encoding tables or decoding trees for use
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   236
with the TBitInput and TBitOutput classes.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   237
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   238
Entries in the table with a frequency of zero will have a zero code length and thus no
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   239
associated huffman encoding. If each such symbol should have a maximum length encoding, they
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   240
must be given at least a frequency of 1.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   241
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   242
For an alphabet of n symbols, this algorithm has a transient memory overhead of 8n, and a
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   243
time complexity of O(n*log(n)).
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   244
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   245
@param "const TUint32 aFrequency[]" The table of code frequencies
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   246
@param "TInt aNumCodes" The number of codes in the table
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   247
@param "TUint32 aHuffman[]" The table for the output code-length table. This must be the same
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   248
size as the frequency table, and can safely be the same table
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   249
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   250
@leave "KErrNoMemory" If memory used for code generation cannot be allocated
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   251
@panic "USER ???" If the number of codes exceeds Huffman::KMaxCodes
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   252
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   253
void Huffman::HuffmanL(const TUint32 aFrequency[],TInt aNumCodes,TUint32 aHuffman[])
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   254
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   255
	if(TUint(aNumCodes)>TUint(KMaxCodes))
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   256
		throw E32ImageCompressionError(HUFFMANTOOMANYCODESERROR);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   257
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   258
	// Sort the values into decreasing order of frequency
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   259
	TNode* nodes = new TNode[aNumCodes];
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   260
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   261
	TInt lCount=0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   262
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   263
	for (TInt ii=0;ii<aNumCodes;++ii)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   264
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   265
		TInt c=aFrequency[ii];
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   266
		if (c!=0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   267
			InsertInOrder(nodes,lCount++,c,ii|KLeaf);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   268
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   269
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   270
	// default code length is zero
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   271
	memset(aHuffman,0,aNumCodes*sizeof(TUint32));
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   272
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   273
	if (lCount==0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   274
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   275
		// no codes with frequency>0. No code has a length
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   276
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   277
	else if (lCount==1)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   278
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   279
		// special case for a single value (always encode as "0")
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   280
		aHuffman[nodes[0].iRight&~KLeaf]=1;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   281
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   282
	else
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   283
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   284
		// Huffman algorithm: pair off least frequent nodes and reorder
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   285
		do
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   286
		{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   287
			--lCount;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   288
			TUint c=nodes[lCount].iCount + nodes[lCount-1].iCount;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   289
			nodes[lCount].iLeft=nodes[lCount-1].iRight;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   290
			// re-order the leaves now to reflect new combined frequency 'c'
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   291
			InsertInOrder(nodes,lCount-1,c,lCount);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   292
		} while (lCount>1);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   293
		// generate code lengths in aHuffman[]
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   294
		HuffmanLengthsL(aHuffman,nodes,1,0);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   295
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   296
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   297
	delete [] nodes;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   298
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   299
	if(!IsValid(aHuffman,aNumCodes))
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   300
		throw E32ImageCompressionError(HUFFMANINVALIDCODINGERROR);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   301
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   302
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   303
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   304
Validate a Huffman encoding
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   305
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   306
This verifies that a Huffman coding described by the code lengths is valid. In particular,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   307
it ensures that no code exceeds the maximum length and that it is possible to generate a
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   308
canonical coding for the specified lengths.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   309
	
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   310
@param "const TUint32 aHuffman[]" The table of code lengths as generated by Huffman::HuffmanL()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   311
@param "TInt aNumCodes" The number of codes in the table
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   312
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   313
@return True if the code is valid, otherwise false
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   314
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   315
TBool Huffman::IsValid(const TUint32 aHuffman[],TInt aNumCodes)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   316
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   317
	// The code is valid if one of the following holds:
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   318
	// (a) the code exactly fills the 'code space'
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   319
	// (b) there is only a single symbol with code length 1
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   320
	// (c) there are no encoded symbols
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   321
	//
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   322
	TUint remain=1<<KMaxCodeLength;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   323
	TInt totlen=0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   324
	for (const TUint32* p=aHuffman+aNumCodes; p>aHuffman;)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   325
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   326
		TInt len=*--p;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   327
		if (len>0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   328
		{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   329
			totlen+=len;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   330
			if (len>KMaxCodeLength)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   331
				return 0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   332
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   333
			TUint c=1<<(KMaxCodeLength-len);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   334
			if (c>remain)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   335
				return 0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   336
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   337
			remain-=c;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   338
		}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   339
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   340
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   341
	return remain==0 || totlen<=1;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   342
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   343
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   344
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   345
Create a canonical Huffman encoding table
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   346
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   347
This generates the huffman codes used by TBitOutput::HuffmanL() to write huffman encoded data.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   348
The input is table of code lengths, as generated by Huffman::HuffmanL() and must represent a
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   349
valid huffman code.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   350
	
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   351
@param "const TUint32 aHuffman[]" The table of code lengths as generated by Huffman::HuffmanL()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   352
@param "TInt aNumCodes" The number of codes in the table
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   353
@param "TUint32 aEncodeTable[]" The table for the output huffman codes. This must be the same
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   354
size as the code-length table, and can safely be the same table.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   355
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   356
@panic "USER ???" If the provided code is not a valid Huffman coding
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   357
	
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   358
@see IsValid()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   359
@see HuffmanL()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   360
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   361
void Huffman::Encoding(const TUint32 aHuffman[],TInt aNumCodes,TUint32 aEncodeTable[])
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   362
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   363
	if (!IsValid(aHuffman,aNumCodes)) 
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   364
		throw E32ImageCompressionError(HUFFMANINVALIDCODINGERROR);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   365
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   366
	TFixedArray<TInt,KMaxCodeLength> lenCount;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   367
	lenCount.Reset();
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   368
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   369
	TInt ii;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   370
	for (ii=0;ii<aNumCodes;++ii)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   371
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   372
		TInt len=aHuffman[ii]-1;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   373
		if (len>=0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   374
			++lenCount[len];
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   375
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   376
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   377
	TFixedArray<TUint,KMaxCodeLength> nextCode;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   378
	TUint code=0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   379
	for (ii=0;ii<KMaxCodeLength;++ii)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   380
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   381
		code<<=1;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   382
		nextCode[ii]=code;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   383
		code+=lenCount[ii];
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   384
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   385
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   386
	for (ii=0;ii<aNumCodes;++ii)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   387
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   388
		TInt len=aHuffman[ii];
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   389
		if (len==0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   390
			aEncodeTable[ii]=0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   391
		else
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   392
		{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   393
			aEncodeTable[ii] = (nextCode[len-1]<<(KMaxCodeLength-len))|(len<<KMaxCodeLength);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   394
			++nextCode[len-1];
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   395
		}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   396
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   397
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   398
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   399
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   400
The encoding table for the externalised code
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   401
@internalComponent
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   402
@released
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   403
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   404
const TUint32 HuffmanEncoding[]=
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   405
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   406
	0x10000000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   407
	0x1c000000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   408
	0x12000000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   409
	0x1d000000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   410
	0x26000000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   411
	0x26800000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   412
	0x2f000000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   413
	0x37400000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   414
	0x37600000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   415
	0x37800000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   416
	0x3fa00000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   417
	0x3fb00000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   418
	0x3fc00000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   419
	0x3fd00000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   420
	0x47e00000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   421
	0x47e80000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   422
	0x47f00000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   423
	0x4ff80000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   424
	0x57fc0000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   425
	0x5ffe0000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   426
	0x67ff0000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   427
	0x77ff8000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   428
	0x7fffa000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   429
	0x7fffb000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   430
	0x7fffc000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   431
	0x7fffd000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   432
	0x7fffe000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   433
	0x87fff000,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   434
	0x87fff800
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   435
};
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   436
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   437
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   438
Function to encode 0a as '0' and 0b as '1', return number of symbols created
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   439
@internalComponent
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   440
@released
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   441
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   442
void EncodeRunLengthL(TBitOutput& aOutput, TInt aLength)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   443
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   444
	if (aLength>0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   445
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   446
		EncodeRunLengthL(aOutput,(aLength-1)>>1);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   447
		aOutput.HuffmanL(HuffmanEncoding[1-(aLength&1)]);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   448
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   449
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   450
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   451
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   452
Store a canonical huffman encoding in compact form
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   453
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   454
As the encoding is canonical, only the code lengths of each code needs to be saved.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   455
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   456
Due to the nature of code length tables, these can usually be stored very compactly by
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   457
encoding the encoding itself, hence the use of the bit output stream.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   458
	
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   459
@param "TBitOutput& aOutput" The output stream for the encoding
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   460
@param "const TUint32 aHuffman[]" The table of code lengths as generated by Huffman::HuffmanL()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   461
@param "TInt aNumCodes" The number of huffman codes in the table
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   462
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   463
@leave "TBitOutput::HuffmanL()"
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   464
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   465
void Huffman::ExternalizeL(TBitOutput& aOutput,const TUint32 aHuffman[],TInt aNumCodes)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   466
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   467
	// We assume that the code length table is generated by the huffman generator,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   468
	// in which case the maxmimum code length is 27 bits.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   469
	//
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   470
	// We apply three transformations to the data:
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   471
	// 1. the data goes through a move-to-front coder
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   472
	// 2. apply a rle-0 coder which replace runs of '0' with streams of '0a' and '0b'
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   473
	// 3. encode the result using a predefined (average) huffman coding
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   474
	//
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   475
	// This can be done in a single pass over the data, avoiding the need for additional
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   476
	// memory.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   477
	//
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   478
	// initialise the list for the MTF coder
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   479
	TFixedArray<TUint8,Huffman::KMetaCodes> list;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   480
	TInt i;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   481
	for (i=0;i<list.Count();++i)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   482
		list[i]=TUint8(i);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   483
	TInt last=0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   484
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   485
	TInt rl=0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   486
	const TUint32* p32=aHuffman;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   487
	const TUint32* e32=p32+aNumCodes;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   488
	while (p32<e32)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   489
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   490
		TInt c=*p32++;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   491
		if (c==last)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   492
			++rl;	// repeat of last symbol
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   493
		else
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   494
		{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   495
			// encode run-length
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   496
			EncodeRunLengthL(aOutput,rl);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   497
			rl=0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   498
			// find code in MTF list
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   499
			TInt j;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   500
			for (j=1;list[j]!=c;++j)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   501
				;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   502
			// store this code
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   503
			aOutput.HuffmanL(HuffmanEncoding[j+1]);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   504
			// adjust list for MTF algorithm
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   505
			while (--j>0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   506
				list[j+1]=list[j];
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   507
			list[1]=TUint8(last);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   508
			last=c;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   509
		}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   510
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   511
	// encod any remaining run-length
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   512
	EncodeRunLengthL(aOutput,rl);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   513
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   514
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   515
const TInt KHuffTerminate=0x0001;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   516
const TUint32 KBranch1=sizeof(TUint32)<<16;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   517
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   518
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   519
Function to write the subtree below aPtr and return the head
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   520
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   521
TUint32* HuffmanSubTree(TUint32* aPtr,const TUint32* aValue,TUint32** aLevel)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   522
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   523
	TUint32* l=*aLevel++;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   524
	if (l>aValue)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   525
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   526
		TUint32* sub0=HuffmanSubTree(aPtr,aValue,aLevel);		// 0-tree first
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   527
		aPtr=HuffmanSubTree(sub0,aValue-(aPtr-sub0)-1,aLevel);	// 1-tree
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   528
		TInt branch0=(TUint8*)sub0-(TUint8*)(aPtr-1);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   529
		*--aPtr=KBranch1|branch0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   530
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   531
	else if (l==aValue)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   532
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   533
		TUint term0=*aValue--;						// 0-term
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   534
		aPtr=HuffmanSubTree(aPtr,aValue,aLevel);	// 1-tree
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   535
		*--aPtr=KBranch1|(term0>>16);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   536
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   537
	else	// l<iNext
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   538
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   539
		TUint term0=*aValue--;						// 0-term
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   540
		TUint term1=*aValue--;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   541
		*--aPtr=(term1>>16<<16)|(term0>>16);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   542
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   543
	return aPtr;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   544
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   545
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   546
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   547
Create a canonical Huffman decoding tree
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   548
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   549
This generates the huffman decoding tree used by TBitInput::HuffmanL() to read huffman
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   550
encoded data. The input is table of code lengths, as generated by Huffman::HuffmanL()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   551
and must represent a valid huffman code.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   552
	
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   553
@param "const TUint32 aHuffman[]" The table of code lengths as generated by Huffman::HuffmanL()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   554
@param "TInt aNumCodes" The number of codes in the table
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   555
@param "TUint32 aDecodeTree[]" The space for the decoding tree. This must be the same
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   556
size as the code-length table, and can safely be the same memory
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   557
@param "TInt aSymbolBase" the base value for the output 'symbols' from the decoding tree, by default
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   558
this is zero.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   559
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   560
@panic "USER ???" If the provided code is not a valid Huffman coding
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   561
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   562
@see IsValid()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   563
@see HuffmanL()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   564
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   565
void Huffman::Decoding(const TUint32 aHuffman[],TInt aNumCodes,TUint32 aDecodeTree[],TInt aSymbolBase)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   566
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   567
	if(!IsValid(aHuffman,aNumCodes))
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   568
		throw E32ImageCompressionError(HUFFMANINVALIDCODINGERROR);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   569
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   570
	TFixedArray<TInt,KMaxCodeLength> counts;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   571
	counts.Reset();
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   572
	TInt codes=0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   573
	TInt ii;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   574
	for (ii=0;ii<aNumCodes;++ii)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   575
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   576
		TInt len=aHuffman[ii];
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   577
		aDecodeTree[ii]=len;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   578
		if (--len>=0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   579
		{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   580
			++counts[len];
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   581
			++codes;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   582
		}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   583
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   584
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   585
	TFixedArray<TUint32*,KMaxCodeLength> level;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   586
	TUint32* lit=aDecodeTree+codes;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   587
	for (ii=0;ii<KMaxCodeLength;++ii)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   588
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   589
		level[ii]=lit;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   590
		lit-=counts[ii];
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   591
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   592
	
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   593
	aSymbolBase=(aSymbolBase<<17)+(KHuffTerminate<<16);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   594
	for (ii=0;ii<aNumCodes;++ii)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   595
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   596
		TUint len=TUint8(aDecodeTree[ii]);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   597
		if (len)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   598
			*--level[len-1]|=(ii<<17)+aSymbolBase;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   599
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   600
	
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   601
	if (codes==1)	// codes==1 special case: tree isn't complete
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   602
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   603
		TUint term=aDecodeTree[0]>>16;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   604
		aDecodeTree[0]=term|(term<<16); // 0- and 1-terminate at root
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   605
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   606
	else if (codes>1)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   607
		HuffmanSubTree(aDecodeTree+codes-1,aDecodeTree+codes-1,&level[0]);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   608
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   609
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   610
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   611
The decoding tree for the externalised code
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   612
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   613
const TUint32 HuffmanDecoding[]=
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   614
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   615
	0x0004006c,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   616
	0x00040064,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   617
	0x0004005c,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   618
	0x00040050,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   619
	0x00040044,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   620
	0x0004003c,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   621
	0x00040034,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   622
	0x00040021,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   623
	0x00040023,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   624
	0x00040025,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   625
	0x00040027,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   626
	0x00040029,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   627
	0x00040014,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   628
	0x0004000c,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   629
	0x00040035,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   630
	0x00390037,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   631
	0x00330031,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   632
	0x0004002b,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   633
	0x002f002d,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   634
	0x001f001d,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   635
	0x001b0019,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   636
	0x00040013,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   637
	0x00170015,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   638
	0x0004000d,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   639
	0x0011000f,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   640
	0x000b0009,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   641
	0x00070003,
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   642
	0x00050001
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   643
};
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   644
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   645
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   646
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   647
Restore a canonical huffman encoding from a bit stream
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   648
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   649
The encoding must have been stored using Huffman::ExternalizeL(). The resulting
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   650
code-length table can be used to create an encoding table using Huffman::Encoding()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   651
or a decoding tree using Huffman::Decoding().
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   652
	
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   653
@param "TBitInput& aInput" The input stream with the encoding
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   654
@param "TUint32 aHuffman[]" The internalized code-length table is placed here
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   655
@param "TInt aNumCodes" The number of huffman codes in the table
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   656
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   657
@leave "TBitInput::HuffmanL()"
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   658
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   659
@see ExternalizeL()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   660
See ExternalizeL for a description of the format
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   661
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   662
void Huffman::InternalizeL(TBitInput& aInput,TUint32 aHuffman[],TInt aNumCodes)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   663
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   664
	// initialise move-to-front list
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   665
	TFixedArray<TUint8,Huffman::KMetaCodes> list;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   666
	for (TInt i=0;i<list.Count();++i)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   667
		list[i]=TUint8(i);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   668
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   669
	TInt last=0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   670
	// extract codes, reverse rle-0 and mtf encoding in one pass
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   671
	TUint32* p=aHuffman;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   672
	const TUint32* end=aHuffman+aNumCodes;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   673
	TInt rl=0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   674
	while (p+rl<end)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   675
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   676
		TInt c=aInput.HuffmanL(HuffmanDecoding);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   677
		if (c<2)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   678
		{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   679
			// one of the zero codes used by RLE-0
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   680
			// update he run-length
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   681
			rl+=rl+c+1;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   682
		}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   683
		else
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   684
		{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   685
			while (rl>0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   686
			{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   687
				if (p>end)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   688
				{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   689
					throw E32ImageCompressionError(HUFFMANINVALIDCODINGERROR);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   690
				}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   691
				*p++=last;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   692
				--rl;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   693
			}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   694
			--c;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   695
			list[0]=TUint8(last);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   696
			last=list[c];
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   697
			
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   698
			memmove((void * const)&list[1],(const void * const)&list[0],(size_t)c);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   699
			if (p>end)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   700
			{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   701
				throw E32ImageCompressionError(HUFFMANINVALIDCODINGERROR);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   702
			}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   703
			*p++=last;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   704
		}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   705
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   706
	while (rl>0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   707
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   708
		if (p>end)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   709
		{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   710
			throw E32ImageCompressionError(HUFFMANINVALIDCODINGERROR);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   711
		}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   712
		*p++=last;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   713
		--rl;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   714
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   715
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   716
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   717
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   718
bit-stream input class
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   719
Reverse the byte-order of a 32 bit value
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   720
This generates optimal ARM code (4 instructions)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   721
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   722
inline TUint reverse(TUint aVal)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   723
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   724
	TUint v=(aVal<<16)|(aVal>>16);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   725
	v^=aVal;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   726
	v&=0xff00ffff;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   727
	aVal=(aVal>>8)|(aVal<<24);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   728
	return aVal^(v>>8);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   729
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   730
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   731
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   732
Construct a bit stream input object
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   733
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   734
Following construction the bit stream is ready for reading bits, but will
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   735
immediately call UnderflowL() as the input buffer is empty.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   736
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   737
TBitInput::TBitInput():iCount(0),iRemain(0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   738
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   739
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   740
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   741
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   742
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   743
Construct a bit stream input object over a buffer
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   744
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   745
Following construction the bit stream is ready for reading bits from the specified buffer.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   746
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   747
@param "const TUint8* aPtr" The address of the buffer containing the bit stream
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   748
@param "TInt aLength" The length of the bitstream in bits
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   749
@param "TInt aOffset" The bit offset from the start of the buffer to the bit stream (defaults to zero)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   750
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   751
TBitInput::TBitInput(const TUint8* aPtr, TInt aLength, TInt aOffset)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   752
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   753
	Set(aPtr,aLength,aOffset);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   754
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   755
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   756
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   757
Set the memory buffer to use for input.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   758
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   759
Bits will be read from this buffer until it is empty, at which point UnderflowL() will be called.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   760
	
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   761
@param "const TUint8* aPtr" The address of the buffer containing the bit stream
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   762
@param "TInt aLength" The length of the bitstream in bits
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   763
@param "TInt aOffset" The bit offset from the start of the buffer to the bit stream (defaults to zero)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   764
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   765
void TBitInput::Set(const TUint8* aPtr, TInt aLength, TInt aOffset)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   766
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   767
	TUint p=(TUint)aPtr;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   768
	p+=aOffset>>3;			// nearest byte to the specified bit offset
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   769
	aOffset&=7;				// bit offset within the byte
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   770
	const TUint32* ptr=(const TUint32*)(p&~3);	// word containing this byte
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   771
	aOffset+=(p&3)<<3;		// bit offset within the word
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   772
	if (aLength==0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   773
		iCount=0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   774
	else
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   775
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   776
		// read the first few bits of the stream
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   777
		iBits=reverse(*ptr++)<<aOffset;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   778
		aOffset=32-aOffset;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   779
		aLength-=aOffset;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   780
		if (aLength<0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   781
			aOffset+=aLength;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   782
		iCount=aOffset;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   783
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   784
	iRemain=aLength;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   785
	iPtr=ptr;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   786
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   787
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   788
#ifndef __HUFFMAN_MACHINE_CODED__
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   789
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   790
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   791
Read a single bit from the input
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   792
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   793
Return the next bit in the input stream. This will call UnderflowL() if there are no more
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   794
bits available.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   795
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   796
@return The next bit in the stream
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   797
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   798
@leave "UnderflowL()" It the bit stream is exhausted more UnderflowL is called to get more
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   799
data
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   800
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   801
TUint TBitInput::ReadL()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   802
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   803
	TInt c=iCount;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   804
	TUint bits=iBits;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   805
	if (--c<0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   806
		return ReadL(1);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   807
	iCount=c;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   808
	iBits=bits<<1;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   809
	return bits>>31;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   810
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   811
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   812
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   813
Read a multi-bit value from the input
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   814
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   815
Return the next few bits as an unsigned integer. The last bit read is the least significant
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   816
bit of the returned value, and the value is zero extended to return a 32-bit result.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   817
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   818
A read of zero bits will always reaturn zero.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   819
	
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   820
This will call UnderflowL() if there are not enough bits available.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   821
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   822
@param "TInt aSize" The number of bits to read
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   823
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   824
@return The bits read from the stream
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   825
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   826
@leave "UnderflowL()" It the bit stream is exhausted more UnderflowL is called to get more
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   827
data
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   828
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   829
TUint TBitInput::ReadL(TInt aSize)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   830
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   831
	if (!aSize)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   832
		return 0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   833
	TUint val=0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   834
	TUint bits=iBits;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   835
	iCount-=aSize;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   836
	while (iCount<0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   837
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   838
		// need more bits
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   839
#ifdef __CPU_X86
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   840
		// X86 does not allow shift-by-32
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   841
		if (iCount+aSize!=0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   842
			val|=bits>>(32-(iCount+aSize))<<(-iCount);	// scrub low order bits
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   843
#else
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   844
		val|=bits>>(32-(iCount+aSize))<<(-iCount);	// scrub low order bits
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   845
#endif
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   846
		aSize=-iCount;	// bits still required
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   847
		if (iRemain>0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   848
		{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   849
			bits=reverse(*iPtr++);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   850
			iCount+=32;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   851
			iRemain-=32;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   852
			if (iRemain<0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   853
				iCount+=iRemain;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   854
		}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   855
		else
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   856
		{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   857
			UnderflowL();
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   858
			bits=iBits;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   859
			iCount-=aSize;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   860
		}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   861
	}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   862
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   863
#ifdef __CPU_X86
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   864
	// X86 does not allow shift-by-32
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   865
	iBits=aSize==32?0:bits<<aSize;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   866
#else
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   867
	iBits=bits<<aSize;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   868
#endif
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   869
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   870
	return val|(bits>>(32-aSize));
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   871
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   872
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   873
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   874
Read and decode a Huffman Code
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   875
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   876
Interpret the next bits in the input as a Huffman code in the specified decoding.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   877
The decoding tree should be the output from Huffman::Decoding().
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   878
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   879
@param "const TUint32* aTree" The huffman decoding tree
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   880
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   881
@return The symbol that was decoded
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   882
	
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   883
@leave "UnderflowL()" It the bit stream is exhausted more UnderflowL is called to get more
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   884
data
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   885
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   886
TUint TBitInput::HuffmanL(const TUint32* aTree)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   887
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   888
	TUint huff=0;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   889
	do
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   890
	{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   891
		aTree=(const TUint32*)(((TUint8*)aTree)+(huff>>16));
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   892
		huff=*aTree;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   893
		if (ReadL()==0)
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   894
			huff<<=16;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   895
	} while ((huff&0x10000u)==0);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   896
	
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   897
	return huff>>17;
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   898
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   899
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   900
#endif
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   901
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   902
/**
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   903
Handle an empty input buffer
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   904
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   905
This virtual function is called when the input buffer is empty and more bits are required.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   906
It should reset the input buffer with more data using Set().
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   907
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   908
A derived class can replace this to read the data from a file (for example) before reseting
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   909
the input buffer.
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   910
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   911
@leave "KErrUnderflow" The default implementation leaves
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   912
*/
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   913
void TBitInput::UnderflowL()
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   914
{
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   915
	throw E32ImageCompressionError(HUFFMANBUFFEROVERFLOWERROR);
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   916
}
5a90ee674b42 Reinstate elf2e32, so that we can change it more easily in GCC_SURGE builds
William Roberts <williamr@symbian.org>
parents:
diff changeset
   917