os/graphics/graphicstools/gdi_tools/bmconv/PBMTOBM.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 <assert.h>
sl@0
    17
#include "BMCONV.H"
sl@0
    18
sl@0
    19
EpocLoader::EpocLoader():
sl@0
    20
	iPbmBits(NULL)
sl@0
    21
	{}
sl@0
    22
sl@0
    23
EpocLoader::~EpocLoader()
sl@0
    24
	{
sl@0
    25
	delete iPbmBits;
sl@0
    26
	}
sl@0
    27
sl@0
    28
int EpocLoader::EpocBitmapCount(char* aFileName, int& aCount, int& isRomFormat)
sl@0
    29
    {
sl@0
    30
#if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
sl@0
    31
	fstream file(aFileName, ios::in | ios::binary);
sl@0
    32
#else //!__MSVCDOTNET__
sl@0
    33
	fstream file(aFileName, ios::in | ios::binary | ios::nocreate);
sl@0
    34
#endif //__MSVCDOTNET__
sl@0
    35
sl@0
    36
	if (file.is_open()==0)
sl@0
    37
		return Files;
sl@0
    38
sl@0
    39
	long int wordbuffer;
sl@0
    40
	file.read((char *)&wordbuffer,4);
sl@0
    41
	if (file.gcount()!=4)
sl@0
    42
		return SourceFile;
sl@0
    43
	if (wordbuffer==KMultiBitmapRomImageUid)
sl@0
    44
		{
sl@0
    45
		// ROM format file - next 4 bytes are the number of bitmaps
sl@0
    46
		isRomFormat=1;
sl@0
    47
		}
sl@0
    48
	else
sl@0
    49
		{
sl@0
    50
		if (wordbuffer!=KWriteOnceFileStoreUid)
sl@0
    51
			return SourceFile;
sl@0
    52
		isRomFormat=0;
sl@0
    53
		file.read((char *)&wordbuffer,4);
sl@0
    54
		if (file.gcount()!=4 || wordbuffer!=KMultiBitmapFileImageUid)
sl@0
    55
			return SourceFile;
sl@0
    56
		file.read((char *)&wordbuffer,4);
sl@0
    57
		if (file.gcount()!=4 || wordbuffer!=0)
sl@0
    58
			return SourceFile;
sl@0
    59
		file.read((char *)&wordbuffer,4);
sl@0
    60
		if (file.gcount()!=4 || wordbuffer!=KMultiBitmapFileImageChecksum)
sl@0
    61
			return SourceFile;
sl@0
    62
		file.read((char *)&wordbuffer,4);
sl@0
    63
		if (file.gcount()!=4)
sl@0
    64
			return SourceFile;
sl@0
    65
		file.seekg(wordbuffer,ios::beg);
sl@0
    66
		}
sl@0
    67
	file.read((char *)&wordbuffer,4);
sl@0
    68
	if (file.gcount()!=4)
sl@0
    69
		return SourceFile;
sl@0
    70
	aCount=wordbuffer;
sl@0
    71
	return NoError;
sl@0
    72
    }
sl@0
    73
sl@0
    74
int EpocLoader::LoadEpocBitmap(char* aFileName,int aIndex)
sl@0
    75
	{
sl@0
    76
#if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
sl@0
    77
	fstream file(aFileName, ios::in | ios::binary);
sl@0
    78
#else //!__MSVCDOTNET__
sl@0
    79
	fstream file(aFileName, ios::in | ios::binary | ios::nocreate);
sl@0
    80
#endif //__MSVCDOTNET__
sl@0
    81
sl@0
    82
	if (file.is_open()==0)
sl@0
    83
		return Files;
sl@0
    84
sl@0
    85
	long int wordbuffer;
sl@0
    86
	file.read((char *)&wordbuffer,4);
sl@0
    87
	if (file.gcount()!=4)
sl@0
    88
		return SourceFile;
sl@0
    89
	file.close();
sl@0
    90
sl@0
    91
	if (wordbuffer==KMultiBitmapRomImageUid)
sl@0
    92
		return LoadRom(aFileName,aIndex);
sl@0
    93
sl@0
    94
	return LoadFile(aFileName,aIndex);
sl@0
    95
	}
sl@0
    96
sl@0
    97
int EpocLoader::LoadFile(char* aFileName,int aIndex)
sl@0
    98
	{
sl@0
    99
#if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
sl@0
   100
	fstream file(aFileName, ios::in | ios::binary);
sl@0
   101
#else //!__MSVCDOTNET__
sl@0
   102
	fstream file(aFileName, ios::in | ios::binary | ios::nocreate);
sl@0
   103
#endif //__MSVCDOTNET__
sl@0
   104
sl@0
   105
	if (file.is_open()==0)
sl@0
   106
		return Files;
sl@0
   107
sl@0
   108
	long int wordbuffer;
sl@0
   109
	file.read((char *)&wordbuffer,4);
sl@0
   110
	if (file.gcount()!=4 || wordbuffer!=KWriteOnceFileStoreUid)
sl@0
   111
		return SourceFile;
sl@0
   112
	file.read((char *)&wordbuffer,4);
sl@0
   113
	if (file.gcount()!=4 || wordbuffer!=KMultiBitmapFileImageUid)
sl@0
   114
		return SourceFile;
sl@0
   115
	file.read((char *)&wordbuffer,4);
sl@0
   116
	if (file.gcount()!=4 || wordbuffer!=0)
sl@0
   117
		return SourceFile;
sl@0
   118
	file.read((char *)&wordbuffer,4);
sl@0
   119
	if (file.gcount()!=4 || wordbuffer!=KMultiBitmapFileImageChecksum)
sl@0
   120
		return SourceFile;
sl@0
   121
	file.read((char *)&wordbuffer,4);
sl@0
   122
	if (file.gcount()!=4)
sl@0
   123
		return SourceFile;
sl@0
   124
	file.seekg(wordbuffer,ios::beg);
sl@0
   125
	file.read((char *)&wordbuffer,4);
sl@0
   126
	if (file.gcount()!=4)
sl@0
   127
		return SourceFile;
sl@0
   128
sl@0
   129
	int numsources=wordbuffer;
sl@0
   130
	if (aIndex >= numsources)
sl@0
   131
		return OutOfRange;
sl@0
   132
	file.seekg(aIndex*4,ios::cur);
sl@0
   133
	file.read((char *)&wordbuffer,4);
sl@0
   134
	if (file.gcount()!=4)
sl@0
   135
		return SourceFile;
sl@0
   136
	file.seekg(wordbuffer,ios::beg);
sl@0
   137
	int ret = DoLoadFile(file);
sl@0
   138
	file.close();
sl@0
   139
	return ret;
sl@0
   140
	}
