~ubuntu-branches/ubuntu/vivid/libicns/vivid

« back to all changes in this revision

Viewing changes to icnsutils/icns2png.c

  • Committer: Package Import Robot
  • Author(s): Paul Wise, Mathew Eis, Paul Wise
  • Date: 2012-06-14 10:16:49 UTC
  • mfrom: (4.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20120614101649-9o2azfu7idmgz6ra
Tags: 0.8.1-1
[ Mathew Eis ]
* New upstream release
  - No longer crashes on ARM/SPARC (Closes: #612698)
  - Understands 'odrp' type (Closes: #614031)
  - Fails with non-zero return code (Closes: #614028)
  - Fixes FTBFS with newer libpng (Closes: #635952)
* debian/control
  - Bump to 3.9.3 Standards-Version (no change needed).

[ Paul Wise ]
* Include changes from Debian NMU
* Wrap and sort various files using wrap-and-sort -s
* Compile against libjpeg-dev instead of the old version (Closes: #643316)
* Compile against libpng-dev instead of the old version (Closes: #662403)
* Adjust the watch file to only look for release versions
* Switch to debhelper compat 9 and dh tiny rules
* Drop autotools_dev and use dh-autoreconf
* Switch to dpkg-source v3
* Use multi-arch paths and fields
* Add myself to uploaders
* Add Vcs-* headers
* Also install the API docs, drop from lib package
* Switch to Debian copyright format 1.0 for the source Debian copyright file

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
File:       icnsinfo.c
3
 
Copyright (C) 2001-2008 Mathew Eis <mathew@eisbox.net>
 
3
Copyright (C) 2001-2012 Mathew Eis <mathew@eisbox.net>
4
4
 
5
5
This library is free software; you can redistribute it and/or
6
6
modify it under the terms of the GNU Library General Public
35
35
        uint8_t  a;
36
36
} pixel32_t;
37
37
 
 
38
#define CONVERSION_SUCCESS   0  // Return code on success
 
39
#define CONVERSION_SHOWDOC   1  // Return code on --version/--help
 
40
#define CONVERSION_INVALID   2  // Return code on invalid arguments
 
41
#define CONVERSION_FAILURE   3  // Return code on conversion failure
 
42
 
38
43
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
39
44
#define MAX_INPUTFILES  4096
40
45
 
41
 
#define PRINT_ICNS_ERRORS       1
 
46
#define PRINT_ICNS_ERRORS        1
42
47
 
43
 
int ExtractAndDescribeIconFamilyFile(char *filename);
 
48
int ExtractAndDescribeIconFamilyFile(char *filepath);
 
49
int ExtractAndDescribeIconFamily(icns_family_t *iconFamily,char *description,char *outfileprefix);
44
50
int WritePNGImage(FILE *outputfile,icns_image_t *image,icns_image_t *mask);
45
51
 
46
52
char    *inputFileNames[MAX_INPUTFILES];
61
67
/* Optional output directory */
62
68
char    *outputPath = NULL;
63
69
 
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 };
66
72
 
67
73
const char *depthStrs[] = { "32", "8", "4", "1" };
68
74
const int   depthVals[] = {  32 ,  8 ,  4 ,  1  };
107
113
{
108
114
        printf("icns2png 1.5                                                                  \n");
109
115
        printf("                                                                              \n");
110
 
        printf("Copyright (c) 2001-2008 Mathew Eis                                            \n");
 
116
        printf("Copyright (c) 2001-2012 Mathew Eis                                            \n");
111
117
        printf("This is free software; see the source for copying conditions.  There is NO    \n");
112
118
        printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   \n");
113
119
        printf("                                                                              \n");
160
166
        if(argc < 2)
161
167
        {
162
168
                PrintUsage();
163
 
                return -1;
 
169
                return CONVERSION_INVALID;
164
170
        }
165
171
 
166
172
        extractMode = 0;
182
188
                        extractIconDepth = ParseDepth(optarg);
183
189
                        if(extractIconSize == -1) {
184
190
                                fprintf(stderr, "Invalid icon color depth specified.\n");
185
 
                                return -1;
 
191
                                return CONVERSION_INVALID;
186
192
                        }
187
193
                        break;
188
194
                case 's':
189
195
                        extractIconSize = ParseSize(optarg);
190
196
                        if(extractIconSize == -1) {
191
197
                                fprintf(stderr, "Invalid icon size specified.\n");
192
 
                                return -1;
 
198
                                return CONVERSION_INVALID;
193
199
                        }
194
200
                        break;
195
201
                case 'v':
196
202
                        PrintVersionInfo();
197
 
                        return 1;
 
203
                        return CONVERSION_SHOWDOC;
198
204
                case 'h':
199
205
                        PrintUsage();
200
206
                        PrintHelp();
201
 
                        return 1;
 
207
                        return CONVERSION_SHOWDOC;
202
208
                case '?':
203
 
                        return -1;
 
209
                        return CONVERSION_SHOWDOC;
204
210
                }
205
211
        }
206
212
 
208
214
        {
209
215
                fprintf(stderr, "Must specify whether to list or extract icons.\n");
210
216
                PrintUsage();
211
 
                return -1;
 
217
                return CONVERSION_INVALID;
212
218
        }
213
219
        
214
220
        argc -= optind;
222
228
                inputFileNames[fileCount] = malloc(strlen(argv[0])+1);
223
229
                if(!inputFileNames[fileCount]) {
224
230
                        printf("Out of Memory\n");
225
 
                        exit(1);
 
231
                        exit(CONVERSION_FAILURE);
226
232
                }
227
233
                strcpy(inputFileNames[fileCount], argv[0]);
228
234
                fileCount++;
230
236
                argv++;
231
237
        }
232
238
        
233
 
        return 0;
 
239
        return CONVERSION_SUCCESS;
234
240
}
235
241
 
236
242
 
237
243
int main(int argc, char *argv[])
238
244
{
239
 
        int count;
240
 
        int result;
 
245
        int result = CONVERSION_SUCCESS;
 
246
        int count = 0;
241
247
        
242
248
        // Initialize the globals;
243
249
        extractIconSize = ALL_SIZES;
245
251
        extractMode = 0; // Do nothing
246
252
        
247
253
        // error messages handled by ParseOptions
248
 
        if((result = ParseOptions(argc, argv)))
 
254
    result = ParseOptions(argc, argv);
 
255
        if(result != CONVERSION_SUCCESS)
249
256
                return result;
250
257
        
251
258
        // display any exceptions thrown by libicns
253
260
        
254
261
        for(count = 0; count < fileCount; count++)
255
262
        {
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;
 
268
        }
258
269
        }
259
270
        
260
271
        for(count = 0; count < fileCount; count++)
261
272
                if(inputFileNames[count] != NULL)
262
273
                        free(inputFileNames[count]);
263
274
 
264
 
        return 0;
 
275
        return result;
265
276
}
266
277
 
267
 
 
268
 
int ExtractAndDescribeIconFamilyFile(char *filename)
 
278
int ExtractAndDescribeIconFamilyFile(char *filepath)
269
279
{
270
 
        int             error = ICNS_STATUS_OK;
271
 
        FILE            *inFile = NULL;
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;
281
 
        
282
 
        #ifdef __APPLE__
283
 
        char    *rsrcfilename = NULL;
284
 
        unsigned int    rsrcfilenamelength = 0;
285
 
        #endif
286
 
        
287
 
        filenamelength = strlen(filename);
288
 
        
289
 
        #ifdef __APPLE__
290
 
        rsrcfilenamelength = filenamelength + 17;
291
 
        rsrcfilename = (char *)malloc(rsrcfilenamelength);
292
 
        if(rsrcfilename == NULL)
293
 
                return -1;
294
 
                        
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);
298
 
        #endif
299
 
 
300
 
        // Set up the output filename...
301
 
        if(extractMode & EXTRACT_MODE)
302
 
        {               
303
 
                unsigned int    outputpathlength = 0;
304
 
                unsigned int    filenamestart = filenamelength;
305
 
                unsigned int    filenameend = filenamelength;
306
 
 
307
 
                if(outputPath != NULL)
308
 
                {       
309
 
                        outputpathlength = strlen(outputPath);
310
 
 
311
 
                        // Create a buffer large enough to hold the worst case
312
 
                        prefilename = (char *)malloc(outputpathlength+filenamelength+1);
313
 
                        if(prefilename == NULL)
314
 
                                return -1;
315
 
                        
316
 
                        // Copy in the output path
317
 
                        strncpy(&prefilename[0],&outputPath[0],outputpathlength);
318
 
                        prefilenamelength = outputpathlength;
319
 
                        if(outputPath[prefilenamelength-1] != '/')
320
 
                        {
321
 
                                prefilename[prefilenamelength] = '/';
322
 
                                prefilenamelength++;
323
 
                                prefilename[prefilenamelength] = 0;
324
 
                        }
325
 
                        
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)
329
 
                                filenamestart--;
330
 
                        if(filenamestart != 0)
331
 
                                filenamestart++;
332
 
                        while(filename[filenameend] != '.' && filenameend > filenamestart)
333
 
                                filenameend--;
334
 
                        if(filenameend == filenamestart)
335
 
                                filenameend = filenamelength;
336
 
                        strncpy(&prefilename[prefilenamelength],&filename[filenamestart],filenameend - filenamestart);
337
 
                        prefilenamelength += (filenameend - filenamestart);
338
 
                        prefilename[prefilenamelength] = 0;
339
 
                }
340
 
                else
341
 
                {
342
 
                        // Create a buffer for the input filename (without the new extension)
343
 
                        prefilename = (char *)malloc(filenamelength+1);
344
 
                        if(prefilename == NULL)
345
 
                                return -1;
346
 
 
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)
350
 
                                filenamestart--;
351
 
                        if(filenamestart != 0)
352
 
                                filenamestart++;
353
 
                        while(filename[filenameend] != '.' && filenameend > filenamestart)
354
 
                                filenameend--;
355
 
                        if(filenameend == filenamestart)
356
 
                                filenameend = filenamelength;
357
 
                        strncpy(&prefilename[0],&filename[filenamestart],filenameend - filenamestart);
358
 
                        prefilenamelength += (filenameend - filenamestart);
359
 
                        prefilename[prefilenamelength] = 0;
360
 
                }
