os/graphics/graphicstools/gdi_tools/bmconv/PBMCOMP.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include "BMCONV.H"
sl@0
    17
#include <stdlib.h>
sl@0
    18
#include <ctype.h>
sl@0
    19
#include <sys/stat.h>
sl@0
    20
sl@0
    21
extern TRgb* color256Palette;
sl@0
    22
extern char* color256InversePalette;
sl@0
    23
sl@0
    24
static inline bool CanCopy16bppData(const char* aDest, const char* aDestEnd, int aDataSize)
sl@0
    25
	{
sl@0
    26
	const char* aDestNew = 	aDest + (aDataSize / 128) * (256 + 1) + //(2 * 128) bytes data + 1 leading byte
sl@0
    27
		                            (aDataSize % 128 ? (aDataSize % 128) * 2 + 1 : 0);
sl@0
    28
	return aDestNew <= aDestEnd;
sl@0
    29
	}
sl@0
    30
sl@0
    31
static inline bool CanWrite16bppValue(const char* aDest, const char* aDestEnd, int aDataSize)
sl@0
    32
	{
sl@0
    33
	const char* aDestNew = 	aDest + (aDataSize / 128) * (2 + 1) + //2 bytes data + 1 leading byte
sl@0
    34
		                            (aDataSize % 128 ? 2 + 1 : 0);
sl@0
    35
	return aDestNew <= aDestEnd;
sl@0
    36
	}
sl@0
    37
sl@0
    38
static inline bool CanCopy8bppData(const char* aDest, const char* aDestEnd, int aDataSize)
sl@0
    39
	{
sl@0
    40
	const char* aDestNew = 	aDest + (aDataSize / 128) * (128 + 1) + //128 bytes data + 1 leading byte
sl@0
    41
		                            (aDataSize % 128 ? (aDataSize % 128) + 1 : 0);
sl@0
    42
	return aDestNew <= aDestEnd;
sl@0
    43
	}
sl@0
    44
sl@0
    45
static inline bool CanWrite8bppValue(const char* aDest, const char* aDestEnd, int aDataSize)
sl@0
    46
	{
sl@0
    47
	const char* aDestNew = 	aDest + (aDataSize / 128) * (1 + 1) + //1 byte data + 1 leading byte
sl@0
    48
		                            (aDataSize % 128 ? 1 + 1 : 0);
sl@0
    49
	return aDestNew <= aDestEnd;
sl@0
    50
	}
sl@0
    51
sl@0
    52
static inline bool CanCopy24bppData(const char* aDest, const char* aDestEnd, int aDataSize)
sl@0
    53
	{
sl@0
    54
	const char* aDestNew = 	aDest + (aDataSize / 128) * (384 + 1) + //(128 * 3) bytes data + 1 leading byte
sl@0
    55
		                            (aDataSize % 128 ? (aDataSize % 128) * 3 + 1 : 0);
sl@0
    56
	return aDestNew <= aDestEnd;
sl@0
    57
	}
sl@0
    58
sl@0
    59
static inline bool CanWrite24bppValue(const char* aDest, const char* aDestEnd, int aDataSize)
sl@0
    60
	{
sl@0
    61
	const char* aDestNew = 	aDest + (aDataSize / 128) * (3 + 1) + //3 bytes data + 1 leading byte
sl@0
    62
		                            (aDataSize % 128 ? 3 + 1 : 0);
sl@0
    63
	return aDestNew <= aDestEnd;
sl@0
    64
	}
sl@0
    65
sl@0
    66
static inline bool CanCopy32bppData(const char* aDest, const char* aDestEnd, int aDataSize)
sl@0
    67
	{
sl@0
    68
	const char* aDestNew = 	aDest + (aDataSize / 128) * (512 + 1) + //(128 * 4) bytes data + 1 leading byte
sl@0
    69
		                            (aDataSize % 128 ? (aDataSize % 128) * 4 + 1 : 0);
sl@0
    70
	return aDestNew <= aDestEnd;
sl@0
    71
	}
sl@0
    72
sl@0
    73
static inline bool CanWrite32bppValue(const char* aDest, const char* aDestEnd, int aDataSize)
sl@0
    74
	{
sl@0
    75
	const char* aDestNew = 	aDest + (aDataSize / 128) * (4 + 1) + //4 bytes data + 1 leading byte
sl@0
    76
		                            (aDataSize % 128 ? 4 + 1 : 0);
sl@0
    77
	return aDestNew <= aDestEnd;
sl@0
    78
	}
sl@0
    79
sl@0
    80
BitmapCompiler::BitmapCompiler(char* aSourcefilenames[],int aNumSources):
sl@0
    81
	iSourcefilenames(aSourcefilenames),
sl@0
    82
	iPbmSources(NULL),
sl@0
    83
	iNumSources(aNumSources)
sl@0
    84
	{}
sl@0
    85
sl@0
    86
BitmapCompiler::~BitmapCompiler()
sl@0
    87
	{
sl@0
    88
	iDestFile.close();
sl@0
    89
	if(iPbmSources)
sl@0
    90
		for(int count=0;count<iNumSources;count++)
sl@0
    91
			delete iPbmSources[count];
sl@0
    92
	delete [] iPbmSources;
sl@0
    93
	iPbmSources = NULL;
sl@0
    94
	}
sl@0
    95
sl@0
    96
int BitmapCompiler::Compile(TStoreType aSt,int aCompress,char* aDestfilename,char* aHeaderFilename,char* aPaletteFilename)
sl@0
    97
	{
sl@0
    98
	int ret = LoadPalette(aPaletteFilename);
sl@0
    99
	if (ret)
sl@0
   100
		return ret;
sl@0
   101
sl@0
   102
	iDestFile.open(aDestfilename, ios::out | ios::binary);
sl@0
   103
	if(iDestFile.is_open()==0)
sl@0
   104
		return DestFile;
sl@0
   105
	if (iNumSources < 1)
sl@0
   106
		return SourceFile;
sl@0
   107
sl@0
   108
	if (iNumSources==1 && ((iSourcefilenames[0][0]==OPTCHAR || iSourcefilenames[0][0]==ALTERNATE_OPTCHAR)) && iSourcefilenames[0][1]=='m')
sl@0
   109
		{
sl@0
   110
		// Source is an existing MBM file, presumably because we want to convert
sl@0
   111
		// a filestore into a ROM image.
sl@0
   112
		if (aHeaderFilename)
sl@0
   113
			{
sl@0
   114
			cout << "Header file generation is not permitted with /m or -m\n";
sl@0
   115
			aHeaderFilename = NULL;
sl@0
   116
			}
sl@0
   117
		iSourcefilenames[0]+=2;
sl@0
   118
		EpocLoader pl;
sl@0
   119
		int romFormat;
sl@0
   120
		ret = pl.EpocBitmapCount(iSourcefilenames[0], iNumSources, romFormat);
sl@0
   121
		if (!ret)
sl@0
   122
			ret = LoadPbmFile(iSourcefilenames[0]);
sl@0
   123
		}
sl@0
   124
	else
sl@0
   125
		{
sl@0
   126
		// Read the usual list of [OPT]bmp_n source bitmaps.
sl@0
   127
		ret = LoadSourcefiles();
sl@0
   128
		}
sl@0
   129
	if (ret)
sl@0
   130
		return ret;
sl@0
   131
sl@0
   132
	ret = CreateHeader(aHeaderFilename);
sl@0
   133
	if (ret)
sl@0
   134
		return ret;
sl@0
   135
sl@0
   136
	if (aSt == ERomStore || aSt == ECompressedRomStore)
sl@0
   137
		ret = RomImage(aSt == ECompressedRomStore);
sl@0
   138
	else
sl@0
   139
		ret = FileImage(aCompress);
sl@0
   140
	return ret;
sl@0
   141
	};
sl@0
   142
sl@0
   143
int BitmapCompiler::AllocatePbmSourcesArray()
sl@0
   144
	{
sl@0
   145
	iPbmSources = new SEpocBitmapHeader*[iNumSources];
sl@0
   146
	if(iPbmSources == NULL)
sl@0
   147
		return NoMemory;
sl@0
   148
sl@0
   149
	memset(iPbmSources,0xff,sizeof(SEpocBitmapHeader*)*iNumSources);
sl@0
   150
	int count;
sl@0
   151
	for(count=0;count<iNumSources;count++)
sl@0
   152
		iPbmSources[count]=NULL;
sl@0
   153
	return NoError;
sl@0
   154
	}