sl@0
   141
sl@0
   142
int EpocLoader::LoadRom(char* aFileName,int aIndex)
sl@0
   143
	{
sl@0
   144
#if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
sl@0
   145
	fstream file(aFileName, ios::in | ios::binary);
sl@0
   146
#else //!__MSVCDOTNET__
sl@0
   147
	fstream file(aFileName, ios::in | ios::binary | ios::nocreate);
sl@0
   148
#endif //__MSVCDOTNET__
sl@0
   149
sl@0
   150
	if (file.is_open()==0)
sl@0
   151
		return Files;
sl@0
   152
sl@0
   153
	long int wordbuffer;
sl@0
   154
	file.read((char *)&wordbuffer,4);
sl@0
   155
	if (file.gcount()!=4)
sl@0
   156
		return SourceFile;
sl@0
   157
	if (wordbuffer!=KMultiBitmapRomImageUid)
sl@0
   158
		return SourceFile;
sl@0
   159
	file.read((char *)&wordbuffer,4);
sl@0
   160
	if (file.gcount()!=4)
sl@0
   161
		return SourceFile;
sl@0
   162
	if (aIndex>=wordbuffer)
sl@0
   163
		return OutOfRange;
sl@0
   164
	file.seekg(aIndex*4,ios::cur);
sl@0
   165
	file.read((char *)&wordbuffer,4);
sl@0
   166
	if (file.gcount()!=4)
sl@0
   167
		return SourceFile;
sl@0
   168
	file.seekg(wordbuffer,ios::beg);
sl@0
   169
	int ret=DoLoadRom(file);
sl@0
   170
	file.close();
sl@0
   171
	return ret;
sl@0
   172
	}
sl@0
   173
sl@0
   174
int EpocLoader::DoLoadFile(fstream& aFile)
sl@0
   175
	{
sl@0
   176
	long size = sizeof(SEpocBitmapHeader);
sl@0
   177
	aFile.read((char *)&iPbmHeader,size);
sl@0
   178
	if (aFile.gcount()!=size)
sl@0
   179
		return SourceFile;
sl@0
   180
	iOriginalPbmHeader = iPbmHeader;
sl@0
   181
	size=iPbmHeader.iBitmapSize-iPbmHeader.iStructSize;
sl@0
   182
sl@0
   183
	iPbmBits=new char[size];
sl@0
   184
	if (iPbmBits==NULL)
sl@0
   185
		return NoMemory;
sl@0
   186
	memset(iPbmBits,0xff,size);
sl@0
   187
	aFile.read(iPbmBits,size);
sl@0
   188
	aFile.close();
sl@0
   189
	if (aFile.gcount() != size)
sl@0
   190
		return SourceFile;
sl@0
   191
sl@0
   192
	if (iPbmHeader.iCompression != ENoBitmapCompression)
sl@0
   193
		{
sl@0
   194
		return Decompress(size);
sl@0
   195
		}
sl@0
   196
sl@0
   197
	return NoError;
sl@0
   198
	}
sl@0
   199
sl@0
   200
int EpocLoader::DoLoadRom(fstream& aFile)
sl@0
   201
	{
sl@0
   202
	Bitmap bmp;
sl@0
   203
	long size=sizeof(Bitmap);
sl@0
   204
	aFile.read((char*)&bmp,size);
sl@0
   205
	if (aFile.gcount() != size)
sl@0
   206
		return SourceFile;
sl@0
   207
sl@0
   208
	size = bmp.iHeader.iBitmapSize - sizeof(SEpocBitmapHeader);
sl@0
   209
	iPbmBits = new char[size];
sl@0
   210
	if (iPbmBits == NULL)
sl@0
   211
		return NoMemory;
sl@0
   212
	memset(iPbmBits,0xff,size);
sl@0
   213
sl@0
   214
	aFile.read(iPbmBits,size);
sl@0
   215
	if (aFile.gcount() != size)
sl@0
   216
		return SourceFile;
sl@0
   217
	iPbmHeader = bmp.iHeader;
sl@0
   218
	iOriginalPbmHeader = iPbmHeader;
sl@0
   219
sl@0
   220
	if (iPbmHeader.iCompression != ENoBitmapCompression)
sl@0
   221
		{
sl@0
   222
		return Decompress(size);
sl@0
   223
		}
sl@0
   224
sl@0
   225
	return NoError;
sl@0
   226
	}