361
 
                
362
 
                // Create a buffer for the output filename
363
 
                outfilename = (char *)malloc(prefilenamelength+20);
364
 
                if(outfilename == NULL)
365
 
                        return -1;
 
280
        int           error = ICNS_STATUS_OK;
 
281
        FILE          *inFile = NULL;
 
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;
 
289
        
 
290
        #ifdef __APPLE__
 
291
        char          *rsrcfilepath = NULL;
 
292
        unsigned int  rsrcfilepathlength = 0;
 
293
        #endif
 
294
        
 
295
        filepathlength = strlen(filepath);
 
296
        
 
297
        #ifdef __APPLE__
 
298
        rsrcfilepathlength = filepathlength + 17;
 
299
        rsrcfilepath = (char *)malloc(rsrcfilepathlength);
 
300
        if(rsrcfilepath == NULL)
 
301
                return ICNS_STATUS_NO_MEMORY;
 
302
        
 
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);
 
306
        #endif
 
307
        
 
308
        // Get the plain filename...
 
309
        filename = (char *)malloc(filepathlength + 1);
 
310
        filenamestart = filepathlength-1;
 
311
        while(filenamestart > 0) {
 
312
                if(filepath[filenamestart] == '/')
 
313
                        break;
 
314
                filenamestart--;
 
315
        }
 
