~ubuntu-branches/ubuntu/trusty/netpbm-free/trusty

« back to all changes in this revision

Viewing changes to ppm/winicontoppm.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Barth
  • Date: 2004-07-29 20:25:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040729202546-9o69r65403wvtla5
Tags: 2:10.0-5
* build-depends against libtiff4.
* fix typo in ppmtowinicon. Closes: #261999.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* winicontoppm.c - read a MS Windows .ico file and write portable pixmap(s)
2
2
**
3
 
** Copyright (C) 2000 by Lee Benfield - lee@recoil.org
 
3
** Copyright (C) 2000,2003 by Lee Benfield - lee@benf.org
4
4
**
5
5
** Permission to use, copy, modify, and distribute this software and its
6
6
** documentation for any purpose and without fee is hereby granted, provided
8
8
** copyright notice and this permission notice appear in supporting
9
9
** documentation.  This software is provided "as is" without express or
10
10
** implied warranty.
 
11
**
 
12
** Changes:
 
13
** 
 
14
** 03/2003 - Added 24+32 bpp support.
11
15
*/
12
16
 
13
17
#include <string.h>
14
18
#include <math.h>
 
19
#include <assert.h>
 
20
 
15
21
#include "ppm.h"
16
22
#include "winico.h"
17
23
 
18
24
#define MAJVERSION 0
19
 
#define MINVERSION 3
20
 
 
21
 
static int      writeToFile = 0;
22
 
static int      verbose = 0;
23
 
static int      allicons = 0;
24
 
static int      writeands = 0;
25
 
static int      bestqual = 0;
26
 
static int      multippm = 0;
27
 
static int      file_offset = 0;    /* not actually used, but useful for debug */
28
 
static char     er_read[] = "%s: read error";
29
 
static char *   infname;
30
 
static char *   outfname;
 
25
#define MINVERSION 4
 
26
 
 
27
int asprintf(char **strp, const char *fmt, ...);
 
28
 
 
29
static int file_offset = 0;    /* not actually used, but useful for debug */
 
30
static const char     er_read[] = "%s: read error";
 
31
static const char *   infname;
31
32
static FILE *   ifp;
32
33
 
 
34
struct cmdlineInfo {
 
35
    /* All the information the user supplied in the command line,
 
36
       in a form easy for the program to use.
 
37
    */
 
38
    const char * inputFilespec;
 
39
    const char * outputFilespec;
 
40
    unsigned int allicons;
 
41
    unsigned int bestqual;
 
42
    unsigned int writeands;
 
43
    unsigned int multippm;
 
44
    unsigned int verbose;
 
45
};
 
46
 
 
47
 
 
48
 
 
49
 
 
50
static void
 
51
parseCommandLine ( int argc, char ** argv,
 
52
                   struct cmdlineInfo *cmdlineP ) {
 
53
/*----------------------------------------------------------------------------
 
54
   parse program command line described in Unix standard form by argc
 
55
   and argv.  Return the information in the options as *cmdlineP.  
 
56
 
 
57
   If command line is internally inconsistent (invalid options, etc.),
 
58
   issue error message to stderr and abort program.
 
59
 
 
60
   Note that the strings we return are stored in the storage that
 
61
   was passed to us as the argv array.  We also trash *argv.
 
62
-----------------------------------------------------------------------------*/
 
63
    optEntry *option_def = malloc(100*sizeof(optEntry));
 
64
        /* Instructions to optParseOptions3 on how to parse our options.
 
65
         */
 
66
    optStruct3 opt;
 
67
 
 
68
    unsigned int option_def_index;
 
69
 
 
70
    option_def_index = 0;   /* incremented by OPTENT3 */
 
71
    OPTENT3(0, "allicons",     OPT_FLAG,   NULL,                  
 
72
            &cmdlineP->allicons,       0 );
 
73
    OPTENT3(0, "bestqual",     OPT_FLAG,   NULL,                  
 
74
            &cmdlineP->bestqual,       0 );
 
75
    OPTENT3(0, "writeands",    OPT_FLAG,   NULL,                  
 
76
            &cmdlineP->writeands,      0 );
 
77
    OPTENT3(0, "multippm",     OPT_FLAG,   NULL,                  
 
78
            &cmdlineP->multippm,       0 );
 
79
    OPTENT3(0, "verbose",      OPT_FLAG,   NULL,                  
 
80
            &cmdlineP->verbose,        0 );
 
81
 
 
82
    opt.opt_table = option_def;
 
83
    opt.short_allowed = FALSE;  /* We have no short (old-fashioned) options */
 
84
    opt.allowNegNum = FALSE;  /* We have no parms that are negative numbers */
 
85
 
 
86
    pm_optParseOptions3( &argc, argv, opt, sizeof(opt), 0);
 
87
        /* Uses and sets argc, argv, and some of *cmdlineP and others. */
 
88
 
 
89
 
 
90
    if (argc-1 < 1) 
 
91
        cmdlineP->inputFilespec = "-";
 
92
    else
 
93
        cmdlineP->inputFilespec = argv[1];
 
94
 
 
95
    if (argc-1 < 2) {
 
96
        cmdlineP->outputFilespec = "-";
 
97
        
 
98
        if (cmdlineP->writeands || cmdlineP->allicons)
 
99
            pm_error("If you specify the -writeands or -allicons option, "
 
100
                     "you must also specify an output file name argument.");
 
101
    } else
 
102
        cmdlineP->outputFilespec = argv[2];
 
103
 
 
104
    if (argc-1 > 2)
 
105
        pm_error("Too many arguments (%d).  Input filespec and "
 
106
                 "output filespec are the only possible arguments.",
 
107
                 argc-1);
 
108
}
 