sl@0
   227
sl@0
   228
int EpocLoader::Decompress(int aSize)
sl@0
   229
	{
sl@0
   230
	int byteWidth = BitmapUtils::ByteWidth(iPbmHeader.iWidthInPixels,iPbmHeader.iBitsPerPixel);
sl@0
   231
	int expandedsize = byteWidth * iPbmHeader.iHeightInPixels;
sl@0
   232
	char* newbits = new char[expandedsize];
sl@0
   233
	if (newbits == NULL)
sl@0
   234
		return NoMemory;
sl@0
   235
	memset(newbits,0xff,expandedsize);
sl@0
   236
	int ret = NoError;
sl@0
   237
	switch (iPbmHeader.iCompression)
sl@0
   238
		{
sl@0
   239
	case EByteRLECompression:
sl@0
   240
		ret = ExpandByteRLEData(newbits,expandedsize,iPbmBits,aSize);
sl@0
   241
		break;
sl@0
   242
	case ETwelveBitRLECompression:
sl@0
   243
		ret = ExpandTwelveBitRLEData(newbits,expandedsize,iPbmBits,aSize);
sl@0
   244
		break;
sl@0
   245
	case ESixteenBitRLECompression:
sl@0
   246
		ret = ExpandSixteenBitRLEData(newbits,expandedsize,iPbmBits,aSize);
sl@0
   247
		break;
sl@0
   248
	case ETwentyFourBitRLECompression:
sl@0
   249
		ret = ExpandTwentyFourBitRLEData(newbits,expandedsize,iPbmBits,aSize);
sl@0
   250
		break;
sl@0
   251
	case EThirtyTwoUBitRLECompression:
sl@0
   252
		ret = ExpandThirtyTwoUBitRLEData(newbits,expandedsize,iPbmBits,aSize);
sl@0
   253
		break;
sl@0
   254
	case EThirtyTwoABitRLECompression:
sl@0
   255
		ret = ExpandThirtyTwoABitRLEData(newbits,expandedsize,iPbmBits,aSize);
sl@0
   256
		break;
sl@0
   257
	default:
sl@0
   258
		ret = UnknownCompression;
sl@0
   259
		break;
sl@0
   260
		}
sl@0
   261
	delete iPbmBits;
sl@0
   262
	iPbmBits = newbits;
sl@0
   263
	iPbmHeader.iCompression = ENoBitmapCompression;
sl@0
   264
	iPbmHeader.iBitmapSize += expandedsize-aSize;
sl@0
   265
	return ret;
sl@0
   266
	}
sl@0
   267
sl@0
   268
int EpocLoader::ExpandByteRLEData(char* aDest,int aDestSize,char* aSrce,int aSrceSize)
sl@0
   269
	{
sl@0
   270
	char* srcelimit=aSrce+aSrceSize;
sl@0
   271
	char* destlimit=aDest+aDestSize;
sl@0
   272
	while(aSrce<srcelimit && aDest<destlimit)
sl@0
   273
		{
sl@0
   274
		char count=*aSrce++;
sl@0
   275
		if (count<0)
sl@0
   276
			{
sl@0
   277
			int runLength=-count;
sl@0
   278
			memcpy(aDest,aSrce,runLength);
sl@0
   279
			aSrce+=runLength;
sl@0
   280
			aDest+=runLength;
sl@0
   281
			}
sl@0
   282
		else
sl@0
   283
			{
sl@0
   284
			char value=*aSrce++;
sl@0
   285
			while(count>=0)
sl@0
   286
				{
sl@0
   287
				*aDest++=value;
sl@0
   288
				count--;
sl@0
   289
				}
sl@0
   290
			}
sl@0
   291
		}
sl@0
   292
	if (aSrce!=srcelimit || aDest!=destlimit)
sl@0
   293
		return DecompressionError;
sl@0
   294
	return NoError;
sl@0
   295
	}
sl@0
   296
sl@0
   297
int EpocLoader::ExpandTwelveBitRLEData(char* aDest,int aDestSizeInBytes,char* aSrce,int aSrceSizeInBytes)
sl@0
   298
	{
sl@0
   299
	unsigned short* srcePtr = (unsigned short*)aSrce;
sl@0
   300
	unsigned short* destPtr = (unsigned short*)aDest;
sl@0
   301
	unsigned short* srcePtrLimit = srcePtr + (aSrceSizeInBytes / 2);
sl@0
   302
	unsigned short* destPtrLimit = destPtr + (aDestSizeInBytes / 2);
sl@0
   303
sl@0
   304
	while (srcePtr < srcePtrLimit && destPtr < destPtrLimit)
sl@0
   305
		{
sl@0
   306
		unsigned short value = *srcePtr++;
sl@0
   307
		int runLength = (value >> 12) + 1;
sl@0
   308
		value &= 0x0fff;
sl@0
   309
sl@0
   310
		for (;runLength > 0;runLength--)
sl@0
   311
			*destPtr++ = value;
sl@0
   312
		}
sl@0
   313
sl@0
   314
	if (srcePtr != srcePtrLimit || destPtr != destPtrLimit)
sl@0
   315
		return DecompressionError;
sl@0
   316
sl@0
   317
	return NoError;
sl@0
   318
	}
sl@0
   319
sl@0
   320
