crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianNativeTools/Source/inflate.cpp
changeset 0 818e61de6cd1
equal deleted inserted replaced
-1:000000000000 0:818e61de6cd1
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 * 
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include "huffman.h"
       
    19 #include "inflate.h"
       
    20 #include "farray.h"
       
    21 
       
    22 /*
       
    23 Inline constructor for CInflater
       
    24 @param aInput
       
    25 @internalComponent
       
    26 @released
       
    27 */
       
    28 inline CInflater::CInflater(TBitInput& aInput):iBits(&aInput),iEncoding(0),iOut(0)
       
    29 {
       
    30 }
       
    31 
       
    32 /*
       
    33 Function for the 2nd phase construction.
       
    34 @param 
       
    35 @internalComponent
       
    36 @released
       
    37 */
       
    38 void CInflater::ConstructL()
       
    39 {
       
    40 	iEncoding=new TEncoding;
       
    41 	InitL();
       
    42 	iLen=0;
       
    43 	iOut=new TUint8[KDeflateMaxDistance];
       
    44 	iAvail=iLimit=iOut;
       
    45 }
       
    46 
       
    47 /*
       
    48 Function NewLC
       
    49 @Leave OutOfMemory
       
    50 @param aInput
       
    51 @return pointer to self
       
    52 @internalComponent
       
    53 @released
       
    54 */
       
    55 CInflater* CInflater::NewLC(TBitInput& aInput)
       
    56 {
       
    57 	CInflater* self=new CInflater(aInput);
       
    58 	self->ConstructL();
       
    59 
       
    60 	return self;
       
    61 }
       
    62 
       
    63 /*
       
    64 Destructor for CInflater
       
    65 @internalComponent
       
    66 @released
       
    67 */
       
    68 CInflater::~CInflater()
       
    69 {
       
    70 	delete iEncoding;
       
    71 	delete [] iOut;
       
    72 }
       
    73 
       
    74 /*
       
    75 Function ReadL
       
    76 @Leave 
       
    77 @param aBuffer
       
    78 @param aLength
       
    79 @internalComponent
       
    80 @released
       
    81 */
       
    82 TInt CInflater::ReadL(TUint8* aBuffer,TInt aLength)
       
    83 {
       
    84 	TInt tfr=0;
       
    85 	for (;;)
       
    86 	{
       
    87 		TInt len;
       
    88 		if(aLength > (iLimit-iAvail))
       
    89 			len=iLimit-iAvail;
       
    90 		else
       
    91 			len=aLength;
       
    92 
       
    93 		if (len && aBuffer)
       
    94 		{
       
    95 			memcpy((void * const)aBuffer,(const void * const)iAvail,(size_t)len);
       
    96 			aBuffer+=len;
       
    97 		}
       
    98 		aLength-=len;
       
    99 		iAvail+=len;
       
   100 		tfr+=len;
       
   101 		if (aLength==0)
       
   102 			return tfr;
       
   103 		len=InflateL();
       
   104 		if (len==0)
       
   105 			return tfr;
       
   106 		iAvail=iOut;
       
   107 		iLimit=iAvail+len;
       
   108 	}
       
   109 }
       
   110 
       
   111 /*
       
   112 Function InitL
       
   113 @Leave
       
   114 @internalComponent
       
   115 @released
       
   116 */
       
   117 void CInflater::InitL()
       
   118 {
       
   119 	// read the encoding
       
   120 	Huffman::InternalizeL(*iBits,iEncoding->iLitLen,KDeflationCodes);
       
   121 	// validate the encoding
       
   122 	if (!Huffman::IsValid(iEncoding->iLitLen,TEncoding::ELitLens) ||
       
   123 		!Huffman::IsValid(iEncoding->iDistance,TEncoding::EDistances))	
       
   124 	{
       
   125         throw E32ImageCompressionError(E32ImageCompressionError::HUFFMANINVALIDCODINGERROR);
       
   126 	}
       
   127 
       
   128 	// convert the length tables into huffman decoding trees
       
   129 	Huffman::Decoding(iEncoding->iLitLen,TEncoding::ELitLens,iEncoding->iLitLen);
       
   130 	Huffman::Decoding(iEncoding->iDistance,TEncoding::EDistances,iEncoding->iDistance,KDeflateDistCodeBase);
       
   131 }
       
   132 
       
   133 /*
       
   134 Consume all data lag in the history buffer, then decode to fill up the output buffer
       
   135 Return the number of available bytes in the output buffer. This is only ever less than the
       
   136 buffer size if the end of stream marker has been read.
       
   137 @internalComponent
       
   138 @released
       
   139 */
       
   140 TInt CInflater::InflateL()
       
   141 {
       
   142 	// empty the history buffer into the output
       
   143 	TUint8* out=iOut;
       
   144 	TUint8* const end=out+KDeflateMaxDistance;
       
   145 	const TUint32* tree=iEncoding->iLitLen;
       
   146 	if (iLen<0)	// EOF
       
   147 		return 0;
       
   148 	if (iLen>0)
       
   149 		goto useHistory;
       
   150 
       
   151 	while (out<end)
       
   152 	{
       
   153 		// get a huffman code
       
   154 		{
       
   155 			TInt val=iBits->HuffmanL(tree)-TEncoding::ELiterals;
       
   156 			if (val<0)
       
   157 			{
       
   158 				*out++=TUint8(val);
       
   159 				continue;			// another literal/length combo
       
   160 			}
       
   161 			if (val==TEncoding::EEos-TEncoding::ELiterals)
       
   162 			{	// eos marker. we're done
       
   163 				iLen=-1;
       
   164 				break;
       
   165 			}
       
   166 		
       
   167 			// get the extra bits for the code
       
   168 			TInt code=val&0xff;
       
   169 			if (code>=8)
       
   170 			{	// xtra bits
       
   171 				TInt xtra=(code>>2)-1;
       
   172 				code-=xtra<<2;
       
   173 				code<<=xtra;
       
   174 				code|=iBits->ReadL(xtra);
       
   175 			}
       
   176 			if (val<KDeflateDistCodeBase-TEncoding::ELiterals)
       
   177 			{	// length code... get the code
       
   178 				iLen=code+KDeflateMinLength;
       
   179 				tree=iEncoding->iDistance;
       
   180 				continue;			// read the huffman code
       
   181 			}
       
   182 			// distance code
       
   183 			iRptr=out-(code+1);
       
   184 			if (iRptr+KDeflateMaxDistance<end)
       
   185 			iRptr+=KDeflateMaxDistance;
       
   186 		}
       
   187 		useHistory:
       
   188 			TInt tfr;
       
   189 			if(iLen > (end-out))
       
   190 				tfr=end-out;
       
   191 			else
       
   192 				tfr=iLen;
       
   193 
       
   194 			iLen-=tfr;
       
   195 			const TUint8* from=iRptr;
       
   196 			do
       
   197 			{
       
   198 				*out++=*from++;
       
   199 				if (from==end)
       
   200 					from-=KDeflateMaxDistance;
       
   201 			}while (--tfr!=0);
       
   202 			iRptr=from;
       
   203 			tree=iEncoding->iLitLen;
       
   204 	};
       
   205 	
       
   206 	return out-iOut;
       
   207 }
       
   208 
       
   209 /*
       
   210 TFileInput Constructor
       
   211 @param source
       
   212 @param size
       
   213 @internalComponent
       
   214 @released
       
   215 */
       
   216 TFileInput::TFileInput(unsigned char* source,int size):iReadBuf(source),iSize(size)
       
   217 {
       
   218 	Set(source,iSize*8);
       
   219 }
       
   220 
       
   221 /*
       
   222 TFileInput Destructor
       
   223 @internalComponent
       
   224 @released
       
   225 */
       
   226 TFileInput::~TFileInput()
       
   227 {
       
   228 
       
   229 }
       
   230 
       
   231 /*
       
   232 Function UnderFlowL
       
   233 @Leave E32ImageCompressionError
       
   234 @internalComponent
       
   235 @released
       
   236 */
       
   237 void TFileInput::UnderflowL()
       
   238 {
       
   239 	throw E32ImageCompressionError(E32ImageCompressionError::HUFFMANBUFFERUNDERFLOWERROR);
       
   240 }
       
   241 
       
   242 /*
       
   243 Function InflateUncompress
       
   244 @param source
       
   245 @param sourcesize
       
   246 @param dest
       
   247 @param destsize
       
   248 @internalComponent
       
   249 @released
       
   250 */
       
   251 TInt InflateUnCompress(unsigned char* source, int sourcesize,unsigned char* dest, int destsize)
       
   252 {
       
   253 	TFileInput* input = new TFileInput(source, sourcesize);
       
   254 	CInflater* inflater=CInflater::NewLC(*input);
       
   255 	const TInt ret = inflater->ReadL(dest,destsize);
       
   256 	delete input;
       
   257 	delete inflater;
       
   258     return ret;
       
   259 }
       
   260