diff -r 000000000000 -r bde4ae8d615e os/graphics/graphicstools/gdi_tools/bmconv/MAINFUNC.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/graphics/graphicstools/gdi_tools/bmconv/MAINFUNC.CPP Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,532 @@ +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#if defined(__MSVCDOTNET__) || defined(__TOOLS2__) +#include <ostream> +#include <iostream> +using namespace std; +#else //!__MSVCDOTNET__ && !__TOOLS2__ +#include <ostream.h> +#endif //__MSVCDOTNET__ + +#include "TOOLSVER.H" +#include "BMCONV.H" +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> + + +/** +Returns an informative error message, the result of the program actions performed. +@return Informative error string +@param aErrorNumber The error returned from the actions performed +@param aDestfile The multiple bitmap store file name +@param aDestCreated True if the multiple bitmap store has been created/modified +*/ + +char* ErrorMessage(int aErrorNumber, char* aDestfile=NULL, bool aDestCreated=false) + { + // Remove the multiple bitmap store if it has been created/modified during an fstream session and there has been an error + if(aDestfile && (aErrorNumber != NoError) && (aDestCreated == true)) + { + remove(aDestfile); + } + + switch(aErrorNumber) + { + case NoError: + return "Success."; + case NoMemory: + return "Out of memory."; + case Arg: + return "Bad argument."; + case Files: + return "File does not exist"; + case SourceFile: + return "Bad source file(s)."; + case DestFile: + return "Bad destination file(s)."; + case CommandFile: + return "Bad command file."; + case OutOfRange: + return "Number of sources/targets mismatch."; + case TooManyArgs: + return "Too many arguments."; + case UnknownCompression: + return "Unknown source compression type."; + case CompressionError: + return "Compression error."; + case DecompressionError: + return "Decompression error."; + case Bpp: + return "Invalid bitmap mode specified."; + case PaletteFile: + return "Bad palette file."; + case PaletteSupportNotImplemented: + return "Palettes not supported"; + case AlphaFiles: + return "Alpha bitmap file does not exist"; + case AlphaDimensions: + return "Alpha channel bitmap's dimensions don't match pixel bitmap's dimensions."; + case AlphaBpp: + return "Alpha channel bitmap must be 8bpp."; + default: + return "Unknown error!"; + }; + } + +void Header() + { + cout << "\n"; + cout << "\n"; + cout << "BMCONV version "<< version << ".\n"; + } + +void Report(int aError) + { + Header(); + cout << ErrorMessage(aError) << "\n"; + } + +/** +Compiliation information to print to the user at the end of the program. +@param aQuiet Flag if the user selected quiet output mode +@param aError The error returned from the actions performed +@param aType The multiple bitmap store type created +@param aDestfile The multiple bitmap store file name +@param aBitmapFiles The array of bitmaps used +@param aNumFiles The amount of bitmaps used +@param aDestCreated True if the multiple bitmap store has been created/modified +*/ + +void CompilationReport(int aQuiet,int aError,TStoreType aType,char* aDestfile,char** aBitmapFiles,int aNumFiles, bool aDestCreated) + { + if(!aQuiet || aError) + { + Header(); + cout << "Compiling...\n"; + if(aType!=ENoStore) + cout << "Multiple bitmap store type: "; + if(aType==EFileStore) + cout << "File store" << "\n"; + else if(aType==ERomStore) + cout << "ROM image store" << "\n"; + else if(aType==ECompressedRomStore) + cout << "Compressed ROM image store" << "\n"; + if(aDestfile!=NULL) + cout << "Epoc file: " << aDestfile << "\n\n"; + for(int count=0;count<aNumFiles;count++) + { + cout << "Bitmap file " << count+1 << " : "; + cout << aBitmapFiles[count] << "\n"; + } + cout << ErrorMessage(aError, aDestfile, aDestCreated) << "\n"; + } + } + +void DecompilationReport(int aError,char* aDestfile,char** aBitmapFiles,int aNumFiles) + { + Header(); + cout << "Decompiling...\n"; + if(aDestfile!=NULL) + cout << "Epoc file: " << aDestfile << "\n\n"; + for(int count=0;count<aNumFiles;count++) + { + cout << "Bitmap file " << count+1 << " : "; + cout << aBitmapFiles[count] << "\n"; + } + cout << ErrorMessage(aError) << "\n"; + } + +void Usage() + { + cout << "\n"; + cout << "BMCONV version "<< version << ".\n"; + cout << "Symbian OS multiple bitmap file/rom store conversion program.\n"; + cout << "Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies)."; + cout << "\n"; + cout << "\n"; + cout << "Usage:\n"; + cout << "BMCONV [-r|-s|-n] [-hfilename] [-q] [-pfilename] epocfile [OPT]bmp_1 ... [OPT]bmp_n\n"; + cout << "BMCONV [-r|-s|-n] [-q] [-pfilename] epocfile -mepocfile2\n"; + cout << "BMCONV -u epocfile bmp_1 [... bmp_n]\n"; + cout << "BMCONV -v epocfile\n"; + cout << "BMCONV commandfile\n"; + cout << "\n"; + cout << " -r specifies a ROM image destination file,\n"; + cout << " -s specifies a compressed ROM image file,\n"; + cout << " -n disables bitmap File Store compression,\n"; + cout << " the default is a compressed File Store file.\n\n"; + cout << " -q specifies quiet mode - only errors are reported.\n\n"; + cout << " -hfilename specifies the filename for the automatic\n"; + cout << " generation of a header file for inclusion into code.\n\n"; + cout << " -pfilename gives the filename of a palette file containing 256 hex\n"; + cout << " numbers (0x00BBGGRR) specifying the palette for 8bpp colour bitmaps.\n"; + cout << " (Omission results in the use of a default palette.)\n\n"; + cout << " OPT may be one of -1, -2, -4, -8, -c4, -c8, -c12, -c16, -c24 -c32 -c32a\n"; + cout << " specifying bits per pixel and grey-scale-colour, or -mepocfile2\n"; + cout << " to specify an existing multiple bitmap file. default is -2.\n\n"; + cout << " To avoid ambiguity when specifying -c32 with a bitmap file whose name\n"; + cout << " begins with an 'a', use a relative or direct directory reference\n"; + cout << " e.g. -c32.\\abitmap.bmp or -c32c:\\abitmap.bmp\n"; + cout << " Directory names must not include spaces.\n\n"; + cout << " -c32a specifies use of an alpha channel in a 32bpp bitmap. Alpha data\n"; + cout << " is supplied in a separate 8bpp bmp file with identical dimensions to\n"; + cout << " the pixel data. This file must be named as bmp_n with the suffix '-alpha'\n"; + cout << " e.g. if bmp_1 is 'my.bmp' then the file 'my-alpha.bmp' is required in the\n"; + cout << " same directory. The alpha file does not need to be specified.\n\n"; + cout << " epocfile specifies the epoc multi-bitmap file name.\n"; + cout << " bmp_n specifies the nth bitmap file name.\n\n"; + cout << " -u decompiles epocfile to bmp_1,...,bmp_n.\n"; + cout << " If an alpha channel is present then a further, 8bpp file is output for \n"; + cout << " the alpha data, named with an '-alpha' suffix as described above.\n\n"; + cout << " -v displays a summary of the bitmaps in epocfile\n"; + cout << " otherwise bmp_1,...,bmp_n are compiled to epocfile\n\n"; + cout << " commandfile specifies a file containing the commandline\n"; + cout << " with commands separated by spaces or newlines.\n\n"; + cout << " When bmconv is used on Windows, options may start with '/' or '-'\n"; + + } + +int IsWhiteSpace(char aCharacter) + { + return(aCharacter==' ' || aCharacter=='\n' || aCharacter=='\r' || aCharacter==0x1a); + } + +int ProcessCommandFile(char* aCommandFileName,char** aArgPtrs,int& aNumArgs) + { + struct stat fileinfo; + if (stat(aCommandFileName,&fileinfo)==-1) + return CommandFile; + + int filesize=fileinfo.st_size; + if (filesize==0) + return NoError; +#if defined(__MSVCDOTNET__) || defined(__TOOLS2__) + fstream commandfile(aCommandFileName, ios::in | ios::binary); +#else //!__MSVCDOTNET__ + fstream commandfile(aCommandFileName, ios::in | ios::binary | ios::nocreate); +#endif //__MSVCDOTNET__ + if(!commandfile.is_open()) + return CommandFile; + + char* commandData=new char[filesize+1]; + if(commandData==NULL) + return NoMemory; + + memset(commandData,0,filesize+1); + commandfile.read(commandData,filesize); + commandData[filesize]='\0'; + + char* commandptr = (char*)commandData; + char* commandptrLimit = (char*)(commandData + filesize); + while (commandptr < commandptrLimit) + { + if(*commandptr=='/' && *(commandptr+1)=='/') + while(*commandptr!='\n' && *commandptr!='\r' && commandptr < commandptrLimit) + *commandptr++=' '; + else if (*commandptr==0x1a) + *commandptr++=' '; + commandptr++; + } + + commandptr = (char*)commandData; + while (commandptr < commandptrLimit) + { + while(IsWhiteSpace(*commandptr) && commandptr < commandptrLimit) + *commandptr++='\0'; + if (commandptr == commandptrLimit) + break; + aArgPtrs[aNumArgs]=commandptr; + while(!IsWhiteSpace(*commandptr) && commandptr < commandptrLimit) + commandptr++; + if (commandptr == commandptrLimit) + break; + aNumArgs++; + } + + commandfile.close(); + return NoError; + } + +int Decompile(int aArgc,int aNumArgs,char** aArgPtrs) + { + int ret=OutOfRange; + char* destfilename=aArgPtrs[1]; + + if(aArgc>=4 || aArgc==2) + { + for(int count=2;count<aNumArgs;count++) + { + EpocLoader pl; + ret=pl.LoadEpocBitmap(destfilename,count-2); + if(!ret) ret=pl.SaveBitmap(aArgPtrs[count]); + if(ret) break; + } + DecompilationReport(ret,destfilename,&aArgPtrs[2],aNumArgs-2); + } + else + DecompilationReport(ret,NULL,NULL,0); + + return ret; + } + +int Compile(int aNumArgs,int aArgArraySize, char** aArgPtrs) + { + TStoreType storeType = EFileStore; + int compression = 1; + int quiet = 0; + char* headerfilename = NULL; + char* palettefilename = NULL; + char* destfilename = NULL; + int ret = OutOfRange; + bool aDestCreated = false; + + for(int argnum=0;argnum<aNumArgs;argnum++) + { + if(aArgPtrs[argnum] && (aArgPtrs[argnum][0] == OPTCHAR || aArgPtrs[argnum][0]==ALTERNATE_OPTCHAR)) + { + if(aArgPtrs[argnum][1]=='r' || aArgPtrs[argnum][1]=='R') + { + if(storeType==ECompressedRomStore) + { + ret=TooManyArgs; + CompilationReport(quiet,ret,storeType,NULL,NULL,0,aDestCreated); + return ret; + } + storeType=ERomStore; + aArgPtrs[argnum] = NULL; + } + else if(aArgPtrs[argnum][1]=='s' || aArgPtrs[argnum][1]=='S') + { + if(storeType==ERomStore) + { + ret=TooManyArgs; + CompilationReport(quiet,ret,storeType,NULL,NULL,0,aDestCreated); + return ret; + } + storeType=ECompressedRomStore; + aArgPtrs[argnum] = NULL; + } + else if(aArgPtrs[argnum][1]=='n' || aArgPtrs[argnum][1]=='N') + { + compression=0; + aArgPtrs[argnum] = NULL; + } + else if(aArgPtrs[argnum][1]=='h' || aArgPtrs[argnum][1]=='H') + { + headerfilename = &aArgPtrs[argnum][2]; + aArgPtrs[argnum] = NULL; + } + else if(aArgPtrs[argnum][1]=='q' || aArgPtrs[argnum][1]=='Q') + { + quiet=1; + aArgPtrs[argnum] = NULL; + } + else if(aArgPtrs[argnum][1]=='p' || aArgPtrs[argnum][1]=='P') + { + palettefilename = &aArgPtrs[argnum][2]; + aArgPtrs[argnum] = NULL; + } + } + else + break; // the RNHQP arguments must precede the output filename + } + + int firstsource=0; + while(firstsource<aArgArraySize && aArgPtrs[firstsource]==NULL) + firstsource++; + if(firstsource==aArgArraySize) firstsource=0; + destfilename=aArgPtrs[firstsource]; + firstsource++; + int numsources=firstsource; + while(numsources<aArgArraySize && aArgPtrs[numsources]!=NULL) + numsources++; + if(numsources==aArgArraySize) numsources=0; + numsources-=firstsource; + + if (numsources > 0) + { + BitmapCompiler mp(&aArgPtrs[firstsource],numsources); + ret = mp.Compile(storeType,compression,destfilename,headerfilename,palettefilename); + aDestCreated = true; // The multiple bitmap store has been created/modified + } + + CompilationReport(quiet,ret,storeType,destfilename,&aArgPtrs[firstsource],aNumArgs-firstsource,aDestCreated); + + return ret; + } + +void GetInfo(char* aSourceFile) + { + Header(); + + EpocLoader pl; + int numSources=-1; + int romFormat=0; + int ret = pl.EpocBitmapCount(aSourceFile, numSources, romFormat); + if (ret) + { + cout << "Problem reading number of bitmaps \n"; + cout << ErrorMessage(ret) << "\n"; + return; + } + + cout << aSourceFile << " is a " << (romFormat? "ROM image":"File store") + << " containing " << numSources << ((numSources==1)? " bitmap\n":" bitmaps\n"); + + for (int count = 0;count<numSources;count++) + { + ret = pl.LoadEpocBitmap(aSourceFile,count); + if (ret == OutOfRange) + break; + cout << "\n"; + if (ret) + { + cout << "Problem loading bitmap number " << count << "\n"; + cout << ErrorMessage(ret) << "\n"; + break; + } + else + { + SEpocBitmapHeader h = pl.Header(); + cout << "Bitmap " << count + 1 << " information:\n"; + cout << "Pixel size " << h.iWidthInPixels << " x " << h.iHeightInPixels << "\n"; + cout << "Twips size " << h.iWidthInTwips << " x " << h.iHeightInTwips << "\n"; + cout << h.iBitsPerPixel << " Bpp "; + if (h.iColor == EColorBitmap) + cout << "Colour"; + else if (h.iColor == EColorBitmapAlpha || h.iColor == EColorBitmapAlphaPM) + cout << "Colour with alpha channel"; + else if(h.iColor == EMonochromeBitmap) + cout << "Monochrome"; + else + cout << "Unknown colour format"; + cout << "\n"; + if (h.iPaletteEntries > 0) + cout << "Palette entries " << h.iPaletteEntries; + + int byteSize = BitmapUtils::ByteWidth(h.iWidthInPixels,h.iBitsPerPixel) * h.iHeightInPixels; + int compressionRatio = 0; + if (byteSize > 0) + compressionRatio = (h.iBitmapSize - sizeof(SEpocBitmapHeader)) * 100 / byteSize; + + switch (h.iCompression) + { + case ENoBitmapCompression: + cout << "No compression\n"; + break; + case EByteRLECompression: + cout << "Bytewise RLE compression " << compressionRatio << "%\n"; + break; + case ETwelveBitRLECompression: + cout << "12 bit RLE compression " << compressionRatio << "%\n"; + break; + case ESixteenBitRLECompression: + cout << "16 bit RLE compression " << compressionRatio << "%\n"; + break; + case ETwentyFourBitRLECompression: + cout << "24 bit RLE compression " << compressionRatio << "%\n"; + break; + case EThirtyTwoUBitRLECompression: + cout << "unsigned 32 bit RLE compression (no alpha channel) " << compressionRatio << "%\n"; + break; + case EThirtyTwoABitRLECompression: + cout << "unsigned 32 bit RLE compression (with alpha channel) " << compressionRatio << "%\n"; + break; + // case ERLECompressionLast: // Added to supress unhandled switch warning + default: + break; + } + } + } + + cout << "\n"; + } + +class TAutoPtr + { +public: + TAutoPtr(char** aPtr) : + iPtr(aPtr) + { + } + ~TAutoPtr() + { + delete iPtr; + } +private: + char** iPtr; + }; + +int main(int argc,char* argv[],char* []) + { + if (argc <= 1) + { + Usage(); + return 0; + } + + int optMaxCnt = argc; + + if(argc==2) // The single argument must be a command file name + { + struct stat fileinfo; + if (stat(argv[1],&fileinfo)==-1) + { + Report(CommandFile); + return 0; + } + optMaxCnt = fileinfo.st_size; + } + + char** argptrs = new char*[optMaxCnt]; + if(!argptrs) + { + Report(NoMemory); + return 0; + } + TAutoPtr autoPtr(argptrs); + memset(argptrs, 0, optMaxCnt * sizeof(char*)); + + int numargs = 0; + if(argc>2) // Explicit arguments are present + { + for(int count=0;count<argc-1;count++) + argptrs[count]=argv[count+1]; + numargs = argc-1; + } + else // The single argument must be a command file name + { + int ret = ProcessCommandFile(argv[1],argptrs,numargs); + if (ret) + { + Report(ret); + return 0; + } + } + + if ((argptrs[0]!=NULL && (argptrs[0][0]==OPTCHAR || argptrs[0][0]==ALTERNATE_OPTCHAR)) && (argptrs[0][1]=='u' || argptrs[0][1]=='U')) { + return Decompile(argc,numargs,argptrs); } + + if ((argptrs[0]!=NULL && (argptrs[0][0]==OPTCHAR || argptrs[0][0]==ALTERNATE_OPTCHAR)) && (argptrs[0][1]=='v' || argptrs[0][1]=='V')) + { + GetInfo(argptrs[1]); + return 0; + } + + return Compile(numargs,optMaxCnt,argptrs); + } +