316
        filenamelength = filepathlength-filenamestart;
 
317
        memcpy(&filename[0],&filepath[filenamestart],filenamelength);
 
318
        filename[filenamelength] = 0;
 
319
        
 
320
        // Set up the output filepath...
 
321
        unsigned int    outputpathlength = 0;
 
322
        unsigned int    filepathstart = filepathlength;
 
323
        unsigned int    filepathend = filepathlength;
 
324
 
 
325
        if(outputPath != NULL)
 
326
        {       
 
327
                outputpathlength = strlen(outputPath);
 
328
 
 
329
                // Create a buffer large enough to hold the worst case
 
330
                outfileprefix = (char *)malloc(outputpathlength+filepathlength+1);
 
331
                if(outfileprefix == NULL)
 
332
                {
 
333
                        error = ICNS_STATUS_NO_MEMORY;
 
334
                        goto cleanup;
 
335
                }
 
336
                
 
337
                // Copy in the output path
 
338
                strncpy(&outfileprefix[0],&outputPath[0],outputpathlength);
 
339
                outfileprefixlength = outputpathlength;
 
340
                if(outputPath[outfileprefixlength-1] != '/')
 
341
                {
 
342
                        outfileprefix[outfileprefixlength] = '/';
 
343
                        outfileprefixlength++;
 
344
                        outfileprefix[outfileprefixlength] = 0;
 
345
                }
 
346
                
 
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)
 