int EpocLoader::ExpandSixteenBitRLEData(char* aDest,int aDestSizeInBytes,char* aSrce,int aSrceSizeInBytes)
sl@0
   321
	{
sl@0
   322
	char* srcePtrLimit = aSrce + aSrceSizeInBytes;
sl@0
   323
	unsigned short* destPtr = (unsigned short*)aDest;
sl@0
   324
	unsigned short* destPtrLimit = destPtr + (aDestSizeInBytes / 2);
sl@0
   325
sl@0
   326
	while (aSrce < srcePtrLimit && destPtr < destPtrLimit)
sl@0
   327
		{
sl@0
   328
		int runLength = *aSrce++;
sl@0
   329
sl@0
   330
		if (runLength >= 0)
sl@0
   331
			{
sl@0
   332
			unsigned short value = *((unsigned short*)(aSrce));
sl@0
   333
			aSrce += 2;
sl@0
   334
			for (runLength++; runLength > 0; runLength--)
sl@0
   335
				*destPtr++ = value;
sl@0
   336
			}
sl@0
   337
		else
sl@0
   338
			{
sl@0
   339
			runLength = -runLength;
sl@0
   340
			int byteLength = runLength * 2;
sl@0
   341
			memcpy(destPtr,aSrce,byteLength);
sl@0
   342
			aSrce += byteLength;
sl@0
   343
			destPtr += runLength;
sl@0
   344
			}
sl@0
   345
		}
sl@0
   346
sl@0
   347
	if (aSrce != srcePtrLimit || destPtr != destPtrLimit)
sl@0
   348
		return DecompressionError;
sl@0
   349
sl@0
   350
	return NoError;
sl@0
   351
	}
sl@0
   352
sl@0
   353
int EpocLoader::ExpandTwentyFourBitRLEData(char* aDest,int aDestSizeInBytes,char* aSrce,int aSrceSizeInBytes)
sl@0
   354
	{
sl@0
   355
	char* srcePtrLimit = aSrce + aSrceSizeInBytes;
sl@0
   356
	char* destPtrLimit = aDest + aDestSizeInBytes;
sl@0
   357
sl@0
   358
	while (aSrce < srcePtrLimit && aDest < destPtrLimit)
sl@0
   359
		{
sl@0
   360
		int runLength = *aSrce++;
sl@0
   361
sl@0
   362
		if (runLength >= 0)
sl@0
   363
			{
sl@0
   364
			char component1 = *aSrce++;
sl@0
   365
			char component2 = *aSrce++;
sl@0
   366
			char component3 = *aSrce++;
sl@0
   367
			for (runLength++; runLength > 0; runLength--)
sl@0
   368
				{
sl@0
   369
				*aDest++ = component1;
sl@0
   370
				*aDest++ = component2;
sl@0
   371
				*aDest++ = component3;
sl@0
   372
				}
sl@0
   373
			}
sl@0
   374
		else
sl@0
   375
			{
sl@0
   376
			runLength = -runLength;
sl@0
   377
			int byteLength = runLength * 3;
sl@0
   378
			memcpy(aDest,aSrce,byteLength);
sl@0
   379
			aSrce += byteLength;
sl@0
   380
			aDest += byteLength;
sl@0
   381
			}
sl@0
   382
		}
sl@0
   383
sl@0
   384
	if (aSrce != srcePtrLimit || aDest != destPtrLimit)
sl@0
   385
		return DecompressionError;
sl@0
   386
sl@0
   387
	return NoError;
sl@0
   388
	}
sl@0
   389
sl@0
   390
/** The function decodes 24-bit compressed pixel buffer into the 32-bit buffer, where top bytes are unused*/
sl@0
   391
int EpocLoader::ExpandThirtyTwoUBitRLEData(char* aDest,int aDestSizeInBytes,char* aSrce,int aSrceSizeInBytes)
sl@0
   392
	{
sl@0
   393
	char* srcePtrLimit = aSrce + aSrceSizeInBytes;
sl@0
   394
	char* destPtrLimit = aDest + aDestSizeInBytes;
sl@0
   395
sl@0
   396
	while (aSrce < srcePtrLimit && aDest < destPtrLimit)
sl@0
   397
		{
sl@0
   398
		int runLength = *aSrce++;
sl@0
   399
sl@0
   400
		if (runLength >= 0)
sl@0
   401
			{
sl@0
   402
			char component1 = *aSrce++;
sl@0
   403
			char component2 = *aSrce++;
sl@0
   404
			char component3 = *aSrce++;
sl@0
   405
			for (runLength++; runLength > 0; runLength--)
sl@0
   406
				{
sl@0
   407
				*aDest++ = component1;
sl@0
   408
				*aDest++ = component2;
sl@0
   409
				*aDest++ = component3;
sl@0
   410
				aDest++;
sl@0
   411
				}
sl@0
   412
			}
sl@0
   413
		else 
sl@0
   414
			{
sl@0
   415
			runLength = -runLength;
sl@0
   416
			for(int ii = 0; ii < runLength; ii++)
sl@0
   417
				{
sl@0
   418
				memcpy(aDest,aSrce,3);
sl@0
   419
				aSrce += 3;
sl@0
   420
				aDest += 4;
sl@0
   421
				}
sl@0
   422
			}
sl@0
   423
		}
sl@0
   424
sl@0
   425
	if (aSrce != srcePtrLimit || aDest != destPtrLimit)
sl@0
   426
		return DecompressionError;
sl@0
   427
sl@0
   428
	return NoError;
sl@0
   429
	}
sl@0
   430
sl@0
   431
/** The function decodes 32-bit compressed pixel buffer into the 32-bit buffer, where top bytes are alpha channel*/
sl@0
   432