sl@0
   155
sl@0
   156
int BitmapCompiler::LoadSourcefiles()
sl@0
   157
	{
sl@0
   158
	int ret = AllocatePbmSourcesArray();
sl@0
   159
	if (ret)
sl@0
   160
		return ret;
sl@0
   161
	for(int count=0;count<iNumSources;count++)
sl@0
   162
		{
sl@0
   163
		bool useAlpha = false;
sl@0
   164
		int bpp = 2;
sl@0
   165
		TBitmapColor color = EMonochromeBitmap;
sl@0
   166
		BitmapLoader bmpload;
sl@0
   167
		if(iSourcefilenames[count][0]==OPTCHAR || iSourcefilenames[count][0]==ALTERNATE_OPTCHAR)
sl@0
   168
			{
sl@0
   169
			iSourcefilenames[count]++;
sl@0
   170
			if(iSourcefilenames[count][0]=='c')
sl@0
   171
				{
sl@0
   172
				color = EColorBitmap;
sl@0
   173
				iSourcefilenames[count]++;
sl@0
   174
				}
sl@0
   175
			bpp=iSourcefilenames[count][0]-'0';
sl@0
   176
			iSourcefilenames[count]++;
sl@0
   177
			int next=iSourcefilenames[count][0]-'0';
sl@0
   178
			if(next==2 || next==6 || next==4)
sl@0
   179
				{
sl@0
   180
				bpp=bpp*10+next;
sl@0
   181
				iSourcefilenames[count]++;
sl@0
   182
				}
sl@0
   183
			if(iSourcefilenames[count][0]=='a')
sl@0
   184
				{
sl@0
   185
				useAlpha = true;
sl@0
   186
				iSourcefilenames[count]++;
sl@0
   187
				if (color!=EColorBitmap || bpp!=32)
sl@0
   188
					return Bpp;
sl@0
   189
				}
sl@0
   190
			if (color == EColorBitmap && bpp!=4 && bpp!=8 && bpp!=12 && bpp!=16 && bpp!=24 && bpp!=32)
sl@0
   191
				return Bpp;
sl@0
   192
			if (color == EMonochromeBitmap && bpp!=1 && bpp!=2 && bpp!=4 && bpp!=8)
sl@0
   193
				return Bpp;
sl@0
   194
			}
sl@0
   195
		if (color == EColorBitmap && useAlpha)
sl@0
   196
			color = EColorBitmapAlpha;
sl@0
   197
		ret = bmpload.LoadBitmap(iSourcefilenames[count],bpp,color,iPbmSources[count]);
sl@0
   198
		if (ret)
sl@0
   199
			return ret;
sl@0
   200
		}
sl@0
   201
	return NoError;
sl@0
   202
	}
sl@0
   203
sl@0
   204
int BitmapCompiler::LoadPbmFile(char* aPbmFilename)
sl@0
   205
	{
sl@0
   206
	int ret = AllocatePbmSourcesArray();
sl@0
   207
	if (ret)
sl@0
   208
		return ret;
sl@0
   209
	for(int count=0;count<iNumSources;count++)
sl@0
   210
		{
sl@0
   211
		EpocLoader pl;
sl@0
   212
		ret = pl.LoadEpocBitmap(aPbmFilename,count);
sl@0
   213
		if (!ret)
sl@0
   214
			ret = pl.DupBitmap(iPbmSources[count]);
sl@0
   215
		if (ret)
sl@0
   216
			return ret;
sl@0
   217
		}
sl@0
   218
	return NoError;
sl@0
   219
	}
sl@0
   220
sl@0
   221
int BitmapCompiler::RomImage(bool aCompress)
sl@0
   222
	{
sl@0
   223
	int count=0;
sl@0
   224
sl@0
   225
	if (aCompress)
sl@0
   226
		{
sl@0
   227
		for(; count<iNumSources; count++)
sl@0
   228
			{
sl@0
   229
			int ret = CompressBitmap(iPbmSources[count]);
sl@0
   230
			if (ret)
sl@0
   231
				return ret;
sl@0
   232
			}
sl@0
   233
		}
sl@0
   234
sl@0
   235
	int ret = WriteRomheader();
sl@0
   236
	if (ret)
sl@0
   237
		return ret;
sl@0
   238
sl@0
   239
	for(count=0;count<iNumSources;count++)
sl@0
   240
		{
sl@0
   241
		ret = WriteRombitmap(iPbmSources[count]);
sl@0
   242
		if (ret)
sl@0
   243
			return ret;
sl@0
   244
		}
sl@0
   245
	return NoError;
sl@0
   246
	}
sl@0
   247
sl@0
   248
int BitmapCompiler::FileImage(int aCompress)
sl@0
   249
	{
sl@0
   250
	int count = 0;
sl@0
   251
	if(aCompress)
sl@0
   252
		{
sl@0
   253
		for(;count<iNumSources;count++)
sl@0
   254
			{
sl@0
   255
			int ret = CompressBitmap(iPbmSources[count]);
sl@0
   256
			if(ret)
sl@0
   257
				return ret;
sl@0
   258
			}
sl@0
   259
		}
sl@0
   260
	int ret = WriteFileheader();
sl@0
   261
	if (ret)
sl@0
   262
		return ret;
sl@0
   263
	for (count=0;count<iNumSources;count++)
sl@0
   264
		{
sl@0
   265
		ret = WriteFilebitmap(iPbmSources[count]);
sl@0
   266
		if (ret)
sl@0
   267
			return ret;
sl@0
   268
		}
sl@0
   269
	ret = WriteHeadStream();
sl@0
   270
	return ret;
sl@0
   271
	}
sl@0
   272
sl@0
   273
int BitmapCompiler::WriteRomheader()
sl@0
   274
	{
sl@0
   275
	iDestFile.write((char*)&KMultiBitmapRomImageUid,4);
sl@0
   276
	iDestFile.write((char*)&iNumSources,4);
sl@0
   277
	int byteswritten=8+(iNumSources*4);
sl@0
   278
	for (int count=0;count<iNumSources;count++)
sl@0
   279
		{
sl@0
   280
		iDestFile.write((char*)&byteswritten,4);
sl@0
   281
		byteswritten+=(((iPbmSources[count]->iBitmapSize)+3)/4*4)-sizeof(SEpocBitmapHeader)+sizeof(Bitmap);
sl@0
   282
		}
sl@0
   283
	return NoError;
sl@0
   284
	}
sl@0
   285
sl@0
   286
int BitmapCompiler::WriteRombitmap(SEpocBitmapHeader* aPbm)
sl@0
   287
	{
sl@0
   288
	if (aPbm->iPaletteEntries != 0)
sl@0
   289
	    return PaletteSupportNotImplemented;
sl@0
   290
sl@0
   291
	int bitmapsize = aPbm->iBitmapSize-sizeof(SEpocBitmapHeader)+sizeof(Bitmap);
sl@0
   292
	bitmapsize = ((bitmapsize+3)/4)*4;
sl@0
   293
sl@0
   294
	char* buffer = new char[bitmapsize];
sl@0
   295
	if (buffer == NULL)
sl@0
   296
		return NoMemory;
sl@0
   297
	memset(buffer,0xff,bitmapsize);
sl@0
   298
sl@0
   299
	Bitmap* bmp = (Bitmap*)buffer;
sl@0
   300
	bmp->iUid=KCBitwiseBitmapUid;
sl@0
   301
	TBitmapColor color = aPbm->iColor;
sl@0
   302
sl@0
   303
	switch(aPbm->iBitsPerPixel)
sl@0
   304
		{ // for corresponding enums, see TDisplayMode in <gdi.h>
sl@0
   305
	case 1:
sl@0
   306
		bmp->iDispMode=1;
sl@0
   307
		break;
sl@0
   308
	case 2:
sl@0
   309
		bmp->iDispMode=2;
sl@0
   310
		break;
sl@0
   311
	case 4:
sl@0
   312
		if (color == EMonochromeBitmap)
sl@0
   313
			bmp->iDispMode=3;
sl@0
   314
		else
sl@0
   315
			bmp->iDispMode=5;
sl@0
   316
		break;
sl@0
   317
	case 8:
sl@0
   318
		if (color == EMonochromeBitmap)
sl@0
   319
			bmp->iDispMode=4;
sl@0
   320
		else
sl@0
   321
			bmp->iDispMode=6;
sl@0
   322
		break;
sl@0
   323
	case 12:
sl@0
   324
		bmp->iDispMode=10;
sl@0
   325
		break;
sl@0
   326
	case 16:
sl@0
   327
		bmp->iDispMode=7;
sl@0
   328
		break;
sl@0
   329
	case 24:
sl@0
   330
		bmp->iDispMode=8;
sl@0
   331
		break;
sl@0
   332
	case 32:
sl@0
   333
		if (color == EColorBitmapAlpha)
sl@0
   334
			bmp->iDispMode=12; // Color16MA
sl@0
   335
		else
sl@0
   336
			bmp->iDispMode=11; // Color16MU
sl@0
   337
		break;
sl@0
   338
	default:
sl@0
   339
		delete [] buffer;
sl@0
   340
		return SourceFile;
sl@0
   341
		}
sl@0
   342
sl@0
   343
	bmp->iHeap = NULL;
sl@0
   344
	bmp->iPile = NULL;
sl@0
   345
	bmp->iHeader = *aPbm;
sl@0
   346
	bmp->iByteWidth = BitmapUtils::ByteWidth(bmp->iHeader.iWidthInPixels,bmp->iHeader.iBitsPerPixel);
sl@0
   347
	bmp->iDataOffset = sizeof(Bitmap);
sl@0
   348
sl@0
   349
	CopyTail(buffer + sizeof(Bitmap), aPbm, aPbm->iBitmapSize, sizeof(SEpocBitmapHeader));
sl@0
   350
	iDestFile.write(buffer,bitmapsize);
sl@0
   351
sl@0
   352
	delete [] buffer;
sl@0
   353
sl@0
   354
	return NoError;
sl@0
   355
	}