350
                        filepathstart--;
 
351
                if(filepathstart != 0)
 
352
                        filepathstart++;
 
353
                while(filepath[filepathend] != '.' && filepathend > filepathstart)
 
354
                        filepathend--;
 
355
                if(filepathend == filepathstart)
 
356
                        filepathend = filepathlength;
 
357
                strncpy(&outfileprefix[outfileprefixlength],&filepath[filepathstart],filepathend - filepathstart);
 
358
                outfileprefixlength += (filepathend - filepathstart);
 
359
                outfileprefix[outfileprefixlength] = 0;
 
360
        }
 
361
        else
 
362
        {
 
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;
 
367
 
 
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)
 
371
                        filepathstart--;
 
372
                if(filepathstart != 0)
 
373
                        filepathstart++;
 
374
                while(filepath[filepathend] != '.' && filepathend > filepathstart)
 
375
                        filepathend--;
 
376
                if(filepathend == filepathstart)
 
377
                        filepathend = filepathlength;
 
378
                strncpy(&outfileprefix[0],&filepath[filepathstart],filepathend - filepathstart);
 
379
                outfileprefixlength += (filepathend - filepathstart);
 
380
                outfileprefix[outfileprefixlength] = 0;
366
381
        }
367
382
        
368
383
        printf("----------------------------------------------------\n");
369
 
        printf("Reading icns family from %s...\n",filename);
 
384
        printf("Reading icns family from %s...\n",filepath);
370
385
        
371
386
        #ifdef __APPLE__
372
387
        // If we're on an apple system, we want to try
375
390
        // hide all internal errors while we try to read the resource fork
376
391
        icns_set_print_errors(0);
377
392
 
378
 
        inFile = fopen( rsrcfilename, "r" );
 
393
        inFile = fopen( rsrcfilepath, "r" );
379
394
        