int EpocLoader::ExpandThirtyTwoABitRLEData(char* aDest,int aDestSizeInBytes,char* aSrce,int aSrceSizeInBytes)
sl@0
   433
	{
sl@0
   434
	char* srcePtrLimit = aSrce + aSrceSizeInBytes;
sl@0
   435
	char* destPtrLimit = aDest + aDestSizeInBytes;
sl@0
   436
sl@0
   437
	while (aSrce < srcePtrLimit && aDest < destPtrLimit)
sl@0
   438
		{
sl@0
   439
		int runLength = *aSrce++;
sl@0
   440
sl@0
   441
		if (runLength >= 0)
sl@0
   442
			{
sl@0
   443
			char component1 = *aSrce++;
sl@0
   444
			char component2 = *aSrce++;
sl@0
   445
			char component3 = *aSrce++;
sl@0
   446
			char component4 = *aSrce++;
sl@0
   447
			for (runLength++; runLength > 0; runLength--)
sl@0
   448
				{
sl@0
   449
				*aDest++ = component1;
sl@0
   450
				*aDest++ = component2;
sl@0
   451
				*aDest++ = component3;
sl@0
   452
				*aDest++ = component4;
sl@0
   453
				}
sl@0
   454
			}
sl@0
   455
		else 
sl@0
   456
			{
sl@0
   457
			runLength = -runLength;
sl@0
   458
			memcpy(aDest,aSrce,4*runLength);
sl@0
   459
			aSrce += 4*runLength;
sl@0
   460
			aDest += 4*runLength;
sl@0
   461
			}
sl@0
   462
		}
sl@0
   463
sl@0
   464
	if (aSrce != srcePtrLimit || aDest != destPtrLimit)
sl@0
   465
		return DecompressionError;
sl@0
   466
sl@0
   467
	return NoError;
sl@0
   468
	}
sl@0
   469
sl@0
   470
TRgb EpocLoader::GetPixel(int aXCoord,int aYCoord)
sl@0
   471
	{
sl@0
   472
	unsigned char col;
sl@0
   473
	aXCoord%=iPbmHeader.iWidthInPixels;
sl@0
   474
	aYCoord%=iPbmHeader.iHeightInPixels;
sl@0
   475
	int byteWidth = BitmapUtils::ByteWidth(iPbmHeader.iWidthInPixels,iPbmHeader.iBitsPerPixel);
sl@0
   476
	int yOffset = aYCoord * byteWidth;
sl@0
   477
sl@0
   478
	switch(iPbmHeader.iBitsPerPixel)
sl@0
   479
		{
sl@0
   480
		case 1:
sl@0
   481
			col = iPbmBits[yOffset + (aXCoord / 8)];
sl@0
   482
			col >>= (aXCoord&7);
sl@0
   483
			return TRgb::Gray2(col & 1);
sl@0
   484
		case 2:
sl@0
   485
			col = iPbmBits[yOffset + (aXCoord / 4)];
sl@0
   486
			col = (unsigned char)(col>>(2*(aXCoord%4)));
sl@0
   487
			return TRgb::Gray4(col & 3);
sl@0
   488
		case 4:
sl@0
   489
			col = iPbmBits[yOffset + (aXCoord / 2)];
sl@0
   490
			if (aXCoord & 1)
sl@0
   491
				col >>= 4;
sl@0
   492
			col &= 0xf;
sl@0
   493
			if (iPbmHeader.iColor==EColorBitmap)
sl@0
   494
				return TRgb::Color16(col);
sl@0
   495
			else
sl@0
   496
				return TRgb::Gray16(col);
sl@0
   497
		case 8:
sl@0
   498
			col=iPbmBits[yOffset + aXCoord];
sl@0
   499
			if (iPbmHeader.iColor==EColorBitmap)
sl@0
   500
				return TRgb::Color256(col);
sl@0
   501
			else
sl@0
   502
				return TRgb::Gray256(col);
sl@0
   503
		case 12:
sl@0
   504
		case 16:
sl@0
   505
			{
sl@0
   506
			unsigned short* shortPtr = (unsigned short*)&iPbmBits[yOffset + (aXCoord * 2)];
sl@0
   507
			if (iPbmHeader.iBitsPerPixel == 12)
sl@0
   508
				return TRgb::Color4K(*shortPtr);
sl@0
   509
			else
sl@0
   510
				return TRgb::Color64K(*shortPtr);
sl@0
   511
			}
sl@0
   512
		case 24:
sl@0
   513
			{
sl@0
   514
			char* pixelPtr = iPbmBits + yOffset + (aXCoord * 3);
sl@0
   515
			TRgb pixelColor;
sl@0
   516
			pixelColor.iBlue = *pixelPtr++;
sl@0
   517
			pixelColor.iGreen = *pixelPtr++;
sl@0
   518
			pixelColor.iRed = *pixelPtr;
sl@0
   519
			return pixelColor;
sl@0
   520
			}
sl@0
   521
		case 32:
sl@0
   522
			{
sl@0
   523
			char* pixelPtr = iPbmBits + yOffset + (aXCoord * 4);
sl@0
   524
			TRgb pixelColor;
sl@0
   525
			pixelColor.iBlue = *pixelPtr++;
sl@0
   526
			pixelColor.iGreen = *pixelPtr++;
sl@0
   527
			pixelColor.iRed = *pixelPtr++;
sl@0
   528
			pixelColor.iSpare = *pixelPtr;
sl@0
   529
			return pixelColor;
sl@0
   530
			}
sl@0
   531
		default:
sl@0
   532
			return TRgb(0);
sl@0
   533
		}
sl@0
   534
	}
