diff -r 000000000000 -r f453ebb75370 gfxconversion/bmconv_s60/src/PBMCOMP.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfxconversion/bmconv_s60/src/PBMCOMP.CPP Tue Feb 02 01:11:11 2010 +0200 @@ -0,0 +1,1307 @@ +/* +* Copyright (c) 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 "BMCONV.H" +#include +#include +#include + +extern TRgb* color256Palette; +extern char* color256InversePalette; + +static inline bool CanCopy16bppData(const char* aDest, const char* aDestEnd, int aDataSize) + { + const char* aDestNew = aDest + (aDataSize / 128) * (256 + 1) + //(2 * 128) bytes data + 1 leading byte + (aDataSize % 128 ? (aDataSize % 128) * 2 + 1 : 0); + return aDestNew <= aDestEnd; + } + +static inline bool CanWrite16bppValue(const char* aDest, const char* aDestEnd, int aDataSize) + { + const char* aDestNew = aDest + (aDataSize / 128) * (2 + 1) + //2 bytes data + 1 leading byte + (aDataSize % 128 ? 2 + 1 : 0); + return aDestNew <= aDestEnd; + } + +static inline bool CanCopy8bppData(const char* aDest, const char* aDestEnd, int aDataSize) + { + const char* aDestNew = aDest + (aDataSize / 128) * (128 + 1) + //128 bytes data + 1 leading byte + (aDataSize % 128 ? (aDataSize % 128) + 1 : 0); + return aDestNew <= aDestEnd; + } + +static inline bool CanWrite8bppValue(const char* aDest, const char* aDestEnd, int aDataSize) + { + const char* aDestNew = aDest + (aDataSize / 128) * (1 + 1) + //1 byte data + 1 leading byte + (aDataSize % 128 ? 1 + 1 : 0); + return aDestNew <= aDestEnd; + } + +static inline bool CanCopy24bppData(const char* aDest, const char* aDestEnd, int aDataSize) + { + const char* aDestNew = aDest + (aDataSize / 128) * (384 + 1) + //(128 * 3) bytes data + 1 leading byte + (aDataSize % 128 ? (aDataSize % 128) * 3 + 1 : 0); + return aDestNew <= aDestEnd; + } + +static inline bool CanWrite24bppValue(const char* aDest, const char* aDestEnd, int aDataSize) + { + const char* aDestNew = aDest + (aDataSize / 128) * (3 + 1) + //3 bytes data + 1 leading byte + (aDataSize % 128 ? 3 + 1 : 0); + return aDestNew <= aDestEnd; + } + +static inline bool CanCopy32bppData(const char* aDest, const char* aDestEnd, int aDataSize) + { + const char* aDestNew = aDest + (aDataSize / 128) * (512 + 1) + //(128 * 4) bytes data + 1 leading byte + (aDataSize % 128 ? (aDataSize % 128) * 4 + 1 : 0); + return aDestNew <= aDestEnd; + } + +static inline bool CanWrite32bppValue(const char* aDest, const char* aDestEnd, int aDataSize) + { + const char* aDestNew = aDest + (aDataSize / 128) * (4 + 1) + //4 bytes data + 1 leading byte + (aDataSize % 128 ? 4 + 1 : 0); + return aDestNew <= aDestEnd; + } +BitmapCompiler::BitmapCompiler(TSourceFile* aSourcefilenames,int aNumSources): + iSourcefilenames(aSourcefilenames), + iPbmSources(NULL), + iNumSources(aNumSources) + {} + +BitmapCompiler::~BitmapCompiler() + { + iDestFile.close(); + if(iPbmSources) + for(int count=0;countiBitmapSize)+3)/4*4)-sizeof(SEpocBitmapHeader)+sizeof(Bitmap); + } + return NoError; + } + +int BitmapCompiler::WriteRombitmap(SEpocBitmapHeader* aPbm) + { + if (aPbm->iPaletteEntries != 0) + return PaletteSupportNotImplemented; + + int bitmapsize = aPbm->iBitmapSize-sizeof(SEpocBitmapHeader)+sizeof(Bitmap); + bitmapsize = ((bitmapsize+3)/4)*4; + + char* buffer = new char[bitmapsize]; + if (buffer == NULL) + return NoMemory; + memset(buffer,0xff,bitmapsize); + + Bitmap* bmp = (Bitmap*)buffer; + bmp->iUid=KCBitwiseBitmapUid; + TBitmapColor color = aPbm->iColor; + + switch(aPbm->iBitsPerPixel) + { // for corresponding enums, see TDisplayMode in + case 1: + bmp->iDispMode=1; + break; + case 2: + bmp->iDispMode=2; + break; + case 4: + if (color == EMonochromeBitmap) + bmp->iDispMode=3; + else + bmp->iDispMode=5; + break; + case 8: + if (color == EMonochromeBitmap) + bmp->iDispMode=4; + else + bmp->iDispMode=6; + break; + case 12: + bmp->iDispMode=10; + break; + case 16: + bmp->iDispMode=7; + break; + case 24: + bmp->iDispMode=8; + break; + case 32: + if (color == EColorBitmapAlpha) + bmp->iDispMode=12; // Color16MA + else + bmp->iDispMode=11; // Color16MU + break; + default: + delete [] buffer; + return SourceFile; + } + + bmp->iHeap = NULL; + bmp->iPile = NULL; + bmp->iHeader = *aPbm; + bmp->iByteWidth = BitmapUtils::ByteWidth(bmp->iHeader.iWidthInPixels,bmp->iHeader.iBitsPerPixel); + bmp->iDataOffset = sizeof(Bitmap); + + CopyTail(buffer + sizeof(Bitmap), aPbm, aPbm->iBitmapSize, sizeof(SEpocBitmapHeader)); + iDestFile.write(buffer,bitmapsize); + + delete [] buffer; + + return NoError; + } + +int BitmapCompiler::WriteFileheader() + { + int zero=0; + iDestFile.write((char*)&KWriteOnceFileStoreUid,4); + iDestFile.write((char*)&KMultiBitmapFileImageUid,4); + iDestFile.write((char*)&zero,4); + iDestFile.write((char*)&KMultiBitmapFileImageChecksum,4); + int byteswritten=16; + for(int count=0;countiBitmapSize; + } + byteswritten+=4; + iDestFile.write((char*)&byteswritten,4); + return NoError; + } + +int BitmapCompiler::WriteHeadStream() + { + iDestFile.write((char*)&iNumSources,4); + int byteswritten=20; + for(int count=0;countiBitmapSize; + } + return NoError; + } + +int BitmapCompiler::WriteFilebitmap(SEpocBitmapHeader* aPbm) + { + if (aPbm->iPaletteEntries != 0) + return PaletteSupportNotImplemented; + + int dataSize = aPbm->iBitmapSize - sizeof(SEpocBitmapHeader); + + iDestFile.write((char*)(aPbm),sizeof(SEpocBitmapHeader)); + // WritePalette() + iDestFile.write(((char*)(aPbm)) + sizeof(SEpocBitmapHeader),dataSize); + + return NoError; + } + +void BitmapCompiler::WritePalette() + { + for (int index = 0; index < 256; index++) + { + iDestFile.write((char*)(&iPalette[index]),3); + } + } + +int BitmapCompiler::LoadPalette(char* aPaletteFilename) + { + if (!aPaletteFilename) + { + iDefaultPalette = 1; + return NoError; + } + + iDefaultPalette = 0; + color256Palette = iPalette; + color256InversePalette = iInversePalette; + + struct stat fileinfo; + if (stat(aPaletteFilename,&fileinfo)==-1) + return CommandFile; + + int filesize = fileinfo.st_size; + if (filesize == 0) + return PaletteFile; + +#if defined(__MSVCDOTNET__) || defined(__TOOLS2__) || defined(__CW32__) + fstream paletteFile(aPaletteFilename, ios::in | ios::binary); +#else + fstream paletteFile(aPaletteFilename, ios::in | ios::binary | ios::nocreate); +#endif + + if(!paletteFile.is_open()) + return PaletteFile; + + char* paletteData = new char[filesize]; + if (!paletteData) + return NoMemory; + + memset(paletteData,0,filesize); + paletteFile.read(paletteData,filesize); + paletteFile.close(); + + char* dataPtr = (char*)paletteData; + char* dataPtrLimit = dataPtr + filesize; + + for (int index = 0; index < 256; index++) + { + char hexBuf[10]; + int ret = ReadHexString(hexBuf,dataPtr,dataPtrLimit); + if (ret) + { + delete paletteData; + return ret; + } + + int red = HexToInt(hexBuf[8],hexBuf[9]); + int green = HexToInt(hexBuf[6],hexBuf[7]); + int blue = HexToInt(hexBuf[4],hexBuf[5]); + + iPalette[index] = TRgb(red,green,blue); + } + + delete paletteData; + CalculateInversePalette(); + return NoError; + } + +void BitmapCompiler::CalculateInversePalette() + { + for (int index = 0; index < 4096; index++) + { + TRgb color = TRgb((index & 0x00f) * 17,((index & 0x0f0) >> 4) * 17,((index & 0xf00) >> 8) * 17); + + int nearest = 0; + int distance = iPalette[0].Difference(color); + + for (int paletteIndex = 0; paletteIndex < 256; paletteIndex++) + { + TRgb paletteColor = iPalette[paletteIndex]; + + if (paletteColor == color) + { + nearest = paletteIndex; + break; + } + + int paletteDistance = paletteColor.Difference(color); + if (paletteDistance < distance) + { + nearest = paletteIndex; + distance = paletteDistance; + } + } + + iInversePalette[index] = (char)nearest; + TRgb palColor = iPalette[nearest]; + color = palColor; + } + } + +int BitmapCompiler::CreateHeader(char* aHeaderFilename) + { + if (!aHeaderFilename) + return NoError; + + fstream hf(aHeaderFilename,ios::out); + if(!hf.is_open()) + return DestFile; + + char* basename = strrchr(aHeaderFilename,'\\'); + if (basename==0) + basename = aHeaderFilename; + else + basename++; // skip directory separator + + char unadornedFile[256]; + strcpy(unadornedFile, UnadornedName(aHeaderFilename)); + + hf << "// " << basename << "\n"; + hf << "// Generated by BitmapCompiler\n"; + hf << "// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.\n"; + hf << "//\n\n"; + hf << "enum TMbm" << unadornedFile << "\n"; + hf << "\t{\n"; + + for (int count=0;count10) && + (strcmp( unadornedSourceFileName + strlen(unadornedSourceFileName) - 10, + "_mask_soft" ) == 0) ) + { + unadornedSourceFileName[ strlen(unadornedSourceFileName) - 5 ] = '\0'; + } + hf << "\tEMbm" << unadornedFile << unadornedSourceFileName; + if(count foundUrl) ? foundDir : foundUrl; + char* firstchar = (foundPath > (char*)0) ? (char*)(foundPath + 1) : aName; + char* lastchar = (foundExt > firstchar) ? foundExt : aName+len; + + static char result[256]; + if (lastchar-firstchar > 255) + { + strcpy(result,"NameTooLong"); + return result; + } + int i=0; + result[0] = (char)toupper(*firstchar); + firstchar+=1; + for (i=1; firstchariBitmapSize-sizeof(SEpocBitmapHeader); + char* newbits=new char[originalsize+sizeof(SEpocBitmapHeader)]; + if(!newbits) + return NoMemory; + + memset(newbits,0xff,sizeof(SEpocBitmapHeader)+originalsize); + memcpy(newbits,aPbm,sizeof(SEpocBitmapHeader)); + char* newbitsptr=newbits+sizeof(SEpocBitmapHeader); + char* oldbits=((char*)(aPbm))+sizeof(SEpocBitmapHeader); + + TBitmapfileCompression compression = ENoBitmapCompression; + int ret = NoCompression; + + if (aPbm->iBitsPerPixel <= 8) + { + compression = EByteRLECompression; + ret = CompressByteData(newbitsptr,oldbits,originalsize); + } + else if (aPbm->iBitsPerPixel == 12) + { + compression = ETwelveBitRLECompression; + ret = CompressTwelveBitData(newbitsptr,oldbits,originalsize); + } + else if (aPbm->iBitsPerPixel == 16) + { + compression = ESixteenBitRLECompression; + ret = CompressSixteenBitData(newbitsptr,oldbits,originalsize); + } + else if (aPbm->iBitsPerPixel == 24) + { + compression = ETwentyFourBitRLECompression; + ret = CompressTwentyFourBitData(newbitsptr,oldbits,originalsize); + } + else if (aPbm->iBitsPerPixel == 32 && (aPbm->iColor == EColorBitmap)) + { + compression = EThirtyTwoUBitRLECompression; + ret = CompressThirtyTwoUBitData(newbitsptr,oldbits,originalsize); + } + else if (aPbm->iBitsPerPixel == 32 && (aPbm->iColor == EColorBitmapAlpha)) + { + compression = EThirtyTwoABitRLECompression; + ret = CompressThirtyTwoABitData(newbitsptr,oldbits,originalsize); + } + + if(ret) + { + delete [] newbits; + if(ret>0) + return ret; + return NoError; + } + + delete aPbm; + aPbm = (SEpocBitmapHeader*)newbits; + aPbm->iBitmapSize = newbitsptr-(newbits+sizeof(SEpocBitmapHeader))+sizeof(SEpocBitmapHeader); + aPbm->iCompression = compression; + return NoError; + } + +int BitmapCompiler::CompressByteData(char*& aDest,char* aSrce,int aSize) + { + const char* destEnd = aDest + aSize; + char* bytepointer=aSrce; + char* limitpointer=bytepointer+aSize; + int margin = (aSize>>6); + char* limitmargin = limitpointer - ((margin > 4) ? margin : 4); + char* cutoffpointer=aDest+(aSize>>1)+(aSize>>2); + int ret=NoError; + char* oldbytepointer=NULL; + while(bytepointercutoffpointer) + return NoCompression; + } + + int remaining = limitpointer-bytepointer; + if(remaining > 0) + { + if (aDest + remaining > cutoffpointer) + return NoCompression; + ret=WriteCompressedByteData(aDest,bytepointer,remaining, destEnd); + if(ret) return ret; + } + return NoError; + } + +int BitmapCompiler::WriteCompressedByteData(char*& aDest,char* aData,int aLength, const char* aDestEnd) + { + if(!CanCopy8bppData(aDest, aDestEnd, aLength)) + return NoCompression; + while(aLength>128) + { + *aDest++=-128; + for(int count=0;count<128;count++) + *aDest++=*aData++; + aLength-=128; + } + if(aLength>128 || aLength<1) return CompressionError; + *aDest++=char(-aLength); + for(int count=0;count 128) + { + *aDest++ = 127; + *aDest++ = aValue; + aLength -= 128; + } + + *aDest++ = char(aLength-1); + *aDest++ = aValue; + + return NoError; + } + +int BitmapCompiler::CompressTwelveBitData(char*& aDest,char* aSrce,int aSizeInBytes) + { + unsigned short* srcePtr = (unsigned short*)aSrce; + unsigned short* srceLimitPtr = srcePtr + (aSizeInBytes / 2); + unsigned short* dest = (unsigned short*)aDest; + + while (srcePtr < srceLimitPtr) + { + unsigned short* runStartPtr = srcePtr; + unsigned short value = *srcePtr; + do + srcePtr++; + while (srcePtr < srceLimitPtr && *srcePtr == value); + WriteCompressedTwelveBitData(dest,*runStartPtr,srcePtr - runStartPtr); // Ignore error return as 12bpp compression never fails + } + + aDest = (char*)dest; + return NoError; + } + +int BitmapCompiler::WriteCompressedTwelveBitData(unsigned short*& aDest,unsigned short aData,int aLength) + { + // The run length l is stored as l-1 in the top 4 bits of each 16-bit word (between 1 and 16) + aData &= 0x0fff; + unsigned short maxLengthData = (unsigned short)(aData | 0xf000); + + while(aLength>16) + { + *aDest++ = maxLengthData; + aLength -= 16; + } + + if (aLength > 0) + *aDest++ = (unsigned short)(aData | ((aLength - 1) << 12)); + + return NoError; + } + +int BitmapCompiler::CompressSixteenBitData(char*& aDest,char* aSrce,int aSizeInBytes) + { + char* destEnd = aDest + aSizeInBytes; + unsigned short* srcePtr = (unsigned short*)aSrce; + unsigned short* srceLimitPtr = srcePtr + (aSizeInBytes / 2); + unsigned short* srceLimitPtrMinusOne = srceLimitPtr - 1; + char* destCompressedLimitPtr = aDest + (aSizeInBytes * 7 / 8); + int ret = NoError; + + while (srcePtr < srceLimitPtrMinusOne) + { + unsigned short value = *srcePtr; + unsigned short* runStartPtr = srcePtr++; + + if(*srcePtr == value) + { + do + srcePtr++; + while ( ( srcePtr < srceLimitPtr ) && ( *srcePtr == value ) ); + + ret = WriteCompressedSixteenBitValues(aDest,value,srcePtr-runStartPtr, destEnd); + if (ret) + return ret; + } + else + { + value = *srcePtr; + while (srcePtr < srceLimitPtrMinusOne && *(srcePtr + 1) != value) + { + srcePtr++; + value = *srcePtr; + } + + ret = WriteCompressedSixteenBitData(aDest,runStartPtr,srcePtr - runStartPtr, destEnd); + if (ret) + return ret; + } + if (aDest > destCompressedLimitPtr) + return NoCompression; + } + + if (srcePtr < srceLimitPtr) + { + ret = WriteCompressedSixteenBitData(aDest,srcePtr,srceLimitPtr - srcePtr, destEnd); + if (ret) + return ret; + } + + if (aDest > destCompressedLimitPtr) + return NoCompression; + return NoError; + } + +int BitmapCompiler::WriteCompressedSixteenBitData(char*& aDest,unsigned short* aData, + int aLength, const char* aDestEnd) + { + if (aLength < 1) + return CompressionError; + + if(!CanCopy16bppData(aDest, aDestEnd, aLength)) + return NoCompression; + + char* srcePtr = (char*)aData; + + while (aLength > 128) + { + *aDest++ = -128; + memcpy(aDest,srcePtr,256); + aDest += 256; + srcePtr += 256; + aLength -= 128; + } + + *aDest++ = char(-aLength); + + int remainingBytes = aLength * 2; + memcpy(aDest,srcePtr,remainingBytes); + aDest += remainingBytes; + + return NoError; + } + +int BitmapCompiler::WriteCompressedSixteenBitValues(char*& aDest,unsigned short aValue, + int aLength, const char* aDestEnd) + { + if (aLength < 1) + return CompressionError; + + if(!CanWrite16bppValue(aDest, aDestEnd, aLength)) + return NoCompression; + + char lowByte = char(aValue); + char highByte = char(aValue >> 8); + + while (aLength > 128) + { + *aDest++ = 127; + *aDest++ = lowByte; + *aDest++ = highByte; + aLength -= 128; + } + + *aDest++ = char(aLength-1); + *aDest++ = lowByte; + *aDest++ = highByte; + + return NoError; + } + +int BitmapCompiler::CompressTwentyFourBitData(char*& aDest,char* aSrce,int aSizeInBytes) + { + const char* destEnd = aDest + aSizeInBytes; + char* srceLimitPtr = aSrce + aSizeInBytes; + char* srceLimitPtrMinusThree = srceLimitPtr - 3; // three bytes == one pixel + char* destCompressedLimitPtr = aDest + (aSizeInBytes * 7 / 8); + int ret = NoError; + + while (aSrce < srceLimitPtrMinusThree) + { + char* runStartPtr = aSrce; + char component1 = *aSrce++; + char component2 = *aSrce++; + char component3 = *aSrce++; + + if (TrueColorPointerCompare(aSrce,component1,component2,component3)) + { + do + aSrce += 3; + while (aSrce < srceLimitPtr && TrueColorPointerCompare(aSrce,component1,component2,component3)); + + ret = WriteCompressedTwentyFourBitValues(aDest,component1,component2,component3,(aSrce - runStartPtr) / 3, destEnd); + if (ret) + return ret; + } + else + { + bool more = true; + bool eqRun = false; + do + { + component1 = *aSrce++; + component2 = *aSrce++; + component3 = *aSrce++; + more = (aSrce < srceLimitPtr); + eqRun = more && TrueColorPointerCompare(aSrce,component1,component2,component3); + } + while (more && !eqRun); + if (eqRun) + aSrce -= 3; + int pixelLength = (aSrce - runStartPtr) / 3; + ret = WriteCompressedTwentyFourBitData(aDest,runStartPtr,pixelLength,destEnd); + if (ret) + return ret; + } + if (aDest > destCompressedLimitPtr) + return NoCompression; + } + + if (aSrce < srceLimitPtr) + { + ret = WriteCompressedTwentyFourBitData(aDest,aSrce,(srceLimitPtr - aSrce) / 3, destEnd); + if (ret) + return ret; + } + + if (aDest > destCompressedLimitPtr) + return NoCompression; + return NoError; + } + +int BitmapCompiler::WriteCompressedTwentyFourBitData(char*& aDest,char* aData, + int aLength, const char* aDestEnd) + { + if (aLength < 1) + return CompressionError; + + if(!CanCopy24bppData(aDest, aDestEnd, aLength)) + return NoCompression; + + while (aLength > 128) + { + *aDest++ = -128; + memcpy(aDest,aData,384); + aDest += 384; + aData += 384; + aLength -= 128; + } + + *aDest++ = char(-aLength); + + int remainingBytes = aLength * 3; + memcpy(aDest,aData,remainingBytes); + aDest += remainingBytes; + + return NoError; + } + +int BitmapCompiler::WriteCompressedTwentyFourBitValues(char*& aDest,char aComponent1, + char aComponent2,char aComponent3, + int aLength, const char* aDestEnd) + { + if (aLength < 1) + return CompressionError; + + if(!CanWrite24bppValue(aDest, aDestEnd, aLength)) + return NoCompression; + + while (aLength > 128) + { + *aDest++ = 127; + *aDest++ = aComponent1; + *aDest++ = aComponent2; + *aDest++ = aComponent3; + aLength -= 128; + } + + *aDest++ = char(aLength-1); + *aDest++ = aComponent1; + *aDest++ = aComponent2; + *aDest++ = aComponent3; + + return NoError; + } + +/** The function encodes 32-bit buffer into 24-bit stream by using RLE compression algorithm*/ +int BitmapCompiler::CompressThirtyTwoUBitData(char*& aDest,char* aSrce,int aSizeInBytes) + { + const char* destEnd = aDest + aSizeInBytes; + char* srceLimitPtr = aSrce + aSizeInBytes; + char* srceLimitPtrMinusFour = srceLimitPtr - 4; // four bytes == one pixel + char* destCompressedLimitPtr = aDest + (aSizeInBytes * 7 / 8); + int ret = NoError; + + while (aSrce < srceLimitPtrMinusFour) + { + char* runStartPtr = aSrce; + char component1 = *aSrce++; + char component2 = *aSrce++; + char component3 = *aSrce++; + aSrce++; + + if (TrueColorPointerCompare(aSrce,component1,component2,component3)) + { + do + aSrce += 4; + while (aSrce < srceLimitPtr && TrueColorPointerCompare(aSrce,component1,component2,component3)); + + ret = WriteCompressedThirtyTwoUBitValues(aDest,component1,component2,component3,(aSrce - runStartPtr) / 4, destEnd); + if (ret) + return ret; + } + else //non repeating pixel buffer + { + bool more = true; + bool eqRun = false; + do { + component1 = *aSrce++; + component2 = *aSrce++; + component3 = *aSrce++; + aSrce++; //last byte is unused (no alpha component) + more = (aSrce < srceLimitPtr); + eqRun = more && TrueColorPointerCompare(aSrce,component1,component2,component3); + } while (more && !eqRun); + if (eqRun) + aSrce -= 4; + int pixelLength = (aSrce - runStartPtr) / 4; + ret = WriteCompressedThirtyTwoUBitData(aDest,runStartPtr,pixelLength,destEnd); + if (ret) + return ret; + } + if (aDest > destCompressedLimitPtr) + return NoCompression; + } + + if (aSrce < srceLimitPtr) + { + ret = WriteCompressedThirtyTwoUBitData(aDest,aSrce,(srceLimitPtr - aSrce) / 4, destEnd); + if (ret) + return ret; + } + + if (aDest > destCompressedLimitPtr) + return NoCompression; + return NoError; + } + +/** The function copies non repeating 32-bit buffer to 24-bit compressed buffer*/ +int BitmapCompiler::WriteCompressedThirtyTwoUBitData(char*& aDest,char* aData, + int aLength, const char* aDestEnd) + { + if (aLength < 1) + return CompressionError; + + if(!CanCopy24bppData(aDest, aDestEnd, aLength)) + return NoCompression; + + while (aLength > 128) + { + *aDest++ = -128; + for(int ii = 0; ii < 128; ii++) + { + memcpy(aDest,aData, 3); + aDest += 3; + aData += 4; + } + aLength -= 128; + } + + *aDest++ = char(-aLength); + + while(aLength--) + { + memcpy(aDest,aData, 3); + aDest += 3; + aData += 4; + } + + return NoError; + } + +/** The function copies repeating colour to the 24-bit compressed buffer */ +int BitmapCompiler::WriteCompressedThirtyTwoUBitValues(char*& aDest,char aComponent1, + char aComponent2,char aComponent3, + int aLength, const char* aDestEnd) + { + if (aLength < 1) + return CompressionError; + + if(!CanWrite24bppValue(aDest, aDestEnd, aLength)) + return NoCompression; + while (aLength > 128) + { + *aDest++ = 127; + *aDest++ = aComponent1; + *aDest++ = aComponent2; + *aDest++ = aComponent3; + aLength -= 128; + } + + *aDest++ = char(aLength-1); + *aDest++ = aComponent1; + *aDest++ = aComponent2; + *aDest++ = aComponent3; + + return NoError; + } + +int BitmapCompiler::TrueColorPointerCompare(char* aColorPointer,char aComponent1,char aComponent2,char aComponent3) + { + return (*aColorPointer == aComponent1 && *(aColorPointer + 1) == aComponent2 && *(aColorPointer + 2) == aComponent3); + } + +/** The function encodes 32-bit buffer into 32-bit stream by using RLE compression algorithm*/ +int BitmapCompiler::CompressThirtyTwoABitData(char*& aDest,char* aSrce,int aSizeInBytes) + { + const char* destEnd = aDest + aSizeInBytes; + char* srceLimitPtr = aSrce + aSizeInBytes; + char* srceLimitPtrMinusFour = srceLimitPtr - 4; // four bytes == one pixel + char* destCompressedLimitPtr = aDest + (aSizeInBytes * 7 / 8); + int ret = NoError; + + while (aSrce < srceLimitPtrMinusFour) + { + char* runStartPtr = aSrce; + char component1 = *aSrce++; + char component2 = *aSrce++; + char component3 = *aSrce++; + char component4 = *aSrce++; + + if (ColorAlphaPointerCompare(aSrce,component1,component2,component3,component4)) + { + do + aSrce += 4; + while (aSrce < srceLimitPtr && ColorAlphaPointerCompare(aSrce,component1,component2,component3,component4)); + int eqPixelLength = (aSrce - runStartPtr) / 4; + ret = WriteCompressedThirtyTwoABitValues(aDest,component1,component2,component3,component4,eqPixelLength,destEnd); + if (ret) + return ret; + } + else //non repeating pixel buffer + { + bool more = true; + bool eqRun = false; + do { + component1 = *aSrce++; + component2 = *aSrce++; + component3 = *aSrce++; + component4 = *aSrce++; + more = (aSrce < srceLimitPtr); + eqRun = more && ColorAlphaPointerCompare(aSrce,component1,component2,component3,component4); + } while (more && !eqRun); + if (eqRun) + aSrce -= 4; + int nePixelLength = (aSrce - runStartPtr) / 4; + ret = WriteCompressedThirtyTwoABitData(aDest,runStartPtr,nePixelLength,destEnd); + if (ret) + return ret; + } + if (aDest > destCompressedLimitPtr) + return NoCompression; + } + + if (aSrce < srceLimitPtr) + { + ret = WriteCompressedThirtyTwoABitData(aDest,aSrce,(srceLimitPtr - aSrce) / 4, destEnd); + if (ret) + return ret; + } + + if (aDest > destCompressedLimitPtr) + return NoCompression; + return NoError; + } + +/** The function copies non repeating 32-bit buffer to 32-bit compressed buffer*/ +int BitmapCompiler::WriteCompressedThirtyTwoABitData(char*& aDest,char* aData, + int aLength, const char* aDestEnd) + { + if (aLength < 1) + return CompressionError; + + if(!CanCopy32bppData(aDest, aDestEnd, aLength)) + return NoCompression; + + while (aLength > 128) + { + *aDest++ = -128; + memcpy(aDest,aData,512); + aDest += 512; + aData += 512; + aLength -= 128; + } + + *aDest++ = char(-aLength); + memcpy(aDest,aData, aLength*4); + aDest += aLength*4; + return NoError; + } + +/** The function copies repeating pixels including alpha to a 32-bit compressed buffer */ +int BitmapCompiler::WriteCompressedThirtyTwoABitValues(char*& aDest,char aComponent1, + char aComponent2,char aComponent3, + char aComponent4,int aLength, + const char* aDestEnd) + + { + if (aLength < 1) + return CompressionError; + + if(!CanWrite32bppValue(aDest, aDestEnd, aLength)) + return NoCompression; + while (aLength > 128) + { + *aDest++ = 127; + *aDest++ = aComponent1; + *aDest++ = aComponent2; + *aDest++ = aComponent3; + *aDest++ = aComponent4; + aLength -= 128; + } + + *aDest++ = char(aLength-1); + *aDest++ = aComponent1; + *aDest++ = aComponent2; + *aDest++ = aComponent3; + *aDest++ = aComponent4; + + return NoError; + } + +int BitmapCompiler::ColorAlphaPointerCompare(char* aColorPointer,char aComponent1,char aComponent2,char aComponent3,char aComponent4) + { + return (*aColorPointer == aComponent1 && *(aColorPointer + 1) == aComponent2 && *(aColorPointer + 2) == aComponent3 && *(aColorPointer + 3) == aComponent4); + } + +int BitmapCompiler::ReadHexString(char aHexBuf[10],char*& aDataPtr,char* aDataPtrLimit) + { + while (aDataPtr < aDataPtrLimit) + { + if (aDataPtr[0] == '0') + { + if (aDataPtr[1] == 'x' || aDataPtr[1] == 'X') + { + memcpy(aHexBuf,aDataPtr,10); + aDataPtr += 10; + return NoError; + } + } + aDataPtr++; + } + + return PaletteFile; + } + +int BitmapCompiler::HexToInt(char aHighNibble,char aLowNibble) + { + return (HexToInt(aHighNibble) << 4) + HexToInt(aLowNibble); + } + +int BitmapCompiler::HexToInt(char aNibble) + { + int value = 0; + + if (aNibble >= '0' && aNibble <= '9') + value = aNibble - '0'; + else if (aNibble >= 'a' && aNibble <= 'f') + value = aNibble - 'a' + 10; + else if (aNibble >= 'A' && aNibble <= 'F') + value = aNibble - 'A' + 10; + + return value; + } + +void BitmapCompiler::CopyTail(void* aDst, void* aSrc, int aFullSize, int aSkipped) + { + memcpy(aDst, ((char*)aSrc)+aSkipped, aFullSize-aSkipped); + } + + + +TSourceFile::TSourceFile() +: iFileName(0), iInfo(EFormatNotImportant) + { + } + +char*& TSourceFile::FileName() + { + return iFileName; + } + +void TSourceFile::SetCompileInfo(TCompileInfo aInfo) + { + iInfo = aInfo; + } + +void TSourceFile::WriteCompileInfo(ostream& aOut) + { + aOut << iFileName; + if (iInfo == ENokiaBitmap) + aOut << " (Nokia format)"; + else if (iInfo == EThirdPartyBitmap) + aOut << " (Third party format)"; + } +