sl@0
   356
sl@0
   357
int BitmapCompiler::WriteFileheader()
sl@0
   358
	{
sl@0
   359
	int zero=0;
sl@0
   360
	iDestFile.write((char*)&KWriteOnceFileStoreUid,4);
sl@0
   361
	iDestFile.write((char*)&KMultiBitmapFileImageUid,4);
sl@0
   362
	iDestFile.write((char*)&zero,4);
sl@0
   363
	iDestFile.write((char*)&KMultiBitmapFileImageChecksum,4);
sl@0
   364
	int byteswritten=16;
sl@0
   365
	for(int count=0;count<iNumSources;count++)
sl@0
   366
		{
sl@0
   367
		byteswritten+=iPbmSources[count]->iBitmapSize;
sl@0
   368
		}
sl@0
   369
	byteswritten+=4;
sl@0
   370
	iDestFile.write((char*)&byteswritten,4);
sl@0
   371
	return NoError;
sl@0
   372
	}
sl@0
   373
sl@0
   374
int BitmapCompiler::WriteHeadStream()
sl@0
   375
	{
sl@0
   376
	iDestFile.write((char*)&iNumSources,4);
sl@0
   377
	int byteswritten=20;
sl@0
   378
	for(int count=0;count<iNumSources;count++)
sl@0
   379
		{
sl@0
   380
		iDestFile.write((char*)&byteswritten,4);
sl@0
   381
		byteswritten+=iPbmSources[count]->iBitmapSize;
sl@0
   382
		}
sl@0
   383
	return NoError;
sl@0
   384
	}
sl@0
   385
sl@0
   386
int BitmapCompiler::WriteFilebitmap(SEpocBitmapHeader* aPbm)
sl@0
   387
	{
sl@0
   388
	if (aPbm->iPaletteEntries != 0)
sl@0
   389
		return PaletteSupportNotImplemented;
sl@0
   390
sl@0
   391
	int dataSize = aPbm->iBitmapSize - sizeof(SEpocBitmapHeader);
sl@0
   392
sl@0
   393
	iDestFile.write((char*)(aPbm),sizeof(SEpocBitmapHeader));
sl@0
   394
	// WritePalette()
sl@0
   395
	iDestFile.write(((char*)(aPbm)) + sizeof(SEpocBitmapHeader),dataSize);
sl@0
   396
sl@0
   397
	return NoError;
sl@0
   398
	}
sl@0
   399
sl@0
   400
void BitmapCompiler::WritePalette()
sl@0
   401
	{
sl@0
   402
	for (int index = 0; index < 256; index++)
sl@0
   403
		{
sl@0
   404
		iDestFile.write((char*)(&iPalette[index]),3);
sl@0
   405
		}
sl@0
   406
	}
sl@0
   407
sl@0
   408
int BitmapCompiler::LoadPalette(char* aPaletteFilename)
sl@0
   409
	{
sl@0
   410
	if (!aPaletteFilename)
sl@0
   411
		{
sl@0
   412
		iDefaultPalette = 1;
sl@0
   413
		return NoError;
sl@0
   414
		}
sl@0
   415
sl@0
   416
	iDefaultPalette = 0;
sl@0
   417
	color256Palette = iPalette;
sl@0
   418
	color256InversePalette = iInversePalette;
sl@0
   419
sl@0
   420
	struct stat fileinfo;
sl@0
   421
	if (stat(aPaletteFilename,&fileinfo)==-1)
sl@0
   422
		return CommandFile;
sl@0
   423
sl@0
   424
	int filesize = fileinfo.st_size;
sl@0
   425
	if (filesize == 0)
sl@0
   426
		return PaletteFile;
sl@0
   427
sl@0
   428
#if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
sl@0
   429
	fstream paletteFile(aPaletteFilename, ios::in | ios::binary);
sl@0
   430
#else
sl@0
   431
	fstream paletteFile(aPaletteFilename, ios::in | ios::binary | ios::nocreate);
sl@0
   432
#endif
sl@0
   433
sl@0
   434
	if(!paletteFile.is_open())
sl@0
   435
		return PaletteFile;
sl@0
   436
sl@0
   437
	char* paletteData = new char[filesize];
sl@0
   438
	if (!paletteData)
sl@0
   439
		return NoMemory;
sl@0
   440
sl@0
   441
	memset(paletteData,0,filesize);
sl@0
   442
	paletteFile.read(paletteData,filesize);
sl@0
   443
	paletteFile.close();
sl@0
   444
sl@0
   445
	char* dataPtr = (char*)paletteData;
sl@0
   446
	char* dataPtrLimit = dataPtr + filesize;
sl@0
   447
sl@0
   448
	for (int index = 0; index < 256; index++)
sl@0
   449
		{
sl@0
   450
		char hexBuf[10];
sl@0
   451
		int ret = ReadHexString(hexBuf,dataPtr,dataPtrLimit);
sl@0
   452
		if (ret)
sl@0
   453
			{
sl@0
   454
			delete paletteData;
sl@0
   455
			return ret;
sl@0
   456
			}
sl@0
   457
sl@0
   458
		int red = HexToInt(hexBuf[8],hexBuf[9]);
sl@0
   459
		int green = HexToInt(hexBuf[6],hexBuf[7]);
sl@0
   460
		int blue = HexToInt(hexBuf[4],hexBuf[5]);
sl@0
   461
sl@0
   462
		iPalette[index] = TRgb(red,green,blue);
sl@0
   463
		}
sl@0
   464
sl@0
   465
	delete paletteData;
sl@0
   466
	CalculateInversePalette();
sl@0
   467
	return NoError;
sl@0
   468
	}
sl@0
   469
sl@0
   470
void BitmapCompiler::CalculateInversePalette()
sl@0
   471
	{
sl@0
   472
	for (int index = 0; index < 4096; index++)
sl@0
   473
		{
sl@0
   474
		TRgb color = TRgb((index & 0x00f) * 17,((index & 0x0f0) >> 4) * 17,((index & 0xf00) >> 8) * 17);
sl@0
   475
sl@0
   476
		int nearest = 0;
sl@0
   477
		int distance = iPalette[0].Difference(color);
sl@0
   478
sl@0
   479
		for (int paletteIndex = 0; paletteIndex < 256; paletteIndex++)
sl@0
   480
			{
sl@0
   481
			TRgb paletteColor = iPalette[paletteIndex];
sl@0
   482
sl@0
   483
			if (paletteColor == color)
sl@0
   484
				{
sl@0
   485
				nearest = paletteIndex;
sl@0
   486
				break;
sl@0
   487
				}
sl@0
   488
sl@0
   489
			int paletteDistance = paletteColor.Difference(color);
sl@0
   490
			if (paletteDistance < distance)
sl@0
   491
				{
sl@0
   492
				nearest = paletteIndex;
sl@0
   493
				distance = paletteDistance;
sl@0
   494
				}
sl@0
   495
			}
sl@0
   496
sl@0
   497
		iInversePalette[index] = (char)nearest;
sl@0
   498
		TRgb palColor = iPalette[nearest];
sl@0
   499
		color = palColor;
sl@0
   500
		}
sl@0
   501
	}