380
395
        if ( inFile != NULL ) {
381
396
                error = icns_read_family_from_rsrc(inFile,&iconFamily);
382
397
                if(error == ICNS_STATUS_OK)
383
 
                        printf(" Using icon from HFS+ resource fork...\n");
 
398
                        printf("Using icon from HFS+ resource fork...\n");
384
399
                fclose(inFile);
385
400
                inFile = NULL;
386
401
        } else {
393
408
        // If we had an error, it was from trying to read the resource fork, so try the data file
394
409
        if(error != ICNS_STATUS_OK)
395
410
        {
396
 
                inFile = fopen( filename, "r" );
 
411
                inFile = fopen( filepath, "r" );
397
412
                
398
413
                if ( inFile == NULL ) {
399
 
                        fprintf (stderr, "Unable to open file %s!\n",filename);
 
414
                        fprintf (stderr, "Unable to open file %s!\n",filepath);
400
415
                        goto cleanup;
401
416
                }
402
417
 
403
418
                error = icns_read_family_from_file(inFile,&iconFamily);
404
 
                        
 
419
                
405
420
                fclose(inFile);
406
421
        }
407
422
        
408
423
        #else
409
424
        // On all other systems, read just the file
410
425
 
411
 
        inFile = fopen( filename, "r" );
 
426
        inFile = fopen( filepath, "r" );
412
427
        
413
428
        if ( inFile == NULL ) {
414
 
                fprintf (stderr, "Unable to open file %s!\n",filename);
 
429
                fprintf (stderr, "Unable to open file %s!\n",filepath);
415
430
                goto cleanup;
416
431
        }
417
432
 
422
437
        #endif
423
438
                        
424
439
        if(error) {
425
 
                fprintf (stderr, "Unable to read icns family from file %s!\n",filename);
 
440
                fprintf (stderr, "Unable to read icns family from file %s!\n",filepath);
426
441
                goto cleanup;
427
442
        }
428
443
        
 
444
        error = ExtractAndDescribeIconFamily(iconFamily,filename,outfileprefix);
 
445
 
 
446
cleanup:
 
447
        
 
448
        
 
449
        #ifdef __APPLE__
 
450
        if(rsrcfilepath != NULL) {
 
451
                free(rsrcfilepath);
 
452
                rsrcfilepath = NULL;
 
453
        }
 
454
        #endif
 
455
        if(iconFamily != NULL) {
 
456
                free(iconFamily);
 
457
                iconFamily = NULL;
 
458
        }
 
459
        if(outfileprefix != NULL) {
 
460
                free(outfileprefix);
 
461
                outfileprefix = NULL;
 
462
        }
 
463
        if(filename != NULL) {
 
464
                free(filename);
 
465
                filename = NULL;
 
466
        }
 
467
 
 
468
        
 
469
        return error;
 
470
}
 
471
 
 
472
int ExtractAndDescribeIconFamily(icns_family_t *iconFamily,char *description,char *outfileprefix) {
 
473
        int             error = ICNS_STATUS_OK;
 
474
        icns_byte_t *dataPtr = (icns_byte_t*)iconFamily;
 
475
        unsigned long  dataOffset = 0;
 
476
        int           imageCount = 0;
 
477
        int           elementCount = 0;
 
478
        int           extractedCount = 0;
 
479
        char           *outfilepath = NULL;
 
480
        
 
481
        printf(" Extracting icons from %s...\n",description);
 
482
        
 
483
        // Create a buffer for the output filename
 
484
        if(extractMode & EXTRACT_MODE) {
 
485
                outfilepath = (char *)malloc(strlen(outfileprefix)+25);
 
486
                if(outfilepath == NULL)
 
487
                        return ICNS_STATUS_NO_MEMORY;
 
488
        }
 
489
        
429
490
        // Start listing info:
430
491
        if(extractMode & LIST_MODE) {
431
492
                char typeStr[5];
432
493
                icns_type_str(iconFamily->resourceType,typeStr);
433
 
                printf(" Icon family type is '%s'\n",typeStr);
434
 
                printf(" Icon family size is %d bytes\n",iconFamily->resourceSize);
 
494
                printf(" Icon family size is %d bytes (including %d byte header)\n",iconFamily->resourceSize,8);
435
495
        }
436
496
        
437
497
        // Skip past the icns header
441
501
        if(extractMode & LIST_MODE)
442
502
                printf(" Listing icon elements...\n");
443
503
        
444
 
        while(((dataOffset+8) < iconFamily->resourceSize) && (error == 0))
 
504
    // Loop through and convert each icon
 
505
        while(((dataOffset+8) < iconFamily->resourceSize) && (error == 0 || error == ICNS_STATUS_UNSUPPORTED))
445
506
        {
446
507
                icns_element_t   iconElement;
447
508
                icns_icon_info_t iconInfo;
458
519
                        printf("  '%s'",typeStr);
459
520
                }
460
521
                
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;
467
 
                        }
468
 
                        if(extractMode & LIST_MODE) {
469
 
                                printf(" value: 0x%08X\n",iconVersion);
470
 
                        }
