61
67
/* Optional output directory */
62
68
char *outputPath = NULL;
64
const char *sizeStrs[] = { "512", "512x512", "256", "256x256", "128", "128x128", "48", "48x48", "32", "32x32", "16", "16x16", "16x12" };
65
const int sizeVals[] = { 512, 512, 256, 256, 128, 128, 48, 48, 32, 32, 16, 16, MINI_SIZE };
70
const char *sizeStrs[] = { "1024", "1024x1024" "512", "512x512", "256", "256x256", "128", "128x128", "48", "48x48", "32", "32x32", "16", "16x16", "16x12" };
71
const int sizeVals[] = { 1024, 1024, 512, 512, 256, 256, 128, 128, 48, 48, 32, 32, 16, 16, MINI_SIZE };
67
73
const char *depthStrs[] = { "32", "8", "4", "1" };
68
74
const int depthVals[] = { 32 , 8 , 4 , 1 };
254
261
for(count = 0; count < fileCount; count++)
256
if(ExtractAndDescribeIconFamilyFile(inputFileNames[count]))
257
fprintf(stderr, "Extracting icns data from %s failed!\n",inputFileNames[count]);
263
int convresult = ExtractAndDescribeIconFamilyFile(inputFileNames[count]);
264
if(convresult != ICNS_STATUS_OK) {
265
fprintf(stderr, "Errors while extracting icns data from %s!\n",inputFileNames[count]);
266
if(result == CONVERSION_SUCCESS)
267
result = CONVERSION_FAILURE;
260
271
for(count = 0; count < fileCount; count++)
261
272
if(inputFileNames[count] != NULL)
262
273
free(inputFileNames[count]);
268
int ExtractAndDescribeIconFamilyFile(char *filename)
278
int ExtractAndDescribeIconFamilyFile(char *filepath)
270
int error = ICNS_STATUS_OK;
272
icns_family_t *iconFamily = NULL;
273
icns_byte_t *dataPtr = NULL;
274
unsigned long dataOffset = 0;
275
int elementCount = 0;
276
int extractedCount = 0;
277
char *prefilename = NULL;
278
char *outfilename = NULL;
279
unsigned int filenamelength = 0;
280
unsigned int prefilenamelength = 0;
283
char *rsrcfilename = NULL;
284
unsigned int rsrcfilenamelength = 0;
287
filenamelength = strlen(filename);
290
rsrcfilenamelength = filenamelength + 17;
291
rsrcfilename = (char *)malloc(rsrcfilenamelength);
292
if(rsrcfilename == NULL)
295
// Append the OS X POSIX-safe filename to access the resource fork
296
strncpy(&rsrcfilename[0],&filename[0],filenamelength);
297
strncpy(&rsrcfilename[filenamelength],"/..namedfork/rsrc",17);
300
// Set up the output filename...
301
if(extractMode & EXTRACT_MODE)
303
unsigned int outputpathlength = 0;
304
unsigned int filenamestart = filenamelength;
305
unsigned int filenameend = filenamelength;
307
if(outputPath != NULL)
309
outputpathlength = strlen(outputPath);
311
// Create a buffer large enough to hold the worst case
312
prefilename = (char *)malloc(outputpathlength+filenamelength+1);
313
if(prefilename == NULL)
316
// Copy in the output path
317
strncpy(&prefilename[0],&outputPath[0],outputpathlength);
318
prefilenamelength = outputpathlength;
319
if(outputPath[prefilenamelength-1] != '/')
321
prefilename[prefilenamelength] = '/';
323
prefilename[prefilenamelength] = 0;
326
// Append the output filename
327
// That is, the input filename from the last '/' or start to the last '.' past the last '/'
328
while(filename[filenamestart] != '/' && filenamestart > 0)
330
if(filenamestart != 0)
332
while(filename[filenameend] != '.' && filenameend > filenamestart)
334
if(filenameend == filenamestart)
335
filenameend = filenamelength;
336
strncpy(&prefilename[prefilenamelength],&filename[filenamestart],filenameend - filenamestart);
337
prefilenamelength += (filenameend - filenamestart);
338
prefilename[prefilenamelength] = 0;
342
// Create a buffer for the input filename (without the new extension)
343
prefilename = (char *)malloc(filenamelength+1);
344
if(prefilename == NULL)
347
// Create the output filename
348
// That is, the input filename from the last '/' or start to the last '.' past the last '/'
349
while(filename[filenamestart] != '/' && filenamestart > 0)
351
if(filenamestart != 0)
353
while(filename[filenameend] != '.' && filenameend > filenamestart)
355
if(filenameend == filenamestart)
356
filenameend = filenamelength;
357
strncpy(&prefilename[0],&filename[filenamestart],filenameend - filenamestart);
358
prefilenamelength += (filenameend - filenamestart);
359
prefilename[prefilenamelength] = 0;
362
// Create a buffer for the output filename
363
outfilename = (char *)malloc(prefilenamelength+20);
364
if(outfilename == NULL)
280
int error = ICNS_STATUS_OK;
282
icns_family_t *iconFamily = NULL;
283
unsigned int filepathlength = 0;
284
char *filename = NULL;
285
unsigned int filenamelength = 0;
286
unsigned int filenamestart = 0;
287
char *outfileprefix = NULL;
288
unsigned int outfileprefixlength = 0;
291
char *rsrcfilepath = NULL;
292
unsigned int rsrcfilepathlength = 0;
295
filepathlength = strlen(filepath);
298
rsrcfilepathlength = filepathlength + 17;
299
rsrcfilepath = (char *)malloc(rsrcfilepathlength);
300
if(rsrcfilepath == NULL)
301
return ICNS_STATUS_NO_MEMORY;
303
// Append the OS X POSIX-safe filepath to access the resource fork
304
strncpy(&rsrcfilepath[0],&filepath[0],filepathlength);
305
strncpy(&rsrcfilepath[filepathlength],"/..namedfork/rsrc",17);
308
// Get the plain filename...
309
filename = (char *)malloc(filepathlength + 1);
310
filenamestart = filepathlength-1;
311
while(filenamestart > 0) {
312
if(filepath[filenamestart] == '/')
316
filenamelength = filepathlength-filenamestart;
317
memcpy(&filename[0],&filepath[filenamestart],filenamelength);
318
filename[filenamelength] = 0;
320
// Set up the output filepath...
321
unsigned int outputpathlength = 0;
322
unsigned int filepathstart = filepathlength;
323
unsigned int filepathend = filepathlength;
325
if(outputPath != NULL)
327
outputpathlength = strlen(outputPath);
329
// Create a buffer large enough to hold the worst case
330
outfileprefix = (char *)malloc(outputpathlength+filepathlength+1);
331
if(outfileprefix == NULL)
333
error = ICNS_STATUS_NO_MEMORY;
337
// Copy in the output path
338
strncpy(&outfileprefix[0],&outputPath[0],outputpathlength);
339
outfileprefixlength = outputpathlength;
340
if(outputPath[outfileprefixlength-1] != '/')
342
outfileprefix[outfileprefixlength] = '/';
343
outfileprefixlength++;
344
outfileprefix[outfileprefixlength] = 0;
347
// Append the output filepath
348
// That is, the input filepath from the last '/' or start to the last '.' past the last '/'
349
while(filepath[filepathstart] != '/' && filepathstart > 0)
351
if(filepathstart != 0)
353
while(filepath[filepathend] != '.' && filepathend > filepathstart)
355
if(filepathend == filepathstart)
356
filepathend = filepathlength;
357
strncpy(&outfileprefix[outfileprefixlength],&filepath[filepathstart],filepathend - filepathstart);
358
outfileprefixlength += (filepathend - filepathstart);
359
outfileprefix[outfileprefixlength] = 0;
363
// Create a buffer for the input filepath (without the new extension)
364
outfileprefix = (char *)malloc(filepathlength+1);
365
if(outfileprefix == NULL)
366
return ICNS_STATUS_NO_MEMORY;
368
// Create the output filepath
369
// That is, the input filepath from the last '/' or start to the last '.' past the last '/'
370
while(filepath[filepathstart] != '/' && filepathstart > 0)
372
if(filepathstart != 0)
374
while(filepath[filepathend] != '.' && filepathend > filepathstart)
376
if(filepathend == filepathstart)
377
filepathend = filepathlength;
378
strncpy(&outfileprefix[0],&filepath[filepathstart],filepathend - filepathstart);
379
outfileprefixlength += (filepathend - filepathstart);
380
outfileprefix[outfileprefixlength] = 0;
368
383
printf("----------------------------------------------------\n");
369
printf("Reading icns family from %s...\n",filename);
384
printf("Reading icns family from %s...\n",filepath);
372
387
// If we're on an apple system, we want to try
458
519
printf(" '%s'",typeStr);
461
if(iconElement.elementType == ICNS_ICON_VERSION) {
462
icns_byte_t iconBytes[4];
463
icns_uint32_t iconVersion = 0;
464
if(iconDataSize == 4) {
465
memcpy(&iconBytes[0],(dataPtr+dataOffset+8),4);
466
iconVersion = iconBytes[3]|iconBytes[2]<<8|iconBytes[1]<<16|iconBytes[0]<<24;
468
if(extractMode & LIST_MODE) {
469
printf(" value: 0x%08X\n",iconVersion);
472
iconInfo = icns_get_image_info_for_type(iconElement.elementType);
474
if(iconInfo.iconWidth == iconInfo.iconHeight) {
475
iconDimSize = iconInfo.iconWidth;
476
} else if(iconElement.elementType == ICNS_16x12_8BIT_DATA) {
477
iconDimSize = MINI_SIZE;
478
} else if(iconElement.elementType == ICNS_16x12_4BIT_DATA) {
479
iconDimSize = MINI_SIZE;
480
} else if(iconElement.elementType == ICNS_16x12_1BIT_DATA) {
481
iconDimSize = MINI_SIZE;
482
} else if(iconElement.elementType == ICNS_16x12_1BIT_MASK) {
483
iconDimSize = MINI_SIZE;
488
if(extractMode & LIST_MODE)
491
printf(" %dx%d",iconInfo.iconWidth,iconInfo.iconHeight);
493
printf(" %d-bit",iconInfo.iconBitDepth);
522
switch(iconElement.elementType) {
523
case ICNS_TABLE_OF_CONTENTS:
525
if(extractMode & LIST_MODE) {
526
printf(" table of contents\n");
530
case ICNS_ICON_VERSION:
532
icns_byte_t iconBytes[4];
533
icns_uint32_t iconVersion = 0;
534
float iconVersionNumber = 0;
535
if(iconDataSize == 4) {
536
memcpy(&iconBytes[0],(dataPtr+dataOffset+8),4);
537
iconVersion = iconBytes[3]|iconBytes[2]<<8|iconBytes[1]<<16|iconBytes[0]<<24;
538
iconVersionNumber = *((float *)(&iconVersion));
540
if(extractMode & LIST_MODE) {
541
printf(" value: %f\n",iconVersionNumber);
545
case ICNS_TILE_VARIANT:
546
case ICNS_ROLLOVER_VARIANT:
547
case ICNS_DROP_VARIANT:
548
case ICNS_OPEN_VARIANT:
549
case ICNS_OPEN_DROP_VARIANT:
551
// Load up the variant, over-write the type and size to make it into an icns
552
icns_byte_t *variantData = (icns_byte_t*)malloc(iconElement.elementSize);
553
icns_family_t *variant = NULL;
554
icns_byte_t b[4] = {0,0,0,0};
555
memcpy(variantData,(dataPtr+dataOffset),iconElement.elementSize);
556
memcpy(variantData,"icns",4);
557
b[0] = iconElement.elementSize >> 24;
558
b[1] = iconElement.elementSize >> 16;
559
b[2] = iconElement.elementSize >> 8;
560
b[3] = iconElement.elementSize;
561
memcpy(&variantData[4], &b[0], sizeof(icns_size_t));
563
// Display some info about the variant
564
switch(iconElement.elementType) {
565
case ICNS_TILE_VARIANT:
566
if(extractMode & LIST_MODE)
567
printf(" icon variant: tile (%d bytes)\n",iconDataSize);
569
case ICNS_ROLLOVER_VARIANT:
570
if(extractMode & LIST_MODE)
571
printf(" icon variant: rollover (%d bytes)\n",iconDataSize);
573
case ICNS_DROP_VARIANT:
574
if(extractMode & LIST_MODE)
575
printf(" icon variant: drop (%d bytes)\n",iconDataSize);
577
case ICNS_OPEN_VARIANT:
578
if(extractMode & LIST_MODE)
579
printf(" icon variant: open (%d bytes)\n",iconDataSize);
581
case ICNS_OPEN_DROP_VARIANT:
582
if(extractMode & LIST_MODE)
583
printf(" icon variant: open/drop (%d bytes)\n",iconDataSize);
587
// Try to parse out the variant
588
error = icns_import_family_data(iconElement.elementSize,variantData,&variant);
591
fprintf (stderr, "Unable to read icon variant type '%s' (error while parsing)\n",typeStr);
593
icns_size_t variantLength = strlen(outfileprefix) + strlen(typeStr) + 2;
594
char *variantPrefix = (char *)malloc(variantLength);
595
if(variantPrefix != NULL) {
596
sprintf(&variantPrefix[0],"%s_%s",outfileprefix,typeStr);
597
variantPrefix[variantLength] = 0;
598
error = ExtractAndDescribeIconFamily((icns_family_t*)variant,typeStr,variantPrefix);
613
iconInfo = icns_get_image_info_for_type(iconElement.elementType);
615
if(iconInfo.iconWidth == iconInfo.iconHeight) {
616
iconDimSize = iconInfo.iconWidth;
617
} else if(iconElement.elementType == ICNS_16x12_8BIT_DATA) {
618
iconDimSize = MINI_SIZE;
619
} else if(iconElement.elementType == ICNS_16x12_4BIT_DATA) {
620
iconDimSize = MINI_SIZE;
621
} else if(iconElement.elementType == ICNS_16x12_1BIT_DATA) {
622
iconDimSize = MINI_SIZE;
623
} else if(iconElement.elementType == ICNS_16x12_1BIT_MASK) {
624
iconDimSize = MINI_SIZE;
632
if(extractMode & LIST_MODE)
635
printf(" %dx%d",iconInfo.iconWidth,iconInfo.iconHeight);
637
printf(" %d-bit",iconInfo.iconBitDepth);
640
if(iconInfo.isImage && iconInfo.isMask)
644
if((iconElement.elementSize-8) < iconInfo.iconRawDataSize) {
645
printf(" (%d bytes compressed to %d)",(int)iconInfo.iconRawDataSize,iconDataSize);
647
printf(" (%d bytes)",iconDataSize);
652
if(extractMode & EXTRACT_MODE)
654
if(extractIconSize == ALL_SIZES || extractIconSize == iconDimSize)
656
if(extractIconDepth == ALL_DEPTHS || extractIconDepth == iconInfo.iconBitDepth)
494
658
if(iconInfo.isImage)
496
if(iconInfo.isImage && iconInfo.isMask)
500
if((iconElement.elementSize-8) < iconInfo.iconRawDataSize) {
501
printf(" (%d bytes compressed to %d)",(int)iconInfo.iconRawDataSize,iconDataSize);
503
printf(" (%d bytes)",iconDataSize);
508
if(extractMode & EXTRACT_MODE)
510
if(extractIconSize == ALL_SIZES || extractIconSize == iconDimSize)
512
if(extractIconDepth == ALL_DEPTHS || extractIconDepth == iconInfo.iconBitDepth)
516
unsigned int outfilenamelength = 0;
517
FILE *outfile = NULL;
518
icns_image_t iconImage;
520
memset ( &iconImage, 0, sizeof(icns_image_t) );
522
error = icns_get_image32_with_mask_from_family(iconFamily,iconElement.elementType,&iconImage);
526
fprintf (stderr, "Unable to load 32-bit icon image with mask from icon family!\n");
530
// Set up the output file name: filename_WWxHHxDD.png
531
outfilenamelength = sprintf(&outfilename[0],"%s_%dx%dx%d.png",prefilename,iconInfo.iconWidth,iconInfo.iconHeight,iconInfo.iconBitDepth);
532
outfilename[outfilenamelength] = 0;
534
outfile = fopen(outfilename,"w");
660
unsigned int outfilepathlength = 0;
661
FILE *outfile = NULL;
662
icns_image_t iconImage;
664
memset ( &iconImage, 0, sizeof(icns_image_t) );
666
error = icns_get_image32_with_mask_from_family(iconFamily,iconElement.elementType,&iconImage);
668
if(error == ICNS_STATUS_UNSUPPORTED)
670
printf(" Unable to convert '%s' element! (Unsupported by this version of libicns)\n",typeStr);
672
else if(error != ICNS_STATUS_OK)
537
fprintf (stderr, "Unable to open %s for writing!\n",outfilename);
674
fprintf (stderr, "Unable to load 32-bit icon image with mask from icon family!\n");
541
error = WritePNGImage(outfile,&iconImage,NULL);
544
fprintf (stderr, "Error writing PNG image!\n");
546
printf(" Saved '%s' element to %s.\n",typeStr,outfilename);
549
if(outfile != NULL) {
678
// Set up the output file name: description_WWxHHxDD.png
679
outfilepathlength = sprintf(&outfilepath[0],"%s_%dx%dx%d.png",outfileprefix,iconInfo.iconWidth,iconInfo.iconHeight,iconInfo.iconBitDepth);
680
outfilepath[outfilepathlength] = 0;
682
outfile = fopen(outfilepath,"w");
685
fprintf (stderr, "Unable to open %s for writing!\n",outfilepath);
689
error = WritePNGImage(outfile,&iconImage,NULL);
692
fprintf (stderr, "Error writing PNG image!\n");
694
printf(" Saved '%s' element to %s.\n",typeStr,outfilepath);
697
if(outfile != NULL) {
705
icns_free_image(&iconImage);
557
icns_free_image(&iconImage);
565
715
// Move on to the next element