sl@0
   535
sl@0
   536
unsigned char EpocLoader::GetAlpha(int aXCoord,int aYCoord)
sl@0
   537
	{
sl@0
   538
	aXCoord%=iPbmHeader.iWidthInPixels;
sl@0
   539
	aYCoord%=iPbmHeader.iHeightInPixels;
sl@0
   540
	int byteWidth = BitmapUtils::ByteWidth(iPbmHeader.iWidthInPixels,iPbmHeader.iBitsPerPixel);
sl@0
   541
	int yOffset = aYCoord * byteWidth;
sl@0
   542
sl@0
   543
	assert(iPbmHeader.iBitsPerPixel == 32); // this method must only be called for 32bpp bitmaps!
sl@0
   544
sl@0
   545
	char* pixelPtr = iPbmBits + yOffset + (aXCoord * 4);
sl@0
   546
	pixelPtr += 3; // skip over RGB
sl@0
   547
	unsigned char col = *pixelPtr;
sl@0
   548
	return col;	
sl@0
   549
	}
sl@0
   550
sl@0
   551
int EpocLoader::SaveBitmap(char* aFileName)
sl@0
   552
	{
sl@0
   553
	TBitmapFileHeader fileheader;
sl@0
   554
	TBitmapInfoHeader bmpHeader;
sl@0
   555
	char* bmpBits;
sl@0
   556
sl@0
   557
	bmpHeader.biSize = sizeof(TBitmapInfoHeader);
sl@0
   558
	bmpHeader.biWidth = iPbmHeader.iWidthInPixels;
sl@0
   559
	bmpHeader.biHeight = iPbmHeader.iHeightInPixels;
sl@0
   560
	bmpHeader.biPlanes = 1;
sl@0
   561
	bmpHeader.biBitCount = 24;
sl@0
   562
	bmpHeader.biCompression = 0;
sl@0
   563
	bmpHeader.biSizeImage = 0;
sl@0
   564
	bmpHeader.biXPelsPerMeter = 0;
sl@0
   565
	bmpHeader.biYPelsPerMeter = 0;
sl@0
   566
	bmpHeader.biClrUsed = 0;
sl@0
   567
	bmpHeader.biClrImportant = 0;
sl@0
   568
sl@0
   569
	long byteWidth = ((bmpHeader.biWidth * 3) + 3) & ~3;
sl@0
   570
	long destlength = bmpHeader.biHeight * byteWidth;
sl@0
   571
sl@0
   572
	fileheader.bfType = 'B'+('M'<<8);
sl@0
   573
	fileheader.bfSize = sizeof(TBitmapFileHeader)+sizeof(TBitmapInfoHeader)+destlength;
sl@0
   574
	fileheader.bfReserved1 = 0;
sl@0
   575
	fileheader.bfReserved2 = 0;
sl@0
   576
	fileheader.bfOffBits = sizeof(TBitmapFileHeader)+sizeof(TBitmapInfoHeader);
sl@0
   577
sl@0
   578
	bmpBits = new char[destlength];
sl@0
   579
	if (bmpBits == NULL)
sl@0
   580
		return NoMemory;
sl@0
   581
	memset(bmpBits,0xff,destlength);
sl@0
   582
sl@0
   583
	for(long y=0;y<bmpHeader.biHeight;y++)
sl@0
   584
		{
sl@0
   585
		char* dest=&bmpBits[(bmpHeader.biHeight-y-1)*byteWidth];
sl@0
   586
		for(long x=0;x<bmpHeader.biWidth;x++)
sl@0
   587
			{
sl@0
   588
			TRgb pixel=GetPixel(x,y);
sl@0
   589
			*dest++=pixel.iBlue;
sl@0
   590
			*dest++=pixel.iGreen;
sl@0
   591
			*dest++=pixel.iRed;
sl@0
   592
			}
sl@0
   593
		}
sl@0
   594
sl@0
   595
	fstream file(aFileName, ios::out | ios::binary);
sl@0
   596
sl@0
   597
	if (file.is_open()==0)
sl@0
   598
		{
sl@0
   599
		delete bmpBits;
sl@0
   600
		return DestFile;
sl@0
   601
		}
sl@0
   602
sl@0
   603
	file.write((char *)&fileheader,sizeof(TBitmapFileHeader));
sl@0
   604
	file.write((char *)&bmpHeader,sizeof(TBitmapInfoHeader));
sl@0
   605
	file.write((char *)bmpBits,destlength);
sl@0
   606
	file.close();
sl@0
   607
sl@0
   608
	delete bmpBits;
sl@0
   609
sl@0
   610
	if (iPbmHeader.iColor == EColorBitmapAlpha || iPbmHeader.iColor ==EColorBitmapAlphaPM)
sl@0
   611
		SaveAlpha(aFileName);
sl@0
   612
	return NoError;
sl@0
   613
	}
sl@0
   614
sl@0
   615
sl@0
   616