471
 
                } else {
472
 
                        iconInfo = icns_get_image_info_for_type(iconElement.elementType);
473
 
                        
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;
484
 
                        } else {
485
 
                                iconDimSize = -1;
486
 
                        }
487
 
                        
488
 
                        if(extractMode & LIST_MODE)
489
 
                        {
490
 
                                // size
491
 
                                printf(" %dx%d",iconInfo.iconWidth,iconInfo.iconHeight);
492
 
                                // bit depth
493
 
                                printf(" %d-bit",iconInfo.iconBitDepth);
 
522
                switch(iconElement.elementType) {
 
523
                        case ICNS_TABLE_OF_CONTENTS:
 
524
                        {
 
525
                                if(extractMode & LIST_MODE) {
 
526
                                        printf(" table of contents\n");
 
527
                                }
 
528
                        }
 
529
                        break;
 
530
                        case ICNS_ICON_VERSION:
 
531
                        {
 
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));
 
539
                                }
 
540
                                if(extractMode & LIST_MODE) {
 
541
                                        printf(" value: %f\n",iconVersionNumber);
 
542
                                }
 
543
                        }
 
544
                        break;
 
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:
 
550
                        {
 
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));
 
562
                                
 
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);
 
568
                                                break;
 
569
                                        case ICNS_ROLLOVER_VARIANT:
 
570
                                                if(extractMode & LIST_MODE)
 
571
                                                        printf(" icon variant: rollover (%d bytes)\n",iconDataSize);
 
572
                                                break;
 
573
                                        case ICNS_DROP_VARIANT:
 
574
                                                if(extractMode & LIST_MODE)
 
575
                                                        printf(" icon variant: drop (%d bytes)\n",iconDataSize);
 
576
                                                break;
 
577
                                        case ICNS_OPEN_VARIANT:
 
578
                                                if(extractMode & LIST_MODE)
 
579
                                                        printf(" icon variant: open (%d bytes)\n",iconDataSize);
 
580
                                                break;
 
581
                                        case ICNS_OPEN_DROP_VARIANT:
 
582
                                                if(extractMode & LIST_MODE)
 
583
                                                        printf(" icon variant: open/drop (%d bytes)\n",iconDataSize);
 
584
                                                break;
 
585
                                }
 
586
 
 
587
                                // Try to parse out the variant
 
588
                                error = icns_import_family_data(iconElement.elementSize,variantData,&variant);
 
589
                                
 
590
                                if(error) {
 
591
                                        fprintf (stderr, "Unable to read icon variant type '%s' (error while parsing)\n",typeStr);
 
592
                                } else {
 
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);
 
599
                                                free(variantPrefix);
 
600
                                        }
 
601
                                }
 
602
                                
 
603
                                free(variant);
 
604
                                
 
605
                                if(variantData) {
 
606
                                        free(variantData);
 
607
                                        variantData = NULL;
 
608
                                }
 
609
                        }
 
610
                        break;
 
611
                        default:
 
612
            {
 
613
                                iconInfo = icns_get_image_info_for_type(iconElement.elementType);
 
614
                                
 
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;
 
625
                                } else {
 
626
                                        iconDimSize = -1;
 
627
                                }
 
628
                
 
629
                if(iconInfo.isImage)
 
630
                    imageCount++;
 
631
                                
 
632
                                if(extractMode & LIST_MODE)
 
633
                                {
 
634
                                        // size
 
635
                                        printf(" %dx%d",iconInfo.iconWidth,iconInfo.iconHeight);
 
636
                                        // bit depth
 
637
                                        printf(" %d-bit",iconInfo.iconBitDepth);
 
638
                                        if(iconInfo.isImage)
 
639
                                                printf(" icon");
 
640
                                        if(iconInfo.isImage && iconInfo.isMask)
 
641
                                                printf(" with");
 
642
                                        if(iconInfo.isMask)
 
643
                                                printf(" mask");
 
644
                                        if((iconElement.elementSize-8) < iconInfo.iconRawDataSize) {
 
645
                                                printf(" (%d bytes compressed to %d)",(int)iconInfo.iconRawDataSize,iconDataSize);
 
646
                                        } else {
 
647
                                                printf(" (%d bytes)",iconDataSize);
 
648
                                        }
 
649
                                        printf("\n");
 
650
                                }
 