sl@0
   502
sl@0
   503
int BitmapCompiler::CreateHeader(char* aHeaderFilename)
sl@0
   504
	{
sl@0
   505
	if (!aHeaderFilename)
sl@0
   506
		return NoError;
sl@0
   507
sl@0
   508
	fstream hf(aHeaderFilename,ios::out);
sl@0
   509
	if(!hf.is_open())
sl@0
   510
		return DestFile;
sl@0
   511
sl@0
   512
	char* basename = strrchr(aHeaderFilename,'\\');
sl@0
   513
	if (basename==0)
sl@0
   514
		basename = aHeaderFilename;
sl@0
   515
	else
sl@0
   516
		basename++;	// skip directory separator
sl@0
   517
sl@0
   518
	char unadornedFile[256];
sl@0
   519
	strcpy(unadornedFile, UnadornedName(aHeaderFilename));
sl@0
   520
sl@0
   521
	hf << "// " << basename << "\n";
sl@0
   522
	hf << "// Generated by BitmapCompiler\n";
sl@0
   523
	hf << "// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).\n";
sl@0
   524
	hf << "//\n\n";
sl@0
   525
	hf << "enum TMbm" << unadornedFile << "\n";
sl@0
   526
	hf << "\t{\n";
sl@0
   527
sl@0
   528
	for (int count=0;count<iNumSources;count++)
sl@0
   529
		{
sl@0
   530
		hf << "\tEMbm" << unadornedFile << UnadornedName(iSourcefilenames[count]);
sl@0
   531
		if(count<iNumSources-1)
sl@0
   532
			hf << ',';
sl@0
   533
		hf << '\n';
sl@0
   534
		}
sl@0
   535
	hf << "\t};\n";
sl@0
   536
	hf.close();
sl@0
   537
	return NoError;
sl@0
   538
	}
sl@0
   539
sl@0
   540
char* BitmapCompiler::UnadornedName(char* aName)
sl@0
   541
	{
sl@0
   542
	int len = strlen(aName);
sl@0
   543
sl@0
   544
	char* foundDir = strrchr(aName,'\\');
sl@0
   545
	char* foundUrl = strrchr(aName,'/');
sl@0
   546
	char* foundExt = strrchr(aName,'.');
sl@0
   547
sl@0
   548
	char* foundPath = (foundDir > foundUrl) ? foundDir : foundUrl;
sl@0
   549
	char* firstchar = (foundPath > 0) ? foundPath + 1 : aName;
sl@0
   550
	char* lastchar = (foundExt > firstchar) ? foundExt : aName+len;
sl@0
   551
sl@0
   552
	static char result[256];
sl@0
   553
	if (lastchar-firstchar > 255)
sl@0
   554
		{
sl@0
   555
		strcpy(result,"NameTooLong");
sl@0
   556
		return result;
sl@0
   557
		}
sl@0
   558
	int i=0;
sl@0
   559
	result[0] = (char)toupper(*firstchar);
sl@0
   560
	firstchar+=1;
sl@0
   561
	for (i=1; firstchar<lastchar; i++,firstchar++)
sl@0
   562
		{
sl@0
   563
		result[i] = (char)tolower(*firstchar);
sl@0
   564
		}
sl@0
   565
	result[i] = '\0';
sl@0
   566
	return result;
sl@0
   567
	}
sl@0
   568
sl@0
   569
int BitmapCompiler::CompressBitmap(SEpocBitmapHeader*& aPbm)
sl@0
   570
	{
sl@0
   571
	int originalsize = aPbm->iBitmapSize-sizeof(SEpocBitmapHeader);
sl@0
   572
	char* newbits=new char[originalsize+sizeof(SEpocBitmapHeader)];
sl@0
   573
	if(!newbits)
sl@0
   574
		return NoMemory;
sl@0
   575
sl@0
   576
	memset(newbits,0xff,sizeof(SEpocBitmapHeader)+originalsize);
sl@0
   577
	memcpy(newbits,aPbm,sizeof(SEpocBitmapHeader));
sl@0
   578
	char* newbitsptr=newbits+sizeof(SEpocBitmapHeader);
sl@0
   579
	char* oldbits=((char*)(aPbm))+sizeof(SEpocBitmapHeader);
sl@0
   580
sl@0
   581
	TBitmapfileCompression compression = ENoBitmapCompression;
sl@0
   582
	int ret = NoCompression;
sl@0
   583
sl@0
   584
	if (aPbm->iBitsPerPixel <= 8)
sl@0
   585
		{
sl@0
   586
		compression = EByteRLECompression;
sl@0
   587
		ret = CompressByteData(newbitsptr,oldbits,originalsize);
sl@0
   588
		}
sl@0
   589
	else if (aPbm->iBitsPerPixel == 12)
sl@0
   590
		{
sl@0
   591
		compression = ETwelveBitRLECompression;
sl@0
   592
		ret = CompressTwelveBitData(newbitsptr,oldbits,originalsize);
sl@0
   593
		}
sl@0
   594
	else if (aPbm->iBitsPerPixel == 16)
sl@0
   595
		{
sl@0
   596
		compression = ESixteenBitRLECompression;
sl@0
   597
		ret = CompressSixteenBitData(newbitsptr,oldbits,originalsize);
sl@0
   598
		}
sl@0
   599
	else if (aPbm->iBitsPerPixel == 24)
sl@0
   600
		{
sl@0
   601
		compression = ETwentyFourBitRLECompression;
sl@0
   602
		ret = CompressTwentyFourBitData(newbitsptr,oldbits,originalsize);
sl@0
   603
		}
sl@0
   604
	else if (aPbm->iBitsPerPixel == 32 && (aPbm->iColor == EColorBitmap))
sl@0
   605
		{
sl@0
   606
		compression = EThirtyTwoUBitRLECompression;
sl@0
   607
		ret = CompressThirtyTwoUBitData(newbitsptr,oldbits,originalsize);
sl@0
   608
		}
sl@0
   609
	else if (aPbm->iBitsPerPixel == 32 && (aPbm->iColor == EColorBitmapAlpha))
sl@0
   610
		{
sl@0
   611
		compression = EThirtyTwoABitRLECompression;
sl@0
   612
		ret = CompressThirtyTwoABitData(newbitsptr,oldbits,originalsize);
sl@0
   613
		}
sl@0
   614
sl@0
   615
	if(ret)
sl@0
   616
		{
sl@0
   617
		delete [] newbits;
sl@0
   618
		if(ret>0)
sl@0
   619
			return ret;
sl@0
   620
		return NoError;
sl@0
   621
		}
sl@0
   622
sl@0
   623
	delete aPbm;
sl@0
   624
	aPbm = (SEpocBitmapHeader*)newbits;
sl@0
   625
	aPbm->iBitmapSize = newbitsptr-(newbits+sizeof(SEpocBitmapHeader))+sizeof(SEpocBitmapHeader);
sl@0
   626
	aPbm->iCompression = compression;
sl@0
   627
	return NoError;
sl@0
   628
	}
sl@0
   629
sl@0
   630