int EpocLoader::SaveAlpha(char* aFileName)
sl@0
   617
	{
sl@0
   618
	TBitmapFileHeader fileheader;
sl@0
   619
	TBitmapInfoHeader alphaHeader;
sl@0
   620
sl@0
   621
	alphaHeader.biSize = sizeof(TBitmapInfoHeader);
sl@0
   622
	alphaHeader.biWidth = iPbmHeader.iWidthInPixels;
sl@0
   623
	alphaHeader.biHeight = iPbmHeader.iHeightInPixels;
sl@0
   624
	alphaHeader.biPlanes = 1;
sl@0
   625
	alphaHeader.biBitCount = 8;
sl@0
   626
	alphaHeader.biCompression = 0;
sl@0
   627
	alphaHeader.biSizeImage = 0;
sl@0
   628
	alphaHeader.biXPelsPerMeter = 0;
sl@0
   629
	alphaHeader.biYPelsPerMeter = 0;
sl@0
   630
	alphaHeader.biClrUsed = 256;
sl@0
   631
	alphaHeader.biClrImportant = 0;
sl@0
   632
sl@0
   633
	const long paletteSize = 1024;
sl@0
   634
sl@0
   635
	// ensure bytes-per-scanline is a large enough multiple of 4
sl@0
   636
	long byteWidth = (alphaHeader.biWidth + 3) & ~3; 
sl@0
   637
	long destlength = alphaHeader.biHeight * byteWidth;
sl@0
   638
	alphaHeader.biSizeImage = destlength;
sl@0
   639
sl@0
   640
	fileheader.bfType = 'B'+('M'<<8);
sl@0
   641
	fileheader.bfSize = sizeof(TBitmapFileHeader)+sizeof(TBitmapInfoHeader)+paletteSize+destlength;
sl@0
   642
	fileheader.bfReserved1 = 0;
sl@0
   643
	fileheader.bfReserved2 = 0;
sl@0
   644
	fileheader.bfOffBits = sizeof(TBitmapFileHeader)+sizeof(TBitmapInfoHeader)+paletteSize;
sl@0
   645
sl@0
   646
	// we need to output the grayscale palette before the actual alpha data as this is an 8bpp BMP
sl@0
   647
	char* palette = new char[paletteSize]; // 256 colors x 4bytes/color (r,g,b,unused)
sl@0
   648
	if (palette == NULL)
sl@0
   649
		return NoMemory;
sl@0
   650
	memset(palette,0,paletteSize);
sl@0
   651
	char* pEnt = palette;
sl@0
   652
	for (long p=0;p<256;++p)
sl@0
   653
		{
sl@0
   654
		unsigned char col = (unsigned char)p;
sl@0
   655
		*pEnt++=col;
sl@0
   656
		*pEnt++=col;
sl@0
   657
		*pEnt++=col;
sl@0
   658
		pEnt++;
sl@0
   659
		}
sl@0
   660
sl@0
   661
	char* alphaBits = new char[destlength];
sl@0
   662
	if (alphaBits == NULL)
sl@0
   663
		{
sl@0
   664
		delete [] palette;
sl@0
   665
		return NoMemory;
sl@0
   666
		}
sl@0
   667
	memset(alphaBits,0,destlength);
sl@0
   668
sl@0
   669
	for(long y=0;y<alphaHeader.biHeight;y++)
sl@0
   670
		{
sl@0
   671
		char* dest=&alphaBits[(alphaHeader.biHeight-y-1)*byteWidth];
sl@0
   672
		for(long x=0;x<alphaHeader.biWidth;x++)
sl@0
   673
			{
sl@0
   674
			unsigned char alphaVal=GetAlpha(x,y);
sl@0
   675
			*dest++=alphaVal;
sl@0
   676
			}
sl@0
   677
		}
sl@0
   678
sl@0
   679
	int fileNameLen = strlen(aFileName);
sl@0
   680
	char* alphaFileName = new char[fileNameLen + 7];// -alpha suffix is 6 chars, plus NUL termination
sl@0
   681
	if (alphaFileName == NULL)
sl@0
   682
		{
sl@0
   683
		delete [] palette;
sl@0
   684
		delete [] alphaBits;
sl@0
   685
		return NoMemory;
sl@0
   686
		}
sl@0
   687
	int dotPos = -1;
sl@0
   688
	for (int i = 0; i < fileNameLen; ++i)
sl@0
   689
		if (aFileName[i]=='.')
sl@0
   690
			dotPos=i;
sl@0
   691
	int prefixLen = (dotPos>=0?dotPos:fileNameLen);
sl@0
   692
	memcpy(alphaFileName,aFileName,prefixLen);
sl@0
   693
	const char* suffix = "-alpha";
sl@0
   694
	memcpy(alphaFileName+prefixLen,suffix,6);
sl@0
   695
	if (dotPos>=0)
sl@0
   696
		memcpy(alphaFileName+prefixLen+6,aFileName+dotPos,fileNameLen-dotPos);
sl@0
   697
	*(alphaFileName + fileNameLen + 6) = '\0';
sl@0
   698
	fstream file(alphaFileName, ios::out | ios::binary);
sl@0
   699
	if (file.is_open()==0)
sl@0
   700
		{
sl@0
   701
		delete [] alphaFileName;
sl@0
   702
		delete [] alphaBits;
sl@0
   703
		delete [] palette;
sl@0
   704
		return DestFile;
sl@0
   705
		}
sl@0
   706
sl@0
   707
	file.write((char *)&fileheader,sizeof(TBitmapFileHeader));
sl@0
   708
	file.write((char *)&alphaHeader,sizeof(TBitmapInfoHeader));
sl@0
   709
	file.write((char *)palette,paletteSize);
sl@0
   710
	file.write((char *)alphaBits,destlength);
sl@0
   711
	file.close();
sl@0
   712
sl@0
   713
	delete [] alphaFileName;
sl@0
   714
	delete [] alphaBits;
sl@0
   715
	delete [] palette;
sl@0
   716
	return NoError;
sl@0
   717
	}