651
                                
 
652
                                if(extractMode & EXTRACT_MODE)
 
653
                                {
 
654
                                if(extractIconSize == ALL_SIZES || extractIconSize == iconDimSize)
 
655
                                {
 
656
                                if(extractIconDepth == ALL_DEPTHS || extractIconDepth == iconInfo.iconBitDepth)
 
657
                                {
494
658
                                if(iconInfo.isImage)
495
 
                                        printf(" icon");
496
 
                                if(iconInfo.isImage && iconInfo.isMask)
497
 
                                        printf(" with");
498
 
                                if(iconInfo.isMask)
499
 
                                        printf(" mask");
500
 
                                if((iconElement.elementSize-8) < iconInfo.iconRawDataSize) {
501
 
                                        printf(" (%d bytes compressed to %d)",(int)iconInfo.iconRawDataSize,iconDataSize);
502
 
                                } else {
503
 
                                        printf(" (%d bytes)",iconDataSize);
504
 
                                }
505
 
                                printf("\n");
506
 
                        }
507
 
                        
508
 
                        if(extractMode & EXTRACT_MODE)
509
 
                        {
510
 
                        if(extractIconSize == ALL_SIZES || extractIconSize == iconDimSize)
511
 
                        {
512
 
                        if(extractIconDepth == ALL_DEPTHS || extractIconDepth == iconInfo.iconBitDepth)
513
 
                        {
514
 
                        if(iconInfo.isImage)
515
 
                        {
516
 
                                unsigned int    outfilenamelength = 0;
517
 
                                FILE            *outfile = NULL;
518
 
                                icns_image_t    iconImage;
519
 
                                
520
 
                                memset ( &iconImage, 0, sizeof(icns_image_t) );
521
 
                                
522
 
                                error = icns_get_image32_with_mask_from_family(iconFamily,iconElement.elementType,&iconImage);
523
 
                                
524
 
                                if(error)
525
 
                                {
526
 
                                        fprintf (stderr, "Unable to load 32-bit icon image with mask from icon family!\n");
527
 
                                }
528
 
                                else
529
 
                                {
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;
533
 
                                        
534
 
                                        outfile = fopen(outfilename,"w");
535
 
                                        if(!outfile)
 
659
                                {
 
660
                                        unsigned int    outfilepathlength = 0;
 
661
                                        FILE            *outfile = NULL;
 
662
                                        icns_image_t    iconImage;
 
663
                                        
 
664
                                        memset ( &iconImage, 0, sizeof(icns_image_t) );
 
665
                                        
 
666
                                        error = icns_get_image32_with_mask_from_family(iconFamily,iconElement.elementType,&iconImage);
 
667
                    
 
668
                    if(error == ICNS_STATUS_UNSUPPORTED)
 
669
                    {
 
670
                        printf("  Unable to convert '%s' element! (Unsupported by this version of libicns)\n",typeStr);
 
671
                    }
 
672
                    else if(error != ICNS_STATUS_OK)
536
673
                                        {
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");
538
675
                                        }
539
676
                                        else
540
677
                                        {
541
 
                                                error = WritePNGImage(outfile,&iconImage,NULL);
542
 
                                                
543
 
                                                if(error) {
544
 
                                                        fprintf (stderr, "Error writing PNG image!\n");
545
 
                                                } else {
546
 
                                                        printf("  Saved '%s' element to %s.\n",typeStr,outfilename);
547
 
                                                }
548
 
                                                
549
 
                                                if(outfile != NULL) {
550
 
                                                        fclose(outfile);
551
 
                                                        outfile = NULL;
552
 
                                                }
 
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;
 
681
                                                
 
682
                                                outfile = fopen(outfilepath,"w");
 
683
                                                if(!outfile)
 
684
                                                {
 
685
                                                        fprintf (stderr, "Unable to open %s for writing!\n",outfilepath);
 
686
                                                }
 
687
                                                else
 
688
                                                {
 
689
                                                        error = WritePNGImage(outfile,&iconImage,NULL);
 
690
                                                        
 
691
                                                        if(error) {
 
692
                                                                fprintf (stderr, "Error writing PNG image!\n");
 
693
                                                        } else {
 
694
                                                                printf("  Saved '%s' element to %s.\n",typeStr,outfilepath);
 
695
                                                        }
 
696
                                                        
 
697
                                                        if(outfile != NULL) {
 
698
                                                                fclose(outfile);
 
699
                                                                outfile = NULL;
 
700
                                                        }
 
701
                                                }
 
702
                                                
 
703
                                                extractedCount++;
 
704
                                                
 
705
                                                icns_free_image(&iconImage);
553
706
                                        }
554
 
                                        
555
 
                                        extractedCount++;
556
 
                                        
557
 
                                        icns_free_image(&iconImage);
558
 
                                }
559
 
                        }
560
 
                        }
561
 
                        }
562
 
                        }
 
707
                                }
 
708
                                }
 
709
                                }
 