109
 
 
110
 
 
111
 
 
112
 
33
113
static int 
34
114
GetByte(void) {
35
115
    int v;
86
166
    overflow_add(length,1);
87
167
    fread(string,sizeof(u1),length,ifp);
88
168
    string[length] = 0;
89
 
    file_offset += length;
 
169
    file_offset += length * sizeof(u1);
90
170
    return string;
91
171
}
92
172
 
114
194
    entry->bitcount      = readU2();
115
195
    entry->size_in_bytes = readU4();
116
196
    entry->file_offset   = readU4();
117
 
 
118
 
    /*
119
 
     * Spec says 0 color count is really 256.
120
 
     */
121
 
    if (entry->color_count == 0) entry->color_count = 256;
122
 
   
 
197
    entry->colors        = NULL;
 
198
    entry->ih            = NULL;
 
199
    entry->xorBitmap     = NULL;
 
200
    entry->andBitmap     = NULL;
 
201
    
123
202
    return entry;
124
203
}
125
204
 
126
205
 
127
206
 
128
207
static IC_InfoHeader 
129
 
readInfoHeader (void) 
 
208
readInfoHeader (IC_Entry entry) 
130
209
{
131
210
    IC_InfoHeader ih = malloc ( sizeof (* ih) );
132
211
    ih->size            = readU4();
140
219
    ih->y_pixels_per_m  = readU4();
141
220
    ih->colors_used     = readU4();
142
221
    ih->colors_important = readU4();
 
222
    
 
223
    if (!entry->bitcount) entry->bitcount = ih->bitcount;
 
224
    if (entry->color_count == 0 && 
 
225
        entry->bitcount <= 8) entry->color_count = 256;
 
226
    if (ih->compression) {
 
227
        pm_error("Can't handle compressed icons");
 
228
    }
143
229
    return ih;
144
230
}
145
231
 
190
276
        int xOrVal = 128;
191
277
        u1 * row = readU1String(xBytes);
192
278
        for (x = 0; x< width; x++) {
193
 
            *(bitmap+((height-tmp-1)*width) + (x)) = (row[rowByte] & xOrVal) / xOrVal;
 
279
            *(bitmap+((height-tmp-1)*width) + (x)) = 
 
280
                (row[rowByte] & xOrVal) / xOrVal;
194
281
            if (xOrVal == 1) {
195
282
                xOrVal = 128;
196
283
                rowByte++;
198
285
                xOrVal >>= 1;
199
286
            }
200
287
        }
 
288
        free(row);
201
289
    }
202
290
    return bitmap;
203
291
}
227
315
             * 2 nibbles, 2 values.
228
316
             */
229
317
            if (bottom) {
230
 
                *(bitmap+((height-tmp-1)*width) + (x)) = (row[rowByte] & 0xF0) >> 4;
 
318
                *(bitmap+((height-tmp-1)*width) + (x)) = 
 
319
                    (row[rowByte] & 0xF0) >> 4;
231
320
            } else {
232
321
                *(bitmap+((height-tmp-1)*width) + (x)) = (row[rowByte] & 0xF);
233
322
                rowByte++;
234
323
            }
