diff -r 24e4ef208cca -r 3a747a240983 e32tools/elf2e32/source/byte_pair.cpp --- a/e32tools/elf2e32/source/byte_pair.cpp Wed Jul 14 14:50:01 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,488 +0,0 @@ -// Copyright (c) 2005-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 "byte_pair.h" - - -#undef ASSERT -#define ASSERT(c) if(!(c)) \ - { \ - __BREAKPOINT() \ - } - -const TInt MaxBlockSize = 0x1000; - -TUint16 PairCount[0x10000]; -TUint16 PairBuffer[MaxBlockSize*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; - } - - -TInt Unpak(TUint8* dst, TInt dstSize, TUint8* src, TInt srcSize, TUint8*& srcNext) - { - TUint8* dstStart = dst; - TUint8* dstEnd = dst+dstSize; - TUint8* srcEnd = src+srcSize; - - TUint32 LUT[0x100/2]; - TUint8* LUT0 = (TUint8*)LUT; - TUint8* LUT1 = LUT0+0x100; - - TUint8 stack[0x100]; - TUint8* stackStart = stack+sizeof(stack); - TUint8* sp = stackStart; - - TUint32 marker = ~0u; - TInt numTokens; - TUint32 p1; - TUint32 p2; - - TUint32* l = (TUint32*)LUT; - TUint32 b = 0x03020100; - TUint32 step = 0x04040404; - do - { - *l++ = b; - b += step; - } - while(b>step); - - if(src>=srcEnd) - goto error; - numTokens = *src++; - if(numTokens) - { - if(src>=srcEnd) - goto error; - marker = *src++; - LUT0[marker] = (TUint8)~marker; - - if(numTokens<32) - { - TUint8* tokenEnd = src+3*numTokens; - if(tokenEnd>srcEnd) - goto error; - do - { - TInt b = *src++; - TInt p1 = *src++; - TInt p2 = *src++; - LUT0[b] = (TUint8)p1; - LUT1[b] = (TUint8)p2; - } - while(srcsrcEnd) - goto error; - TInt b=0; - do - { - TUint8 mask = bitMask[b>>3]; - if(mask&(1<<(b&7))) - { - if(src>srcEnd) - goto error; - TInt p1 = *src++; - if(src>srcEnd) - goto error; - TInt p2 = *src++; - LUT0[b] = (TUint8)p1; - LUT1[b] = (TUint8)p2; - --numTokens; - } - ++b; - } - while(b<0x100); - if(numTokens) - goto error; - } - } - - if(src>=srcEnd) - goto error; - b = *src++; - if(dst>=dstEnd) - goto error; - p1 = LUT0[b]; - if(p1!=b) - goto not_single; -next: - if(src>=srcEnd) - goto done_s; - b = *src++; - *dst++ = (TUint8)p1; - if(dst>=dstEnd) - goto done_d; - p1 = LUT0[b]; - if(p1==b) - goto next; - -not_single: - if(b==marker) - goto do_marker; - -do_pair: - p2 = LUT1[b]; - b = p1; - p1 = LUT0[b]; - if(sp<=stack) - goto error; - *--sp = (TUint8)p2; - -recurse: - if(b!=p1) - goto do_pair; - - if(sp==stackStart) - goto next; - b = *sp++; - if(dst>=dstEnd) - goto error; - *dst++ = (TUint8)p1; - p1 = LUT0[b]; - goto recurse; - -do_marker: - if(src>=srcEnd) - goto error; - p1 = *src++; - goto next; - -error: - srcNext = 0; - return KErrCorrupt; - -done_s: - *dst++ = (TUint8)p1; - srcNext = src; - return dst-dstStart; - -done_d: - if(dst>=dstEnd) - --src; - srcNext = src; - return dst-dstStart; - } - - -TUint8 PakBuffer[MaxBlockSize*4]; -TUint8 UnpakBuffer[MaxBlockSize]; - - -TInt BytePairCompress(TUint8* dst, TUint8* src, TInt size) - { - ASSERT(size<=MaxBlockSize); - TInt compressedSize = Pak(PakBuffer,src,size); - TUint8* pakEnd; - TInt us = Unpak(UnpakBuffer,MaxBlockSize,PakBuffer,compressedSize,pakEnd); - ASSERT(us==size) - ASSERT(pakEnd==PakBuffer+compressedSize) - ASSERT(!memcmp(src,UnpakBuffer,size)) - if(compressedSize>=size) - return KErrTooBig; - memcpy(dst,PakBuffer,compressedSize); - return compressedSize; - }