From 05a96f64484d61039b4f93061a897563fa684792 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Tue, 3 Oct 2023 21:53:43 +0000 Subject: cleanup git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@4720 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- converter/ppm/ppmtowinicon.c | 1100 ++++++++++++++++++++++-------------------- converter/ppm/winico.h | 20 +- converter/ppm/winicontoppm.c | 94 ++-- 3 files changed, 633 insertions(+), 581 deletions(-) (limited to 'converter') diff --git a/converter/ppm/ppmtowinicon.c b/converter/ppm/ppmtowinicon.c index c673798f..e3786922 100644 --- a/converter/ppm/ppmtowinicon.c +++ b/converter/ppm/ppmtowinicon.c @@ -1,4 +1,4 @@ -/* ppmtowinicon.c - read portable pixmap file(s) and write a MS Windows .ico +/* ppmtowinicon.c - read PPM images and write a MS Windows .ico ** ** Copyright (C) 2000 by Lee Benfield - lee@benf.org ** @@ -25,31 +25,30 @@ #define MAXCOLORS 256 -struct cmdlineInfo { +struct CmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. */ - unsigned int iconCount; - const char **inputFilespec; /* '-' if stdin; malloc'ed array */ - const char **andpgmFilespec; /* NULL if unspecified; malloc'ed array */ - const char *output; /* '-' if unspecified */ - unsigned int truetransparent; - unsigned int verbose; + unsigned int iconCount; + const char ** inputFileNm; /* '-' if stdin; malloc'ed array */ + const char ** andpgmFileNm; /* NULL if unspecified; malloc'ed array */ + const char * output; /* '-' if unspecified */ + unsigned int truetransparent; + unsigned int verbose; }; static bool verbose; -static int file_offset = 0; /* not actually used, but useful for debug. */ -static FILE * ofp; +static int fileOffset = 0; /* not actually used, but useful for debug. */ static void -parseCommandLine(int argc, - char ** argv, - struct cmdlineInfo *cmdlineP ) { +parseCommandLine(int argc, + const char ** argv, + struct CmdlineInfo * cmdlineP) { /*---------------------------------------------------------------------------- Parse program command line described in Unix standard form by argc - and argv. Return the information in the options as *cmdlineP. + and argv. Return the information in the options as *cmdlineP. If command line is internally inconsistent (invalid options, etc.), issue error message to stderr and abort program. @@ -82,31 +81,30 @@ parseCommandLine(int argc, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ - pm_optParseOptions3( &argc, argv, opt, sizeof(opt), 0); + pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (!outputSpec) cmdlineP->output = "-"; - if (!andpgms) { if (argc-1 == 0) { cmdlineP->iconCount = 1; - MALLOCARRAY_NOFAIL(cmdlineP->inputFilespec, cmdlineP->iconCount); - cmdlineP->inputFilespec[0] = "-"; + MALLOCARRAY_NOFAIL(cmdlineP->inputFileNm, cmdlineP->iconCount); + cmdlineP->inputFileNm[0] = "-"; } else { unsigned int iconIndex; cmdlineP->iconCount = argc-1; - MALLOCARRAY_NOFAIL(cmdlineP->inputFilespec, cmdlineP->iconCount); + MALLOCARRAY_NOFAIL(cmdlineP->inputFileNm, cmdlineP->iconCount); for (iconIndex = 0; iconIndex < cmdlineP->iconCount; ++iconIndex) - cmdlineP->inputFilespec[iconIndex] = argv[iconIndex+1]; + cmdlineP->inputFileNm[iconIndex] = argv[iconIndex+1]; } { unsigned int iconIndex; - MALLOCARRAY_NOFAIL(cmdlineP->andpgmFilespec, cmdlineP->iconCount); + MALLOCARRAY_NOFAIL(cmdlineP->andpgmFileNm, cmdlineP->iconCount); for (iconIndex = 0; iconIndex < cmdlineP->iconCount; ++iconIndex) - cmdlineP->andpgmFilespec[iconIndex] = NULL; + cmdlineP->andpgmFileNm[iconIndex] = NULL; } } else { if (argc-1 < 2) @@ -119,11 +117,11 @@ parseCommandLine(int argc, else { unsigned int iconIndex; cmdlineP->iconCount = (argc-1)/2; - MALLOCARRAY_NOFAIL(cmdlineP->inputFilespec, cmdlineP->iconCount); - MALLOCARRAY_NOFAIL(cmdlineP->andpgmFilespec, cmdlineP->iconCount); + MALLOCARRAY_NOFAIL(cmdlineP->inputFileNm, cmdlineP->iconCount); + MALLOCARRAY_NOFAIL(cmdlineP->andpgmFileNm, cmdlineP->iconCount); for (iconIndex = 0; iconIndex < cmdlineP->iconCount; ++iconIndex) { - cmdlineP->inputFilespec[iconIndex] = argv[1 + iconIndex*2]; - cmdlineP->andpgmFilespec[iconIndex] = argv[2 + iconIndex*2]; + cmdlineP->inputFileNm[iconIndex] = argv[1 + iconIndex*2]; + cmdlineP->andpgmFileNm[iconIndex] = argv[2 + iconIndex*2]; } } } @@ -132,369 +130,399 @@ parseCommandLine(int argc, -static void -PutByte(int const v) { - - if (putc(v, ofp) == EOF) - pm_error("Unable to write byte to output file."); +static void +freeCmdline(struct CmdlineInfo const cmdline) { + + free(cmdline.inputFileNm); + free(cmdline.andpgmFileNm); } - -static void -PutShort(short const v) { - - if (pm_writelittleshort(ofp, v) == -1) - pm_error("Unable to write short integer to output file"); -} - +static void +writeU1(FILE * const ofP, + u1 const v) { -static void -PutLong(long const v) { - - if (pm_writelittlelong(ofp, v) == -1) - pm_error("Unable to write long integer to output file"); + ++fileOffset; + pm_writechar(ofP, v); } - -/* - * These have no purpose but to wrapper the Byte, Short & Long - * functions. - */ -static void -writeU1 (u1 const v) { - file_offset++; - PutByte(v); -} -static void -writeU2 (u2 const v) { - file_offset +=2; - PutShort(v); +static void +writeU2(FILE * const ofP, + u2 const v) { + + fileOffset +=2; + pm_writelittleshort(ofP, v); } -static void -writeU4 (u4 const v) { - file_offset += 4; - PutLong(v); + + +static void +writeU4(FILE * const ofP, + u4 const v) { + + fileOffset += 4; + pm_writelittlelong(ofP, v); } -static MS_Ico -createIconFile (void) { - MS_Ico MSIconData; - - MALLOCVAR_NOFAIL(MSIconData); - - MSIconData->reserved = 0; - MSIconData->type = 1; - MSIconData->count = 0; - MSIconData->entries = NULL; - return MSIconData; + + +static MS_Ico * +newIconFile(void) { + + MS_Ico * MSIconDataP; + + MALLOCVAR_NOFAIL(MSIconDataP); + + MSIconDataP->reserved = 0; + MSIconDataP->type = 1; + MSIconDataP->count = 0; + MSIconDataP->entries = NULL; + + return MSIconDataP; } -/* create andBitmap from pgm */ -static ICON_bmp -createAndBitmap (gray ** const ba, int const cols, int const rows, - gray const maxval) { - /* - * How wide should the u1 string for each row be? - * each byte is 8 pixels, but must be a multiple of 4 bytes. - */ - unsigned int const xBytes = ROUNDUP(cols, 32)/8; - ICON_bmp icBitmap; - int y,x; - u1 ** rowData; - - MALLOCVAR_NOFAIL(icBitmap); - - MALLOCARRAY_NOFAIL(rowData, rows); - icBitmap->xBytes = xBytes; - icBitmap->data = rowData; - icBitmap->size = xBytes * rows; - for (y=0;yxBytes = xByteCt; + icBitmapP->data = rowData; + icBitmapP->size = xByteCt * rows; + for (row = 0; row < rows; ++row) { + u1 * thisRow; /* malloc'ed */ + unsigned int byteOn; + unsigned int bitOn; + + MALLOCARRAY_NOFAIL(thisRow, xByteCt); + + byteOn = 0; /* initial value */ + bitOn = 128; /* initial value */ + + memset (thisRow, 0, xByteCt); + rowData[rows - row - 1] = thisRow; + + if (ba) { + unsigned int col; + + for (col = 0; col < cols; ++col) { + /* Black (bit clear) is transparent in PGM alpha maps, + in ICO bit *set* is transparent. + */ + if (ba[row][col] <= maxval/2) thisRow[byteOn] |= bitOn; + + if (bitOn == 1) { + ++byteOn; + bitOn = 128; + } else { + bitOn >>= 1; + } + } } else { - bitOn >>= 1; + /* No array -- we're just faking this */ } - } - } - } - return icBitmap; + } + return icBitmapP; } -/* - * Depending on if the image is stored as 1bpp, 4bpp or 8bpp, the - * encoding mechanism is different. - * - * I didn't re-use the code from ppmtobmp since I need to keep the - * bitmaps in memory till I've loaded all ppms. - * - * 8bpp => 1 byte/palette index. - * 4bpp => High Nibble, Low Nibble - * 1bpp => 1 palette value per bit, high bit 1st. - */ -static ICON_bmp -create1Bitmap (pixel ** const pa, int const cols, int const rows, - colorhash_table const cht) { - /* - * How wide should the u1 string for each row be? - * each byte is 8 pixels, but must be a multiple of 4 bytes. + +/* Depending on if the image is stored as 1bpp, 4bpp or 8bpp, the + encoding mechanism is different. + + I didn't re-use the code from ppmtobmp since I need to keep the + bitmaps in memory until I've loaded all ppms. + + 8bpp => 1 byte/palette index. + 4bpp => High Nibble, Low Nibble + 1bpp => 1 palette value per bit, high bit 1st. +*/ + + + +static ICON_bmp * +new1Bitmap (pixel ** const pa, + unsigned int const cols, + unsigned int const rows, + colorhash_table const cht) { + + /* How wide should the u1 string for each row be? Each byte is 8 pixels, + but must be a multiple of 4 bytes. */ - ICON_bmp icBitmap; - int xBytes,y,x; - int wt = cols; - u1 ** rowData; - - MALLOCVAR_NOFAIL(icBitmap); - - wt >>= 3; - if (wt & 3) { - wt = (wt & ~3) + 4; - } - xBytes = wt; - MALLOCARRAY_NOFAIL(rowData, rows); - icBitmap->xBytes = xBytes; - icBitmap->data = rowData; - icBitmap->size = xBytes * rows; - for (y=0;y>= 3; + if (wt & 0x3) { + wt = (wt & ~0x3) + 4; + } + xByteCt = wt; + MALLOCARRAY_NOFAIL(rowData, rows); + icBitmapP->xBytes = xByteCt; + icBitmapP->data = rowData; + icBitmapP->size = xByteCt * rows; + + for (row = 0; row >= 1; + } + } } else { - bitOn >>= 1; + /* No pixel array -- we're just faking this */ } - } - } - } - return icBitmap; + } + return icBitmapP; } -static ICON_bmp -create4Bitmap (pixel ** const pa, int const cols, int const rows, - colorhash_table const cht) { - /* - * How wide should the u1 string for each row be? - * each byte is 8 pixels, but must be a multiple of 4 bytes. + +static ICON_bmp * +new4Bitmap(pixel ** const pa, + unsigned int const cols, + unsigned int const rows, + colorhash_table const cht) { + + /* How wide should the u1 string for each row be? Each byte is 8 pixels, + but must be a multiple of 4 bytes. */ - ICON_bmp icBitmap; - int xBytes,y,x; - int wt = cols; - u1 ** rowData; - - MALLOCVAR_NOFAIL(icBitmap); - - wt >>= 1; - if (wt & 3) { - wt = (wt & ~3) + 4; - } - xBytes = wt; - MALLOCARRAY_NOFAIL(rowData, rows); - icBitmap->xBytes = xBytes; - icBitmap->data = rowData; - icBitmap->size = xBytes * rows; - - for (y=0;y>= 1; + if (wt & 0x3) { + wt = (wt & ~0x3) + 4; + } + xByteCt = wt; + MALLOCARRAY_NOFAIL(rowData, rows); + icBitmapP->xBytes = xByteCt; + icBitmapP->data = rowData; + icBitmapP->size = xByteCt * rows; + + for (row = 0; row xBytes = xBytes; - icBitmap->data = rowData; - icBitmap->size = xBytes * rows; - - for (y=0;yxBytes = xByteCt; + icBitmapP->data = rowData; + icBitmapP->size = xByteCt * rows; + for (row = 0; row < rows; ++row) { + u1 * thisRow; /* malloc'ed */ + MALLOCARRAY_NOFAIL(thisRow, xByteCt); + memset (thisRow, 0, xByteCt); + rowData[rows - row - 1] = thisRow; + if (pa) { + unsigned int col; -static IC_InfoHeader -createInfoHeader(IC_Entry const entry, ICON_bmp const xbmp, - ICON_bmp const abmp) { - IC_InfoHeader ih; - - MALLOCVAR_NOFAIL(ih); - - ih->size = 40; - ih->width = entry->width; - ih->height = entry->height * 2; - ih->planes = 1; - ih->bitcount = entry->bitcount; - ih->compression = 0; - ih->imagesize = entry->width * entry->height * 8 / entry->bitcount; - ih->x_pixels_per_m= 0; - ih->y_pixels_per_m= 0; - ih->colors_used = 1 << entry->bitcount; - ih->colors_important = 0; - return ih; + for (col = 0; col < cols; ++col) + thisRow[col] = ppm_lookupcolor(cht, &pa[row][col]); + } else { + /* No pixel array -- we're just faking this */ + } + } + return icBitmapP; } -static IC_Palette -createCleanPalette(void) { - IC_Palette palette; - int x; - - MALLOCVAR_NOFAIL(palette); +static IC_InfoHeader * +newInfoHeader(IC_Entry const entry) { + + IC_InfoHeader * ihP; + + MALLOCVAR_NOFAIL(ihP); - MALLOCARRAY_NOFAIL(palette->colors, MAXCOLORS); - for (x=0;xcolors[x] = NULL; - } - return palette; + ihP->size = 40; + ihP->width = entry.width; + ihP->height = entry.height * 2; + ihP->planes = 1; + ihP->bitcount = entry.bitcount; + ihP->compression = 0; + ihP->imagesize = entry.width * entry.height * 8 / entry.bitcount; + ihP->x_pixels_per_m = 0; + ihP->y_pixels_per_m = 0; + ihP->colors_used = 1 << entry.bitcount; + ihP->colors_important = 0; + + return ihP; } -static void -addColorToPalette(IC_Palette const palette, int const i, - int const r, int const g, int const b) { +static IC_Palette * +newCleanPalette(void) { + + IC_Palette * paletteP; /* malloc'ed */ + + unsigned int i; + + MALLOCVAR_NOFAIL(paletteP); + + MALLOCARRAY_NOFAIL(paletteP->colors, MAXCOLORS); + + for (i=0; i colors[i] = NULL; + } + return paletteP; +} - MALLOCVAR_NOFAIL(palette->colors[i]); - palette->colors[i]->red = r; - palette->colors[i]->green = g; - palette->colors[i]->blue = b; - palette->colors[i]->reserved = 0; + +static void +addColorToPalette(IC_Palette * const paletteP, + unsigned int const i, + unsigned int const r, + unsigned int const g, + unsigned int const b) { + + MALLOCVAR_NOFAIL(paletteP->colors[i]); + + paletteP->colors[i]->red = r; + paletteP->colors[i]->green = g; + paletteP->colors[i]->blue = b; + paletteP->colors[i]->reserved = 0; } -static ICON_bmp -createBitmap (int const bpp, pixel ** const pa, - int const cols, int const rows, - colorhash_table const cht) { - - ICON_bmp retval; - const int assumed_bpp = (pa == NULL) ? 1 : bpp; +static ICON_bmp * +newBitmap(unsigned int const bpp, + pixel ** const pa, + unsigned int const cols, + unsigned int const rows, + colorhash_table const cht) { - switch (assumed_bpp) { + ICON_bmp * retval; + + int const assumedBpp = (pa == NULL) ? 1 : bpp; + + switch (assumedBpp) { case 1: - retval = create1Bitmap (pa,cols,rows,cht); + retval = new1Bitmap(pa, cols, rows, cht); break; case 4: - retval = create4Bitmap (pa,cols,rows,cht); + retval = new4Bitmap(pa, cols, rows, cht); break; case 8: default: - retval = create8Bitmap (pa,cols,rows,cht); + retval = new8Bitmap(pa, cols, rows, cht); break; } return retval; @@ -504,57 +532,61 @@ createBitmap (int const bpp, pixel ** const pa, static void makePalette(pixel ** const xorPPMarray, - int const xorCols, - int const xorRows, + unsigned int const xorCols, + unsigned int const xorRows, pixval const xorMaxval, - IC_Palette * const paletteP, + IC_Palette ** const palettePP, colorhash_table * const xorChtP, - int * const colorsP, + unsigned int * const colorsP, const char ** const errorP) { - /* - * Figure out the colormap and turn it into the appropriate GIF - * colormap - this code's pretty much straight from ppmtobpm - */ +/*---------------------------------------------------------------------------- + Figure out the colormap and turn it into the appropriate GIF colormap - + this code's pretty much straight from 'ppmtobpm'. +-----------------------------------------------------------------------------*/ + IC_Palette * const paletteP = newCleanPalette(); + colorhist_vector xorChv; unsigned int i; - int colors; - IC_Palette palette = createCleanPalette(); + int colorCt; + + if (verbose) + pm_message("computing colormap..."); - if (verbose) pm_message("computing colormap..."); - xorChv = ppm_computecolorhist(xorPPMarray, xorCols, xorRows, MAXCOLORS, - &colors); - if (xorChv == NULL) + xorChv = ppm_computecolorhist(xorPPMarray, xorCols, xorRows, MAXCOLORS, + &colorCt); + if (!xorChv) pm_asprintf(errorP, - "image has too many colors - try doing a 'pnmquant %d'", + "image has too many colors - try doing a 'pnmquant %u'", MAXCOLORS); else { *errorP = NULL; - if (verbose) pm_message("%d colors found", colors); - + if (verbose) + pm_message("%u colors found", colorCt); + if (verbose && (xorMaxval > 255)) pm_message("maxval is not 255 - automatically rescaling colors"); - for (i = 0; i < colors; ++i) { + for (i = 0; i < colorCt; ++i) { if (xorMaxval == 255) { - addColorToPalette(palette,i, + addColorToPalette(paletteP, i, PPM_GETR(xorChv[i].color), PPM_GETG(xorChv[i].color), PPM_GETB(xorChv[i].color)); } else { - addColorToPalette(palette,i, + addColorToPalette(paletteP, i, PPM_GETR(xorChv[i].color) * 255 / xorMaxval, PPM_GETG(xorChv[i].color) * 255 / xorMaxval, PPM_GETB(xorChv[i].color) * 255 / xorMaxval); } } - + /* And make a hash table for fast lookup. */ - *xorChtP = ppm_colorhisttocolorhash(xorChv, colors); - + *xorChtP = ppm_colorhisttocolorhash(xorChv, colorCt); + ppm_freecolorhist(xorChv); - - *paletteP = palette; - *colorsP = colors; + + *palettePP = paletteP; + *colorsP = colorCt; } } @@ -562,15 +594,15 @@ makePalette(pixel ** const xorPPMarray, static void getOrFakeAndMap(const char * const andPgmFname, - int const xorCols, - int const xorRows, + unsigned int const xorCols, + unsigned int const xorRows, gray *** const andPGMarrayP, pixval * const andMaxvalP, colorhash_table * const andChtP, const char ** const errorP) { int andRows, andCols; - + if (!andPgmFname) { /* He's not supplying a bitmap for 'and'. Fake the bitmap. */ *andPGMarrayP = NULL; @@ -578,15 +610,15 @@ getOrFakeAndMap(const char * const andPgmFname, *andChtP = NULL; *errorP = NULL; } else { - FILE * andfile; - andfile = pm_openr(andPgmFname); - *andPGMarrayP = pgm_readpgm(andfile, &andCols, &andRows, andMaxvalP); - pm_close(andfile); + FILE * andFileP; + andFileP = pm_openr(andPgmFname); + *andPGMarrayP = pgm_readpgm(andFileP, &andCols, &andRows, andMaxvalP); + pm_close(andFileP); if ((andCols != xorCols) || (andRows != xorRows)) { pm_asprintf(errorP, "And mask and image have different dimensions " - "(%d x %d vs %d x %d). Aborting.", + "(%u x %u vs %u x %u). Aborting.", andCols, xorCols, andRows, xorRows); } else *errorP = NULL; @@ -596,18 +628,20 @@ getOrFakeAndMap(const char * const andPgmFname, static void -blackenTransparentAreas(pixel ** const xorPPMarray, - int const cols, - int const rows, - gray ** const andPGMarray, - pixval const andMaxval) { +blackenTransparentAreas(pixel ** const xorPPMarray, + unsigned int const cols, + unsigned int const rows, + gray ** const andPGMarray, + pixval const andMaxval) { unsigned int row; - if (verbose) pm_message("Setting transparent pixels to black"); + if (verbose) + pm_message("Setting transparent pixels to black"); for (row = 0; row < rows; ++row) { unsigned int col; + for (col = 0; col < cols; ++col) { if (andPGMarray[row][col] < andMaxval) /* It's not opaque here; make it black */ @@ -618,70 +652,69 @@ blackenTransparentAreas(pixel ** const xorPPMarray, -static void -addEntryToIcon(MS_Ico const MSIconData, +static void +addEntryToIcon(MS_Ico * const MSIconDataP, const char * const xorPpmFname, const char * const andPgmFname, bool const trueTransparent) { - IC_Entry entry; + IC_Entry * entryP; FILE * xorfile; pixel ** xorPPMarray; gray ** andPGMarray; - ICON_bmp xorBitmap; - ICON_bmp andBitmap; + ICON_bmp * xorBitmapP; + ICON_bmp * andBitmapP; int rows, cols; - int bpp, colors; - int entry_cols; - IC_Palette palette; - colorhash_table xorCht; - colorhash_table andCht; + unsigned int bpp; + unsigned int colorCt; + unsigned int entryCols; + IC_Palette * paletteP; + colorhash_table xorCht; + colorhash_table andCht; const char * error; - + pixval xorMaxval; gray andMaxval; - MALLOCVAR_NOFAIL(entry); + MALLOCVAR_NOFAIL(entryP); - /* - * Read the xor PPM. - */ + /* Read the xor PPM. */ xorfile = pm_openr(xorPpmFname); xorPPMarray = ppm_readppm(xorfile, &cols, &rows, &xorMaxval); pm_close(xorfile); - /* - * Since the entry uses 1 byte to hold the width and height of the icon, the - * image can't be more than 256 x 256. + + /* Since the entry uses 1 byte to hold the width and height of the icon, + the image can't be more than 256 x 256. */ if (rows > 255 || cols > 255) { pm_error("Max size for a icon is 255 x 255 (1 byte fields). " - "%s is %d x %d", xorPpmFname, cols, rows); + "%s is %u x %u", xorPpmFname, cols, rows); } - - if (verbose) pm_message("read PPM: %dw x %dh, maxval = %d", - cols, rows, xorMaxval); - makePalette(xorPPMarray, cols, rows, xorMaxval, - &palette, &xorCht, &colors, &error); + if (verbose) + pm_message("read PPM: %uw x %uh, maxval = %u", cols, rows, xorMaxval); + + makePalette(xorPPMarray, cols, rows, xorMaxval, + &paletteP, &xorCht, &colorCt, &error); if (error) pm_error("Unable to make palette for '%s'. %s", xorPpmFname, error); - /* - * All the icons I found seemed to pad the palette to the max entries - * for that bitdepth. - * - * The spec indicates this isn't necessary, but I'll follow this behaviour - * just in case. + + /* All the icons I found seemed to pad the palette to the max entries for + that bitdepth. + + The spec indicates this isn't necessary, but I'll follow this behaviour + just in case. */ - if (colors < 3) { + if (colorCt < 3) { bpp = 1; - entry_cols = 2; - } else if (colors < 17) { + entryCols = 2; + } else if (colorCt < 17) { bpp = 4; - entry_cols = 16; + entryCols = 16; } else { bpp = 8; - entry_cols = 256; + entryCols = 256; } getOrFakeAndMap(andPgmFname, cols, rows, @@ -690,164 +723,182 @@ addEntryToIcon(MS_Ico const MSIconData, pm_error("Error in and map for '%s'. %s", xorPpmFname, error); if (andPGMarray && trueTransparent) - blackenTransparentAreas(xorPPMarray, cols, rows, + blackenTransparentAreas(xorPPMarray, cols, rows, andPGMarray, andMaxval); - xorBitmap = createBitmap(bpp, xorPPMarray, cols, rows, xorCht); - andBitmap = createAndBitmap(andPGMarray, cols, rows, andMaxval); - /* - * Fill in the entry data fields. - */ - entry->width = cols; - entry->height = rows; - entry->color_count = entry_cols; - entry->reserved = 0; - entry->planes = 1; - /* - * all the icons I looked at ignored this value... + xorBitmapP = newBitmap(bpp, xorPPMarray, cols, rows, xorCht); + andBitmapP = newAndBitmap(andPGMarray, cols, rows, andMaxval); + + /* Fill in the entry data fields. */ + entryP->width = cols; + entryP->height = rows; + entryP->color_count = entryCols; + entryP->reserved = 0; + entryP->planes = 1; + entryP->bitcount = bpp; + /* all the icons I looked at ignored this value */ + entryP->ih = newInfoHeader(*entryP); + entryP->colors = paletteP->colors; + entryP->size_in_bytes = + xorBitmapP->size + andBitmapP->size + 40 + (4 * entryP->color_count); + if (verbose) + pm_message("entry->size_in_bytes = %u + %u + %u = %u", + xorBitmapP->size, andBitmapP->size, + 40, entryP->size_in_bytes ); + + /* We don't know the offset ATM, set to 0 for now. Have to calculate this + at the end. */ - entry->bitcount = bpp; - entry->ih = createInfoHeader(entry, xorBitmap, andBitmap); - entry->colors = palette->colors; - entry->size_in_bytes = - xorBitmap->size + andBitmap->size + 40 + (4 * entry->color_count); - if (verbose) - pm_message("entry->size_in_bytes = %d + %d + %d = %d", - xorBitmap->size ,andBitmap->size, - 40, entry->size_in_bytes ); - /* - * We don't know the offset ATM, set to 0 for now. - * Have to calculate this at the end. - */ - entry->file_offset = 0; - entry->xorBitmapOut = xorBitmap->data; - entry->andBitmapOut = andBitmap->data; - entry->xBytesXor = xorBitmap->xBytes; - entry->xBytesAnd = andBitmap->xBytes; - /* - * Add the entry to the entries array. - */ - ++MSIconData->count; + entryP->file_offset = 0; + entryP->xorBitmapOut = xorBitmapP->data; + entryP->andBitmapOut = andBitmapP->data; + entryP->xBytesXor = xorBitmapP->xBytes; + entryP->xBytesAnd = andBitmapP->xBytes; + + /* Add the entry to the entries array. */ + ++MSIconDataP->count; + /* Perhaps I should allocate ahead, and take fewer trips to the well. */ - REALLOCARRAY(MSIconData->entries, MSIconData->count); - MSIconData->entries[MSIconData->count-1] = entry; + REALLOCARRAY(MSIconDataP->entries, MSIconDataP->count); + MSIconDataP->entries[MSIconDataP->count - 1] = entryP; } -static void -writeIC_Entry (IC_Entry const entry) { - writeU1(entry->width); - writeU1(entry->height); - writeU1(entry->color_count); /* chops 256->0 on its own.. */ - writeU1(entry->reserved); - writeU2(entry->planes); - writeU2(entry->bitcount); - writeU4(entry->size_in_bytes); - writeU4(entry->file_offset); +static void +writeIC_Entry(FILE * const ofP, + IC_Entry * const entryP) { + + writeU1(ofP, entryP->width); + writeU1(ofP, entryP->height); + writeU1(ofP, entryP->color_count); /* chops 256->0 on its own.. */ + writeU1(ofP, entryP->reserved); + writeU2(ofP, entryP->planes); + writeU2(ofP, entryP->bitcount); + writeU4(ofP, entryP->size_in_bytes); + writeU4(ofP, entryP->file_offset); } -static void -writeIC_InfoHeader (IC_InfoHeader const ih) { - writeU4(ih->size); - writeU4(ih->width); - writeU4(ih->height); - writeU2(ih->planes); - writeU2(ih->bitcount); - writeU4(ih->compression); - writeU4(ih->imagesize); - writeU4(ih->x_pixels_per_m); - writeU4(ih->y_pixels_per_m); - writeU4(ih->colors_used); - writeU4(ih->colors_important); +static void +writeIC_InfoHeader(FILE * const ofP, + IC_InfoHeader * const ihP) { + + writeU4(ofP, ihP->size); + writeU4(ofP, ihP->width); + writeU4(ofP, ihP->height); + writeU2(ofP, ihP->planes); + writeU2(ofP, ihP->bitcount); + writeU4(ofP, ihP->compression); + writeU4(ofP, ihP->imagesize); + writeU4(ofP, ihP->x_pixels_per_m); + writeU4(ofP, ihP->y_pixels_per_m); + writeU4(ofP, ihP->colors_used); + writeU4(ofP, ihP->colors_important); } -static void -writeIC_Color (IC_Color const col) { - /* Since the ppm might not have as many colors in it as we'd like, - * (2, 16, 256), stick 0 in the gaps. - * - * This means that we lose palette information, but that can't be - * helped. +static void +writeIC_Color(FILE * const ofP, + IC_Color * const colorP) { + + /* Since the ppm might not have as many colors in it as we'd like, + (2, 16, 256), stick 0 in the gaps. + + This means that we lose palette information, but that can't be helped. */ - if (col == NULL) { - writeU1(0); - writeU1(0); - writeU1(0); - writeU1(0); - } else { - writeU1(col->blue); - writeU1(col->green); - writeU1(col->red); - writeU1(col->reserved); - } + if (!colorP) { + writeU1(ofP, 0); + writeU1(ofP, 0); + writeU1(ofP, 0); + writeU1(ofP, 0); + } else { + writeU1(ofP, colorP->blue); + writeU1(ofP, colorP->green); + writeU1(ofP, colorP->red); + writeU1(ofP, colorP->reserved); + } } static void -writeBitmap(u1 ** const bitmap, int const xBytes, int const height) { - int y; - for (y = 0;yreserved); - writeU2(MSIconData->type); - writeU2(MSIconData->count); - for (x=0;xcount;x++) writeIC_Entry(MSIconData->entries[x]); - for (x=0;xcount;x++) { - writeIC_InfoHeader(MSIconData->entries[x]->ih); - for (y=0;y<(MSIconData->entries[x]->color_count);y++) { - writeIC_Color(MSIconData->entries[x]->colors[y]); + + FILE * const ofP = pm_openw(outFname); + + unsigned int i; + + writeU2(ofP, MSIconDataP->reserved); + writeU2(ofP, MSIconDataP->type); + writeU2(ofP, MSIconDataP->count); + + for (i = 0; i < MSIconDataP->count; ++i) + writeIC_Entry(ofP, MSIconDataP->entries[i]); + + for (i = 0; i < MSIconDataP->count; ++i) { + IC_Entry * const entryP = MSIconDataP->entries[i]; + + unsigned int j; + + writeIC_InfoHeader(ofP, MSIconDataP->entries[i]->ih); + + for (j = 0; j < (MSIconDataP->entries[i]->color_count); ++j) { + writeIC_Color(ofP, MSIconDataP->entries[i]->colors[j]); } - if (verbose) pm_message("writing xor bitmap"); - writeBitmap(MSIconData->entries[x]->xorBitmapOut, - MSIconData->entries[x]->xBytesXor, - MSIconData->entries[x]->height); - if (verbose) pm_message("writing and bitmap"); - writeBitmap(MSIconData->entries[x]->andBitmapOut, - MSIconData->entries[x]->xBytesAnd, - MSIconData->entries[x]->height); + if (verbose) + pm_message("writing xor bitmap"); + + writeBitmap(ofP, + entryP->xorBitmapOut, entryP->xBytesXor, entryP->height); + if (verbose) + pm_message("writing and bitmap"); + + writeBitmap(ofP, + entryP->andBitmapOut, entryP->xBytesAnd, entryP->height); } - fclose(ofp); + fclose(ofP); } -int -main(int argc, char ** argv) { +int +main(int argc, const char ** argv) { - struct cmdlineInfo cmdline; + MS_Ico * const MSIconDataP = newIconFile(); - MS_Ico const MSIconDataP = createIconFile(); + struct CmdlineInfo cmdline; unsigned int iconIndex; unsigned int offset; - - ppm_init (&argc, argv); + + pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); verbose = cmdline.verbose; for (iconIndex = 0; iconIndex < cmdline.iconCount; ++iconIndex) { - addEntryToIcon(MSIconDataP, cmdline.inputFilespec[iconIndex], - cmdline.andpgmFilespec[iconIndex], + addEntryToIcon(MSIconDataP, cmdline.inputFileNm[iconIndex], + cmdline.andpgmFileNm[iconIndex], cmdline.truetransparent); } /* @@ -856,22 +907,23 @@ main(int argc, char ** argv) { */ offset = (MSIconDataP->count * 16) + 6; for (iconIndex = 0; iconIndex < MSIconDataP->count; ++iconIndex) { - IC_Entry entry = MSIconDataP->entries[iconIndex]; - entry->file_offset = offset; - /* + IC_Entry * const entryP = MSIconDataP->entries[iconIndex]; + + entryP->file_offset = offset; + /* * Increase the offset by the size of this offset & data. * this includes the size of the color data. */ - offset += entry->size_in_bytes; + offset += entryP->size_in_bytes; } /* * And now, we have to actually SAVE the .ico! */ writeMS_Ico(MSIconDataP, cmdline.output); - free(cmdline.inputFilespec); - free(cmdline.andpgmFilespec); + freeCmdline(cmdline); return 0; } + diff --git a/converter/ppm/winico.h b/converter/ppm/winico.h index c6133ef0..de05ca4d 100644 --- a/converter/ppm/winico.h +++ b/converter/ppm/winico.h @@ -11,19 +11,19 @@ typedef unsigned char u1; typedef unsigned short int u2; typedef unsigned int u4; -typedef struct MS_Ico_ * MS_Ico; -typedef struct IC_Entry_ * IC_Entry; -typedef struct IC_InfoHeader_ * IC_InfoHeader; -typedef struct IC_Color_ * IC_Color; +typedef struct MS_Ico_ MS_Ico; +typedef struct IC_Entry_ IC_Entry; +typedef struct IC_InfoHeader_ IC_InfoHeader; +typedef struct IC_Color_ IC_Color; /* Not part of the spec, but useful in constructing the icon. */ -typedef struct IC_Palette_ * IC_Palette; -typedef struct ICON_bmp_ * ICON_bmp; +typedef struct IC_Palette_ IC_Palette; +typedef struct ICON_bmp_ ICON_bmp; struct MS_Ico_ { u2 reserved; u2 type; u2 count; - IC_Entry * entries; + IC_Entry ** entries; }; @@ -40,8 +40,8 @@ struct IC_Entry_ { u2 bitcount; /* 0, 1, 4, or 8 */ u4 size_in_bytes; u4 file_offset; - IC_InfoHeader ih; - IC_Color * colors; + IC_InfoHeader * ih; + IC_Color ** colors; /* * Below here, I have useful fields which aren't in the spec, but * save having to keep stoopid amounts of global data. @@ -77,7 +77,7 @@ struct IC_Color_ { struct IC_Palette_ { u4 col_amount; - IC_Color * colors; + IC_Color ** colors; }; struct ICON_bmp_ { diff --git a/converter/ppm/winicontoppm.c b/converter/ppm/winicontoppm.c index ede0a2b9..91277441 100644 --- a/converter/ppm/winicontoppm.c +++ b/converter/ppm/winicontoppm.c @@ -216,17 +216,17 @@ readU4 (FILE * const ifP) { -static IC_Entry +static IC_Entry * readICEntry(FILE * const ifP) { - IC_Entry entryP; + IC_Entry * entryP; /* malloc'ed */ u1 widthFld; /* 0 means 256 */ u1 heightFld; /* 0 means 256 */ u1 colorCtFld; /* 0 means 256 */ MALLOCVAR(entryP); - if (entryP == NULL) + if (!entryP) pm_error("Unable to allocate memory for IC entry"); widthFld = readU1(ifP); @@ -255,15 +255,15 @@ readICEntry(FILE * const ifP) { -static IC_InfoHeader -readInfoHeader (FILE * const ifP, - IC_Entry const entryP) { +static IC_InfoHeader * +readInfoHeader(FILE * const ifP, + const IC_Entry * const entryP) { - IC_InfoHeader ihP; + IC_InfoHeader * ihP; /* malloc'ed */ MALLOCVAR(ihP); - if (ihP == NULL) + if (!ihP) pm_error("Unable to allocate memory for info header"); ihP->size = readU4(ifP); /* never referenced */ @@ -315,14 +315,14 @@ readInfoHeader (FILE * const ifP, -static IC_Color +static IC_Color * readICColor(FILE * const ifP) { - IC_Color colorP; + IC_Color * colorP; /* malloc'ed */ MALLOCVAR(colorP); - if (colorP == NULL) + if (!colorP) pm_error("Unable to allocate memory for color"); /* I don't know why this isn't the same as the spec, it just isn't. @@ -514,40 +514,40 @@ readXBitmap (FILE * const ifP, -static MS_Ico +static MS_Ico * readIconFile(FILE * const ifP, bool const verbose) { unsigned int i; - MS_Ico MSIconData; + MS_Ico * MSIconDataP; /* malloc'ed */ - MALLOCVAR(MSIconData); + MALLOCVAR(MSIconDataP); - MSIconData->reserved = readU2(ifP); /* should be 0 */ - MSIconData->type = readU2(ifP); /* should be 1 (ICO) or 2 (CUR) */ - MSIconData->count = readU2(ifP); /* # icons in file */ + MSIconDataP->reserved = readU2(ifP); /* should be 0 */ + MSIconDataP->type = readU2(ifP); /* should be 1 (ICO) or 2 (CUR) */ + MSIconDataP->count = readU2(ifP); /* # icons in file */ - if (MSIconData->reserved != 0) + if (MSIconDataP->reserved != 0) pm_message("Signature 'reserved' field is %u (should be 0)", - MSIconData->reserved); + MSIconDataP->reserved); - if (MSIconData->type != 1 && MSIconData->type != 2) + if (MSIconDataP->type != 1 && MSIconDataP->type != 2) pm_error("Type %u file. Can handle only type 1 or 2.", - MSIconData->type); + MSIconDataP->type); - if (MSIconData->count == 0) + if (MSIconDataP->count == 0) pm_error("Invalid image count: 0"); else if (verbose) - pm_message("File contains %u images", MSIconData->count); + pm_message("File contains %u images", MSIconDataP->count); - MALLOCARRAY(MSIconData->entries, MSIconData->count); - if (MSIconData->entries == NULL) + MALLOCARRAY(MSIconDataP->entries, MSIconDataP->count); + if (MSIconDataP->entries == NULL) pm_error("out of memory"); /* Read in each of the entries */ - for (i = 0; i < MSIconData->count; ++i) - MSIconData->entries[i] = readICEntry(ifP); + for (i = 0; i < MSIconDataP->count; ++i) + MSIconDataP->entries[i] = readICEntry(ifP); /* Read in the infoheader, color map (if any) and the actual bit/pix maps for the icons. @@ -555,12 +555,12 @@ readIconFile(FILE * const ifP, if (verbose) pm_message("#\tColors\tBPP\tWidth\tHeight\n"); - for (i = 0; i < MSIconData->count; ++i) { - IC_Entry const entryP = MSIconData->entries[i]; + for (i = 0; i < MSIconDataP->count; ++i) { + IC_Entry * const entryP = MSIconDataP->entries[i]; unsigned int bpp; /* bits per pixel */ - entryP->ih = readInfoHeader(ifP, MSIconData->entries[i]); + entryP->ih = readInfoHeader(ifP, MSIconDataP->entries[i]); bpp = entryP->bitcount ? entryP->bitcount : entryP->ih->bitcount; @@ -633,7 +633,7 @@ readIconFile(FILE * const ifP, } } - return MSIconData; + return MSIconDataP; } @@ -655,15 +655,15 @@ trimmedOutputName(const char inputName[]) { static int -getBestQualityIcon(MS_Ico MSIconData) -{ +getBestQualityIcon(MS_Ico * const MSIconDataP) { + unsigned int i; unsigned int best; unsigned int bestSize; unsigned int bestBpp; - for (i = 0, bestSize = 0, bestBpp = 0; i < MSIconData->count; ++i) { - IC_Entry const entryP = MSIconData->entries[i]; + for (i = 0, bestSize = 0, bestBpp = 0; i < MSIconDataP->count; ++i) { + IC_Entry * const entryP = MSIconDataP->entries[i]; unsigned int const size = entryP->width * entryP->height; unsigned int const bpp = entryP->bitcount ? entryP->bitcount : entryP->ih->bitcount; @@ -682,12 +682,12 @@ getBestQualityIcon(MS_Ico MSIconData) static void -writeXors(FILE * const multiOutF, - char * const outputFileBase, - IC_Entry const entryP, - int const entryNum, - bool const multiple, - bool const xor) { +writeXors(FILE * const multiOutF, + char * const outputFileBase, + IC_Entry * const entryP, + int const entryNum, + bool const multiple, + bool const xor) { /*---------------------------------------------------------------------------- Write an "xor" image (i.e. the main image) out. @@ -751,7 +751,7 @@ writeXors(FILE * const multiOutF, pm_error("Invalid color index %u (max is %u)", colorIndex, entryP->color_count - 1); } else { - IC_Color const colorP = entryP->colors[colorIndex]; + IC_Color * const colorP = entryP->colors[colorIndex]; PPM_ASSIGN(pixArray[row][col], colorP->red, colorP->green, colorP->blue); } @@ -775,7 +775,7 @@ writeXors(FILE * const multiOutF, static void writeAnds(FILE * const multiOutF, char const outputFileBase[], - IC_Entry const entryP, + IC_Entry * const entryP, unsigned int const entryNum, bool const multiple) { /*---------------------------------------------------------------------------- @@ -866,7 +866,7 @@ openMultiAnd(char const outputFileBase[], static void -freeIconentry(IC_Entry const entryP) { +freeIconentry(IC_Entry * const entryP) { if (entryP->colors && entryP->color_count) { unsigned int i; @@ -883,7 +883,7 @@ freeIconentry(IC_Entry const entryP) { static void -freeIcondata(MS_Ico const MSIconDataP) { +freeIcondata(MS_Ico * const MSIconDataP) { unsigned int i; for (i = 0; i < MSIconDataP->count; ++i) @@ -900,7 +900,7 @@ main(int argc, const char *argv[]) { struct cmdlineInfo cmdline; FILE * ifP; unsigned int startEntry, endEntry; - MS_Ico MSIconDataP; + MS_Ico * MSIconDataP; char * outputFileBase; FILE * multiOutF; FILE * multiAndOutF; @@ -961,7 +961,7 @@ main(int argc, const char *argv[]) { unsigned int entryNum; for (entryNum = startEntry; entryNum < endEntry; ++entryNum) { - IC_Entry const entryP = MSIconDataP->entries[entryNum]; + IC_Entry * const entryP = MSIconDataP->entries[entryNum]; writeXors(multiOutF, outputFileBase, entryP, entryNum, cmdline.allicons, cmdline.writeands); -- cgit 1.4.1