int BitmapCompiler::CompressByteData(char*& aDest,char* aSrce,int aSize)
sl@0
   631
	{
sl@0
   632
	const char* destEnd = aDest + aSize;
sl@0
   633
	char* bytepointer=aSrce;
sl@0
   634
	char* limitpointer=bytepointer+aSize;
sl@0
   635
	int margin = (aSize>>6);
sl@0
   636
	char* limitmargin = limitpointer - ((margin > 4) ? margin : 4);
sl@0
   637
	char* cutoffpointer=aDest+(aSize>>1)+(aSize>>2);
sl@0
   638
	int ret=NoError;
sl@0
   639
	char* oldbytepointer=NULL;
sl@0
   640
	while(bytepointer<limitmargin)
sl@0
   641
		{
sl@0
   642
		char value=*bytepointer;
sl@0
   643
		if(*(bytepointer+1)==value && *(bytepointer+2)==value)
sl@0
   644
			{
sl@0
   645
			oldbytepointer=bytepointer;
sl@0
   646
			bytepointer+=3;
sl@0
   647
			while ( ( bytepointer < limitmargin ) && ( *bytepointer == value ) )
sl@0
   648
				bytepointer++;
sl@0
   649
			ret = WriteCompressedByteValues(aDest,value,bytepointer-oldbytepointer, destEnd);
sl@0
   650
			if(ret) return ret;
sl@0
   651
			}
sl@0
   652
		else
sl@0
   653
			{
sl@0
   654
			oldbytepointer=bytepointer;
sl@0
   655
			while((bytepointer<limitmargin) && (*(bytepointer+1)!=value || *(bytepointer+2)!=value))
sl@0
   656
				{
sl@0
   657
				bytepointer++;
sl@0
   658
				value=*bytepointer;
sl@0
   659
				}
sl@0
   660
			ret = WriteCompressedByteData(aDest,oldbytepointer,bytepointer-oldbytepointer, destEnd);
sl@0
   661
			if(ret) return ret;
sl@0
   662
			}
sl@0
   663
		if(aDest>cutoffpointer)
sl@0
   664
			return NoCompression;
sl@0
   665
		}
sl@0
   666
sl@0
   667
	int remaining = limitpointer-bytepointer;
sl@0
   668
	if(remaining > 0)
sl@0
   669
		{
sl@0
   670
		if (aDest + remaining > cutoffpointer)
sl@0
   671
			return NoCompression;
sl@0
   672
		ret=WriteCompressedByteData(aDest,bytepointer,remaining, destEnd);
sl@0
   673
		if(ret) return ret;
sl@0
   674
		}
sl@0
   675
	return NoError;
sl@0
   676
	}
sl@0
   677
sl@0
   678
int BitmapCompiler::WriteCompressedByteData(char*& aDest,char* aData,int aLength, const char* aDestEnd)
sl@0
   679
	{
sl@0
   680
	if(!CanCopy8bppData(aDest, aDestEnd, aLength))
sl@0
   681
		return NoCompression;
sl@0
   682
	while(aLength>128)
sl@0
   683
		{
sl@0
   684
		*aDest++=-128;
sl@0
   685
		for(int count=0;count<128;count++)
sl@0
   686
			*aDest++=*aData++;
sl@0
   687
		aLength-=128;
sl@0
   688
		}
sl@0
   689
	if(aLength>128 || aLength<1) return CompressionError;
sl@0
   690
	*aDest++=char(-aLength);
sl@0
   691
	for(int count=0;count<aLength;count++)
sl@0
   692
		*aDest++=*aData++;
sl@0
   693
	return NoError;
sl@0
   694
	}
sl@0
   695
sl@0
   696
int BitmapCompiler::WriteCompressedByteValues(char*& aDest,char aValue,int aLength, const char* aDestEnd)
sl@0
   697
	{
sl@0
   698
	if (aLength < 1)
sl@0
   699
		return CompressionError;
sl@0
   700
sl@0
   701
	if(!CanWrite8bppValue(aDest, aDestEnd, aLength))
sl@0
   702
		return NoCompression;
sl@0
   703
sl@0
   704
	while (aLength > 128)
sl@0
   705
		{
sl@0
   706
		*aDest++ = 127;
sl@0
   707
		*aDest++ = aValue;
sl@0
   708
		aLength -= 128;
sl@0
   709
		}
sl@0
   710
sl@0
   711
	*aDest++ = char(aLength-1);
sl@0
   712
	*aDest++ = aValue;
sl@0
   713
sl@0
   714
	return NoError;
sl@0
   715
	}
sl@0
   716
sl@0
   717
int BitmapCompiler::CompressTwelveBitData(char*& aDest,char* aSrce,int aSizeInBytes)
sl@0
   718
	{
sl@0
   719
	unsigned short* srcePtr = (unsigned short*)aSrce;
sl@0
   720
	unsigned short* srceLimitPtr = srcePtr + (aSizeInBytes / 2);
sl@0
   721
	unsigned short* dest = (unsigned short*)aDest;
sl@0
   722
sl@0
   723
	while (srcePtr < srceLimitPtr)
sl@0
   724
		{
sl@0
   725
		unsigned short* runStartPtr = srcePtr;
sl@0
   726
		unsigned short value = *srcePtr;
sl@0
   727
		do
sl@0
   728
			srcePtr++;
sl@0
   729
		while (srcePtr < srceLimitPtr && *srcePtr == value);
sl@0
   730
		WriteCompressedTwelveBitData(dest,*runStartPtr,srcePtr - runStartPtr); // Ignore error return as 12bpp compression never fails
sl@0
   731
		}
sl@0
   732
sl@0
   733
	aDest = (char*)dest;
sl@0
   734
	return NoError;
sl@0
   735
	}
sl@0
   736
sl@0
   737
int BitmapCompiler::WriteCompressedTwelveBitData(unsigned short*& aDest,unsigned short aData,int aLength)
sl@0
   738
	{
sl@0
   739
	// The run length l is stored as l-1 in the top 4 bits of each 16-bit word (between 1 and 16)
sl@0
   740
	aData &= 0x0fff;
sl@0
   741
	unsigned short maxLengthData = (unsigned short)(aData | 0xf000);
sl@0
   742
sl@0
   743
	while(aLength>16)
sl@0
   744
		{
sl@0
   745
		*aDest++ = maxLengthData;
sl@0
   746
		aLength -= 16;
sl@0
   747
		}
sl@0
   748
sl@0
   749
	if (aLength > 0)
sl@0
   750
		*aDest++ = (unsigned short)(aData | ((aLength - 1) << 12));
sl@0
   751
sl@0
   752
	return NoError;
sl@0
   753
	}
sl@0
   754
sl@0
   755
int BitmapCompiler::CompressSixteenBitData(char*& aDest,char* aSrce,int aSizeInBytes)
sl@0
   756
	{
sl@0
   757
	char* destEnd = aDest + aSizeInBytes;
sl@0
   758
	unsigned short* srcePtr = (unsigned short*)aSrce;
sl@0
   759
	unsigned short* srceLimitPtr = srcePtr + (aSizeInBytes / 2);
sl@0
   760
	unsigned short* srceLimitPtrMinusOne = srceLimitPtr - 1;
sl@0
   761
	char* destCompressedLimitPtr = aDest + (aSizeInBytes * 7 / 8);
sl@0
   762
	int ret = NoError;
sl@0
   763
sl@0
   764
	while (srcePtr < srceLimitPtrMinusOne)
sl@0
   765
		{
sl@0
   766
		unsigned short value = *srcePtr;
sl@0
   767
		unsigned short* runStartPtr = srcePtr++;
sl@0
   768
sl@0
   769
		if(*srcePtr == value)
sl@0
   770
			{
sl@0
   771
			do
sl@0
   772
				srcePtr++;
sl@0
   773
			while ( ( srcePtr < srceLimitPtr ) && ( *srcePtr == value ) );
sl@0
   774
sl@0
   775
			ret = WriteCompressedSixteenBitValues(aDest,value,srcePtr-runStartPtr, destEnd);
sl@0
   776
			if (ret)
sl@0
   777
				return ret;
sl@0
   778
			}
sl@0
   779
		else
sl@0
   780
			{
sl@0
   781
			value = *srcePtr;
sl@0
   782
			while (srcePtr < srceLimitPtrMinusOne && *(srcePtr + 1) != value)
sl@0
   783
				{
sl@0
   784
				srcePtr++;
sl@0
   785
				value = *srcePtr;
sl@0
   786
				}
sl@0
   787
sl@0
   788
			ret = WriteCompressedSixteenBitData(aDest,runStartPtr,srcePtr - runStartPtr, destEnd);
sl@0
   789
			if (ret)
sl@0
   790
				return ret;
sl@0
   791
			}
sl@0
   792
		if (aDest > destCompressedLimitPtr)
sl@0
   793
			return NoCompression;
sl@0
   794
		}
sl@0
   795
sl@0
   796
	if (srcePtr < srceLimitPtr)
sl@0
   797
		{
sl@0
   798
		ret = WriteCompressedSixteenBitData(aDest,srcePtr,srceLimitPtr - srcePtr, destEnd);
sl@0
   799
		if (ret)
sl@0
   800
			return ret;
sl@0
   801
		}
sl@0
   802
sl@0
   803
	if (aDest > destCompressedLimitPtr)
sl@0
   804
		return NoCompression;
sl@0
   805
	return NoError;
sl@0
   806
	}