sl@0
   718
sl@0
   719
int EpocLoader::DupBitmap(SEpocBitmapHeader*& aPbm)
sl@0
   720
	{
sl@0
   721
	char* newPbm = new char[iPbmHeader.iBitmapSize];
sl@0
   722
	if (newPbm == NULL)
sl@0
   723
		return NoMemory;
sl@0
   724
	memcpy(newPbm, &iPbmHeader, sizeof(SEpocBitmapHeader));
sl@0
   725
	memcpy(newPbm+sizeof(SEpocBitmapHeader), iPbmBits, iPbmHeader.iBitmapSize - sizeof(SEpocBitmapHeader));
sl@0
   726
	aPbm = (SEpocBitmapHeader*)newPbm;
sl@0
   727
	return NoError;
sl@0
   728
	}
sl@0
   729
sl@0
   730
/**
sl@0
   731
Validates an mbm files bitmap information to ensure that the length of each bitmaps matches their location
sl@0
   732
within the file. Also checks that the number of bitmap offsets available matches the number of bitmaps.
sl@0
   733
sl@0
   734
@param aFilename The mbm file to be validated
sl@0
   735
@return An error code from the Errors enumeration
sl@0
   736
 */
sl@0
   737
int EpocLoader::ValidateEpocBitmap(char* aFilename)
sl@0
   738
	{
sl@0
   739
#if defined(__MSVCDOTNET__) || defined(__TOOLS2__)
sl@0
   740
	fstream file(aFilename, ios::in | ios::binary);
sl@0
   741
#else //!__MSVCDOTNET__
sl@0
   742
	fstream file(aFilename, ios::in | ios::binary | ios::nocreate);
sl@0
   743
#endif //__MSVCDOTNET__
sl@0
   744
	if (file.is_open()==0)
sl@0
   745
		return Files;
sl@0
   746
sl@0
   747
	long int wordbuffer;
sl@0
   748
	int isRomFormat;
sl@0
   749
	
sl@0
   750
	file.read((char *)&wordbuffer,4);
sl@0
   751
	if (file.gcount()!=4)
sl@0
   752
		return SourceFile;
sl@0
   753
	if (wordbuffer==KMultiBitmapRomImageUid)
sl@0
   754
		{
sl@0
   755
		//Validation not implemented for ROM only files.
sl@0
   756
		}
sl@0
   757
	else
sl@0
   758
		{
sl@0
   759
		if (wordbuffer!=KWriteOnceFileStoreUid)
sl@0
   760
			return SourceFile;
sl@0
   761
		isRomFormat=0;
sl@0
   762
		file.read((char *)&wordbuffer,4);
sl@0
   763
		if (file.gcount()!=4 || wordbuffer!=KMultiBitmapFileImageUid)
sl@0
   764
			return SourceFile;
sl@0
   765
		file.read((char *)&wordbuffer,4);
sl@0
   766
		if (file.gcount()!=4 || wordbuffer!=0)
sl@0
   767
			return SourceFile;
sl@0
   768
		file.read((char *)&wordbuffer,4);
sl@0
   769
		if (file.gcount()!=4 || wordbuffer!=KMultiBitmapFileImageChecksum)
sl@0
   770
			return SourceFile;
sl@0
   771
		file.read((char *)&wordbuffer,4);
sl@0
   772
		if (file.gcount()!=4)
sl@0
   773
			return SourceFile;
sl@0
   774
		//The 5th byte is a pointer to the footer containing the number of bitmaps
sl@0
   775
		//and the offset from the beginning of the file each begins at.
sl@0
   776
		int footerPos = wordbuffer;
sl@0
   777
		
sl@0
   778
		file.seekg(footerPos,ios::beg);
sl@0
   779
		
sl@0
   780
		file.read((char *)&wordbuffer, 4);
sl@0
   781
		if (file.gcount()!=4)
sl@0
   782
			return SourceFile;
sl@0
   783
		
sl@0
   784
		int numBitmaps = wordbuffer;
sl@0
   785
sl@0
   786
		int bmpOffset[numBitmaps+1];
sl@0
   787
		
sl@0
   788
		for (int i = 0; i < numBitmaps; i++)
sl@0
   789
			{
sl@0
   790
			file.read((char *)&wordbuffer,4);
sl@0
   791
					if (file.gcount()!=4)
sl@0
   792
						return SourceFile;
sl@0
   793
			bmpOffset[i] = wordbuffer;
sl@0
   794
			}
sl@0
   795
		
sl@0
   796
		//The byte at the end of the last bitmap is the location of the footer
sl@0
   797
		bmpOffset[numBitmaps] = footerPos;
sl@0
   798
		
sl@0
   799
		//Check length of a bitmap is reflected in the difference between the offsets
sl@0
   800
		for (int i = 0 ; i < numBitmaps ; i++)
sl@0
   801
			{
sl@0
   802
			file.seekg(bmpOffset[i]);
sl@0
   803
			
sl@0
   804
			//Read the length of this bitmap
sl@0
   805
			file.read((char *)&wordbuffer,4);
sl@0
   806
				if (file.gcount()!=4)
sl@0
   807
					return SourceFile;
sl@0
   808
sl@0
   809
			//Validate length against offsets of this & next bmp
sl@0
   810
			if (bmpOffset[i+1]-wordbuffer != bmpOffset[i])
sl@0
   811
				return SourceFile;
sl@0
   812
			}
sl@0
   813
		}
sl@0
   814
	return NoError;
sl@0
   815
	}