235
324
            bottom = !bottom;
236
325
        }
 
326
    free(row);
237
327
    }
238
328
    return bitmap;
239
329
}
262
352
            *(bitmap+((height-tmp-1)*width) + (x)) = row[rowByte];
263
353
            rowByte++;
264
354
        }
265
 
    }
266
 
    return bitmap;
267
 
}
268
 
   
269
 
 
 
355
        free(row);
 
356
    }
 
357
    return bitmap;
 
358
}
 
359
 
 
360
/*
 
361
 * Read a true color bitmap. (24/32 bits)
 
362
 * 
 
363
 * The output routine deplanarizes it for us, we keep it flat here.
 
364
 */
 
365
static u1 *
 
366
readXBitmap (int width, int height, int bpp)
 
367
{
 
368
    int tmp = 0;
 
369
    int bytes = bpp >> 3;
 
370
    u1 * bitmap = malloc3 (sizeof(u1)*bytes, width, height);
 
371
    /* remember - bmp (dib) stored upside down, so reverse */
 
372
    u1 * bitcurptr = bitmap + (bytes * width * (height-1) ) * (sizeof (u1));
 
373
    unsigned int xBytes = width * bytes;
 
374
    overflow2(bytes,sizeof(u1));
 
375
 
 
376
    if (bitmap == NULL)
 
377
        pm_error("out of memory");
 
378
 
 
379
    for (tmp = 0;tmp < height; tmp++, bitcurptr -= xBytes) {
 
380
        u1 * row = readU1String(xBytes);
 
381
        memcpy(bitcurptr, row, xBytes);
 
382
        free(row);
 
383
    }
 
384
    return bitmap;
 
385
}
270
386
 
271
387
static MS_Ico 
272
 
readIconFile (void) 
273
 