sl@0
   807
sl@0
   808
int BitmapCompiler::WriteCompressedSixteenBitData(char*& aDest,unsigned short* aData,
sl@0
   809
												  int aLength, const char* aDestEnd)
sl@0
   810
	{
sl@0
   811
	if (aLength < 1)
sl@0
   812
		return CompressionError;
sl@0
   813
sl@0
   814
	if(!CanCopy16bppData(aDest, aDestEnd, aLength))
sl@0
   815
		return NoCompression;
sl@0
   816
sl@0
   817
	char* srcePtr = (char*)aData;
sl@0
   818
sl@0
   819
	while (aLength > 128)
sl@0
   820
		{
sl@0
   821
		*aDest++ = -128;
sl@0
   822
		memcpy(aDest,srcePtr,256);
sl@0
   823
		aDest += 256;
sl@0
   824
		srcePtr += 256;
sl@0
   825
		aLength -= 128;
sl@0
   826
		}
sl@0
   827
sl@0
   828
	*aDest++ = char(-aLength);
sl@0
   829
sl@0
   830
	int remainingBytes = aLength * 2;
sl@0
   831
	memcpy(aDest,srcePtr,remainingBytes);
sl@0
   832
	aDest += remainingBytes;
sl@0
   833
sl@0
   834
	return NoError;
sl@0
   835
	}
sl@0
   836
sl@0
   837
int BitmapCompiler::WriteCompressedSixteenBitValues(char*& aDest,unsigned short aValue,
sl@0
   838
													int aLength, const char* aDestEnd)
sl@0
   839
	{
sl@0
   840
	if (aLength < 1)
sl@0
   841
		return CompressionError;
sl@0
   842
sl@0
   843
	if(!CanWrite16bppValue(aDest, aDestEnd, aLength))
sl@0
   844
		return NoCompression;
sl@0
   845
sl@0
   846
	char lowByte = char(aValue);
sl@0
   847
	char highByte = char(aValue >> 8);
sl@0
   848
sl@0
   849
	while (aLength > 128)
sl@0
   850
		{
sl@0
   851
		*aDest++ = 127;
sl@0
   852
		*aDest++ = lowByte;
sl@0
   853
		*aDest++ = highByte;
sl@0
   854
		aLength -= 128;
sl@0
   855
		}
sl@0
   856
sl@0
   857
	*aDest++ = char(aLength-1);
sl@0
   858
	*aDest++ = lowByte;
sl@0
   859
	*aDest++ = highByte;
sl@0
   860
sl@0
   861
	return NoError;
sl@0
   862
	}
sl@0
   863
sl@0
   864
int BitmapCompiler::CompressTwentyFourBitData(char*& aDest,char* aSrce,int aSizeInBytes)
sl@0
   865
	{
sl@0
   866
	const char* destEnd = aDest + aSizeInBytes; 
sl@0
   867
	char* srceLimitPtr = aSrce + aSizeInBytes;
sl@0
   868
	char* srceLimitPtrMinusThree = srceLimitPtr - 3; // three bytes == one pixel
sl@0
   869
	char* destCompressedLimitPtr = aDest + (aSizeInBytes * 7 / 8);
sl@0
   870
	int ret = NoError;
sl@0
   871
sl@0
   872
	while (aSrce < srceLimitPtrMinusThree)
sl@0
   873
		{
sl@0
   874
		char* runStartPtr = aSrce;
sl@0
   875
		char component1 = *aSrce++;
sl@0
   876
		char component2 = *aSrce++;
sl@0
   877
		char component3 = *aSrce++;
sl@0
   878
sl@0
   879
		if (TrueColorPointerCompare(aSrce,component1,component2,component3))
sl@0
   880
			{
sl@0
   881
			do
sl@0
   882
				aSrce += 3;
sl@0
   883
			while (aSrce < srceLimitPtr && TrueColorPointerCompare(aSrce,component1,component2,component3));
sl@0
   884
sl@0
   885
			ret = WriteCompressedTwentyFourBitValues(aDest,component1,component2,component3,(aSrce - runStartPtr) / 3, destEnd);
sl@0
   886
			if (ret)
sl@0
   887
				return ret;
sl@0
   888
			}
sl@0
   889
		else
sl@0
   890
			{
sl@0
   891
			bool more  = true;
sl@0
   892
			bool eqRun = false;
sl@0
   893
			do
sl@0
   894
				{
sl@0
   895
				component1 = *aSrce++;
sl@0
   896
				component2 = *aSrce++;
sl@0
   897
				component3 = *aSrce++;
sl@0
   898
				more = (aSrce < srceLimitPtr);
sl@0
   899
				eqRun = more && TrueColorPointerCompare(aSrce,component1,component2,component3);
sl@0
   900
				}
sl@0
   901
			while (more && !eqRun);
sl@0
   902
			if (eqRun)
sl@0
   903
				aSrce -= 3;
sl@0
   904
			int pixelLength = (aSrce - runStartPtr) / 3;
sl@0
   905
			ret = WriteCompressedTwentyFourBitData(aDest,runStartPtr,pixelLength,destEnd);
sl@0
   906
			if (ret)
sl@0
   907
				return ret;
sl@0
   908
			}
sl@0
   909
		if (aDest > destCompressedLimitPtr)
sl@0
   910
			return NoCompression;
sl@0
   911
		}
sl@0
   912
sl@0
   913
	if (aSrce < srceLimitPtr)
sl@0
   914
		{
sl@0
   915
		ret = WriteCompressedTwentyFourBitData(aDest,aSrce,(srceLimitPtr - aSrce) / 3, destEnd);
sl@0
   916
		if (ret)
sl@0
   917
			return ret;
sl@0
   918
		}
sl@0
   919
sl@0
   920
	if (aDest > destCompressedLimitPtr)
sl@0
   921
		return NoCompression;
sl@0
   922
	return NoError;
sl@0
   923
	}
sl@0
   924
sl@0
   925
int BitmapCompiler::WriteCompressedTwentyFourBitData(char*& aDest,char* aData,
sl@0
   926
													 int aLength, const char* aDestEnd)
sl@0
   927
	{
sl@0
   928
	if (aLength < 1)
sl@0
   929
		return CompressionError;
sl@0
   930
sl@0
   931
	if(!CanCopy24bppData(aDest, aDestEnd, aLength))
sl@0
   932
		return NoCompression;
sl@0
   933
sl@0
   934
	while (aLength > 128)
sl@0
   935
		{
sl@0
   936
		*aDest++ = -128;
sl@0
   937
		memcpy(aDest,aData,384);
sl@0
   938
		aDest += 384;
sl@0
   939
		aData += 384;
sl@0
   940
		aLength -= 128;
sl@0
   941
		}
sl@0
   942
sl@0
   943
	*aDest++ = char(-aLength);
sl@0
   944
sl@0
   945
	int remainingBytes = aLength * 3;
sl@0
   946
	memcpy(aDest,aData,remainingBytes);
sl@0
   947
	aDest += remainingBytes;
sl@0
   948
sl@0
   949
	return NoError;
sl@0
   950
	}
sl@0
   951
sl@0
   952
int BitmapCompiler::WriteCompressedTwentyFourBitValues(char*& aDest,char aComponent1,
sl@0
   953
													   char aComponent2,char aComponent3,
sl@0
   954
													   int aLength, const char* aDestEnd)
sl@0
   955
	{
sl@0
   956
	if (aLength < 1)
sl@0
   957
		return CompressionError;
sl@0
   958
sl@0
   959
	if(!CanWrite24bppValue(aDest, aDestEnd, aLength))
sl@0
   960
		return NoCompression;
sl@0
   961
sl@0
   962
	while (aLength > 128)
sl@0
   963
		{
sl@0
   964
		*aDest++ = 127;
sl@0
   965
		*aDest++ = aComponent1;
sl@0
   966
		*aDest++ = aComponent2;
sl@0
   967
		*aDest++ = aComponent3;
sl@0
   968
		aLength -= 128;
sl@0
   969
		}
sl@0
   970
sl@0
   971
	*aDest++ = char(aLength-1);
sl@0
   972
	*aDest++ = aComponent1;
sl@0
   973
	*aDest++ = aComponent2;
sl@0
   974
	*aDest++ = aComponent3;
sl@0
   975
sl@0
   976
	return NoError;
sl@0
   977
	}
