sl@0: // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include "BMCONV.H" sl@0: sl@0: EpocLoader::EpocLoader(): sl@0: iPbmBits(NULL) sl@0: {} sl@0: sl@0: EpocLoader::~EpocLoader() sl@0: { sl@0: delete iPbmBits; sl@0: } sl@0: sl@0: int EpocLoader::EpocBitmapCount(char* aFileName, int& aCount, int& isRomFormat) sl@0: { sl@0: #if defined(__MSVCDOTNET__) || defined(__TOOLS2__) sl@0: fstream file(aFileName, ios::in | ios::binary); sl@0: #else //!__MSVCDOTNET__ sl@0: fstream file(aFileName, ios::in | ios::binary | ios::nocreate); sl@0: #endif //__MSVCDOTNET__ sl@0: sl@0: if (file.is_open()==0) sl@0: return Files; sl@0: sl@0: long int wordbuffer; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4) sl@0: return SourceFile; sl@0: if (wordbuffer==KMultiBitmapRomImageUid) sl@0: { sl@0: // ROM format file - next 4 bytes are the number of bitmaps sl@0: isRomFormat=1; sl@0: } sl@0: else sl@0: { sl@0: if (wordbuffer!=KWriteOnceFileStoreUid) sl@0: return SourceFile; sl@0: isRomFormat=0; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4 || wordbuffer!=KMultiBitmapFileImageUid) sl@0: return SourceFile; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4 || wordbuffer!=0) sl@0: return SourceFile; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4 || wordbuffer!=KMultiBitmapFileImageChecksum) sl@0: return SourceFile; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4) sl@0: return SourceFile; sl@0: file.seekg(wordbuffer,ios::beg); sl@0: } sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4) sl@0: return SourceFile; sl@0: aCount=wordbuffer; sl@0: return NoError; sl@0: } sl@0: sl@0: int EpocLoader::LoadEpocBitmap(char* aFileName,int aIndex) sl@0: { sl@0: #if defined(__MSVCDOTNET__) || defined(__TOOLS2__) sl@0: fstream file(aFileName, ios::in | ios::binary); sl@0: #else //!__MSVCDOTNET__ sl@0: fstream file(aFileName, ios::in | ios::binary | ios::nocreate); sl@0: #endif //__MSVCDOTNET__ sl@0: sl@0: if (file.is_open()==0) sl@0: return Files; sl@0: sl@0: long int wordbuffer; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4) sl@0: return SourceFile; sl@0: file.close(); sl@0: sl@0: if (wordbuffer==KMultiBitmapRomImageUid) sl@0: return LoadRom(aFileName,aIndex); sl@0: sl@0: return LoadFile(aFileName,aIndex); sl@0: } sl@0: sl@0: int EpocLoader::LoadFile(char* aFileName,int aIndex) sl@0: { sl@0: #if defined(__MSVCDOTNET__) || defined(__TOOLS2__) sl@0: fstream file(aFileName, ios::in | ios::binary); sl@0: #else //!__MSVCDOTNET__ sl@0: fstream file(aFileName, ios::in | ios::binary | ios::nocreate); sl@0: #endif //__MSVCDOTNET__ sl@0: sl@0: if (file.is_open()==0) sl@0: return Files; sl@0: sl@0: long int wordbuffer; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4 || wordbuffer!=KWriteOnceFileStoreUid) sl@0: return SourceFile; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4 || wordbuffer!=KMultiBitmapFileImageUid) sl@0: return SourceFile; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4 || wordbuffer!=0) sl@0: return SourceFile; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4 || wordbuffer!=KMultiBitmapFileImageChecksum) sl@0: return SourceFile; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4) sl@0: return SourceFile; sl@0: file.seekg(wordbuffer,ios::beg); sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4) sl@0: return SourceFile; sl@0: sl@0: int numsources=wordbuffer; sl@0: if (aIndex >= numsources) sl@0: return OutOfRange; sl@0: file.seekg(aIndex*4,ios::cur); sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4) sl@0: return SourceFile; sl@0: file.seekg(wordbuffer,ios::beg); sl@0: int ret = DoLoadFile(file); sl@0: file.close(); sl@0: return ret; sl@0: } sl@0: sl@0: int EpocLoader::LoadRom(char* aFileName,int aIndex) sl@0: { sl@0: #if defined(__MSVCDOTNET__) || defined(__TOOLS2__) sl@0: fstream file(aFileName, ios::in | ios::binary); sl@0: #else //!__MSVCDOTNET__ sl@0: fstream file(aFileName, ios::in | ios::binary | ios::nocreate); sl@0: #endif //__MSVCDOTNET__ sl@0: sl@0: if (file.is_open()==0) sl@0: return Files; sl@0: sl@0: long int wordbuffer; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4) sl@0: return SourceFile; sl@0: if (wordbuffer!=KMultiBitmapRomImageUid) sl@0: return SourceFile; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4) sl@0: return SourceFile; sl@0: if (aIndex>=wordbuffer) sl@0: return OutOfRange; sl@0: file.seekg(aIndex*4,ios::cur); sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4) sl@0: return SourceFile; sl@0: file.seekg(wordbuffer,ios::beg); sl@0: int ret=DoLoadRom(file); sl@0: file.close(); sl@0: return ret; sl@0: } sl@0: sl@0: int EpocLoader::DoLoadFile(fstream& aFile) sl@0: { sl@0: long size = sizeof(SEpocBitmapHeader); sl@0: aFile.read((char *)&iPbmHeader,size); sl@0: if (aFile.gcount()!=size) sl@0: return SourceFile; sl@0: iOriginalPbmHeader = iPbmHeader; sl@0: size=iPbmHeader.iBitmapSize-iPbmHeader.iStructSize; sl@0: sl@0: iPbmBits=new char[size]; sl@0: if (iPbmBits==NULL) sl@0: return NoMemory; sl@0: memset(iPbmBits,0xff,size); sl@0: aFile.read(iPbmBits,size); sl@0: aFile.close(); sl@0: if (aFile.gcount() != size) sl@0: return SourceFile; sl@0: sl@0: if (iPbmHeader.iCompression != ENoBitmapCompression) sl@0: { sl@0: return Decompress(size); sl@0: } sl@0: sl@0: return NoError; sl@0: } sl@0: sl@0: int EpocLoader::DoLoadRom(fstream& aFile) sl@0: { sl@0: Bitmap bmp; sl@0: long size=sizeof(Bitmap); sl@0: aFile.read((char*)&bmp,size); sl@0: if (aFile.gcount() != size) sl@0: return SourceFile; sl@0: sl@0: size = bmp.iHeader.iBitmapSize - sizeof(SEpocBitmapHeader); sl@0: iPbmBits = new char[size]; sl@0: if (iPbmBits == NULL) sl@0: return NoMemory; sl@0: memset(iPbmBits,0xff,size); sl@0: sl@0: aFile.read(iPbmBits,size); sl@0: if (aFile.gcount() != size) sl@0: return SourceFile; sl@0: iPbmHeader = bmp.iHeader; sl@0: iOriginalPbmHeader = iPbmHeader; sl@0: sl@0: if (iPbmHeader.iCompression != ENoBitmapCompression) sl@0: { sl@0: return Decompress(size); sl@0: } sl@0: sl@0: return NoError; sl@0: } sl@0: sl@0: int EpocLoader::Decompress(int aSize) sl@0: { sl@0: int byteWidth = BitmapUtils::ByteWidth(iPbmHeader.iWidthInPixels,iPbmHeader.iBitsPerPixel); sl@0: int expandedsize = byteWidth * iPbmHeader.iHeightInPixels; sl@0: char* newbits = new char[expandedsize]; sl@0: if (newbits == NULL) sl@0: return NoMemory; sl@0: memset(newbits,0xff,expandedsize); sl@0: int ret = NoError; sl@0: switch (iPbmHeader.iCompression) sl@0: { sl@0: case EByteRLECompression: sl@0: ret = ExpandByteRLEData(newbits,expandedsize,iPbmBits,aSize); sl@0: break; sl@0: case ETwelveBitRLECompression: sl@0: ret = ExpandTwelveBitRLEData(newbits,expandedsize,iPbmBits,aSize); sl@0: break; sl@0: case ESixteenBitRLECompression: sl@0: ret = ExpandSixteenBitRLEData(newbits,expandedsize,iPbmBits,aSize); sl@0: break; sl@0: case ETwentyFourBitRLECompression: sl@0: ret = ExpandTwentyFourBitRLEData(newbits,expandedsize,iPbmBits,aSize); sl@0: break; sl@0: case EThirtyTwoUBitRLECompression: sl@0: ret = ExpandThirtyTwoUBitRLEData(newbits,expandedsize,iPbmBits,aSize); sl@0: break; sl@0: case EThirtyTwoABitRLECompression: sl@0: ret = ExpandThirtyTwoABitRLEData(newbits,expandedsize,iPbmBits,aSize); sl@0: break; sl@0: default: sl@0: ret = UnknownCompression; sl@0: break; sl@0: } sl@0: delete iPbmBits; sl@0: iPbmBits = newbits; sl@0: iPbmHeader.iCompression = ENoBitmapCompression; sl@0: iPbmHeader.iBitmapSize += expandedsize-aSize; sl@0: return ret; sl@0: } sl@0: sl@0: int EpocLoader::ExpandByteRLEData(char* aDest,int aDestSize,char* aSrce,int aSrceSize) sl@0: { sl@0: char* srcelimit=aSrce+aSrceSize; sl@0: char* destlimit=aDest+aDestSize; sl@0: while(aSrce=0) sl@0: { sl@0: *aDest++=value; sl@0: count--; sl@0: } sl@0: } sl@0: } sl@0: if (aSrce!=srcelimit || aDest!=destlimit) sl@0: return DecompressionError; sl@0: return NoError; sl@0: } sl@0: sl@0: int EpocLoader::ExpandTwelveBitRLEData(char* aDest,int aDestSizeInBytes,char* aSrce,int aSrceSizeInBytes) sl@0: { sl@0: unsigned short* srcePtr = (unsigned short*)aSrce; sl@0: unsigned short* destPtr = (unsigned short*)aDest; sl@0: unsigned short* srcePtrLimit = srcePtr + (aSrceSizeInBytes / 2); sl@0: unsigned short* destPtrLimit = destPtr + (aDestSizeInBytes / 2); sl@0: sl@0: while (srcePtr < srcePtrLimit && destPtr < destPtrLimit) sl@0: { sl@0: unsigned short value = *srcePtr++; sl@0: int runLength = (value >> 12) + 1; sl@0: value &= 0x0fff; sl@0: sl@0: for (;runLength > 0;runLength--) sl@0: *destPtr++ = value; sl@0: } sl@0: sl@0: if (srcePtr != srcePtrLimit || destPtr != destPtrLimit) sl@0: return DecompressionError; sl@0: sl@0: return NoError; sl@0: } sl@0: sl@0: int EpocLoader::ExpandSixteenBitRLEData(char* aDest,int aDestSizeInBytes,char* aSrce,int aSrceSizeInBytes) sl@0: { sl@0: char* srcePtrLimit = aSrce + aSrceSizeInBytes; sl@0: unsigned short* destPtr = (unsigned short*)aDest; sl@0: unsigned short* destPtrLimit = destPtr + (aDestSizeInBytes / 2); sl@0: sl@0: while (aSrce < srcePtrLimit && destPtr < destPtrLimit) sl@0: { sl@0: int runLength = *aSrce++; sl@0: sl@0: if (runLength >= 0) sl@0: { sl@0: unsigned short value = *((unsigned short*)(aSrce)); sl@0: aSrce += 2; sl@0: for (runLength++; runLength > 0; runLength--) sl@0: *destPtr++ = value; sl@0: } sl@0: else sl@0: { sl@0: runLength = -runLength; sl@0: int byteLength = runLength * 2; sl@0: memcpy(destPtr,aSrce,byteLength); sl@0: aSrce += byteLength; sl@0: destPtr += runLength; sl@0: } sl@0: } sl@0: sl@0: if (aSrce != srcePtrLimit || destPtr != destPtrLimit) sl@0: return DecompressionError; sl@0: sl@0: return NoError; sl@0: } sl@0: sl@0: int EpocLoader::ExpandTwentyFourBitRLEData(char* aDest,int aDestSizeInBytes,char* aSrce,int aSrceSizeInBytes) sl@0: { sl@0: char* srcePtrLimit = aSrce + aSrceSizeInBytes; sl@0: char* destPtrLimit = aDest + aDestSizeInBytes; sl@0: sl@0: while (aSrce < srcePtrLimit && aDest < destPtrLimit) sl@0: { sl@0: int runLength = *aSrce++; sl@0: sl@0: if (runLength >= 0) sl@0: { sl@0: char component1 = *aSrce++; sl@0: char component2 = *aSrce++; sl@0: char component3 = *aSrce++; sl@0: for (runLength++; runLength > 0; runLength--) sl@0: { sl@0: *aDest++ = component1; sl@0: *aDest++ = component2; sl@0: *aDest++ = component3; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: runLength = -runLength; sl@0: int byteLength = runLength * 3; sl@0: memcpy(aDest,aSrce,byteLength); sl@0: aSrce += byteLength; sl@0: aDest += byteLength; sl@0: } sl@0: } sl@0: sl@0: if (aSrce != srcePtrLimit || aDest != destPtrLimit) sl@0: return DecompressionError; sl@0: sl@0: return NoError; sl@0: } sl@0: sl@0: /** The function decodes 24-bit compressed pixel buffer into the 32-bit buffer, where top bytes are unused*/ sl@0: int EpocLoader::ExpandThirtyTwoUBitRLEData(char* aDest,int aDestSizeInBytes,char* aSrce,int aSrceSizeInBytes) sl@0: { sl@0: char* srcePtrLimit = aSrce + aSrceSizeInBytes; sl@0: char* destPtrLimit = aDest + aDestSizeInBytes; sl@0: sl@0: while (aSrce < srcePtrLimit && aDest < destPtrLimit) sl@0: { sl@0: int runLength = *aSrce++; sl@0: sl@0: if (runLength >= 0) sl@0: { sl@0: char component1 = *aSrce++; sl@0: char component2 = *aSrce++; sl@0: char component3 = *aSrce++; sl@0: for (runLength++; runLength > 0; runLength--) sl@0: { sl@0: *aDest++ = component1; sl@0: *aDest++ = component2; sl@0: *aDest++ = component3; sl@0: aDest++; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: runLength = -runLength; sl@0: for(int ii = 0; ii < runLength; ii++) sl@0: { sl@0: memcpy(aDest,aSrce,3); sl@0: aSrce += 3; sl@0: aDest += 4; sl@0: } sl@0: } sl@0: } sl@0: sl@0: if (aSrce != srcePtrLimit || aDest != destPtrLimit) sl@0: return DecompressionError; sl@0: sl@0: return NoError; sl@0: } sl@0: sl@0: /** The function decodes 32-bit compressed pixel buffer into the 32-bit buffer, where top bytes are alpha channel*/ sl@0: int EpocLoader::ExpandThirtyTwoABitRLEData(char* aDest,int aDestSizeInBytes,char* aSrce,int aSrceSizeInBytes) sl@0: { sl@0: char* srcePtrLimit = aSrce + aSrceSizeInBytes; sl@0: char* destPtrLimit = aDest + aDestSizeInBytes; sl@0: sl@0: while (aSrce < srcePtrLimit && aDest < destPtrLimit) sl@0: { sl@0: int runLength = *aSrce++; sl@0: sl@0: if (runLength >= 0) sl@0: { sl@0: char component1 = *aSrce++; sl@0: char component2 = *aSrce++; sl@0: char component3 = *aSrce++; sl@0: char component4 = *aSrce++; sl@0: for (runLength++; runLength > 0; runLength--) sl@0: { sl@0: *aDest++ = component1; sl@0: *aDest++ = component2; sl@0: *aDest++ = component3; sl@0: *aDest++ = component4; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: runLength = -runLength; sl@0: memcpy(aDest,aSrce,4*runLength); sl@0: aSrce += 4*runLength; sl@0: aDest += 4*runLength; sl@0: } sl@0: } sl@0: sl@0: if (aSrce != srcePtrLimit || aDest != destPtrLimit) sl@0: return DecompressionError; sl@0: sl@0: return NoError; sl@0: } sl@0: sl@0: TRgb EpocLoader::GetPixel(int aXCoord,int aYCoord) sl@0: { sl@0: unsigned char col; sl@0: aXCoord%=iPbmHeader.iWidthInPixels; sl@0: aYCoord%=iPbmHeader.iHeightInPixels; sl@0: int byteWidth = BitmapUtils::ByteWidth(iPbmHeader.iWidthInPixels,iPbmHeader.iBitsPerPixel); sl@0: int yOffset = aYCoord * byteWidth; sl@0: sl@0: switch(iPbmHeader.iBitsPerPixel) sl@0: { sl@0: case 1: sl@0: col = iPbmBits[yOffset + (aXCoord / 8)]; sl@0: col >>= (aXCoord&7); sl@0: return TRgb::Gray2(col & 1); sl@0: case 2: sl@0: col = iPbmBits[yOffset + (aXCoord / 4)]; sl@0: col = (unsigned char)(col>>(2*(aXCoord%4))); sl@0: return TRgb::Gray4(col & 3); sl@0: case 4: sl@0: col = iPbmBits[yOffset + (aXCoord / 2)]; sl@0: if (aXCoord & 1) sl@0: col >>= 4; sl@0: col &= 0xf; sl@0: if (iPbmHeader.iColor==EColorBitmap) sl@0: return TRgb::Color16(col); sl@0: else sl@0: return TRgb::Gray16(col); sl@0: case 8: sl@0: col=iPbmBits[yOffset + aXCoord]; sl@0: if (iPbmHeader.iColor==EColorBitmap) sl@0: return TRgb::Color256(col); sl@0: else sl@0: return TRgb::Gray256(col); sl@0: case 12: sl@0: case 16: sl@0: { sl@0: unsigned short* shortPtr = (unsigned short*)&iPbmBits[yOffset + (aXCoord * 2)]; sl@0: if (iPbmHeader.iBitsPerPixel == 12) sl@0: return TRgb::Color4K(*shortPtr); sl@0: else sl@0: return TRgb::Color64K(*shortPtr); sl@0: } sl@0: case 24: sl@0: { sl@0: char* pixelPtr = iPbmBits + yOffset + (aXCoord * 3); sl@0: TRgb pixelColor; sl@0: pixelColor.iBlue = *pixelPtr++; sl@0: pixelColor.iGreen = *pixelPtr++; sl@0: pixelColor.iRed = *pixelPtr; sl@0: return pixelColor; sl@0: } sl@0: case 32: sl@0: { sl@0: char* pixelPtr = iPbmBits + yOffset + (aXCoord * 4); sl@0: TRgb pixelColor; sl@0: pixelColor.iBlue = *pixelPtr++; sl@0: pixelColor.iGreen = *pixelPtr++; sl@0: pixelColor.iRed = *pixelPtr++; sl@0: pixelColor.iSpare = *pixelPtr; sl@0: return pixelColor; sl@0: } sl@0: default: sl@0: return TRgb(0); sl@0: } sl@0: } sl@0: sl@0: unsigned char EpocLoader::GetAlpha(int aXCoord,int aYCoord) sl@0: { sl@0: aXCoord%=iPbmHeader.iWidthInPixels; sl@0: aYCoord%=iPbmHeader.iHeightInPixels; sl@0: int byteWidth = BitmapUtils::ByteWidth(iPbmHeader.iWidthInPixels,iPbmHeader.iBitsPerPixel); sl@0: int yOffset = aYCoord * byteWidth; sl@0: sl@0: assert(iPbmHeader.iBitsPerPixel == 32); // this method must only be called for 32bpp bitmaps! sl@0: sl@0: char* pixelPtr = iPbmBits + yOffset + (aXCoord * 4); sl@0: pixelPtr += 3; // skip over RGB sl@0: unsigned char col = *pixelPtr; sl@0: return col; sl@0: } sl@0: sl@0: int EpocLoader::SaveBitmap(char* aFileName) sl@0: { sl@0: TBitmapFileHeader fileheader; sl@0: TBitmapInfoHeader bmpHeader; sl@0: char* bmpBits; sl@0: sl@0: bmpHeader.biSize = sizeof(TBitmapInfoHeader); sl@0: bmpHeader.biWidth = iPbmHeader.iWidthInPixels; sl@0: bmpHeader.biHeight = iPbmHeader.iHeightInPixels; sl@0: bmpHeader.biPlanes = 1; sl@0: bmpHeader.biBitCount = 24; sl@0: bmpHeader.biCompression = 0; sl@0: bmpHeader.biSizeImage = 0; sl@0: bmpHeader.biXPelsPerMeter = 0; sl@0: bmpHeader.biYPelsPerMeter = 0; sl@0: bmpHeader.biClrUsed = 0; sl@0: bmpHeader.biClrImportant = 0; sl@0: sl@0: long byteWidth = ((bmpHeader.biWidth * 3) + 3) & ~3; sl@0: long destlength = bmpHeader.biHeight * byteWidth; sl@0: sl@0: fileheader.bfType = 'B'+('M'<<8); sl@0: fileheader.bfSize = sizeof(TBitmapFileHeader)+sizeof(TBitmapInfoHeader)+destlength; sl@0: fileheader.bfReserved1 = 0; sl@0: fileheader.bfReserved2 = 0; sl@0: fileheader.bfOffBits = sizeof(TBitmapFileHeader)+sizeof(TBitmapInfoHeader); sl@0: sl@0: bmpBits = new char[destlength]; sl@0: if (bmpBits == NULL) sl@0: return NoMemory; sl@0: memset(bmpBits,0xff,destlength); sl@0: sl@0: for(long y=0;y=0?dotPos:fileNameLen); sl@0: memcpy(alphaFileName,aFileName,prefixLen); sl@0: const char* suffix = "-alpha"; sl@0: memcpy(alphaFileName+prefixLen,suffix,6); sl@0: if (dotPos>=0) sl@0: memcpy(alphaFileName+prefixLen+6,aFileName+dotPos,fileNameLen-dotPos); sl@0: *(alphaFileName + fileNameLen + 6) = '\0'; sl@0: fstream file(alphaFileName, ios::out | ios::binary); sl@0: if (file.is_open()==0) sl@0: { sl@0: delete [] alphaFileName; sl@0: delete [] alphaBits; sl@0: delete [] palette; sl@0: return DestFile; sl@0: } sl@0: sl@0: file.write((char *)&fileheader,sizeof(TBitmapFileHeader)); sl@0: file.write((char *)&alphaHeader,sizeof(TBitmapInfoHeader)); sl@0: file.write((char *)palette,paletteSize); sl@0: file.write((char *)alphaBits,destlength); sl@0: file.close(); sl@0: sl@0: delete [] alphaFileName; sl@0: delete [] alphaBits; sl@0: delete [] palette; sl@0: return NoError; sl@0: } sl@0: sl@0: int EpocLoader::DupBitmap(SEpocBitmapHeader*& aPbm) sl@0: { sl@0: char* newPbm = new char[iPbmHeader.iBitmapSize]; sl@0: if (newPbm == NULL) sl@0: return NoMemory; sl@0: memcpy(newPbm, &iPbmHeader, sizeof(SEpocBitmapHeader)); sl@0: memcpy(newPbm+sizeof(SEpocBitmapHeader), iPbmBits, iPbmHeader.iBitmapSize - sizeof(SEpocBitmapHeader)); sl@0: aPbm = (SEpocBitmapHeader*)newPbm; sl@0: return NoError; sl@0: } sl@0: sl@0: /** sl@0: Validates an mbm files bitmap information to ensure that the length of each bitmaps matches their location sl@0: within the file. Also checks that the number of bitmap offsets available matches the number of bitmaps. sl@0: sl@0: @param aFilename The mbm file to be validated sl@0: @return An error code from the Errors enumeration sl@0: */ sl@0: int EpocLoader::ValidateEpocBitmap(char* aFilename) sl@0: { sl@0: #if defined(__MSVCDOTNET__) || defined(__TOOLS2__) sl@0: fstream file(aFilename, ios::in | ios::binary); sl@0: #else //!__MSVCDOTNET__ sl@0: fstream file(aFilename, ios::in | ios::binary | ios::nocreate); sl@0: #endif //__MSVCDOTNET__ sl@0: if (file.is_open()==0) sl@0: return Files; sl@0: sl@0: long int wordbuffer; sl@0: int isRomFormat; sl@0: sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4) sl@0: return SourceFile; sl@0: if (wordbuffer==KMultiBitmapRomImageUid) sl@0: { sl@0: //Validation not implemented for ROM only files. sl@0: } sl@0: else sl@0: { sl@0: if (wordbuffer!=KWriteOnceFileStoreUid) sl@0: return SourceFile; sl@0: isRomFormat=0; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4 || wordbuffer!=KMultiBitmapFileImageUid) sl@0: return SourceFile; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4 || wordbuffer!=0) sl@0: return SourceFile; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4 || wordbuffer!=KMultiBitmapFileImageChecksum) sl@0: return SourceFile; sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4) sl@0: return SourceFile; sl@0: //The 5th byte is a pointer to the footer containing the number of bitmaps sl@0: //and the offset from the beginning of the file each begins at. sl@0: int footerPos = wordbuffer; sl@0: sl@0: file.seekg(footerPos,ios::beg); sl@0: sl@0: file.read((char *)&wordbuffer, 4); sl@0: if (file.gcount()!=4) sl@0: return SourceFile; sl@0: sl@0: int numBitmaps = wordbuffer; sl@0: sl@0: int bmpOffset[numBitmaps+1]; sl@0: sl@0: for (int i = 0; i < numBitmaps; i++) sl@0: { sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4) sl@0: return SourceFile; sl@0: bmpOffset[i] = wordbuffer; sl@0: } sl@0: sl@0: //The byte at the end of the last bitmap is the location of the footer sl@0: bmpOffset[numBitmaps] = footerPos; sl@0: sl@0: //Check length of a bitmap is reflected in the difference between the offsets sl@0: for (int i = 0 ; i < numBitmaps ; i++) sl@0: { sl@0: file.seekg(bmpOffset[i]); sl@0: sl@0: //Read the length of this bitmap sl@0: file.read((char *)&wordbuffer,4); sl@0: if (file.gcount()!=4) sl@0: return SourceFile; sl@0: sl@0: //Validate length against offsets of this & next bmp sl@0: if (bmpOffset[i+1]-wordbuffer != bmpOffset[i]) sl@0: return SourceFile; sl@0: } sl@0: } sl@0: return NoError; sl@0: }