{
 
388
readIconFile (bool const verbose) {
274
389
    int iter,iter2;
275
390
 
276
391
    MS_Ico MSIconData= malloc( sizeof (* MSIconData) );
302
417
    /* After that, we have to read in the infoheader, color map (if
303
418
     * any) and the actual bit/pix maps for the icons.  
304
419
     */
305
 
    if (verbose) fprintf (stderr,"#\tColors\tBPP\tWidth\tHeight\n");
 
420
    if (verbose) 
 
421
        fprintf (stderr,"#\tColors\tBPP\tWidth\tHeight\n");
306
422
    for (iter = 0;iter < MSIconData->count ; iter++ ) {
307
423
        int bpp;
308
 
        MSIconData->entries[iter]->ih = readInfoHeader ();
309
 
        MSIconData->entries[iter]->colors = 
310
 
            malloc2 (MSIconData->entries[iter]->color_count,
311
 
                    sizeof(IC_Color *));
312
 
        for (iter2 = 0;
313
 
             iter2 < MSIconData->entries[iter]->color_count ; 
314
 
             iter2++ ) {
315
 
            MSIconData->entries[iter]->colors[iter2] = readICColor();
 
424
        MSIconData->entries[iter]->ih =
 
425
            readInfoHeader (MSIconData->entries[iter]);
 
426
       
 
427
        /* What's the bits per pixel? */
 
428
        bpp = MSIconData->entries[iter]->bitcount; 
 
429
        /* Read the palette, if appropriate */
 
430
        switch (bpp) {
 
431
        case 24:
 
432
        case 32:
 
433
            /* 24/32 bpp icon has no palette */
 
434
            break;
 
435
        default:
 
436
            MSIconData->entries[iter]->colors = 
 
437
                malloc2 (MSIconData->entries[iter]->color_count,
 
438
                sizeof(IC_Color *));
 
439
            if (MSIconData->entries[iter]->colors == NULL)
 
440
                pm_error("out of memory");
 
441
 
 
442
            for (iter2 = 0;
 
443
                 iter2 < MSIconData->entries[iter]->color_count ; 
 
444
                 iter2++ ) {
 
445
                MSIconData->entries[iter]->colors[iter2] = readICColor();
 
446
            }
 
447
            break;
316
448
        }
317
 
        /* What's the bits per pixel?  Bit confusing, since there's a
318
 
         * field in entry, and in the infoheader.  I'll use both but
319
 
         * let the entry field take precedence.  
320
 
         */
321
 
        bpp = MSIconData->entries[iter]->bitcount ? 
322
 
            MSIconData->entries[iter]->bitcount : 
323
 
            MSIconData->entries[iter]->ih->bitcount;
324
 
        if (verbose) 
 
449
        if (verbose) {
 
450
            char cols_text[10];
 
451
            sprintf (cols_text, "%d", MSIconData->entries[iter]->color_count);
325
452
            fprintf (stderr,
326
 
                     "%d\t%d\t%d\t%d\t%d\n", iter,
327
 
                     MSIconData->entries[iter]->color_count, 
 
453
                     "%d\t%s\t%d\t%d\t%d\n", iter,
 
454
                     MSIconData->entries[iter]->color_count ? 
 
455
                     cols_text : "TRUE",
328
456
                     bpp, MSIconData->entries[iter]->width, 
329
457
                     MSIconData->entries[iter]->height);
 
458
        }
330
459
        /* Pixels are stored bottom-up, left-to-right. Pixel lines are
331
460
         * padded with zeros to end on a 32bit (4byte) boundary. Every
332
461
         * line will have the same number of bytes. Color indices are
333
462
         * zero based, meaning a pixel color of 0 represents the first
334
463
         * color table entry, a pixel color of 255 (if there are that
335
464
         * many) represents the 256th entry.  
 
465
         * 
 
466
         * 24+32 bit (16 is an abomination, which I'll avoid, and expect
 
467
         * no-one to mind) are stored 1byte/plane with a spare (alpha?)
 
468
         * byte for 32 bit.
336
469
         */
337
470
        {
338
471
            /*
354
487
                    read8Bitmap(MSIconData->entries[iter]->width,
355
488
                                MSIconData->entries[iter]->height);
356
489
                break;
 
490
            case 24:
 
491
            case 32:
 
492
                MSIconData->entries[iter]->xorBitmap = 
 
493
                    readXBitmap(MSIconData->entries[iter]->width,
 
494
                                MSIconData->entries[iter]->height,bpp);
 
495
                break;
357
496
            default:
358
 
                pm_error("Uncatered bit depth %d\n",bpp);
 
497
                pm_error("Uncatered bit depth %d",bpp);
359
498
            }
360
499
            /*
361
500
             * Read AND Bitmap
372
511
 
373
512
 
374
513
static char * 
375
 
trimOutputName (char * inputName)
 
514
trimOutputName(const char inputName[])
376
515
{
377
516
    /*
378
517
     * Just trim off the final ".ppm", if there is one, else return as is.
379
518
     * oh, for =~ ... :)
380
519
     */
381
 
    char * outFile = malloc ( sizeof (char) * (strlen (inputName) + 1));
382
 
    overflow_add(strlen(inputName), 1);
383
 
    strcpy(outFile, inputName);
 
520
    char * outFile = strdup(inputName);
384
521
    if (!strcmp (outFile + (strlen (outFile) - 4), ".ppm")) {
385
522
        *(outFile + (strlen (outFile) - 4)) = 0;
386
523
    }
412
549
    return best;
413
550
}
414
551
 
415
 
 
416
 
 
417
552
static void
418
 
writeXors(bool const writeToFile, FILE * const multiOutF,
419
 
          char outputFileBase[], IC_Entry const entry,
420
 
          int const entryNum, bool const multiple, bool const xor) {
 
553
writeXors(FILE *   const multiOutF,
 
554
          char           outputFileBase[], 
 
555
          IC_Entry const entry,
 
556
          int      const entryNum,
 
557
          bool     const multiple, 
 
558
          bool     const xor) {
421
559
/*----------------------------------------------------------------------------
422
560
   Write an "xor" image (i.e. the main image) out.
423
561
 
435
573
    FILE * outF;
436
574
    pixel ** ppm_array;
437
575
    int row;
 
576
    int pel_size;
438
577
    char *outputFile;
439
 
 
440
 
    overflow_add(strlen(outputFileBase),20);
441
 
    outputFile = malloc(sizeof(char) * (strlen (outputFileBase) + 20));
442
 
 
443
 
    if (multiOutF)
 
578
    int maxval;
 
579
    int forcetext;
 
580
 
 
581
    if (multiOutF) {
444
582
        outF = multiOutF;
445
 
    else {
446
 
        if (writeToFile) {
 
583
        outputFile = strdup("");
 
584
    } else {
 
585
        if (outputFileBase) {
447
586
            if (multiple) {
448
 
                sprintf(outputFile, "%s%s_%d.ppm",
449
 
                        outputFileBase,(xor ? "_xor" : ""), entryNum);
 
587
                asprintf(&outputFile, "%s%s_%d.ppm",
 
588
                          outputFileBase,(xor ? "_xor" : ""), entryNum);
450
589
            } else { 
451
 
                sprintf(outputFile, "%s%s.ppm",
452
 
                        outputFileBase,(xor ? "_xor" : ""));
 
590
                asprintf(&outputFile, "%s%s.ppm",
 
591
                          outputFileBase,(xor ? "_xor" : ""));
453
592
            }
454
593
        } else
455
 
            strcpy(outputFile, "-");
 
594
            outputFile = strdup("-");
456
595
        
457
596
        outF = pm_openw(outputFile);
458
597
    }
465
604
    for (row=0; row < entry->height; row++) {
466
605
        u1 * xorRow;
467
606
        int col;
468
 
        xorRow = entry->xorBitmap + row * entry->width;
469
 
        for (col=0; col < entry->width; col++) {
470
 
            int colorIndex;
471
 
            IC_Color color;
472
 
            colorIndex  = xorRow[col];
473
 
            color = entry->colors[colorIndex];
474
 
            PPM_ASSIGN(ppm_array[row][col],
475
 
                       color->red,color->green,color->blue);
 
607
        switch (entry->bitcount) {
 
608
        case 24:
 
609
        case 32:
 
610
            pel_size = entry->bitcount >> 3;
 
611
            xorRow = entry->xorBitmap + row * entry->width * pel_size;
 
612
            for (col=0; col < entry->width*pel_size;col+=pel_size) {
 
613
                PPM_ASSIGN(ppm_array[row][col/pel_size],
 
614
                           xorRow[col+2],xorRow[col+1],xorRow[col]);
 
615
            }
 
616
            break;
 
617
        default:
 
618
            xorRow = entry->xorBitmap + row * entry->width;
 
619
            for (col=0; col < entry->width; col++) {
 
620
                int colorIndex;
 
621
                IC_Color color;
 
622
                colorIndex  = xorRow[col];
 
623
                color = entry->colors[colorIndex];
 
624
                PPM_ASSIGN(ppm_array[row][col],
 
625
                           color->red,color->green,color->blue);
 
626
            }
 
627
            break;
476
628
        }
477
629
    }    
 
630
    
 
631
    maxval = 255;
 
632
    forcetext = 0;
 
633
 
478
634
    ppm_writeppm(outF,ppm_array,entry->width, entry->height, 
479
 
                 (pixval) 255, 0);
 
635
                 (pixval) maxval, forcetext);
480
636
    ppm_freearray(ppm_array,entry->height);
481
637
 
 
638
    free(outputFile);
 
639
    
482
640
    if (!multiOutF) 
483
641
        pm_close(outF);
484
642
}
490
648
          char outputFileBase[], IC_Entry const entry, int const entryNum, 
491
649
          bool multiple) {
492
650
/*----------------------------------------------------------------------------
493
 
   Write an "and" image (i.e. the alpha mask) out.
 
651
   Write the "and" image (i.e. the alpha mask) of the image 'IC_Entry' out.
494
652
 
495
653
   'multiple' means this is one of multiple images that are being written.
496
654
   'entryNum' is the sequence number within the winicon file of the image
511
669
    else {
512
670
        char *outputFile;
513
671
 
514
 
        overflow_add(strlen(outputFileBase),20);
515
 
        outputFile =  malloc ( sizeof (char) * (strlen (outputFileBase) + 20));
 
672
        assert(outputFileBase);
516
673
 
517
 
        if (allicons) 
518
 
            sprintf(outputFile, "%s_and_%d.pbm", outputFileBase, entryNum);
 
674
        if (multiple) 
 
675
            asprintf(&outputFile, "%s_and_%d.pbm", outputFileBase, entryNum);
519
676
        else 
520
 
            sprintf(outputFile, "%s_and.pbm", outputFileBase);
 
677
            asprintf(&outputFile, "%s_and.pbm", outputFileBase);
521
678
        outF = pm_openw(outputFile);
522
679
        free(outputFile);
523
680
    }
535
692
 
536
693
    pbm_freearray(pbm_array, entry->height);
537
694
    if (!multiOutF)
538
 
        pm_close (outF);         
 
695
        pm_close (outF);     
539
696
}
540
697
 
541
698
 
542
699
 
543
700
static void
544
 
openMultiXor(char outputFileBase[], FILE ** const multiOutFP) {
 
701
openMultiXor(char          outputFileBase[], 
 
702
             bool    const writeands,
 
703
             FILE ** const multiOutFP) {
545
704
 
546
705
    char *outputFile;
547
706
 
548
 
    overflow_add(strlen(outputFileBase),20);
549
 
    outputFile =  malloc ( sizeof (char) * (strlen (outputFileBase) + 20));
 
707
    if (outputFileBase) {
 
708
        asprintf(&outputFile, "%s%s.ppm",
 
709
                  outputFileBase, (writeands ? "_xor" : ""));
 
710
    } else
 
711
        outputFile = strdup("-");
 
712
 
550
713
    /*
551
714
     * Open the output file now, it'll stay open the whole time.
552
715
     */
553
 
    if (writeToFile) {
554
 
        sprintf(outputFile, "%s%s.ppm",
555
 
                outputFileBase, (writeands ? "_xor" : ""));
556
 
    } else {
557
 
        sprintf(outputFile,"-");
558
 
    }
559
716
    *multiOutFP = pm_openw(outputFile);
 
717
 
560
718
    free(outputFile);
561
719
}
562
720
 
567
725
 
568
726
    char *outputFile;
569
727
 
570
 
    overflow_add(strlen(outputFileBase),20);
571
 
    outputFile =  malloc ( sizeof (char) * (strlen (outputFileBase) + 20));
572
 
    
573
 
    sprintf(outputFile, "%s_and.pbm", outputFileBase);
 
728
    assert(outputFileBase);
 
729
 
 
730
    asprintf(&outputFile, "%s_and.pbm", outputFileBase);
574
731
    
575
732
    *multiAndOutFP = pm_openw(outputFile);
 
733
 
576
734
    free(outputFile);
577
735
}
578
736
 
579
 
 
580
 
 
581
 
 
582
 
int main (int argc, char *argv[]) {
583
 
 
584
 
    int argn;
 
737
static void free_iconentry(IC_Entry entry) {
 
738
    int x;
 
739
    if (entry->colors && entry->color_count) {
 
740
        for (x=0;x<entry->color_count;x++) free(entry->colors[x]);
 
741
        free(entry->colors);
 
742
    }
 
743
    if (entry->andBitmap) free(entry->andBitmap);
 
744
    if (entry->xorBitmap) free(entry->xorBitmap);
 
745
    if (entry->ih) free(entry->ih);
 
746
    free(entry);
 
747
}
 
748
 
 
749
static void free_icondata(MS_Ico MSIconData)
 
750
{
 
751
    int x;
 
752
    for (x=0;x<MSIconData->count;x++) {
 
753
    free_iconentry(MSIconData->entries[x]);
 
754
    }
 
755
    free(MSIconData);
 
756
}
 
757
 
 
758
 
 
759
int 
 
760
main(int argc, char *argv[]) {
 
761
 
 
762
    struct cmdlineInfo cmdline;
585
763
    int startEntry, endEntry;
586
 
    char * usage = "[-writeands] [-allicons|-bestqual] [-multippm] "
587
 
        "[-verbose] [iconfile] [ppmdestfile]";
588
764
    MS_Ico MSIconData;
589
765
    char * outputFileBase;
590
 
    char * outputFile;
591
766
    FILE * multiOutF;
592
767
    FILE * multiAndOutF;
593
768
   
594
769
    ppm_init (&argc, argv);
595
 
    /*
596
 
     * Parse command line arguments.
597
 
     */
598
 
    argn = 1;
599
 
    while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0') {
600
 
        if (pm_keymatch(argv[argn], "-verbose", 2))
601
 
            verbose++;
602
 
        else if (pm_keymatch(argv[argn], "-allicons", 2))
603
 
            allicons++;
604
 
        else if (pm_keymatch(argv[argn], "-bestqual", 2))
605
 
            bestqual++;
606
 
        else if (pm_keymatch(argv[argn], "-writeands", 2))
607
 
            writeands++;
608
 
        else if (pm_keymatch(argv[argn], "-multippm", 2))
609
 
            multippm++;
610
 
        else pm_usage(usage);
611
 
        ++argn;
612
 
    }
613
 
   
614
 
    if (bestqual && allicons) {
615
 
        pm_message ("bestqual flag ignored.");
616
 
        bestqual--;
617
 
    }
618
 
   
619
 
    if (argn < argc) {
620
 
        ifp = pm_openr(argv[argn]);
621
 
        infname = argv[argn];
622
 
        ++argn;
623
 
    } else {
624
 
        ifp = stdin;
625
 
        infname = "noname";
626
 
    }
627
 
   
628
 
    if (argn < argc && strcmp(argv[argn],"-")) {
629
 
        outputFileBase = trimOutputName(argv[argn]);
630
 
        outfname = argv[argn];
631
 
        overflow_add(strlen(outputFileBase),20);
632
 
        outputFile =  malloc ( sizeof (char) * (strlen (outputFileBase) + 20));
633
 
        writeToFile++;
634
 
        ++argn;
635
 
    } else {
636
 
        outfname = "noname";
637
 
        if (allicons || writeands) {
638
 
            pm_error("When using -allicons or -writeands, "
639
 
                     "please supply an output filename.\n");
640
 
        }
641
 
        if (argn < argc) argn++;
642
 
    }
643
 
   
644
 
    if (argn != argc)
645
 
        pm_usage(usage);
646
 
   
647
 
    MSIconData = readIconFile ();
 
770
 
 
771
    parseCommandLine(argc, argv, &cmdline);
 
772
 
 
773
    if (cmdline.bestqual && cmdline.allicons)
 
774
        pm_message("-bestqual doesn't make sense with -allicons.  "
 
775
                   "Ignoring -bestqual.");
 
776
   
 
777
    if (strcmp(cmdline.outputFilespec, "-") == 0)
 
778
        outputFileBase = NULL;
 
779
    else
 
780
        outputFileBase = trimOutputName(cmdline.outputFilespec);
 
781
 
 
782
    ifp = pm_openr(cmdline.inputFilespec);
 
783
 
 
784
    infname = cmdline.inputFilespec;
 
785
 
 
786
    MSIconData = readIconFile(cmdline.verbose);
648
787
    /*
649
788
     * Now we've read the icon file in (Hopefully! :)
650
789
     * Go through each of the entries, and write out files of the
659
798
     * If allicons is set, we want everything, if not, just go through once.
660
799
     */
661
800
    startEntry = 0;
662
 
    if (allicons) {
 
801
    if (cmdline.allicons) {
663
802
        endEntry = MSIconData->count;
664
803
    } else {
665
804
        endEntry = 1;
667
806
    /*
668
807
     * If bestqual is set, find the icon with highest size & bpp.
669
808
     */
670
 
    if (bestqual) {
 
809
    if (cmdline.bestqual) {
671
810
        startEntry = getBestQualityIcon(MSIconData);
672
811
        endEntry = startEntry+1;
673
812
    }
674
813
   
675
 
    if (multippm) 
676
 
        openMultiXor(outputFileBase, &multiOutF);
 
814
    if (cmdline.multippm) 
 
815
        openMultiXor(outputFileBase, cmdline.writeands, &multiOutF);
677
816
    else
678
817
        multiOutF = NULL;
679
818
 
680
 
    if (writeands && multippm) 
 
819
    if (cmdline.writeands && cmdline.multippm) 
681
820
        openMultiAnd(outputFileBase, &multiAndOutF);
682
821
    else
683
822
        multiAndOutF = NULL;
688
827
        for (entryNum = startEntry ; entryNum < endEntry ; entryNum++ ) {
689
828
            IC_Entry const entry = MSIconData->entries[entryNum];
690
829
 
691
 
            writeXors(writeToFile, multiOutF, outputFileBase, entry, entryNum, 
692
 
                      allicons, writeands);
693
 
            if (writeands)
 
830
            writeXors(multiOutF, outputFileBase, entry, entryNum, 
 
831
                      cmdline.allicons, cmdline.writeands);
 
832
            if (cmdline.writeands)
694
833
                writeAnds(multiAndOutF, outputFileBase, 
695
 
                          entry, entryNum, allicons);
 
834
                          entry, entryNum, cmdline.allicons);
696
835
        }
697
836
    }
698
837
    if (multiOutF)
699
 
        pm_close (multiOutF);    
 
838
        pm_close (multiOutF);    
700
839
    if (multiAndOutF)
701
840
        pm_close(multiAndOutF);
 
841
    
 
842
    /* free up the image data here. */
 
843
    free_icondata(MSIconData);
702
844
    return 0;
703
845
}
704