710
                                }
 
711
            }
 
712
            break;
563
713
                }
564
714
                
565
715
                // Move on to the next element
570
720
        if(extractMode & LIST_MODE)
571
721
        {
572
722
                if(elementCount > 0) {
573
 
                        printf(" %d elements total in %s.\n",elementCount,filename);
 
723
                        printf("%d elements total found in %s.\n",elementCount,description);
574
724
                } else {
575
 
                        printf(" No elements found in %s.\n",filename);
 
725
                        printf("No elements found in %s.\n",description);
576
726
                }
577
727
        }
578
728
        
579
729
        if(extractMode & EXTRACT_MODE)
580
730
        {
581
731
                if(extractedCount > 0) {
582
 
                        printf(" Extracted %d elements from %s.\n",extractedCount,filename);
 
732
            if(extractedCount == imageCount) {
 
733
                printf("Extracted %d images from %s.\n",extractedCount,description);
 
734
            } else {
 
735
                printf("Extracted %d of %d images from %s.\n",extractedCount,imageCount,description);
 
736
            }
583
737
                } else {
584
 
                        printf(" No elements were extracted from %s.\n",filename);
 
738
                        printf("No elements were extracted from %s.\n",description);
585
739
                }               
586
740
        }
587
741
        
588
 
cleanup:
589
 
        
590
 
        
591
 
        #ifdef __APPLE__
592
 
        if(rsrcfilename != NULL) {
593
 
                free(rsrcfilename);
594
 
                rsrcfilename = NULL;
595
 
        }
596
 
        #endif
597
 
        if(iconFamily != NULL) {
598
 
                free(iconFamily);
599
 
                iconFamily = NULL;
600
 
        }
601
 
        if(prefilename != NULL) {
602
 
                free(prefilename);
603
 
                prefilename = NULL;
604
 
        }
605
 
        if(outfilename != NULL) {
606
 
                free(outfilename);
607
 
                outfilename = NULL;
 
742
        if(outfilepath != NULL) {
 
743
                free(outfilepath);
 
744
                outfilepath = NULL;
608
745
        }
609
746
        
610
747
        return error;
611
748
}
612
749
 
613
 
 
614
750
//***************************** WritePNGImage **************************//
615
751
// Relatively generic PNG file writing routine
616
752
 
621
757
        int                     image_channels = 0;
622
758
        int                     image_pixel_depth = 0;
623
759
        int                     mask_channels = 0;
624
 
        int                     mask_bit_depth = 0;
625
760
        png_structp             png_ptr;
626
761
        png_infop               info_ptr;
627
762
        png_bytep               *row_pointers;
647
782
        
648
783
        if(mask != NULL) {
649
784
                mask_channels = mask->imageChannels;
650
 
                mask_bit_depth = mask->imagePixelDepth;
651
785
        }
652
786
        
653
787
        png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);