sl@0
   978
sl@0
   979
/** The function encodes 32-bit buffer into 24-bit stream by using RLE compression algorithm*/
sl@0
   980
int BitmapCompiler::CompressThirtyTwoUBitData(char*& aDest,char* aSrce,int aSizeInBytes)
sl@0
   981
	{
sl@0
   982
	const char* destEnd = aDest + aSizeInBytes; 
sl@0
   983
	char* srceLimitPtr = aSrce + aSizeInBytes;
sl@0
   984
	char* srceLimitPtrMinusFour = srceLimitPtr - 4; // four bytes == one pixel
sl@0
   985
	char* destCompressedLimitPtr = aDest + (aSizeInBytes * 7 / 8);
sl@0
   986
	int ret = NoError;
sl@0
   987
sl@0
   988
	while (aSrce < srceLimitPtrMinusFour)
sl@0
   989
		{
sl@0
   990
		char* runStartPtr = aSrce;
sl@0
   991
		char component1 = *aSrce++;
sl@0
   992
		char component2 = *aSrce++;
sl@0
   993
		char component3 = *aSrce++;
sl@0
   994
		aSrce++;
sl@0
   995
sl@0
   996
		if (TrueColorPointerCompare(aSrce,component1,component2,component3))
sl@0
   997
			{
sl@0
   998
			do
sl@0
   999
				aSrce += 4;
sl@0
  1000
			while (aSrce < srceLimitPtr && TrueColorPointerCompare(aSrce,component1,component2,component3));
sl@0
  1001
sl@0
  1002
			ret = WriteCompressedThirtyTwoUBitValues(aDest,component1,component2,component3,(aSrce - runStartPtr) / 4, destEnd);
sl@0
  1003
			if (ret)
sl@0
  1004
				return ret;
sl@0
  1005
			}
sl@0
  1006
		else //non repeating pixel buffer
sl@0
  1007
			{
sl@0
  1008
			bool more  = true;
sl@0
  1009
			bool eqRun = false;
sl@0
  1010
			do {
sl@0
  1011
				component1 = *aSrce++;
sl@0
  1012
				component2 = *aSrce++;
sl@0
  1013
				component3 = *aSrce++;
sl@0
  1014
				aSrce++; //last byte is unused (no alpha component)
sl@0
  1015
				more = (aSrce < srceLimitPtr);
sl@0
  1016
				eqRun = more && TrueColorPointerCompare(aSrce,component1,component2,component3);
sl@0
  1017
				} while (more && !eqRun);
sl@0
  1018
			if (eqRun)
sl@0
  1019
				aSrce -= 4;
sl@0
  1020
			int pixelLength = (aSrce - runStartPtr) / 4;
sl@0
  1021
			ret = WriteCompressedThirtyTwoUBitData(aDest,runStartPtr,pixelLength,destEnd);
sl@0
  1022
 			if (ret)
sl@0
  1023
				return ret;
sl@0
  1024
			}
sl@0
  1025
		if (aDest > destCompressedLimitPtr)
sl@0
  1026
			return NoCompression;
sl@0
  1027
		}
sl@0
  1028
sl@0
  1029
	if (aSrce < srceLimitPtr)
sl@0
  1030
		{
sl@0
  1031
		ret = WriteCompressedThirtyTwoUBitData(aDest,aSrce,(srceLimitPtr - aSrce) / 4, destEnd);
sl@0
  1032
		if (ret)
sl@0
  1033
			return ret;
sl@0
  1034
		}
sl@0
  1035
sl@0
  1036
	if (aDest > destCompressedLimitPtr)
sl@0
  1037
		return NoCompression;
sl@0
  1038
	return NoError;
sl@0
  1039
	}
sl@0
  1040
sl@0
  1041
/** The function copies non repeating 32-bit buffer to 24-bit compressed buffer*/
sl@0
  1042
int BitmapCompiler::WriteCompressedThirtyTwoUBitData(char*& aDest,char* aData,
sl@0
  1043
													 int aLength, const char* aDestEnd)
sl@0
  1044
	{
sl@0
  1045
	if (aLength < 1)
sl@0
  1046
		return CompressionError;
sl@0
  1047
sl@0
  1048
	if(!CanCopy24bppData(aDest, aDestEnd, aLength))
sl@0
  1049
		return NoCompression;
sl@0
  1050
sl@0
  1051
	while (aLength > 128)
sl@0
  1052
		{
sl@0
  1053
		*aDest++ = -128;
sl@0
  1054
		for(int ii = 0; ii < 128; ii++)
sl@0
  1055
			{
sl@0
  1056
			memcpy(aDest,aData, 3);
sl@0
  1057
			aDest += 3;
sl@0
  1058
			aData += 4;
sl@0
  1059
			}
sl@0
  1060
		aLength -= 128;
sl@0
  1061
		}
sl@0
  1062
sl@0
  1063
	*aDest++ = char(-aLength);
sl@0
  1064
sl@0
  1065
	while(aLength--)
sl@0
  1066
		{
sl@0
  1067
		memcpy(aDest,aData, 3);
sl@0
  1068
		aDest += 3;
sl@0
  1069
		aData += 4;
sl@0
  1070
		}
sl@0
  1071
sl@0
  1072
	return NoError;
sl@0
  1073
	}
sl@0
  1074
sl@0
  1075
/** The function copies repeating colour to the 24-bit compressed buffer */
sl@0
  1076
int BitmapCompiler::WriteCompressedThirtyTwoUBitValues(char*& aDest,char aComponent1,
sl@0
  1077
													   char aComponent2,char aComponent3,
sl@0
  1078
													   int aLength, const char* aDestEnd)
sl@0
  1079
	{
sl@0
  1080
	if (aLength < 1)
sl@0
  1081
		return CompressionError;
sl@0
  1082
sl@0
  1083
	if(!CanWrite24bppValue(aDest, aDestEnd, aLength))
sl@0
  1084
		return NoCompression;
sl@0
  1085
	while (aLength > 128)
sl@0
  1086
		{
sl@0
  1087
		*aDest++ = 127;
sl@0
  1088
		*aDest++ = aComponent1;
sl@0
  1089
		*aDest++ = aComponent2;
sl@0
  1090
		*aDest++ = aComponent3;
sl@0
  1091
		aLength -= 128;
sl@0
  1092
		}
sl@0
  1093
sl@0
  1094
	*aDest++ = char(aLength-1);
sl@0
  1095
	*aDest++ = aComponent1;
sl@0
  1096
	*aDest++ = aComponent2;
sl@0
  1097
	*aDest++ = aComponent3;
sl@0
  1098
sl@0
  1099
	return NoError;
sl@0
  1100
	}
sl@0
  1101
sl@0
  1102
int BitmapCompiler::TrueColorPointerCompare(char* aColorPointer,char aComponent1,char aComponent2,char aComponent3)
sl@0
  1103
	{
sl@0
  1104
	return (*aColorPointer == aComponent1 && *(aColorPointer + 1) == aComponent2 && *(aColorPointer + 2) == aComponent3);
sl@0
  1105
	}
sl@0
  1106
sl@0
  1107
/** The function encodes 32-bit buffer into 32-bit stream by using RLE compression algorithm*/
sl@0
  1108
