diff -r 59148e28d9f6 -r 626366955efb toolsandutils/e32tools/elf2e32/source/deflatecompress.cpp --- a/toolsandutils/e32tools/elf2e32/source/deflatecompress.cpp Fri Jun 25 18:24:47 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,514 +0,0 @@ -// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). -// All rights reserved. -// This component and the accompanying materials are made available -// under the terms of "Eclipse Public License v1.0" -// which accompanies this distribution, and is available -// at the URL "http://www.eclipse.org/legal/epl-v10.html". -// -// Initial Contributors: -// Nokia Corporation - initial contribution. -// -// Contributors: -// -// Description: -// - -#include -#include - -#include "e32imagedefs.h" -#include "errorhandler.h" -#include "farray.h" -#include "huffman.h" - -const TInt KDeflateMinLength=3; -const TInt KDeflateMaxLength=KDeflateMinLength-1 + (1<iHash);} - -/** -@Leave - OutOfMemory -This function allocates memory for HDeflateHash -@param aLinks -@return pointer to allocated memory -@internalComponent -@released -*/ -inline HDeflateHash* HDeflateHash::NewLC(TInt aLinks) -{ -#if __GNUC__ >= 4 - // Try to detect if the class' layout has changed. - COMPILE_TIME_ASSERT( sizeof(HDeflateHash) == 1028 ); - COMPILE_TIME_ASSERT( sizeof(TOffset) == 2 ); - COMPILE_TIME_ASSERT( offsetof(HDeflateHash, iHash) < offsetof(HDeflateHash, iOffset) ); - - // Compute the size of the class, including rounding it up to a multiple of 4 - // bytes. - - unsigned n = sizeof(TInt) * 256 + sizeof(TOffset) * Min(aLinks, KDeflateMaxDistance); - - while (n & 0x1f) - { - n++; - } - - // Allocate the raw memory ... - void* p = ::operator new(n); - - // ... And create the object in that memory. - return new(p) HDeflateHash; -#else - return new(new char[_FOFF(HDeflateHash,iOffset[Min(aLinks,KDeflateMaxDistance)])]) HDeflateHash; -#endif -} - -/** -Hash function for HDeflateHash -@param aPtr -@return Hash value -@internalComponent -@released -*/ -inline TInt HDeflateHash::Hash(const TUint8* aPtr) -{ - TUint x=aPtr[0]|(aPtr[1]<<8)|(aPtr[2]<<16); - return (x*KDeflateHashMultiplier)>>KDeflateHashShift; -} - -/** -Function First -@param aPtr -@param aPos -@internalComponent -@released -*/ -inline TInt HDeflateHash::First(const TUint8* aPtr,TInt aPos) -{ - TInt h=Hash(aPtr); - TInt offset=Min(aPos-iHash[h],KDeflateMaxDistance<<1); - iHash[h]=aPos; - iOffset[aPos&(KDeflateMaxDistance-1)]=TOffset(offset); - return offset; -} - -/** -Function Next -@param aPtr -@param aPos -@internalComponent -@released -*/ -inline TInt HDeflateHash::Next(TInt aPos,TInt aOffset) const -{return aOffset+iOffset[(aPos-aOffset)&(KDeflateMaxDistance-1)];} - - -// Class TDeflater -// -// generic deflation algorithm, can do either statistics and the encoder - -/** -Function Match -@param aPtr -@param aEnd -@param aPos -@param aHash -@internalComponent -@released -*/ -TInt MDeflater::Match(const TUint8* aPtr,const TUint8* aEnd,TInt aPos,HDeflateHash& aHash) -{ - TInt offset=aHash.First(aPtr,aPos); - if (offset>KDeflateMaxDistance) - return 0; - TInt match=0; - aEnd=Min(aEnd,aPtr+KDeflateMaxLength); - TUint8 c=*aPtr; - do - { - const TUint8* p=aPtr-offset; - if (p[match>>16]==c) - { // might be a better match - const TUint8* m=aPtr; - for (;;) - { - if (*p++!=*m++) - break; - if (mmatch>>16) - { - match=(l<<16)|offset; - c=m[-1]; - } - } - offset=aHash.Next(aPos,offset); - } while (offset<=KDeflateMaxDistance); - return match; -} - -/* -Apply the deflation algorithm to the data [aBase,aEnd) -Return a pointer after the last byte that was deflated (which may not be aEnd) -@param aBase -@param aEnd -@param aHash -@internalComponent -@released -*/ -const TUint8* MDeflater::DoDeflateL(const TUint8* aBase,const TUint8* aEnd,HDeflateHash& aHash) -{ - const TUint8* ptr=aBase; - TInt prev=0; // the previous deflation match - do - { - TInt match=Match(ptr,aEnd,ptr-aBase,aHash); -// Extra deflation applies two optimisations which double the time taken -// 1. If we have a match at p, then test for a better match at p+1 before using it -// 2. When we have a match, add the hash links for all the data which will be skipped - if (match>>16 < prev>>16) - { // use the previous match--it was better - TInt len=prev>>16; - SegmentL(len,prev-(len<<16)); - // fill in missing hash entries for better compression - const TUint8* e=ptr+len-2; - do - { - ++ptr; - if (ptr + 2 < aEnd) - aHash.First(ptr,ptr-aBase); - } while (ptr>16; - SegmentL(len,prev-(len<<16)); - ptr+=len-1; - } - return ptr; -} - -/* -The generic deflation algorithm -@param aBase -@param aLength -@internalComponent -@released -*/ -void MDeflater::DeflateL(const TUint8* aBase,TInt aLength) -{ - const TUint8* end=aBase+aLength; - if (aLength>KDeflateMinLength) - { // deflation kicks in if there is enough data - HDeflateHash* hash=HDeflateHash::NewLC(aLength); - - aBase=DoDeflateL(aBase,end,*hash); - delete hash; - } - while (aBase=8) - { - ++extralen; - len>>=1; - } - LitLenL((extralen<<2)+len+TEncoding::ELiterals); - if (extralen) - ExtraL(extralen,aLength); -// - aDistance--; - extralen=0; - TUint dist=aDistance; - while (dist>=8) - { - ++extralen; - dist>>=1; - } - OffsetL((extralen<<2)+dist); - if (extralen) - ExtraL(extralen,aDistance); -} - -/** -Class TDeflateStats -This class analyses the data stream to generate the frequency tables -for the deflation algorithm -@internalComponent -@released -*/ -inline TDeflateStats::TDeflateStats(TEncoding& aEncoding) - :iEncoding(aEncoding) - {} -/* -Function LitLenL -@Leave -@param aCode -@internalComponent -@released -*/ -void TDeflateStats::LitLenL(TInt aCode) - { - ++iEncoding.iLitLen[aCode]; - } - -/* -@Leave ArrayIndexOutOfBounds -Finction OffsetL -@param aCode -@internalComponent -@released -*/ -void TDeflateStats::OffsetL(TInt aCode) - { - ++iEncoding.iDistance[aCode]; - } - -/* -Function ExtraL -@Leave -@internalComponent -@released -*/void TDeflateStats::ExtraL(TInt,TUint) - {} - -/** -Constructor of Class TDeflater -Extends MDeflater to provide huffman encoding of the output -@internalComponent -@released -*/ -inline TDeflater::TDeflater(TBitOutput& aOutput,const TEncoding& aEncoding) -// -// construct for encoding -// - :iOutput(aOutput),iEncoding(aEncoding) - {} - -/* -Function LitLenL -@Leave -@param aCode -@internalComponent -@released -*/ -void TDeflater::LitLenL(TInt aCode) - { - iOutput.HuffmanL(iEncoding.iLitLen[aCode]); - } - -/* -Function OffsetL -@Leave -@param aCdoe -@internalComponent -@released -*/ -void TDeflater::OffsetL(TInt aCode) - { - iOutput.HuffmanL(iEncoding.iDistance[aCode]); - } - -/* -Function ExtraL -@Leave -@param aLen -@param aBits -@internalComponent -@released -*/ -void TDeflater::ExtraL(TInt aLen,TUint aBits) - { - iOutput.WriteL(aBits,aLen); - } -/* -Function DoDeflateL -@Leave -@param aBuf -@param aLength -@param aOutput -@param aEncoding -@internalComponent -@released -*/ -void DoDeflateL(const TUint8* aBuf,TInt aLength,TBitOutput& aOutput,TEncoding& aEncoding) - { -// analyse the data for symbol frequency - TDeflateStats analyser(aEncoding); - analyser.DeflateL(aBuf,aLength); - -// generate the required huffman encodings - Huffman::HuffmanL(aEncoding.iLitLen,TEncoding::ELitLens,aEncoding.iLitLen); - Huffman::HuffmanL(aEncoding.iDistance,TEncoding::EDistances,aEncoding.iDistance); - -// Store the encoding table - Huffman::ExternalizeL(aOutput,aEncoding.iLitLen,KDeflationCodes); - -// generate the tables - Huffman::Encoding(aEncoding.iLitLen,TEncoding::ELitLens,aEncoding.iLitLen); - Huffman::Encoding(aEncoding.iDistance,TEncoding::EDistances,aEncoding.iDistance); - -// now finally deflate the data with the generated encoding - TDeflater deflater(aOutput,aEncoding); - deflater.DeflateL(aBuf,aLength); - aOutput.PadL(1); - } - -/* -Function DeflateL -@Leave -@param aBuf -@param aLength -@param aOutput -@internalComponent -@released -*/ -void DeflateL(const TUint8* aBuf, TInt aLength, TBitOutput& aOutput) - { - TEncoding* encoding=new TEncoding; - memset(encoding,0,sizeof(TEncoding)); - DoDeflateL(aBuf,aLength,aOutput,*encoding); - delete encoding; - } -/* -Function DeflateCompress -@param bytes -@param size -@param os -@internalComponent -@released -*/ -void DeflateCompress(char *bytes,size_t size, std::ofstream & os) - { - TFileOutput* output=new TFileOutput(os); - output->iDataCount = 0; - DeflateL((TUint8*)bytes,size,*output); - output->FlushL(); - delete output; - } -