|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__) || defined(__CW32__) |
|
19 #include <ostream> |
|
20 #include <iostream> |
|
21 using namespace std; |
|
22 #else //!__MSVCDOTNET__ && !__TOOLS2__ && !__CW32__ |
|
23 #pragma warning(disable: 4100) |
|
24 #pragma warning(disable: 4511) |
|
25 #pragma warning(disable: 4512) |
|
26 #pragma warning(disable: 4530) |
|
27 #pragma warning(disable: 4663) |
|
28 #pragma warning(disable: 4710) |
|
29 #pragma warning(disable: 4786) |
|
30 #pragma warning(disable: 4800) |
|
31 #include <ostream.h> |
|
32 #endif //__MSVCDOTNET__ |
|
33 |
|
34 #include "TOOLSVER.H" |
|
35 #include "BMCONV.H" |
|
36 #include <sys/types.h> |
|
37 #include <sys/stat.h> |
|
38 #include <stdio.h> |
|
39 #include <string> |
|
40 |
|
41 const int KMaxPaletteFileLen = 256; |
|
42 |
|
43 #ifdef __linux__ |
|
44 const char* DefaultPaletteFileSearchLocations[] = |
|
45 { |
|
46 "/epoc32/include/mw/ThirdPartyBitmap.pal", |
|
47 "/epoc32/include/middleware/ThirdPartyBitmap.pal", |
|
48 "/epoc32/include/ThirdPartyBitmap.pal" |
|
49 }; |
|
50 #else |
|
51 const char* DefaultPaletteFileSearchLocations[] = |
|
52 { |
|
53 "\\epoc32\\include\\mw\\ThirdPartyBitmap.pal", |
|
54 "\\epoc32\\include\\middleware\\ThirdPartyBitmap.pal", |
|
55 "\\epoc32\\include\\ThirdPartyBitmap.pal" |
|
56 }; |
|
57 #endif |
|
58 |
|
59 /** |
|
60 Returns an informative error message, the result of the program actions performed. |
|
61 @return Informative error string |
|
62 @param aErrorNumber The error returned from the actions performed |
|
63 @param aDestfile The multiple bitmap store file name |
|
64 @param aDestCreated True if the multiple bitmap store has been created/modified |
|
65 */ |
|
66 |
|
67 char* ErrorMessage(int aErrorNumber, char* aDestfile=NULL, bool aDestCreated=false) |
|
68 { |
|
69 // Remove the multiple bitmap store if it has been created/modified during an fstream session and there has been an error |
|
70 if(aDestfile && (aErrorNumber != NoError) && (aDestCreated == true)) |
|
71 { |
|
72 remove(aDestfile); |
|
73 } |
|
74 |
|
75 switch(aErrorNumber) |
|
76 { |
|
77 case NoError: |
|
78 return "Success."; |
|
79 case NoMemory: |
|
80 return "Out of memory."; |
|
81 case Arg: |
|
82 return "Bad argument."; |
|
83 case Files: |
|
84 return "File does not exist"; |
|
85 case SourceFile: |
|
86 return "Bad source file(s)."; |
|
87 case DestFile: |
|
88 return "Bad destination file(s)."; |
|
89 case CommandFile: |
|
90 return "Bad command file."; |
|
91 case OutOfRange: |
|
92 return "Number of sources/targets mismatch."; |
|
93 case TooManyArgs: |
|
94 return "Too many arguments."; |
|
95 case UnknownCompression: |
|
96 return "Unknown source compression type."; |
|
97 case CompressionError: |
|
98 return "Compression error."; |
|
99 case DecompressionError: |
|
100 return "Decompression error."; |
|
101 case Bpp: |
|
102 return "Invalid bitmap mode specified."; |
|
103 case PaletteFile: |
|
104 return "Bad palette file."; |
|
105 case PaletteSupportNotImplemented: |
|
106 return "Palettes not supported"; |
|
107 case AlphaFiles: |
|
108 return "Alpha bitmap file does not exist"; |
|
109 case AlphaDimensions: |
|
110 return "Alpha channel bitmap's dimensions don't match pixel bitmap's dimensions."; |
|
111 case AlphaBpp: |
|
112 return "Alpha channel bitmap must be 8bpp."; |
|
113 default: |
|
114 return "Unknown error!"; |
|
115 }; |
|
116 } |
|
117 |
|
118 void Header() |
|
119 { |
|
120 cout << "\n"; |
|
121 cout << "\n"; |
|
122 cout << "BMCONV S60 version "<< version << ".\n"; |
|
123 } |
|
124 |
|
125 void Report(int aError) |
|
126 { |
|
127 Header(); |
|
128 cout << ErrorMessage(aError) << "\n"; |
|
129 } |
|
130 |
|
131 /** |
|
132 Compiliation information to print to the user at the end of the program. |
|
133 @param aQuiet Flag if the user selected quiet output mode |
|
134 @param aError The error returned from the actions performed |
|
135 @param aType The multiple bitmap store type created |
|
136 @param aDestfile The multiple bitmap store file name |
|
137 @param aBitmapFiles The array of bitmaps used |
|
138 @param aNumFiles The amount of bitmaps used |
|
139 @param aDestCreated True if the multiple bitmap store has been created/modified |
|
140 */ |
|
141 |
|
142 void CompilationReport(int aQuiet,int aError,TStoreType aType,char* aDestfile,TSourceFile* aBitmapFiles,int aNumFiles, bool aDestCreated) |
|
143 { |
|
144 if(!aQuiet || aError) |
|
145 { |
|
146 Header(); |
|
147 cout << "Compiling...\n"; |
|
148 if(aType!=ENoStore) |
|
149 cout << "Multiple bitmap store type: "; |
|
150 if(aType==EFileStore) |
|
151 cout << "File store" << "\n"; |
|
152 else if(aType==ERomStore) |
|
153 cout << "ROM image store" << "\n"; |
|
154 else if(aType==ECompressedRomStore) |
|
155 cout << "Compressed ROM image store" << "\n"; |
|
156 if(aDestfile!=NULL) |
|
157 cout << "Epoc file: " << aDestfile << "\n\n"; |
|
158 for(int count=0;count<aNumFiles;count++) |
|
159 { |
|
160 cout << "Bitmap file " << count+1 << " : "; |
|
161 aBitmapFiles[count].WriteCompileInfo(cout); |
|
162 cout << endl; |
|
163 } |
|
164 cout << ErrorMessage(aError, aDestfile, aDestCreated) << "\n"; |
|
165 } |
|
166 } |
|
167 |
|
168 void DecompilationReport(int aError,char* aDestfile,char** aBitmapFiles,int aNumFiles) |
|
169 { |
|
170 Header(); |
|
171 cout << "Decompiling...\n"; |
|
172 if(aDestfile!=NULL) |
|
173 cout << "Epoc file: " << aDestfile << "\n\n"; |
|
174 for(int count=0;count<aNumFiles;count++) |
|
175 { |
|
176 cout << "Bitmap file " << count+1 << " : "; |
|
177 cout << aBitmapFiles[count] << "\n"; |
|
178 } |
|
179 cout << ErrorMessage(aError) << "\n"; |
|
180 } |
|
181 |
|
182 void Usage() |
|
183 { |
|
184 cout << "\n"; |
|
185 cout << "BMCONV S60 version "<< version << ".\n"; |
|
186 cout << "Symbian OS multiple bitmap file/rom store conversion program.\n"; |
|
187 cout << "Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved."; |
|
188 cout << "\n"; |
|
189 cout << "\n"; |
|
190 cout << "Usage:\n"; |
|
191 cout << "BMCONV [-r|-s|-n] [-hfilename] [-q] [-pfilename] epocfile [OPT]bmp_1 ... [OPT]bmp_n\n"; |
|
192 cout << "BMCONV [-r|-s|-n] [-q] [-pfilename] epocfile -mepocfile2\n"; |
|
193 cout << "BMCONV -u epocfile bmp_1 [... bmp_n]\n"; |
|
194 cout << "BMCONV -v epocfile\n"; |
|
195 cout << "BMCONV commandfile\n"; |
|
196 cout << "\n"; |
|
197 cout << " -r specifies a ROM image destination file,\n"; |
|
198 cout << " -s specifies a compressed ROM image file,\n"; |
|
199 cout << " -n disables bitmap File Store compression,\n"; |
|
200 cout << " the default is a compressed File Store file.\n\n"; |
|
201 cout << " -q specifies quiet mode - only errors are reported.\n\n"; |
|
202 cout << " -hfilename specifies the filename for the automatic\n"; |
|
203 cout << " generation of a header file for inclusion into code.\n\n"; |
|
204 cout << " -pfilename gives the filename of a palette file containing 256 hex\n"; |
|
205 cout << " numbers (0x00BBGGRR) specifying the palette for 8bpp colour bitmaps.\n"; |
|
206 cout << " (Omission results in the use of a default palette.)\n\n"; |
|
207 cout << " OPT may be one of -1, -2, -4, -8, -c4, -c8, -c12, -c16, -c24 -c32 -c32a\n"; |
|
208 cout << " specifying bits per pixel and grey-scale-colour, or -mepocfile2\n"; |
|
209 cout << " to specify an existing multiple bitmap file. default is -2.\n\n"; |
|
210 cout << " To avoid ambiguity when specifying -c32 with a bitmap file whose name\n"; |
|
211 cout << " begins with an 'a', use a relative or direct directory reference\n"; |
|
212 cout << " e.g. -c32.\\abitmap.bmp or -c32c:\\abitmap.bmp\n"; |
|
213 cout << " Directory names must not include spaces.\n\n"; |
|
214 cout << " -c32a specifies use of an alpha channel in a 32bpp bitmap. Alpha data\n"; |
|
215 cout << " is supplied in a separate 8bpp bmp file with identical dimensions to\n"; |
|
216 cout << " the pixel data. This file must be named as bmp_n with the suffix '-alpha'\n"; |
|
217 cout << " e.g. if bmp_1 is 'my.bmp' then the file 'my-alpha.bmp' is required in the\n"; |
|
218 cout << " same directory. The alpha file does not need to be specified.\n\n"; |
|
219 cout << " epocfile specifies the epoc multi-bitmap file name.\n"; |
|
220 cout << " bmp_n specifies the nth bitmap file name.\n\n"; |
|
221 cout << " -u decompiles epocfile to bmp_1,...,bmp_n.\n"; |
|
222 cout << " If an alpha channel is present then a further, 8bpp file is output for \n"; |
|
223 cout << " the alpha data, named with an '-alpha' suffix as described above.\n\n"; |
|
224 cout << " -v displays a summary of the bitmaps in epocfile\n"; |
|
225 cout << " otherwise bmp_1,...,bmp_n are compiled to epocfile\n\n"; |
|
226 cout << " commandfile specifies a file containing the commandline\n"; |
|
227 cout << " with commands separated by spaces or newlines.\n\n"; |
|
228 cout << " When bmconv is used on Windows, options may start with '/' or '-'\n"; |
|
229 } |
|
230 |
|
231 int IsWhiteSpace(char aCharacter) |
|
232 { |
|
233 return(aCharacter==' ' || aCharacter=='\n' || aCharacter=='\r' || aCharacter==0x1a); |
|
234 } |
|
235 |
|
236 int ProcessCommandFile(char* aCommandFileName,char** aArgPtrs,int& aNumArgs) |
|
237 { |
|
238 struct stat fileinfo; |
|
239 if (stat(aCommandFileName,&fileinfo)==-1) |
|
240 return CommandFile; |
|
241 |
|
242 int filesize=fileinfo.st_size; |
|
243 if (filesize==0) |
|
244 return NoError; |
|
245 #if defined(__MSVCDOTNET__) || defined(__TOOLS2__) || defined(__CW32__) |
|
246 fstream commandfile(aCommandFileName, ios::in | ios::binary); |
|
247 #else //!__MSVCDOTNET__ |
|
248 fstream commandfile(aCommandFileName, ios::in | ios::binary | ios::nocreate); |
|
249 #endif //__MSVCDOTNET__ |
|
250 if(!commandfile.is_open()) |
|
251 return CommandFile; |
|
252 |
|
253 char* commandData=new char[filesize+1]; |
|
254 if(commandData==NULL) |
|
255 return NoMemory; |
|
256 |
|
257 memset(commandData,0,filesize+1); |
|
258 commandfile.read(commandData,filesize); |
|
259 commandData[filesize]='\0'; |
|
260 |
|
261 char* commandptr = (char*)commandData; |
|
262 char* commandptrLimit = (char*)(commandData + filesize); |
|
263 while (commandptr < commandptrLimit) |
|
264 { |
|
265 if(*commandptr=='/' && *(commandptr+1)=='/') |
|
266 while(*commandptr!='\n' && *commandptr!='\r' && commandptr < commandptrLimit) |
|
267 *commandptr++=' '; |
|
268 else if (*commandptr==0x1a) |
|
269 *commandptr++=' '; |
|
270 commandptr++; |
|
271 } |
|
272 |
|
273 commandptr = (char*)commandData; |
|
274 while (commandptr < commandptrLimit) |
|
275 { |
|
276 while(IsWhiteSpace(*commandptr) && commandptr < commandptrLimit) |
|
277 *commandptr++='\0'; |
|
278 if (commandptr == commandptrLimit) |
|
279 break; |
|
280 aArgPtrs[aNumArgs]=commandptr; |
|
281 if ( (*commandptr == '/') && (*(commandptr+1) == 'p'||*(commandptr+1) == 'P') && (*(commandptr+2) == '"') ) |
|
282 { |
|
283 commandptr+=3; |
|
284 while(*commandptr != '"') |
|
285 commandptr++; |
|
286 *commandptr=' '; |
|
287 |
|
288 } |
|
289 while(!IsWhiteSpace(*commandptr) && commandptr < commandptrLimit) |
|
290 commandptr++; |
|
291 if (commandptr == commandptrLimit) |
|
292 break; |
|
293 aNumArgs++; |
|
294 } |
|
295 |
|
296 commandfile.close(); |
|
297 return NoError; |
|
298 } |
|
299 |
|
300 int Decompile(int aArgc,int aNumArgs,char** aArgPtrs) |
|
301 { |
|
302 int ret=OutOfRange; |
|
303 char* destfilename=aArgPtrs[1]; |
|
304 |
|
305 if(aArgc>=4 || aArgc==2) |
|
306 { |
|
307 for(int count=2;count<aNumArgs;count++) |
|
308 { |
|
309 EpocLoader pl; |
|
310 ret=pl.LoadEpocBitmap(destfilename,count-2); |
|
311 if(!ret) ret=pl.SaveBitmap(aArgPtrs[count]); |
|
312 if(ret) break; |
|
313 } |
|
314 DecompilationReport(ret,destfilename,&aArgPtrs[2],aNumArgs-2); |
|
315 } |
|
316 else |
|
317 DecompilationReport(ret,NULL,NULL,0); |
|
318 |
|
319 return ret; |
|
320 } |
|
321 |
|
322 const char* AddEpocRootTo(std::string& aBuf, const std::string& aName) |
|
323 { |
|
324 int nameLen = aName.length(); |
|
325 int rootLen = 0; |
|
326 aBuf = ""; // Clear old contents |
|
327 char* epocroot = getenv("EPOCROOT"); |
|
328 if (epocroot) |
|
329 { |
|
330 rootLen = strlen(epocroot); |
|
331 if (nameLen+rootLen < KMaxPaletteFileLen) |
|
332 { |
|
333 if( rootLen > 0 && epocroot[rootLen-1] == '\\') |
|
334 { |
|
335 aBuf = std::string(epocroot, rootLen-1); |
|
336 } |
|
337 else if( rootLen > 0 ) |
|
338 { |
|
339 aBuf = std::string(epocroot); |
|
340 } |
|
341 } |
|
342 } |
|
343 aBuf += aName; |
|
344 return aBuf.c_str(); |
|
345 } |
|
346 |
|
347 bool FileExists( const char* aFileName ) |
|
348 { |
|
349 struct stat fileInfo; |
|
350 int retVal = 0; |
|
351 |
|
352 // Try to get file attributes to see if the file exists or not: |
|
353 retVal = stat( aFileName, &fileInfo); |
|
354 return retVal == 0; |
|
355 } |
|
356 |
|
357 const char* DefaultPaletteFileName(std::string& aBuf) |
|
358 { |
|
359 const char* palettefilename = NULL; |
|
360 int numOfSearchLocations = sizeof(DefaultPaletteFileSearchLocations)/sizeof(char*); |
|
361 |
|
362 for( int i = 0; i < numOfSearchLocations; ++i ) |
|
363 { |
|
364 palettefilename = AddEpocRootTo(aBuf, DefaultPaletteFileSearchLocations[i]); |
|
365 if( FileExists( palettefilename)) |
|
366 { |
|
367 return palettefilename; |
|
368 } |
|
369 } |
|
370 |
|
371 return NULL; |
|
372 } |
|
373 |
|
374 int Compile(int aNumArgs,int aArgArraySize, char** aArgPtrs) |
|
375 { |
|
376 TStoreType storeType = EFileStore; |
|
377 int compression = 1; |
|
378 int quiet = 0; |
|
379 char* headerfilename = NULL; |
|
380 char paletteBuf[KMaxPaletteFileLen]; |
|
381 memset(paletteBuf, 0, KMaxPaletteFileLen); |
|
382 std::string paletteStr; |
|
383 const char* defaultPalettefile = DefaultPaletteFileName(paletteStr); |
|
384 char* palettefilename = NULL; |
|
385 char* destfilename = NULL; |
|
386 int ret = OutOfRange; |
|
387 bool aDestCreated = false; |
|
388 |
|
389 for(int argnum=0;argnum<aNumArgs;argnum++) |
|
390 { |
|
391 if(aArgPtrs[argnum] && (aArgPtrs[argnum][0] == OPTCHAR || aArgPtrs[argnum][0]==ALTERNATE_OPTCHAR)) |
|
392 { |
|
393 if(aArgPtrs[argnum][1]=='r' || aArgPtrs[argnum][1]=='R') |
|
394 { |
|
395 if(storeType==ECompressedRomStore) |
|
396 { |
|
397 ret=TooManyArgs; |
|
398 CompilationReport(quiet,ret,storeType,NULL,NULL,0,aDestCreated); |
|
399 return ret; |
|
400 } |
|
401 storeType=ERomStore; |
|
402 aArgPtrs[argnum] = NULL; |
|
403 } |
|
404 else if(aArgPtrs[argnum][1]=='s' || aArgPtrs[argnum][1]=='S') |
|
405 { |
|
406 if(storeType==ERomStore) |
|
407 { |
|
408 ret=TooManyArgs; |
|
409 CompilationReport(quiet,ret,storeType,NULL,NULL,0,aDestCreated); |
|
410 return ret; |
|
411 } |
|
412 storeType=ECompressedRomStore; |
|
413 aArgPtrs[argnum] = NULL; |
|
414 } |
|
415 else if(aArgPtrs[argnum][1]=='n' || aArgPtrs[argnum][1]=='N') |
|
416 { |
|
417 compression=0; |
|
418 aArgPtrs[argnum] = NULL; |
|
419 } |
|
420 else if(aArgPtrs[argnum][1]=='h' || aArgPtrs[argnum][1]=='H') |
|
421 { |
|
422 headerfilename = &aArgPtrs[argnum][2]; |
|
423 aArgPtrs[argnum] = NULL; |
|
424 } |
|
425 else if(aArgPtrs[argnum][1]=='q' || aArgPtrs[argnum][1]=='Q') |
|
426 { |
|
427 if (getenv("BMCONV_NOT_QUIET") == 0) |
|
428 quiet=1; |
|
429 aArgPtrs[argnum] = NULL; |
|
430 } |
|
431 else if(aArgPtrs[argnum][1]=='p' || aArgPtrs[argnum][1]=='P') |
|
432 { |
|
433 palettefilename = &aArgPtrs[argnum][2]; |
|
434 if (*palettefilename=='"') |
|
435 { |
|
436 palettefilename+=1; |
|
437 } |
|
438 aArgPtrs[argnum] = NULL; |
|
439 } |
|
440 } |
|
441 else |
|
442 break; // the RNHQP arguments must precede the output filename |
|
443 } |
|
444 |
|
445 if( palettefilename == NULL ) |
|
446 { |
|
447 // Palette file not given in arguments. If the default palette file |
|
448 // was found, use it, otherwise return error. |
|
449 if( defaultPalettefile != NULL ) |
|
450 { |
|
451 memcpy(paletteBuf, defaultPalettefile, strlen(defaultPalettefile)); |
|
452 palettefilename = paletteBuf; |
|
453 } |
|
454 else |
|
455 { |
|
456 // Palettefile not given in arguments nor found from default locations: |
|
457 ret = PaletteFile; |
|
458 CompilationReport(quiet,ret,storeType,NULL,NULL,0,aDestCreated); |
|
459 return ret; |
|
460 } |
|
461 } |
|
462 int firstsource=0; |
|
463 while(firstsource<aArgArraySize && aArgPtrs[firstsource]==NULL) |
|
464 firstsource++; |
|
465 if(firstsource==aArgArraySize) firstsource=0; |
|
466 destfilename=aArgPtrs[firstsource]; |
|
467 firstsource++; |
|
468 int numsources=firstsource; |
|
469 while(numsources<aArgArraySize && aArgPtrs[numsources]!=NULL) |
|
470 numsources++; |
|
471 if(numsources==aArgArraySize) numsources=0; |
|
472 numsources-=firstsource; |
|
473 |
|
474 TSourceFile* sources = 0; |
|
475 |
|
476 if (numsources > 0) |
|
477 { |
|
478 sources = new TSourceFile[numsources]; |
|
479 for (int ii=0; ii<numsources; ii++) |
|
480 sources[ii].FileName() = aArgPtrs[firstsource + ii]; |
|
481 BitmapCompiler mp(sources,numsources); |
|
482 ret = mp.Compile(storeType,compression,destfilename,headerfilename,palettefilename); |
|
483 aDestCreated = true; // The multiple bitmap store has been created/modified |
|
484 } |
|
485 |
|
486 CompilationReport(quiet,ret,storeType,destfilename,sources,aNumArgs-firstsource,aDestCreated); |
|
487 delete [] sources; |
|
488 |
|
489 return ret; |
|
490 } |
|
491 |
|
492 void GetInfo(char* aSourceFile) |
|
493 { |
|
494 Header(); |
|
495 |
|
496 EpocLoader pl; |
|
497 int numSources=-1; |
|
498 int romFormat=0; |
|
499 int ret = pl.EpocBitmapCount(aSourceFile, numSources, romFormat); |
|
500 if (ret) |
|
501 { |
|
502 cout << "Problem reading number of bitmaps \n"; |
|
503 cout << ErrorMessage(ret) << "\n"; |
|
504 return; |
|
505 } |
|
506 |
|
507 cout << aSourceFile << " is a " << (romFormat? "ROM image":"File store") |
|
508 << " containing " << numSources << ((numSources==1)? " bitmap\n":" bitmaps\n"); |
|
509 |
|
510 for (int count = 0;count<numSources;count++) |
|
511 { |
|
512 ret = pl.LoadEpocBitmap(aSourceFile,count); |
|
513 if (ret == OutOfRange) |
|
514 break; |
|
515 cout << "\n"; |
|
516 if (ret) |
|
517 { |
|
518 cout << "Problem loading bitmap number " << count << "\n"; |
|
519 cout << ErrorMessage(ret) << "\n"; |
|
520 break; |
|
521 } |
|
522 else |
|
523 { |
|
524 SEpocBitmapHeader h = pl.Header(); |
|
525 cout << "Bitmap " << count + 1 << " information:\n"; |
|
526 cout << "Pixel size " << h.iWidthInPixels << " x " << h.iHeightInPixels << "\n"; |
|
527 cout << "Twips size " << h.iWidthInTwips << " x " << h.iHeightInTwips << "\n"; |
|
528 cout << h.iBitsPerPixel << " Bpp "; |
|
529 if (h.iColor == EColorBitmap) |
|
530 cout << "Colour"; |
|
531 else if (h.iColor == EColorBitmapAlpha) |
|
532 cout << "Colour with alpha channel"; |
|
533 else if(h.iColor == EMonochromeBitmap) |
|
534 cout << "Monochrome"; |
|
535 else |
|
536 cout << "Unknown colour format"; |
|
537 cout << "\n"; |
|
538 if (h.iPaletteEntries > 0) |
|
539 cout << "Palette entries " << h.iPaletteEntries; |
|
540 |
|
541 int byteSize = BitmapUtils::ByteWidth(h.iWidthInPixels,h.iBitsPerPixel) * h.iHeightInPixels; |
|
542 int compressionRatio = 0; |
|
543 if (byteSize > 0) |
|
544 compressionRatio = (h.iBitmapSize - sizeof(SEpocBitmapHeader)) * 100 / byteSize; |
|
545 |
|
546 switch (h.iCompression) |
|
547 { |
|
548 case ENoBitmapCompression: |
|
549 cout << "No compression\n"; |
|
550 break; |
|
551 case EByteRLECompression: |
|
552 cout << "Bytewise RLE compression " << compressionRatio << "%\n"; |
|
553 break; |
|
554 case ETwelveBitRLECompression: |
|
555 cout << "12 bit RLE compression " << compressionRatio << "%\n"; |
|
556 break; |
|
557 case ESixteenBitRLECompression: |
|
558 cout << "16 bit RLE compression " << compressionRatio << "%\n"; |
|
559 break; |
|
560 case ETwentyFourBitRLECompression: |
|
561 cout << "24 bit RLE compression " << compressionRatio << "%\n"; |
|
562 break; |
|
563 case EThirtyTwoUBitRLECompression: |
|
564 cout << "unsigned 32 bit RLE compression (no alpha channel) " << compressionRatio << "%\n"; |
|
565 break; |
|
566 case EThirtyTwoABitRLECompression: |
|
567 cout << "unsigned 32 bit RLE compression (with alpha channel) " << compressionRatio << "%\n"; |
|
568 break; |
|
569 // case ERLECompressionLast: // Added to supress unhandled switch warning |
|
570 default: |
|
571 break; |
|
572 } |
|
573 } |
|
574 } |
|
575 |
|
576 cout << "\n"; |
|
577 } |
|
578 |
|
579 class TAutoPtr |
|
580 { |
|
581 public: |
|
582 TAutoPtr(char** aPtr) : |
|
583 iPtr(aPtr) |
|
584 { |
|
585 } |
|
586 ~TAutoPtr() |
|
587 { |
|
588 delete iPtr; |
|
589 } |
|
590 private: |
|
591 char** iPtr; |
|
592 }; |
|
593 |
|
594 int main(int argc,char* argv[],char* []) |
|
595 { |
|
596 if (argc <= 1) |
|
597 { |
|
598 Usage(); |
|
599 return 0; |
|
600 } |
|
601 |
|
602 int optMaxCnt = argc; |
|
603 |
|
604 if(argc==2) // The single argument must be a command file name |
|
605 { |
|
606 struct stat fileinfo; |
|
607 if (stat(argv[1],&fileinfo)==-1) |
|
608 { |
|
609 Report(CommandFile); |
|
610 return 0; |
|
611 } |
|
612 optMaxCnt = fileinfo.st_size; |
|
613 } |
|
614 |
|
615 char** argptrs = new char*[optMaxCnt]; |
|
616 if(!argptrs) |
|
617 { |
|
618 Report(NoMemory); |
|
619 return 0; |
|
620 } |
|
621 TAutoPtr autoPtr(argptrs); |
|
622 memset(argptrs, 0, optMaxCnt * sizeof(char*)); |
|
623 |
|
624 int numargs = 0; |
|
625 if(argc>2) // Explicit arguments are present |
|
626 { |
|
627 for(int count=0;count<argc-1;count++) |
|
628 argptrs[count]=argv[count+1]; |
|
629 numargs = argc-1; |
|
630 } |
|
631 else // The single argument must be a command file name |
|
632 { |
|
633 int ret = ProcessCommandFile(argv[1],argptrs,numargs); |
|
634 if (ret) |
|
635 { |
|
636 Report(ret); |
|
637 return 0; |
|
638 } |
|
639 } |
|
640 |
|
641 if ((argptrs[0]!=NULL && (argptrs[0][0]==OPTCHAR || argptrs[0][0]==ALTERNATE_OPTCHAR)) && (argptrs[0][1]=='u' || argptrs[0][1]=='U')) { |
|
642 return Decompile(argc,numargs,argptrs); } |
|
643 |
|
644 if ((argptrs[0]!=NULL && (argptrs[0][0]==OPTCHAR || argptrs[0][0]==ALTERNATE_OPTCHAR)) && (argptrs[0][1]=='v' || argptrs[0][1]=='V')) |
|
645 { |
|
646 GetInfo(argptrs[1]); |
|
647 return 0; |
|
648 } |
|
649 |
|
650 return Compile(numargs,optMaxCnt,argptrs); |
|
651 } |
|
652 |