int BitmapCompiler::CompressThirtyTwoABitData(char*& aDest,char* aSrce,int aSizeInBytes)
sl@0
  1109
	{
sl@0
  1110
	const char* destEnd = aDest + aSizeInBytes; 
sl@0
  1111
	char* srceLimitPtr = aSrce + aSizeInBytes;
sl@0
  1112
	char* srceLimitPtrMinusFour = srceLimitPtr - 4; // four bytes == one pixel
sl@0
  1113
	char* destCompressedLimitPtr = aDest + (aSizeInBytes * 7 / 8);
sl@0
  1114
	int ret = NoError;
sl@0
  1115
sl@0
  1116
	while (aSrce < srceLimitPtrMinusFour)
sl@0
  1117
		{
sl@0
  1118
		char* runStartPtr = aSrce;
sl@0
  1119
		char component1 = *aSrce++;
sl@0
  1120
		char component2 = *aSrce++;
sl@0
  1121
		char component3 = *aSrce++;
sl@0
  1122
		char component4 = *aSrce++;
sl@0
  1123
sl@0
  1124
		if (ColorAlphaPointerCompare(aSrce,component1,component2,component3,component4))
sl@0
  1125
			{
sl@0
  1126
			do
sl@0
  1127
				aSrce += 4;
sl@0
  1128
			while (aSrce < srceLimitPtr && ColorAlphaPointerCompare(aSrce,component1,component2,component3,component4));
sl@0
  1129
			int eqPixelLength = (aSrce - runStartPtr) / 4;
sl@0
  1130
			ret = WriteCompressedThirtyTwoABitValues(aDest,component1,component2,component3,component4,eqPixelLength,destEnd);
sl@0
  1131
			if (ret)
sl@0
  1132
				return ret;
sl@0
  1133
			}
sl@0
  1134
		else //non repeating pixel buffer
sl@0
  1135
			{
sl@0
  1136
			bool more  = true;
sl@0
  1137
			bool eqRun = false;
sl@0
  1138
			do {
sl@0
  1139
				component1 = *aSrce++;
sl@0
  1140
				component2 = *aSrce++;
sl@0
  1141
				component3 = *aSrce++;
sl@0
  1142
				component4 = *aSrce++;
sl@0
  1143
				more = (aSrce < srceLimitPtr);
sl@0
  1144
				eqRun = more && ColorAlphaPointerCompare(aSrce,component1,component2,component3,component4);
sl@0
  1145
				} while (more && !eqRun);
sl@0
  1146
			if (eqRun)
sl@0
  1147
				aSrce -= 4;
sl@0
  1148
			int nePixelLength = (aSrce - runStartPtr) / 4;
sl@0
  1149
			ret = WriteCompressedThirtyTwoABitData(aDest,runStartPtr,nePixelLength,destEnd);
sl@0
  1150
			if (ret)
sl@0
  1151
				return ret;
sl@0
  1152
			}
sl@0
  1153
		if (aDest > destCompressedLimitPtr)
sl@0
  1154
			return NoCompression;
sl@0
  1155
		}
sl@0
  1156
sl@0
  1157
	if (aSrce < srceLimitPtr)
sl@0
  1158
		{
sl@0
  1159
		ret = WriteCompressedThirtyTwoABitData(aDest,aSrce,(srceLimitPtr - aSrce) / 4, destEnd);
sl@0
  1160
		if (ret)
sl@0
  1161
			return ret;
sl@0
  1162
		}
sl@0
  1163
sl@0
  1164
	if (aDest > destCompressedLimitPtr)
sl@0
  1165
		return NoCompression;
sl@0
  1166
	return NoError;
sl@0
  1167
	}
sl@0
  1168
sl@0
  1169
/** The function copies non repeating 32-bit buffer to 32-bit compressed buffer*/
sl@0
  1170
int BitmapCompiler::WriteCompressedThirtyTwoABitData(char*& aDest,char* aData,
sl@0
  1171
													 int aLength, const char* aDestEnd)
sl@0
  1172
	{
sl@0
  1173
	if (aLength < 1)
sl@0
  1174
		return CompressionError;
sl@0
  1175
sl@0
  1176
	if(!CanCopy32bppData(aDest, aDestEnd, aLength))
sl@0
  1177
		return NoCompression;
sl@0
  1178
sl@0
  1179
	while (aLength > 128)
sl@0
  1180
		{
sl@0
  1181
		*aDest++ = -128;
sl@0
  1182
		memcpy(aDest,aData,512);
sl@0
  1183
		aDest += 512;
sl@0
  1184
		aData += 512;
sl@0
  1185
		aLength -= 128;
sl@0
  1186
		}
sl@0
  1187
sl@0
  1188
	*aDest++ = char(-aLength);
sl@0
  1189
	memcpy(aDest,aData, aLength*4);
sl@0
  1190
	aDest += aLength*4;
sl@0
  1191
	return NoError;
sl@0
  1192
	}
sl@0
  1193
sl@0
  1194
/** The function copies repeating pixels including alpha to a 32-bit compressed buffer */
sl@0
  1195
int BitmapCompiler::WriteCompressedThirtyTwoABitValues(char*& aDest,char aComponent1,
sl@0
  1196
													   char aComponent2,char aComponent3,
sl@0
  1197
													   char aComponent4,int aLength,
sl@0
  1198
													   const char* aDestEnd)
sl@0
  1199
sl@0
  1200
	{
sl@0
  1201
	if (aLength < 1)
sl@0
  1202
		return CompressionError;
sl@0
  1203
sl@0
  1204
	if(!CanWrite32bppValue(aDest, aDestEnd, aLength))
sl@0
  1205
		return NoCompression;
sl@0
  1206
	while (aLength > 128)
sl@0
  1207
		{
sl@0
  1208
		*aDest++ = 127;
sl@0
  1209
		*aDest++ = aComponent1;
sl@0
  1210
		*aDest++ = aComponent2;
sl@0
  1211
		*aDest++ = aComponent3;
sl@0
  1212
		*aDest++ = aComponent4;
sl@0
  1213
		aLength -= 128;
sl@0
  1214
		}
sl@0
  1215
sl@0
  1216
	*aDest++ = char(aLength-1);
sl@0
  1217
	*aDest++ = aComponent1;
sl@0
  1218
	*aDest++ = aComponent2;
sl@0
  1219
	*aDest++ = aComponent3;
sl@0
  1220
	*aDest++ = aComponent4;
sl@0
  1221
sl@0
  1222
	return NoError;
sl@0
  1223
	}
sl@0
  1224
sl@0
  1225
int BitmapCompiler::ColorAlphaPointerCompare(char* aColorPointer,char aComponent1,char aComponent2,char aComponent3,char aComponent4)
sl@0
  1226
	{
sl@0
  1227
	return (*aColorPointer == aComponent1 && *(aColorPointer + 1) == aComponent2 && *(aColorPointer + 2) == aComponent3 && *(aColorPointer + 3) == aComponent4);
sl@0
  1228
	}
sl@0
  1229
sl@0
  1230
int BitmapCompiler::ReadHexString(char aHexBuf[10],char*& aDataPtr,char* aDataPtrLimit)
sl@0
  1231
	{
sl@0
  1232
	while (aDataPtr < aDataPtrLimit)
sl@0
  1233
		{
sl@0
  1234
		if (aDataPtr[0] == '0')
sl@0
  1235
			{
sl@0
  1236
			if (aDataPtr[1] == 'x' || aDataPtr[1] == 'X')
sl@0
  1237
				{
sl@0
  1238
				memcpy(aHexBuf,aDataPtr,10);
sl@0
  1239
				aDataPtr += 10;
sl@0
  1240
				return NoError;
sl@0
  1241
				}
sl@0
  1242
			}
sl@0
  1243
		aDataPtr++;
sl@0
  1244
		}
sl@0
  1245
sl@0
  1246
	return PaletteFile;
sl@0
  1247
	}
sl@0
  1248
sl@0
  1249
int BitmapCompiler::HexToInt(char aHighNibble,char aLowNibble)
sl@0
  1250
	{
sl@0
  1251
	return (HexToInt(aHighNibble) << 4) + HexToInt(aLowNibble);
sl@0
  1252
	}
sl@0
  1253
sl@0
  1254
int BitmapCompiler::HexToInt(char aNibble)
sl@0
  1255
	{
sl@0
  1256
	int value = 0;
sl@0
  1257
sl@0
  1258
	if (aNibble >= '0' && aNibble <= '9')
sl@0
  1259
		value = aNibble - '0';
sl@0
  1260
	else if (aNibble >= 'a' && aNibble <= 'f')
sl@0
  1261
		value = aNibble - 'a' + 10;
sl@0
  1262
	else if (aNibble >= 'A' && aNibble <= 'F')
sl@0
  1263
		value = aNibble - 'A' + 10;
sl@0
  1264
sl@0
  1265
	return value;
sl@0
  1266
	}
sl@0
  1267
sl@0
  1268
void BitmapCompiler::CopyTail(void* aDst, void* aSrc, int aFullSize, int aSkipped)
sl@0
  1269
	{
sl@0
  1270
	memcpy(aDst, ((char*)aSrc)+aSkipped, aFullSize-aSkipped);
sl@0
  1271
	}