diff -r 000000000000 -r a41df078684a kernel/eka/include/byte_pair_compress.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/include/byte_pair_compress.h Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,317 @@ +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "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: +// e32\include\byte_pair_compress.h +// This header file contains both the prototype and implementation for the byte pair compressor. +// This is done to facilitate sharing the code between the e32 test code and the tools. The +// implementation is only included if the macro BYTE_PAIR_COMPRESS_INCLUDE_IMPLEMENTATION is +// defined. +// +// WARNING: This file contains some APIs which are internal and are subject +// to change without notice. Such APIs should therefore not be used +// outside the Kernel and Hardware Services package. +// + +#ifndef __BYTE_PAIR_COMPRESS_H__ +#define __BYTE_PAIR_COMPRESS_H__ + +#include + +/** + * @internalTechnology + * + * Compress up to 4096 bytes of data usign the byte-pair compression algorithm. + * + * @param aDest Destination buffer, must be at least four times the size of the source data. + * @param aSrc Source data to compress. + * @param aSize The size of the source data. + */ +extern TInt BytePairCompress(TUint8* aDest, TUint8* aSrc, TInt aSize); + +#ifdef BYTE_PAIR_COMPRESS_INCLUDE_IMPLEMENTATION + +const TInt BlockSize = 0x1000; +TInt ExtraSave = 0; + +TUint16 PairCount[0x10000]; +TUint16 PairBuffer[BlockSize*2]; + +TUint16 GlobalPairs[0x10000] = {0}; +TUint16 GlobalTokenCounts[0x100] = {0}; + +TUint16 ByteCount[0x100+4]; + +void CountBytes(TUint8* data, TInt size) + { + memset(ByteCount,0,sizeof(ByteCount)); + TUint8* dataEnd = data+size; + while(databestCount) + { + bestCount = f; + bestPair = p; + bestTieBreak = TieBreak(p&0xff,p>>8); + } + else if(f==bestCount) + { + TInt tieBreak = TieBreak(p&0xff,p>>8); + if(tieBreak>bestTieBreak) + { + bestCount = f; + bestPair = p; + bestTieBreak = tieBreak; + } + } + } + pair = bestPair; + return bestCount; + } + +TInt LeastCommonByte(TInt& byte) + { + TInt bestCount = 0xffff; + TInt bestByte = -1; + for(TInt b = 0; b<0x100; b++) + { + TInt f = ByteCount[b]; + if(f0; --r) + { + TInt byte; + TInt byteCount = LeastCommonByte(byte); + TInt pair; + TInt pairCount = MostCommonPair(pair,in,size,overhead+1,marker); + TInt saving = pairCount-byteCount; + if(saving<=overhead) + break; + + overhead = 3; + if(tokenCount>=32) + overhead = 2; + + TUint8* d=tokens+3*tokenCount; + ++tokenCount; + *d++ = (TUint8)byte; + ByteUsed(byte); + *d++ = (TUint8)pair; + ByteUsed(pair&0xff); + *d++ = (TUint8)(pair>>8); + ByteUsed(pair>>8); + ++GlobalPairs[pair]; + + inEnd = in+size; + outStart = out; + while(in>8)) + { + ++in; + b = byte; + --pairCount; + } + *out++ = (TUint8)b; + } + ASSERT(!byteCount); + ASSERT(!pairCount); + size = out-outStart; + + outToggle ^= 1; + if(outToggle) + { + in = dst; + out = dst2; + } + else + { + in = dst2; + out = dst; + } + } + + // sort tokens with a bubble sort... + for(TInt x=0; xtokens[y*3]) + { + TInt z = tokens[x*3]; + tokens[x*3] = tokens[y*3]; + tokens[y*3] = (TUint8)z; + z = tokens[x*3+1]; + tokens[x*3+1] = tokens[y*3+1]; + tokens[y*3+1] = (TUint8)z; + z = tokens[x*3+2]; + tokens[x*3+2] = tokens[y*3+2]; + tokens[y*3+2] = (TUint8)z; + } + + // check for not being able to compress... + if(size>originalSize) + { + *dst++ = 0; // store zero token count + memcpy(dst,src,originalSize); // store original data + return originalSize+1; + } + + // make sure data is in second buffer (dst2) + if(in!=dst2) + memcpy(dst2,dst,size); + + // store tokens... + TUint8* originalDst = dst; + *dst++ = (TUint8)tokenCount; + if(tokenCount) + { + *dst++ = (TUint8)marker; + if(tokenCount<32) + { + memcpy(dst,tokens,tokenCount*3); + dst += tokenCount*3; + } + else + { + TUint8* bitMask = dst; + memset(bitMask,0,32); + dst += 32; + TUint8* d=tokens; + do + { + TInt t=*d++; + bitMask[t>>3] |= (1<<(t&7)); + *dst++ = *d++; + *dst++ = *d++; + } + while(--tokenCount); + } + } + // store data... + memcpy(dst,dst2,size); + dst += size; + + // get stats... + ++GlobalTokenCounts[tokenCount]; + + // return total size of compressed data... + return dst-originalDst; + } + +#endif +#endif