diff options
47 files changed, 2313 insertions, 554 deletions
diff --git a/analyzer/ppmhist.c b/analyzer/ppmhist.c index 4bafe73c..c2024018 100644 --- a/analyzer/ppmhist.c +++ b/analyzer/ppmhist.c @@ -374,31 +374,16 @@ printColorSummary(ColorSummary const colorSummary, -typedef struct { -/*---------------------------------------------------------------------------- - A map of color name to color. - - The actual information is outside of this structure; we just point to it. ------------------------------------------------------------------------------*/ - unsigned int n; - - pixel * color; - - const char ** name; -} ColorDict; - - - static const char * -colornameLabel(pixel const color, - pixval const maxval, - ColorDict const colorDict) { +colornameLabel(pixel const color, + pixval const maxval, + const ppm_ColorDict * const colorDictP) { /*---------------------------------------------------------------------------- Return the name of the color 'color' or the closest color in the dictionary to it. If the name returned is not the exact color, prefix it with "*". Otherwise, prefix it with " ". - 'colorDict' is the color dictionary. + *colorDictP is the color dictionary. Return the name in static storage within this subroutine. -----------------------------------------------------------------------------*/ @@ -412,16 +397,17 @@ colornameLabel(pixel const color, PPM_DEPTH(color255, color, maxval, 255); - colorIndex = ppm_findclosestcolor(colorDict.color, colorDict.n, &color255); + colorIndex = ppm_findclosestcolor(colorDictP->color, colorDictP->count, + &color255); - assert(colorIndex >= 0 && colorIndex < colorDict.n); + assert(colorIndex >= 0 && colorIndex < colorDictP->count); - if (PPM_EQUAL(colorDict.color[colorIndex], color)) + if (PPM_EQUAL(colorDictP->color[colorIndex], color)) STRSCPY(retval, " "); else STRSCPY(retval, "*"); - STRSCAT(retval, colorDict.name[colorIndex]); + STRSCAT(retval, colorDictP->name[colorIndex]); return retval; } @@ -429,12 +415,12 @@ colornameLabel(pixel const color, static void -printColors(colorhist_vector const chv, - int const colorCt, - pixval const maxval, - enum ColorFmt const colorFmt, - bool const withColorName, - ColorDict const colorDict) { +printColors(colorhist_vector const chv, + int const colorCt, + pixval const maxval, + enum ColorFmt const colorFmt, + bool const withColorName, + const ppm_ColorDict * const colorDictP) { /*---------------------------------------------------------------------------- Print to Standard Output the list of colors, one per line in 'chv', of which there are 'colorCt'. @@ -460,7 +446,7 @@ printColors(colorhist_vector const chv, const char * colornameValue; if (withColorName) - colornameValue = colornameLabel(chv[i].color, maxval, colorDict); + colornameValue = colornameLabel(chv[i].color, maxval, colorDictP); else colornameValue = ""; @@ -498,7 +484,7 @@ printHistogram(colorhist_vector const chv, bool const wantHeader, bool const wantColorName) { - ColorDict colorDict; + ppm_ColorDict * colorDictP; if (colorFmt == FMT_PPMPLAIN) printf("P3\n# color map\n%d 1\n%d\n", colorCt, maxval); @@ -515,18 +501,16 @@ printHistogram(colorhist_vector const chv, } if (wantColorName) { bool const mustOpenTrue = TRUE; - ppm_readcolordict(NULL, mustOpenTrue, - &colorDict.n, &colorDict.name, &colorDict.color, - NULL); - } + + colorDictP = ppm_colorDict_new(NULL, mustOpenTrue); + } else + colorDictP = NULL; printColors(chv, colorCt, maxval, - colorFmt, wantColorName, colorDict); + colorFmt, wantColorName, colorDictP); - if (wantColorName) { - free(colorDict.color); - free(colorDict.name); - } + if (colorDictP) + ppm_colorDict_destroy(colorDictP); } diff --git a/converter/other/infotopam.c b/converter/other/infotopam.c index bb7d2e74..e9ce4d04 100644 --- a/converter/other/infotopam.c +++ b/converter/other/infotopam.c @@ -45,9 +45,128 @@ * bit-plane, and '0' is padding. Thanks again to Ben Hutchings for his * very helpful post! * - * This program uses code from "sidplay" and an older "infotoxpm" program I - * wrote, both of which are released under GPL. + *----------------------------------------------------------------------------- + * The following specification for the DiskObject header is from + * http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node0241.html + * on 2024.03.14. * + * The DiskObject C structure is defined in the include file + * <workbench/workbench.h>. For a complete listing, see the Amiga ROM Kernel + * Reference Manual: Includes and Autodocs. The DiskObject structure contains + * the following elements: + * + * struct DiskObject { + * UWORD do_Magic; magic number at start of file + * UWORD do_Version; so we can change structure + * struct Gadget do_Gadget; a copy of in core gadget + * UBYTE do_Type; + * char *do_DefaultTool; + * char **do_ToolTypes; + * LONG do_CurrentX; + * LONG do_CurrentY; + * struct DrawerData *do_DrawerData; + * char *do_ToolWindow; applies only to tools + * LONG do_StackSize; applies only to tools + * }; + * + * do_Magic + * + * A magic number that the icon library looks for to make sure that the + * file it is reading really contains an icon. It should be the manifest + * constant WB_DISKMAGIC. PutDiskObject() will put this value in the + * structure, and GetDiskObject() will not believe that a file is really + * an icon unless this value is correct. + * + * do_Version + * + * This provides a way to enhance the .info file in an upwardly-compatible + * way. It should be WB_DISKVERSION. The icon library will set this value + * for you and will not believe weird values. + * + * do_Gadget + * + * This contains all the imagery for the icon. See the "Gadget Structure" + * section below for more details. + * + * do_Type + * + * The type of the icon; can be set to any of the following values. + * + * WBDISK The root of a disk + * WBDRAWER A directory on the disk + * WBTOOL An executable program + * WBPROJECT A data file + * WBGARBAGE The Trashcan directory + * WBKICK A Kickstart disk + * WBAPPICON Any object not directly associated with a filing system + * object, such as a print spooler (new in Release 2). + * + * do_DefaultTool + * + * Default tools are used for project and disk icons. For projects (data + * files), the default tool is the program Workbench runs when the project + * is activated. Any valid AmigaDOS path may be entered in this field + * such as "SYS:myprogram", "df0:mypaint", "myeditor" or ":work/mytool". + * + * For disk icons, the default tool is the diskcopy program + * ("SYS:System/DiskCopy") that will be used when this disk is the source + * of a copy. + * + * do_ToolTypes + * + * This is an array of free-format strings. Workbench does not enforce + * any rules on these strings, but they are useful for passing + * environment information. See the section on "The Tool Types Array" + * below for more information. + * + * do_CurrentX, do_CurrentY + * + * Drawers have a virtual coordinate system. The user can scroll around + * in this system using the scroll gadgets on the window that opens when + * the drawer is activated. Each icon in the drawer has a position in + * the coordinate system. CurrentX and CurrentY contain the icon's + * current position in the drawer. Picking a position for a newly + * created icon can be tricky. NO_ICON_POSITION is a system constant + * for do_CurrentX and do_CurrentY that instructs Workbench to pick a + * reasonable place for the icon. Workbench will place the icon in an + * unused region of the drawer. If there is no space in the drawers + * window, the icon will be placed just to the right of the visible + * region. + * + * do_DrawerData + * + * If the icon is associated with a directory (WBDISK, WBDRAWER, + * WBGARBAGE), it needs a DrawerData structure to go with it. This + * structure contains an Intuition NewWindow structure (see the + * "Intuition Windows" chapter for more information): + * + * struct DrawerData { + * struct NewWindow dd_NewWindow; structure to open window + * LONG dd_CurrentX; current x coordinate of origin + * LONG dd_CurrentY; current y coordinate of origin + * }; + * + * Workbench uses this to hold the current window position and size of + * the window so it will reopen in the same place. + * + * do_ToolWindow + * + * This field is reserved for future use. + * + * do_StackSize + * + * This is the size of the stack (in bytes) used for running the tool. + * If this is NULL, then Workbench will use a reasonable default stack + * size (currently 4K bytes). + * + * When a tool is run via the default tool mechanism (i.e., a project + * was activated, not the tool itself), Workbench uses the stack size + * specified in the project's .info file and the tool's .info file is + * ignored. + * + *------------------------------------------------------------------------- + * This program uses code from "sidplay" and an older "infotoxpm" program + * Richard Griswold wrote, both of which are offered under GPL. *------------------------------------------------------------------------- * * This program is free software; you can redistribute it and/or @@ -72,9 +191,10 @@ #include <stdio.h> #include "pm_c_util.h" -#include "pam.h" -#include "shhopt.h" #include "mallocvar.h" +#include "nstring.h" +#include "shhopt.h" +#include "pam.h" typedef struct CmdlineInfo_ { @@ -101,7 +221,11 @@ typedef struct IconInfo_ { typedef struct IconHeader_ { /* 20 bytes */ /* Text of header for one icon image */ - unsigned char pad0[4]; /* Padding (always seems to be zero) */ + unsigned char type[4]; + /* Reverse engineered. This always seems to be 0x00000000 in + icon headers, but we've seen 0x00000010 in some 51-byte object + we don't understand. + */ unsigned char iconWidth[2]; /* Width (usually equal to Gadget width) */ unsigned char iconHeight[2]; /* Height (usually equal to Gadget height -1) */ @@ -282,16 +406,28 @@ readIconHeader(FILE * const ifP, "Read only %u of %u bytes", (unsigned)bytesRead, (unsigned)sizeof(ihead)); + if (!memeq(ihead.type, "\0\0\0\0", 4)) { + pm_message("Unrecognized object where icon header expected. " + "First 4 bytes are 0x%02x%02x%02x%02x. We expect " + "0x00000000", + ihead.type[0], ihead.type[1], ihead.type[2], ihead.type[3]); + } + *widthP = (ihead.iconWidth[0] << 8) + ihead.iconWidth[1]; *heightP = (ihead.iconHeight[0] << 8) + ihead.iconHeight[1]; *depthP = (ihead.bpp[0] << 8) + ihead.bpp[1]; - *bpwidthP = ROUNDUP(*widthP, 16); + if (*widthP < 1) + pm_error("Invalid width value in icon header: %u", *widthP); + + if (*heightP < 1) + pm_error("Invalid height value in icon header: %u", *heightP); - /* Validate number of bit planes */ if (*depthP > 2 || *depthP < 1) pm_error("We don't know how to interpret file with %u bitplanes. ", *depthP); + + *bpwidthP = ROUNDUP(*widthP, 16); } diff --git a/converter/pbm/g3topbm.c b/converter/pbm/g3topbm.c index 56462768..80b7b37d 100644 --- a/converter/pbm/g3topbm.c +++ b/converter/pbm/g3topbm.c @@ -96,7 +96,6 @@ parseCommandLine(int argc, const char ** const argv, was passed to us as the argv array. -----------------------------------------------------------------------------*/ optEntry * option_def; /* malloc'ed */ - /* Instructions to OptParseOptions3 on how to parse our options. */ optStruct3 opt; unsigned int option_def_index; @@ -126,7 +125,7 @@ parseCommandLine(int argc, const char ** const argv, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We may have parms that are negative numbers */ - pm_optParseOptions3(&argc, (char**)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (widthSpec && paper_sizeSpec) diff --git a/converter/pbm/pbmtoepsi.c b/converter/pbm/pbmtoepsi.c index 7ffd6103..bfa87032 100644 --- a/converter/pbm/pbmtoepsi.c +++ b/converter/pbm/pbmtoepsi.c @@ -26,14 +26,15 @@ */ #include "pm_c_util.h" -#include "pbm.h" +#include "mallocvar.h" #include "shhopt.h" +#include "pbm.h" -struct cmdlineInfo { +struct CmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. */ - const char *inputFileName; + const char * inputFileName; unsigned int dpiX; /* horiz component of DPI option */ unsigned int dpiY; /* vert component of DPI option */ @@ -80,21 +81,20 @@ parseDpi(char * const dpiOpt, static void parseCommandLine(int argc, const char ** const argv, - struct cmdlineInfo * const cmdlineP) { + struct CmdlineInfo * const cmdlineP) { /*---------------------------------------------------------------------------- Note that the file spec array we return is stored in the storage that was passed to us as the argv array. -----------------------------------------------------------------------------*/ - optEntry *option_def = malloc(100*sizeof(optEntry)); - /* Instructions to OptParseOptions2 on how to parse our options. - */ + optEntry * option_def; optStruct3 opt; - unsigned int option_def_index; char * dpiOpt; unsigned int dpiOptSpec; + MALLOCARRAY_NOFAIL(option_def, 100); + option_def_index = 0; /* incremented by OPTENTRY */ OPTENT3(0, "bbonly", OPT_FLAG, NULL, &cmdlineP->bbonly, 0); OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); @@ -104,7 +104,7 @@ parseCommandLine(int argc, const char ** const argv, 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ @@ -235,7 +235,7 @@ eightPixels(bit ** const bits, int main(int argc, const char * argv[]) { - struct cmdlineInfo cmdline; + struct CmdlineInfo cmdline; FILE * ifP; bit ** bits; int rows, cols; diff --git a/converter/pbm/pbmtoepson.c b/converter/pbm/pbmtoepson.c index 69742368..293167ac 100644 --- a/converter/pbm/pbmtoepson.c +++ b/converter/pbm/pbmtoepson.c @@ -55,11 +55,8 @@ parseCommandLine(int argc, Note that the strings we return are stored in the storage that was passed to us as the argv array. We also trash *argv. -----------------------------------------------------------------------------*/ - optEntry *option_def; - /* Instructions to pm_optParseOptions3 on how to parse our options. - */ + optEntry * option_def; optStruct3 opt; - unsigned int option_def_index; char * protocol; @@ -82,7 +79,7 @@ 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4( &argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ diff --git a/converter/pbm/pbmtoescp2.c b/converter/pbm/pbmtoescp2.c index 54a77e44..d4d98388 100644 --- a/converter/pbm/pbmtoescp2.c +++ b/converter/pbm/pbmtoescp2.c @@ -49,12 +49,15 @@ parseCommandLine(int argc, const char ** argv, struct CmdlineInfo *cmdlineP) { optStruct3 opt; - unsigned int option_def_index = 0; - optEntry * option_def = malloc(100*sizeof(optEntry)); + unsigned int option_def_index; + optEntry * option_def; unsigned int compressSpec, resolutionSpec, stripeHeightSpec, rawSpec, formfeedSpec; + MALLOCARRAY(option_def, 100); + + option_def_index = 0; opt.opt_table = option_def; opt.short_allowed = FALSE; opt.allowNegNum = FALSE; @@ -69,7 +72,7 @@ parseCommandLine(int argc, const char ** argv, OPTENT3(0, "formfeed", OPT_FLAG, NULL, &formfeedSpec, 0); - pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); if (argc-1 > 1) pm_error("Too many arguments: %d. " diff --git a/converter/pbm/pbmtog3.c b/converter/pbm/pbmtog3.c index 48de8885..ac190d22 100644 --- a/converter/pbm/pbmtog3.c +++ b/converter/pbm/pbmtog3.c @@ -57,11 +57,11 @@ parseCommandLine(int argc, const char ** const argv, optEntry * option_def; /* Instructions to OptParseOptions2 on how to parse our options. */ optStruct3 opt; + unsigned int option_def_index; + unsigned int nofixedwidth; unsigned int align8, align16; - unsigned int option_def_index; - MALLOCARRAY_NOFAIL(option_def, 100); option_def_index = 0; /* incremented by OPTENTRY */ @@ -84,7 +84,7 @@ parseCommandLine(int argc, const char ** const argv, opt.short_allowed = false; /* We have no short (old-fashioned) options */ opt.allowNegNum = true; /* We may have parms that are negative numbers */ - pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ free(option_def); diff --git a/converter/pbm/pbmtolj.c b/converter/pbm/pbmtolj.c index 1936544f..1805206b 100644 --- a/converter/pbm/pbmtolj.c +++ b/converter/pbm/pbmtolj.c @@ -67,11 +67,9 @@ parseCommandLine(int argc, const char ** argv, was passed to us as the argv array. -----------------------------------------------------------------------------*/ optEntry *option_def; - /* Instructions to OptParseOptions3 on how to parse our options. - */ optStruct3 opt; - unsigned int option_def_index; + unsigned int dpiSpec, copiesSpec, compressSpec; MALLOCARRAY(option_def, 100); @@ -96,7 +94,7 @@ parseCommandLine(int argc, const char ** argv, opt.short_allowed = false; /* We have no short (old-fashioned) options */ opt.allowNegNum = false; /* We may have parms that are negative numbers */ - pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (argc-1 == 0) diff --git a/converter/pbm/pbmtolps.c b/converter/pbm/pbmtolps.c index 2c6b01a0..e1e057f8 100644 --- a/converter/pbm/pbmtolps.c +++ b/converter/pbm/pbmtolps.c @@ -69,9 +69,7 @@ parseCommandLine(int argc, and argv. Return the information in the options as *cmdlineP. -----------------------------------------------------------------------------*/ optEntry * option_def; /* malloc'ed */ - /* Instructions to OptParseOptions3 on how to parse our options. */ optStruct3 opt; - unsigned int option_def_index; MALLOCARRAY_NOFAIL(option_def, 100); @@ -86,7 +84,7 @@ 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (cmdlineP->dpiSpec) diff --git a/converter/pbm/pbmtomacp.c b/converter/pbm/pbmtomacp.c index 5fa54ad6..0a6dcf93 100644 --- a/converter/pbm/pbmtomacp.c +++ b/converter/pbm/pbmtomacp.c @@ -73,7 +73,6 @@ parseCommandLine(int argc, and argv. Return the information in the options as *cmdlineP. -----------------------------------------------------------------------------*/ optEntry * option_def; /* malloc'ed */ - /* Instructions to OptParseOptions3 on how to parse our options. */ optStruct3 opt; unsigned int norleSpec; @@ -98,7 +97,7 @@ 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ cmdlineP->norle = norleSpec; diff --git a/converter/pbm/pbmtomda.c b/converter/pbm/pbmtomda.c index 2ed862fc..f684276f 100644 --- a/converter/pbm/pbmtomda.c +++ b/converter/pbm/pbmtomda.c @@ -46,8 +46,6 @@ parseCommandLine(int argc, const char ** argv, was passed to as as the argv array. -----------------------------------------------------------------------------*/ optEntry * option_def; - /* Instructions to pm_optParseOptions3 on how to parse our options. - */ optStruct3 opt; unsigned int option_def_index; @@ -62,7 +60,7 @@ parseCommandLine(int argc, const char ** argv, 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others */ if (argc-1 < 1) diff --git a/converter/pbm/pbmtoxbm.c b/converter/pbm/pbmtoxbm.c index 4bd33dd8..a452d6fa 100644 --- a/converter/pbm/pbmtoxbm.c +++ b/converter/pbm/pbmtoxbm.c @@ -61,8 +61,6 @@ parseCommandLine(int argc, was passed to us as the argv array. We also trash *argv. -----------------------------------------------------------------------------*/ optEntry * option_def; - /* Instructions to pm_optParseOptions3 on how to parse our options. */ - optStruct3 opt; unsigned int option_def_index; unsigned int x10, x11, nameSpec; @@ -78,7 +76,7 @@ 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (!nameSpec) diff --git a/converter/pbm/pi3topbm.c b/converter/pbm/pi3topbm.c index 82665f6c..36ff4127 100644 --- a/converter/pbm/pi3topbm.c +++ b/converter/pbm/pi3topbm.c @@ -56,7 +56,6 @@ parseCommandLine(int argc, --------------------------------------------------------------------------*/ optEntry * option_def; optStruct3 opt; - /* Instructions to pm_optParseOptions3 on how to parse our options. */ unsigned int option_def_index; MALLOCARRAY_NOFAIL(option_def, 100); @@ -68,7 +67,7 @@ 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (argc-1 < 1) diff --git a/converter/pbm/pktopbm.c b/converter/pbm/pktopbm.c index c45af082..201b046a 100644 --- a/converter/pbm/pktopbm.c +++ b/converter/pbm/pktopbm.c @@ -52,8 +52,6 @@ parseCommandLine(int argc, const char ** argv, was passed to us as the argv array. -----------------------------------------------------------------------------*/ optEntry * option_def; - /* Instructions to pm_optParseOptions3 on how to parse our options. - */ optStruct3 opt; unsigned int option_def_index; @@ -80,7 +78,7 @@ parseCommandLine(int argc, const char ** argv, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We may have parms that are negative numbers */ - pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (characterSpec) { diff --git a/converter/pgm/rawtopgm.c b/converter/pgm/rawtopgm.c index 7eb68694..a90bbf46 100644 --- a/converter/pgm/rawtopgm.c +++ b/converter/pgm/rawtopgm.c @@ -45,8 +45,6 @@ parseCommandLine(int argc, const char ** argv, was passed to us as the argv array. -----------------------------------------------------------------------------*/ optEntry * option_def; - /* Instructions to OptParseOptions3 on how to parse our options. - */ optStruct3 opt; unsigned int option_def_index; @@ -85,7 +83,7 @@ parseCommandLine(int argc, const char ** argv, opt.short_allowed = false; /* We have no short (old-fashioned) options */ opt.allowNegNum = false; /* We may have parms that are negative numbers */ - pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (argc-1 == 0) { diff --git a/converter/pgm/sbigtopgm.c b/converter/pgm/sbigtopgm.c index 8b28f740..c56d5eae 100644 --- a/converter/pgm/sbigtopgm.c +++ b/converter/pgm/sbigtopgm.c @@ -46,8 +46,6 @@ parseCommandLine(int argc, const char ** argv, was passed to as as the argv array. -----------------------------------------------------------------------------*/ optEntry * option_def; - /* Instructions to pm_optParseOptions3 on how to parse our options. - */ optStruct3 opt; unsigned int option_def_index; @@ -60,7 +58,7 @@ parseCommandLine(int argc, const char ** argv, 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others */ if (argc-1 < 1) diff --git a/converter/ppm/411toppm.c b/converter/ppm/411toppm.c index a50e5145..9d338fa7 100644 --- a/converter/ppm/411toppm.c +++ b/converter/ppm/411toppm.c @@ -86,8 +86,6 @@ parseCommandLine(int argc, const char ** argv, -----------------------------------------------------------------------------*/ optEntry * option_def; - /* Instructions to OptParseOptions2 on how to parse our options. - */ optStruct3 opt; unsigned int option_def_index; @@ -106,7 +104,7 @@ parseCommandLine(int argc, const char ** argv, 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (cmdlineP->width <= 0) diff --git a/converter/ppm/pcxtoppm.c b/converter/ppm/pcxtoppm.c index 05e09d73..f06dd4e8 100644 --- a/converter/ppm/pcxtoppm.c +++ b/converter/ppm/pcxtoppm.c @@ -87,13 +87,13 @@ parseCommandLine(int argc, const char ** argv, Note that the strings we return are stored in the storage that was passed to us as the argv array. We also trash *argv. -----------------------------------------------------------------------------*/ - optEntry *option_def = malloc( 100*sizeof( optEntry ) ); - /* Instructions to pm_optParseOptions3 on how to parse our options. - */ + optEntry * option_def; optStruct3 opt; unsigned int option_def_index; + MALLOCARRAY_NOFAIL(option_def, 100); + option_def_index = 0; /* incremented by OPTENT3 */ OPTENT3(0, "stdpalette", OPT_FLAG, NULL, &cmdlineP->stdpalette, 0 ); @@ -101,10 +101,10 @@ parseCommandLine(int argc, const char ** argv, &cmdlineP->verbose, 0 ); opt.opt_table = option_def; - opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ - opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + 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, (char**)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdline_p and others. */ if (argc-1 < 1) diff --git a/converter/ppm/picttoppm.c b/converter/ppm/picttoppm.c index 8ca553bd..fc73a92c 100644 --- a/converter/ppm/picttoppm.c +++ b/converter/ppm/picttoppm.c @@ -78,7 +78,6 @@ parseCommandLine(int argc, --------------------------------------------------------------------------*/ optEntry * option_def; optStruct3 opt; - /* Instructions to pm_optParseOptions3 on how to parse our options. */ unsigned int option_def_index; @@ -102,7 +101,7 @@ 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (!fontdirSpec) diff --git a/converter/ppm/ppmtoarbtxt.c b/converter/ppm/ppmtoarbtxt.c index cb2c388b..a8d7a004 100644 --- a/converter/ppm/ppmtoarbtxt.c +++ b/converter/ppm/ppmtoarbtxt.c @@ -62,8 +62,6 @@ parseCommandLine(int argc, const char ** argv, in argv! -----------------------------------------------------------------------------*/ optEntry * option_def; - /* Instructions to OptParseOptions3 on how to parse our options. - */ optStruct3 opt; unsigned int hdSpec, tlSpec; @@ -84,7 +82,7 @@ parseCommandLine(int argc, const char ** argv, 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); free(option_def); if (!hdSpec) diff --git a/converter/ppm/ppmtoascii.c b/converter/ppm/ppmtoascii.c index 524bcd2c..b7c6669d 100644 --- a/converter/ppm/ppmtoascii.c +++ b/converter/ppm/ppmtoascii.c @@ -102,7 +102,6 @@ parseCommandLine(int argc, const char **argv, struct cmdlineInfo * const cmdlineP) { optEntry * option_def; - /* Instructions to OptParseOptions3 on how to parse our options */ optStruct3 opt; unsigned int option_def_index; @@ -118,7 +117,7 @@ parseCommandLine(int argc, const char **argv, 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (dim1x2Spec && dim2x4Spec) diff --git a/converter/ppm/ppmtobmp.c b/converter/ppm/ppmtobmp.c index 8590c5ef..ed44b83a 100644 --- a/converter/ppm/ppmtobmp.c +++ b/converter/ppm/ppmtobmp.c @@ -17,6 +17,7 @@ #define _BSD_SOURCE 1 /* Make sure strdup() is in string.h */ #define _XOPEN_SOURCE 500 /* Make sure strdup() is in string.h */ +#include <stdbool.h> #include <assert.h> #include <string.h> @@ -87,8 +88,6 @@ parseCommandLine(int argc, const char ** argv, in argv! -----------------------------------------------------------------------------*/ optEntry * option_def; - /* Instructions to OptParseOptions3 on how to parse our options. - */ optStruct3 opt; unsigned int windowsSpec, os2Spec, mapfileSpec; @@ -106,10 +105,10 @@ parseCommandLine(int argc, const char ** argv, &mapfileSpec, 0); opt.opt_table = option_def; - opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ - opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); if (windowsSpec && os2Spec) pm_error("Can't specify both -windows and -os2 options."); diff --git a/converter/ppm/ppmtogif.c b/converter/ppm/ppmtogif.c index 0564b7b4..b50a934d 100644 --- a/converter/ppm/ppmtogif.c +++ b/converter/ppm/ppmtogif.c @@ -14,6 +14,7 @@ #define _BSD_SOURCE /* Make sure strdup() is in string.h */ #define _XOPEN_SOURCE 500 /* Make sure strdup() is in string.h */ +#include <stdbool.h> #include <assert.h> #include <string.h> #include <stdio.h> @@ -144,10 +145,10 @@ parseCommandLine(int argc, const char ** argv, */ opt.opt_table = option_def; - opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ - opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (latex2htmlhack) diff --git a/converter/ppm/ppmtoicr.c b/converter/ppm/ppmtoicr.c index de21fc68..2c9fd3a1 100644 --- a/converter/ppm/ppmtoicr.c +++ b/converter/ppm/ppmtoicr.c @@ -50,9 +50,7 @@ parseCommandLine(int argc, const char ** argv, Note that the file spec array we return is stored in the storage that was passed to us as the argv array. -----------------------------------------------------------------------------*/ - optEntry *option_def; - /* Instructions to OptParseOptions3 on how to parse our options. - */ + optEntry * option_def; optStruct3 opt; unsigned int option_def_index; @@ -75,10 +73,10 @@ parseCommandLine(int argc, const char ** argv, &rleSpec, 0); opt.opt_table = option_def; - opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ - opt.allowNegNum = FALSE; /* We may have parms that are negative numbers */ + opt.short_allowed = false; /* We have no short (old-fashioned) options */ + opt.allowNegNum = false; /* We may have parms that are negative numbers */ - pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (!expandSpec) diff --git a/converter/ppm/ppmtopcx.c b/converter/ppm/ppmtopcx.c index 5b7e1003..68ad4db0 100644 --- a/converter/ppm/ppmtopcx.c +++ b/converter/ppm/ppmtopcx.c @@ -17,6 +17,7 @@ ** http://bespin.org/~qz/pc-gpe/pcx.txt ** http://web.archive.org/web/20100206055706/http://www.qzx.com/pc-gpe/pcx.txt */ +#include <stdbool.h> #include <assert.h> #include "pm_c_util.h" @@ -83,8 +84,6 @@ parseCommandLine(int argc, const char ** argv, was passed to us as the argv array. We also trash *argv. -----------------------------------------------------------------------------*/ optEntry * option_def; - /* Instructions to pm_optParseOptions3 on how to parse our options. - */ optStruct3 opt; unsigned int option_def_index; @@ -112,10 +111,10 @@ parseCommandLine(int argc, const char ** argv, OPTENT3(0, "ypos", OPT_INT, &cmdlineP->ypos, &yposSpec, 0); opt.opt_table = option_def; - opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ - opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + 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, (char **)argv, opt, sizeof(opt), 0 ); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0 ); /* Uses and sets argc, argv, and some of *cmdline_p and others. */ if (!xposSpec) diff --git a/converter/ppm/ppmtosixel.c b/converter/ppm/ppmtosixel.c index 4fdf6a66..24454214 100644 --- a/converter/ppm/ppmtosixel.c +++ b/converter/ppm/ppmtosixel.c @@ -102,7 +102,7 @@ parseCommandLine(int argc, const char ** argv, 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ cmdlineP->charWidth = opt7Bit ? CHARWIDTH_7BIT : CHARWIDTH_8BIT; diff --git a/converter/ppm/ppmtospu.c b/converter/ppm/ppmtospu.c index df0fb970..4ba70f02 100644 --- a/converter/ppm/ppmtospu.c +++ b/converter/ppm/ppmtospu.c @@ -5,6 +5,7 @@ * Copyright (C) 1990, Steve Belczyk */ +#include <stdbool.h> #include <assert.h> #include <stdio.h> @@ -56,10 +57,10 @@ parseCommandLine(int argc, const char ** argv, NULL, &d4Spec, 0); opt.opt_table = option_def; - opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ - opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ diff --git a/converter/ppm/ppmtoterm.c b/converter/ppm/ppmtoterm.c index 6e41a8cb..b1d94fa2 100644 --- a/converter/ppm/ppmtoterm.c +++ b/converter/ppm/ppmtoterm.c @@ -19,6 +19,7 @@ ** */ +#include <stdbool.h> #include <assert.h> #include <string.h> @@ -43,7 +44,6 @@ parseCommandLine(int argc, const char ** argv, struct cmdlineInfo * const cmdlineP) { optEntry * option_def; - /* Instructions to OptParseOptions3 on how to parse our options */ optStruct3 opt; unsigned int option_def_index; @@ -54,10 +54,10 @@ parseCommandLine(int argc, const char ** argv, OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); opt.opt_table = option_def; - opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ - opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (argc-1 < 1) diff --git a/converter/ppm/ppmtowinicon.c b/converter/ppm/ppmtowinicon.c index 69baa2f6..2d8ddaf7 100644 --- a/converter/ppm/ppmtowinicon.c +++ b/converter/ppm/ppmtowinicon.c @@ -10,6 +10,7 @@ ** implied warranty. */ +#include <stdbool.h> #include <assert.h> #include <math.h> #include <string.h> @@ -57,9 +58,7 @@ parseCommandLine(int argc, Note that the strings we return are stored in the storage that was passed to us as the argv array. We also trash *argv. -----------------------------------------------------------------------------*/ - optEntry *option_def; - /* Instructions to pm_optParseOptions3 on how to parse our options. - */ + optEntry * option_def; optStruct3 opt; unsigned int option_def_index; @@ -79,10 +78,10 @@ parseCommandLine(int argc, &cmdlineP->verbose, 0); opt.opt_table = option_def; - opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ - opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (!outputSpec) diff --git a/converter/ppm/ppmtoxpm.c b/converter/ppm/ppmtoxpm.c index 2167acb2..9cbab8f3 100644 --- a/converter/ppm/ppmtoxpm.c +++ b/converter/ppm/ppmtoxpm.c @@ -97,9 +97,7 @@ parseCommandLine(int argc, const char ** argv, Note that the file spec array we return is stored in the storage that was passed to us as the argv array. -----------------------------------------------------------------------------*/ - optEntry *option_def; - /* Instructions to OptParseOptions3 on how to parse our options. - */ + optEntry * option_def; optStruct3 opt; unsigned int option_def_index; @@ -125,10 +123,10 @@ parseCommandLine(int argc, const char ** argv, cmdlineP->rgb = NULL; /* no rgb file specified */ opt.opt_table = option_def; - opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ - opt.allowNegNum = FALSE; /* We may have parms that are negative numbers */ + opt.short_allowed = false; /* We have no short (old-fashioned) options */ + opt.allowNegNum = false; /* We may have parms that are negative numbers */ - pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (argc-1 == 0) @@ -271,8 +269,7 @@ static void genCmap(colorhist_vector const chv, unsigned int const ncolors, pixval const maxval, - colorhash_table const colornameHash, - const char ** const colornames, + ppm_ColorDict * const colorDictP, bool const includeTransparent, CixelMap ** const cmapP, unsigned int * const transIndexP, @@ -290,14 +287,10 @@ genCmap(colorhist_vector const chv, This map includes an entry for transparency, whether the raster uses it or not. We return its index as *transIndexP. - In the map, identify colors by the names given by 'colornameHash' and - colornames[]. 'colornameHash' maps a color in 'pixel' form to an - index into colornames[]; colornames[] contains the text to identify the - color in the XPM format. The colors in 'colornameHash' have maxval 255. - If a color is not in 'colornameHash', use hexadecimal notation in the - output colormap. + In the map, identify colors by the names given by *colorDictP. If a color + is not in *colorDictP, use hexadecimal notation in the output colormap. - But if 'colornameHash' is null, don't use color names at all. Just use + But if *colorDictP is null, don't use color names at all. Just use hexadecimal notation. Return as *charsPerPixel the number of characters, or digits, that @@ -338,13 +331,13 @@ genCmap(colorhist_vector const chv, PPM_DEPTH(color255, color, maxval, 255); - if (colornameHash == NULL) + if (!colorDictP) colorname = NULL; else { int colornameIndex; - colornameIndex = ppm_lookupcolor(colornameHash, &color255); + colornameIndex = ppm_lookupcolor(colorDictP->cht, &color255); if (colornameIndex >= 0) - colorname = strdup(colornames[colornameIndex]); + colorname = strdup(colorDictP->name[colornameIndex]); else colorname = NULL; } @@ -537,7 +530,7 @@ computecolorhash(pixel ** const pixels, ++ncolors; } } else - *transparentSomewhereP = TRUE; + *transparentSomewhereP = true; } } *chtP = cht; @@ -599,12 +592,7 @@ main(int argc, const char * *argv) { colorhash_table cht; colorhist_vector chv; - colorhash_table colornameHash; - /* Hash table to map colors to their names */ - const char ** colornames; - /* Table of color names; 'colornameHash' yields an index into this - array. - */ + ppm_ColorDict * colorDictP; /* The color name dictionary we use */ pixel ** pixels; gray ** alpha; @@ -638,28 +626,26 @@ main(int argc, const char * *argv) { &chv, &cht, &ncolors, &transparentSomewhere); if (cmdline.hexonly) - colornameHash = NULL; + colorDictP = NULL; else if (cmdline.rgb) - ppm_readcolornamefile(cmdline.rgb, TRUE, &colornameHash, &colornames); + colorDictP = ppm_colorDict_new(cmdline.rgb, true); else - ppm_readcolornamefile(NULL, FALSE, &colornameHash, &colornames); + colorDictP = ppm_colorDict_new(NULL, false); /* Now generate the character-pixel colormap table. */ - genCmap(chv, ncolors, maxval, - colornameHash, colornames, transparentSomewhere, + genCmap(chv, ncolors, maxval, colorDictP, transparentSomewhere, &cmap, &transIndex, &cmapSize, &charsPerPixel); writeXpmFile(stdout, pixels, alpha, alphaMaxval, cmdline.name, cols, rows, cmapSize, charsPerPixel, cmap, cht, transIndex); - if (colornameHash) { - ppm_freecolorhash(colornameHash); - ppm_freecolornames(colornames); - } + if (colorDictP) + ppm_colorDict_destroy(colorDictP); destroyCmap(cmap, cmapSize); ppm_freearray(pixels, rows); - if (alpha) pgm_freearray(alpha, rows); + if (alpha) + pgm_freearray(alpha, rows); return 0; } diff --git a/converter/ppm/winicontoppm.c b/converter/ppm/winicontoppm.c index 54bc0809..f7847df5 100644 --- a/converter/ppm/winicontoppm.c +++ b/converter/ppm/winicontoppm.c @@ -18,6 +18,7 @@ #define _BSD_SOURCE 1 /* Make sure strdup() is in string.h */ #define _XOPEN_SOURCE 500 /* Make sure strdup() is in string.h */ +#include <stdbool.h> #include <math.h> #include <string.h> #include <assert.h> @@ -66,8 +67,6 @@ parseCommandLine (int argc, const char ** argv, was passed to us as the argv array. We also trash *argv. -----------------------------------------------------------------------------*/ optEntry * option_def; - /* Instructions to pm_optParseOptions3 on how to parse our options. - */ optStruct3 opt; unsigned int option_def_index; @@ -87,10 +86,10 @@ parseCommandLine (int argc, const char ** argv, &cmdlineP->verbose, 0 ); opt.opt_table = option_def; - opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ - opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (argc-1 < 1) diff --git a/converter/ppm/ximtoppm.c b/converter/ppm/ximtoppm.c index b82463c3..c5ba7e80 100644 --- a/converter/ppm/ximtoppm.c +++ b/converter/ppm/ximtoppm.c @@ -57,10 +57,10 @@ parseCommandLine(int argc, const char ** argv, &cmdlineP->alphaFilename, &alphaoutSpec, 0); opt.opt_table = option_def; - opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ - opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + 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, (char**)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and all of *cmdlineP. */ if (!alphaoutSpec) diff --git a/converter/ppm/yuvtoppm.c b/converter/ppm/yuvtoppm.c index 87f541e5..5ee250e2 100644 --- a/converter/ppm/yuvtoppm.c +++ b/converter/ppm/yuvtoppm.c @@ -43,7 +43,6 @@ parseCommandLine(int argc, const char ** argv, struct CmdlineInfo * const cmdlineP) { optEntry * option_def; - /* Instructions to OptParseOptions3 on how to parse our options */ optStruct3 opt; unsigned int option_def_index; @@ -55,7 +54,7 @@ parseCommandLine(int argc, const char ** argv, 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, (char **)argv, opt, sizeof(opt), 0); + pm_optParseOptions4(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (argc-1 < 2) diff --git a/doc/HISTORY b/doc/HISTORY index 5f8dd993..259e9dbd 100644 --- a/doc/HISTORY +++ b/doc/HISTORY @@ -4,13 +4,35 @@ Netpbm. CHANGE HISTORY -------------- -not yet BJH Release 11.06.00 +not yet BJH Release 11.07.00 + + libnetpbm: Fix double free crash when memory allocation via + REALLOCARRAY fails. Introduced in Netpbm 10.40 (September + 2007). + + libnetpbm: Allow color dictionary with more than 1000 entries. + + ppmhist, ppmtoxpm: Work with color dictionary with more than + 1000 color entries. + + rgb.txt: Add Resene paint colors, 2010. + +24.03.30 BJH Release 11.06.00 pamcut: add -reportonly. + infotopam: Add input validation. + infotopam: Remove input file name from messages. Add -verbose and issue informational message only if it is specified. + libnetpbm: Don't ignore garbage at the end of a color specifier + (e.g. rgbi:0/.5/1xyz). + + color database: change names of "Spring Green", "Lamp Black", + and "light grey" to "SpringGreen", "LampBlack", and "LightGrey" + to be consistent with other color names. + pamcut: fix incorrect output when rectangle to cut is entirely above the input image. Invisible junk after image. Always broken. (The ability to cut outside the input image was new in diff --git a/editor/pamcut.c b/editor/pamcut.c index 31b44f81..b6190098 100644 --- a/editor/pamcut.c +++ b/editor/pamcut.c @@ -699,8 +699,9 @@ extractRowsGen(const struct pam * const inpamP, destroyRowCutter(rowCutterP); /* Write out bottom padding */ - if (bottomrow > inpamP->height-1) - writeBlackRows(outpamP, bottomrow - (inpamP->height-1)); + if (bottomrow >= inpamP->height) + writeBlackRows(outpamP, bottomrow - MAX(inpamP->height, toprow) + 1); + } @@ -758,14 +759,16 @@ extractRowsPbm(const struct pam * const inpamP, } bitrow = pbm_allocrow_packed(totalWidth); - - makeBlackPbmRow(bitrow, totalWidth); /* Initialize row buffer to all black for top and side padding */ /* Write out top padding */ - for (row = toprow; row < MIN(0, bottomrow+1); ++row) - pbm_writepbmrow_packed(outpamP->file, bitrow, outpamP->width, 0); + if (toprow < 0) { + makeBlackPbmRow(bitrow, outpamP->width); + for (row = toprow; row < MIN(0, bottomrow+1); ++row) + pbm_writepbmrow_packed(outpamP->file, bitrow, outpamP->width, 0); + } + makeBlackPbmRow(bitrow, totalWidth); for (row = 0; row < inpamP->height; ++row){ if (row >= toprow && row <= bottomrow) { pbm_readpbmrow_bitoffset(inpamP->file, bitrow, inpamP->width, @@ -783,9 +786,11 @@ extractRowsPbm(const struct pam * const inpamP, } /* Write out bottom padding */ - makeBlackPbmRow(bitrow, outpamP->width); - for (row = MAX(inpamP->height, toprow); row < bottomrow+1; ++row) - pbm_writepbmrow_packed(outpamP->file, bitrow, outpamP->width, 0); + if (bottomrow >= inpamP->height) { + makeBlackPbmRow(bitrow, outpamP->width); + for (row = MAX(inpamP->height, toprow); row < bottomrow+1; ++row) + pbm_writepbmrow_packed(outpamP->file, bitrow, outpamP->width, 0); + } pbm_freerow_packed(bitrow); } diff --git a/lib/colorname.c b/lib/colorname.c index fe580cb9..3e51055c 100644 --- a/lib/colorname.c +++ b/lib/colorname.c @@ -16,13 +16,14 @@ #define _BSD_SOURCE 1 /* Make sure strdup() is in string.h */ #define _XOPEN_SOURCE 500 /* Make sure strdup() is in string.h */ -#include "netpbm/pm_c_util.h" +#include <stdbool.h> #include <ctype.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <math.h> +#include "netpbm/pm_c_util.h" #include "netpbm/nstring.h" #include "netpbm/mallocvar.h" @@ -68,7 +69,7 @@ openColornameFileSearch(const char * const searchPath, bool eol; cursor = &buffer[0]; - eol = FALSE; /* initial value */ + eol = false; /* initial value */ *filePP = NULL; /* initial value */ while (!eol && !*filePP) { const char * token; @@ -76,7 +77,7 @@ openColornameFileSearch(const char * const searchPath, if (token) { *filePP = fopen(token, "r"); } else - eol = TRUE; + eol = true; } free(buffer); } else @@ -86,7 +87,8 @@ openColornameFileSearch(const char * const searchPath, FILE * -pm_openColornameFile(const char * const fileName, const int must_open) { +pm_openColornameFile(const char * const fileName, + int const mustOpen) { /*---------------------------------------------------------------------------- Open the colorname dictionary file. Its file name is 'fileName', unless 'fileName' is NULL. In that case, its file name is the value of the @@ -94,19 +96,19 @@ pm_openColornameFile(const char * const fileName, const int must_open) { if that environment variable is not set, it is the first file found, if any, in the search path RGB_DB_PATH. - 'must_open' is a logical: we must get the file open or die. If - 'must_open' is true and we can't open the file (e.g. it doesn't - exist), exit the program with an error message. If 'must_open' is + 'mustOpen' is a logical: we must get the file open or die. If + 'mustOpen' is true and we can't open the file (e.g. it doesn't + exist), exit the program with an error message. If 'mustOpen' is false and we can't open the file, just return a null pointer. -----------------------------------------------------------------------------*/ - FILE *f; + FILE * fileP; if (fileName == NULL) { const char * rgbdef = getenv(RGBENV); if (rgbdef) { /* The environment variable is set */ - f = fopen(rgbdef, "r"); - if (f == NULL && must_open) + fileP = fopen(rgbdef, "r"); + if (fileP == NULL && mustOpen) pm_error("Can't open the color names dictionary file " "named %s, per the %s environment variable. " "errno = %d (%s)", @@ -115,9 +117,9 @@ pm_openColornameFile(const char * const fileName, const int must_open) { /* The environment variable isn't set, so try the hardcoded default color name dictionary locations. */ - openColornameFileSearch(RGB_DB_PATH, &f); + openColornameFileSearch(RGB_DB_PATH, &fileP); - if (f == NULL && must_open) { + if (fileP == NULL && mustOpen) { pm_error("can't open color names dictionary file from the " "path '%s' " "and Environment variable %s not set. Set %s to " @@ -127,20 +129,20 @@ pm_openColornameFile(const char * const fileName, const int must_open) { } } } else { - f = fopen(fileName, "r"); - if (f == NULL && must_open) + fileP = fopen(fileName, "r"); + if (fileP == NULL && mustOpen) pm_error("Can't open the color names dictionary file '%s'. " "errno = %d (%s)", fileName, errno, strerror(errno)); } lineNo = 0; - return(f); + return fileP; } struct colorfile_entry -pm_colorget(FILE * const f) { +pm_colorget(FILE * const fileP) { /*---------------------------------------------------------------------------- Get next color entry from the color name dictionary file 'f'. @@ -155,20 +157,18 @@ pm_colorget(FILE * const f) { struct colorfile_entry retval; char * rc; - gotOne = FALSE; /* initial value */ - eof = FALSE; - while (!gotOne && !eof) { + for (gotOne = false, eof = false; !gotOne && !eof; ) { lineNo++; - rc = fgets(buf, sizeof(buf), f); + rc = fgets(buf, sizeof(buf), fileP); if (rc == NULL) - eof = TRUE; + eof = true; else { if (buf[0] != '#' && buf[0] != '\n' && buf[0] != '!' && buf[0] != '\0') { if (sscanf(buf, "%ld %ld %ld %[^\n]", &retval.r, &retval.g, &retval.b, colorname) == 4 ) - gotOne = TRUE; + gotOne = true; else { if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0'; @@ -191,14 +191,27 @@ pm_colorget(FILE * const f) { void pm_parse_dictionary_namen(char const colorname[], tuplen const color) { +/*---------------------------------------------------------------------------- + Return as *tuplen a tuple of type RGB that represents the color named + 'colorname'. This is an actual name, like "pink", not just a color + specification, like "rgb:0/0/0". + + If the color name is unknown, abort the program. If there are two entries + in the dictionary for the same color name, use the first one. + + We use the Netpbm color dictionary used by 'pm_openColornamefile'. - FILE * fP; + Caller must ensure there is enough memory at 'tuplen' for at least 3 + samples. We set the first 3 samples of the tuple value and ignore any + others. +-----------------------------------------------------------------------------*/ + FILE * fileP; bool gotit; bool colorfileExhausted; struct colorfile_entry colorfileEntry; char * canoncolor; - fP = pm_openColornameFile(NULL, TRUE); /* exits if error */ + fileP = pm_openColornameFile(NULL, true); /* exits if error */ canoncolor = strdup(colorname); if (!canoncolor) @@ -207,18 +220,18 @@ pm_parse_dictionary_namen(char const colorname[], pm_canonstr(canoncolor); - for(gotit = FALSE, colorfileExhausted = FALSE; + for (gotit = false, colorfileExhausted = false; !gotit && !colorfileExhausted; ) { - colorfileEntry = pm_colorget(fP); + colorfileEntry = pm_colorget(fileP); if (colorfileEntry.colorname) { pm_canonstr(colorfileEntry.colorname); if (streq(canoncolor, colorfileEntry.colorname)) - gotit = TRUE; + gotit = true; } else - colorfileExhausted = TRUE; + colorfileExhausted = true; } - fclose(fP); + fclose(fileP); if (!gotit) pm_error("unknown color '%s'", colorname); @@ -237,7 +250,15 @@ pm_parse_dictionary_name(char const colorname[], pixval const maxval, int const closeOk, pixel * const colorP) { +/*---------------------------------------------------------------------------- + Same as 'pm_parse_dictionary_name' except return the color as a + pixel value of type 'pixel', with a maxval of 'maxval'. + We round the color to the nearest one that can be represented with the + resolution indicated by 'maxval' (rounding each component independently). + Iff rounding is necessary and 'closeOK' is false, we issue an informational + message about the rounding. +-----------------------------------------------------------------------------*/ double const epsilon = 1.0/65536.0; tuplen color; @@ -271,4 +292,3 @@ pm_parse_dictionary_name(char const colorname[], } - diff --git a/lib/libpamcolor.c b/lib/libpamcolor.c index cc68fe1a..831057ab 100644 --- a/lib/libpamcolor.c +++ b/lib/libpamcolor.c @@ -130,21 +130,29 @@ isNormal(samplen const arg) { static void parseNewDecX11(const char * const colorname, tuplen const color) { - +/*---------------------------------------------------------------------------- + Return as *colorP the color specified by the new-style decimal specifier + colorname[] (e.g. "rgbi:0/.5/1"). +-----------------------------------------------------------------------------*/ + char invalidExtra; int rc; - rc = sscanf(colorname, "rgbi:%f/%f/%f", + rc = sscanf(colorname, "rgbi:%f/%f/%f%c", &color[PAM_RED_PLANE], &color[PAM_GRN_PLANE], - &color[PAM_BLU_PLANE]); + &color[PAM_BLU_PLANE], + &invalidExtra); if (rc != 3) - pm_error("invalid color specifier '%s'", colorname); + pm_error("invalid rgbi: color specifier '%s' - " + "does not have form rgbi:n/n/n " + "(where n is floating point number)", + colorname); if (!(isNormal(color[PAM_RED_PLANE]) && isNormal(color[PAM_GRN_PLANE]) && isNormal(color[PAM_BLU_PLANE]))) { - pm_error("invalid color specifier '%s' - " + pm_error("invalid rgbi: color specifier '%s' - " "values must be between 0.0 and 1.0", colorname); } } @@ -154,16 +162,21 @@ parseNewDecX11(const char * const colorname, static void parseInteger(const char * const colorname, tuplen const color) { - +/*---------------------------------------------------------------------------- + Return as *colorP the color specified by the integer specifier + colorname[] (e.g. "rgb-255/10/20/30"). +-----------------------------------------------------------------------------*/ unsigned int maxval; unsigned int r, g, b; + char invalidExtra; int rc; - rc = sscanf(colorname, "rgb-%u:%u/%u/%u", &maxval, &r, &g, &b); + rc = sscanf(colorname, "rgb-%u:%u/%u/%u%c", + &maxval, &r, &g, &b, &invalidExtra); if (rc != 4) - pm_error("invalid color specifier '%s'. " - "If it starts with \"rgb-\", then it must have the format " + pm_error("invalid rgb- color specifier '%s' - " + "Does not have form " "rgb-<MAXVAL>:<RED>:<GRN>:<BLU>, " "where <MAXVAL>, <RED>, <GRN>, and <BLU> are " "unsigned integers", @@ -200,7 +213,7 @@ parseOldX11(const char * const colorname, tuplen const color) { /*---------------------------------------------------------------------------- Return as *colorP the color specified by the old X11 style color - specififier colorname[] (e.g. #554055). + specifier colorname[] (e.g. #554055). -----------------------------------------------------------------------------*/ if (!pm_strishex(&colorname[1])) pm_error("Non-hexadecimal characters in #-type color specification"); @@ -276,21 +289,29 @@ parseOldX11(const char * const colorname, static void parseOldX11Dec(const char* const colorname, tuplen const color) { - +/*---------------------------------------------------------------------------- + Return as *colorP the color specified by the old X11 style decimal color + specifier colorname[] (e.g. 0,.5,1). +-----------------------------------------------------------------------------*/ + char invalidExtra; int rc; - rc = sscanf(colorname, "%f,%f,%f", + rc = sscanf(colorname, "%f,%f,%f%c", &color[PAM_RED_PLANE], &color[PAM_GRN_PLANE], - &color[PAM_BLU_PLANE]); + &color[PAM_BLU_PLANE], + &invalidExtra); if (rc != 3) - pm_error("invalid color specifier '%s'", colorname); + pm_error("invalid old-style X11 decimal color specifier '%s' - " + "does not have form n,n,n (where n is a floating point " + "decimal number", + colorname); if (!(isNormal(color[PAM_RED_PLANE]) && isNormal(color[PAM_GRN_PLANE]) && isNormal(color[PAM_BLU_PLANE]))) { - pm_error("invalid color specifier '%s' - " + pm_error("invalid old-style X11 decimal color specifier '%s' - " "values must be between 0.0 and 1.0", colorname); } } diff --git a/lib/libppmcmap.c b/lib/libppmcmap.c index 0f6439ae..24302c6a 100644 --- a/lib/libppmcmap.c +++ b/lib/libppmcmap.c @@ -784,17 +784,23 @@ int ppm_findclosestcolor(const pixel * const colormap, int const ncolors, const pixel * const pP) { +/*---------------------------------------------------------------------------- + The index in colormap[] (which has 'ncolors' entries) of the color that is + closest to color *pP. - /* Search colormap for closest match. */ + Where two entries in colormap[] are identical, return the lesser of their + two indices. - int i; + Iff there are no colors in the amp ('ncolors' is zero), return -1. +-----------------------------------------------------------------------------*/ + unsigned int i; int ind; unsigned int bestDist; bestDist = UINT_MAX; ind = -1; - for(i = 0; i < ncolors && bestDist > 0; ++i) { + for (i = 0; i < ncolors && bestDist > 0; ++i) { unsigned int const dist = PPM_DISTANCE(*pP, colormap[i]); if (dist < bestDist ) { @@ -806,6 +812,7 @@ ppm_findclosestcolor(const pixel * const colormap, } + void ppm_colorrowtomapfile(FILE *ofp, pixel *colormap, int ncolors, pixval maxval) { diff --git a/lib/libppmcolor.c b/lib/libppmcolor.c index c0a88dc2..04858f6a 100644 --- a/lib/libppmcolor.c +++ b/lib/libppmcolor.c @@ -9,6 +9,7 @@ ** implied warranty. */ +#include <stdbool.h> #include <assert.h> #include <stdlib.h> #include <string.h> @@ -22,182 +23,98 @@ #include "pam.h" -pixel -ppm_parsecolor2(const char * const colorname, - pixval const maxval, - int const closeOk) { - tuple const color = pnm_parsecolor2(colorname, maxval, closeOk); +#define MAXCOLORNAMES 1000u + /* The maximum size of a colornames array, in the old interface */ - pixel retval; +static colorhash_table +allocColorHash(void) { - PPM_PUTR(retval, color[PAM_RED_PLANE]); - PPM_PUTG(retval, color[PAM_GRN_PLANE]); - PPM_PUTB(retval, color[PAM_BLU_PLANE]); + colorhash_table cht; + jmp_buf jmpbuf; + jmp_buf * origJmpbufP; - free(color); + if (setjmp(jmpbuf) != 0) + cht = NULL; + else { + pm_setjmpbufsave(&jmpbuf, &origJmpbufP); + cht = ppm_alloccolorhash(); + } + pm_setjmpbuf(origJmpbufP); - return retval; + return cht; } -pixel -ppm_parsecolor(const char * const colorname, - pixval const maxval) { +static ppm_ColorDict * +colorDict_newEmpty() { - return ppm_parsecolor2(colorname, maxval, TRUE); -} + ppm_ColorDict * colorDictP; + MALLOCVAR_NOFAIL(colorDictP); + colorDictP->version = 0; + colorDictP->size = 0; + colorDictP->name = NULL; + colorDictP->color = NULL; + colorDictP->cht = allocColorHash(); + colorDictP->count = 0; -char * -ppm_colorname(const pixel * const colorP, - pixval const maxval, - int const hexok) { + if (!colorDictP->cht) + pm_error("Unable to allocate space for color hash"); - int r, g, b; - FILE * f; - static char colorname[200]; - /* Null string means no suitable name so far */ - - if (maxval == 255) { - r = PPM_GETR(*colorP); - g = PPM_GETG(*colorP); - b = PPM_GETB(*colorP); - } else { - r = (int) PPM_GETR(*colorP) * 255 / (int) maxval; - g = (int) PPM_GETG(*colorP) * 255 / (int) maxval; - b = (int) PPM_GETB(*colorP) * 255 / (int) maxval; - } - - f = pm_openColornameFile(NULL, !hexok); - - if (!f) - STRSCPY(colorname, ""); - else { - int bestDiff; - bool eof; - - for (bestDiff = 32767, eof = FALSE; - !eof && bestDiff > 0; ) { - struct colorfile_entry const ce = pm_colorget(f); - if (ce.colorname) { - int const thisDiff = - abs(r - (int)ce.r) + - abs(g - (int)ce.g) + - abs(b - (int)ce.b); - - if (thisDiff < bestDiff) { - bestDiff = thisDiff; - STRSCPY(colorname, ce.colorname); - } - } else - eof = TRUE; - } - fclose(f); - - if (bestDiff == 32767) { - /* Color file contain no entries, so we can't even pick a close - one - */ - STRSCPY(colorname, ""); - } else if (bestDiff > 0 && hexok) { - /* We didn't find an exact match and user is willing to accept - hex, so we don't have to use an approximate match. - */ - STRSCPY(colorname, ""); - } - } - - if (streq(colorname, "")) { - if (hexok) { - /* Color lookup failed, but caller is willing to take an X11-style - hex specifier, so return that. - */ - sprintf(colorname, "#%02x%02x%02x", r, g, b); - } else { - pm_error("Couldn't find any name colors at all"); - } - } - - return colorname; + return colorDictP; } -#define MAXCOLORNAMES 1000u - -static const char ** -allocColorNames() { - - const char ** colornames; - - MALLOCARRAY(colornames, MAXCOLORNAMES); - - if (colornames) { - unsigned int i; - for (i = 0; i < MAXCOLORNAMES; ++i) - colornames[i] = NULL; - } - return colornames; -} - +void +ppm_colorDict_destroy(ppm_ColorDict * const colorDictP) { + unsigned int i; -static colorhash_table -allocColorHash(void) { + for (i = 0; i < colorDictP->size; ++i) + pm_strfree(colorDictP->name[i]); - colorhash_table cht; - jmp_buf jmpbuf; - jmp_buf * origJmpbufP; + if (colorDictP->name) + free(colorDictP->name); + if (colorDictP->color) + free(colorDictP->color); - if (setjmp(jmpbuf) != 0) - cht = NULL; - else { - pm_setjmpbufsave(&jmpbuf, &origJmpbufP); - cht = ppm_alloccolorhash(); - } - pm_setjmpbuf(origJmpbufP); + ppm_freecolorhash(colorDictP->cht); - return cht; + free(colorDictP); } static void -processColorfileEntry(struct colorfile_entry const ce, - colorhash_table const cht, - const char ** const colornames, - pixel * const colors, - unsigned int * const colornameIndexP, - const char ** const errorP) { +colorDict_resize(ppm_ColorDict * const colorDictP, + unsigned int const newSz, + const char ** const errorP) { + + const char ** newName; - if (*colornameIndexP >= MAXCOLORNAMES) - pm_asprintf(errorP, "Too many colors in colorname dictionary. " - "Max allowed is %u", MAXCOLORNAMES); + newName = realloc(colorDictP->name, newSz * sizeof(colorDictP->name[0])); + if (!newName) + pm_asprintf(errorP, "Failed to extend allocation for color " + "dictionary to %u entries", newSz); else { - pixel color; + pixel * newColor; - PPM_ASSIGN(color, ce.r, ce.g, ce.b); + colorDictP->name = newName; - if (ppm_lookupcolor(cht, &color) >= 0) { - /* The color is already in the hash, which means we saw it - earlier in the file. We prefer the first name that the - file gives for each color, so we just ignore the - current entry. - */ + newColor = + realloc(colorDictP->color, newSz * sizeof(colorDictP->color[0])); + + if (!newColor) + pm_asprintf(errorP, "Failed to extend allocation for color " + "dictionary to %u entries", newSz); + else { *errorP = NULL; - } else { - ppm_addtocolorhash(cht, &color, *colornameIndexP); - colornames[*colornameIndexP] = pm_strdup(ce.colorname); - colors[*colornameIndexP] = color; - if (colornames[*colornameIndexP] == pm_strsol) - pm_asprintf(errorP, "Unable to allocate space for color name"); - else { - *errorP = NULL; - ++(*colornameIndexP); - } + colorDictP->color = newColor; + colorDictP->size = newSz; } } } @@ -228,44 +145,41 @@ openColornameFile(const char * const fileName, static void -readOpenColorFile(FILE * const colorFileP, - unsigned int * const nColorsP, - const char ** const colornames, - pixel * const colors, - colorhash_table const cht, - const char ** const errorP) { +processColorfileEntry(struct colorfile_entry const ce, + ppm_ColorDict * const colorDictP, + const char ** const errorP) { /*---------------------------------------------------------------------------- - Read the color dictionary file *colorFileP and add the colors in it - to colornames[], colors[], and 'cht'. - - colornames[] and colors[] must be allocated with MAXCOLORNAMES entries - at entry. - - We may add colors to 'cht' even if we fail. + Add the color file entry 'ce' to *colorDictP as required. -----------------------------------------------------------------------------*/ - unsigned int nColorsDone; - bool done; + pixel color; - nColorsDone = 0; - done = FALSE; - *errorP = NULL; + PPM_ASSIGN(color, ce.r, ce.g, ce.b); - while (!done && !*errorP) { - struct colorfile_entry const ce = pm_colorget(colorFileP); - - if (!ce.colorname) - done = TRUE; - else - processColorfileEntry(ce, cht, colornames, colors, - &nColorsDone, errorP); - } - *nColorsP = nColorsDone; + if (ppm_lookupcolor(colorDictP->cht, &color) >= 0) { + /* The color is already in the hash, which means we saw it earlier in + the file. We prefer the first name that the file gives for each + color, so we just ignore the current entry. + */ + *errorP = NULL; + } else { + ppm_addtocolorhash(colorDictP->cht, &color, colorDictP->count); + if (colorDictP->count >= colorDictP->size) { + colorDict_resize(colorDictP, + MAX(1024, colorDictP->size * 2), + errorP); + } else + *errorP = NULL; - if (*errorP) { - unsigned int colorIndex; + assert(colorDictP->size >= colorDictP->count); - for (colorIndex = 0; colorIndex < nColorsDone; ++colorIndex) - pm_strfree(colornames[colorIndex]); + if (!*errorP) { + colorDictP->name[colorDictP->count] = pm_strdup(ce.colorname); + colorDictP->color[colorDictP->count] = color; + if (colorDictP->name[colorDictP->count] == pm_strsol) + pm_asprintf(errorP, "Unable to allocate space for color name"); + else + ++colorDictP->count; + } } } @@ -274,38 +188,37 @@ readOpenColorFile(FILE * const colorFileP, static void readColorFile(const char * const fileName, bool const mustOpen, - unsigned int * const nColorsP, - const char ** const colornames, - pixel * const colors, - colorhash_table const cht, + ppm_ColorDict * const colorDictP, const char ** const errorP) { /*---------------------------------------------------------------------------- Read the color dictionary file named 'fileName' and add the colors in it - to colornames[], colors[], and 'cht'. Return as *nColorsP the number - of colors in it. + to *colorDictP. - If the file is not openable (e.g. not file by that name exists), abort the + If the file is not openable (e.g. no file by that name exists), abort the program if 'mustOpen' is true; otherwise, return values indicating a dictionary with no colors. - colornames[] and colors[] must be allocated with MAXCOLORNAMES entries - at entry. - - We may add colors to 'cht' even if we fail. + We may add colors to *colorDictP even if we fail. -----------------------------------------------------------------------------*/ FILE * colorFileP; openColornameFile(fileName, mustOpen, &colorFileP, errorP); if (!*errorP) { - if (colorFileP == NULL) { - /* Couldn't open it, but Caller says treat same as - empty file - */ - *nColorsP = 0; + if (!colorFileP) { + /* Couldn't open it, but Caller says treat same as empty file */ *errorP = NULL; } else { - readOpenColorFile(colorFileP, nColorsP, colornames, colors, cht, - errorP); + bool done; + + for (done = false, *errorP = NULL; !done && !*errorP; ) { + + struct colorfile_entry const ce = pm_colorget(colorFileP); + + if (!ce.colorname) + done = true; + else + processColorfileEntry(ce, colorDictP, errorP); + } fclose(colorFileP); } @@ -314,55 +227,127 @@ readColorFile(const char * const fileName, -static void -readcolordict(const char * const fileName, - bool const mustOpen, - unsigned int * const nColorsP, - const char *** const colornamesP, - pixel ** const colorsP, - colorhash_table * const chtP, - const char ** const errorP) { +ppm_ColorDict * +ppm_colorDict_new(const char * const fileName, + int const mustOpen) { - const char ** colornames; + ppm_ColorDict * colorDictP; + const char * error; - colornames = allocColorNames(); + colorDictP = colorDict_newEmpty(); - if (colornames == NULL) - pm_asprintf(errorP, "Unable to allocate space for colorname table."); - else { - pixel * colors; + readColorFile(fileName, mustOpen, colorDictP, &error); + + if (error) { + pm_errormsg("%s", error); + pm_strfree(error); + pm_longjmp(); + } + return colorDictP; +} - MALLOCARRAY(colors, MAXCOLORNAMES); - if (colors == NULL) - pm_asprintf(errorP, "Unable to allocate space for color table."); - else { - colorhash_table cht; - cht = allocColorHash(); +pixel +ppm_parsecolor2(const char * const colorname, + pixval const maxval, + int const closeOk) { - if (cht == NULL) - pm_asprintf(errorP, "Unable to allocate space for color hash"); - else { - readColorFile(fileName, mustOpen, - nColorsP, colornames, colors, cht, - errorP); + tuple const color = pnm_parsecolor2(colorname, maxval, closeOk); - if (*errorP) - ppm_freecolorhash(cht); - else - *chtP = cht; - } - if (*errorP) - free(colors); - else - *colorsP = colors; + pixel retval; + + PPM_PUTR(retval, color[PAM_RED_PLANE]); + PPM_PUTG(retval, color[PAM_GRN_PLANE]); + PPM_PUTB(retval, color[PAM_BLU_PLANE]); + + free(color); + + return retval; +} + + + +pixel +ppm_parsecolor(const char * const colorname, + pixval const maxval) { + + return ppm_parsecolor2(colorname, maxval, true); +} + + + +char * +ppm_colorname(const pixel * const colorP, + pixval const maxval, + int const hexok) { + + int r, g, b; + FILE * fileP; + static char colorname[200]; + /* Null string means no suitable name so far */ + + if (maxval == 255) { + r = PPM_GETR(*colorP); + g = PPM_GETG(*colorP); + b = PPM_GETB(*colorP); + } else { + r = (int) PPM_GETR(*colorP) * 255 / (int) maxval; + g = (int) PPM_GETG(*colorP) * 255 / (int) maxval; + b = (int) PPM_GETB(*colorP) * 255 / (int) maxval; + } + + fileP = pm_openColornameFile(NULL, !hexok); + + if (!fileP) + STRSCPY(colorname, ""); + else { + int bestDiff; + bool eof; + + for (bestDiff = 32767, eof = false; + !eof && bestDiff > 0; ) { + struct colorfile_entry const ce = pm_colorget(fileP); + if (ce.colorname) { + int const thisDiff = + abs(r - (int)ce.r) + + abs(g - (int)ce.g) + + abs(b - (int)ce.b); + + if (thisDiff < bestDiff) { + bestDiff = thisDiff; + STRSCPY(colorname, ce.colorname); + } + } else + eof = true; + } + fclose(fileP); + + if (bestDiff == 32767) { + /* Color file contain no entries, so we can't even pick a close + one + */ + STRSCPY(colorname, ""); + } else if (bestDiff > 0 && hexok) { + /* We didn't find an exact match and user is willing to accept + hex, so we don't have to use an approximate match. + */ + STRSCPY(colorname, ""); + } + } + + if (streq(colorname, "")) { + if (hexok) { + /* Color lookup failed, but caller is willing to take an X11-style + hex specifier, so return that. + */ + sprintf(colorname, "#%02x%02x%02x", r, g, b); + } else { + pm_error("Couldn't find any name colors at all"); } - if (*errorP) - free(colornames); - else - *colornamesP = colornames; } + + return colorname; } @@ -371,60 +356,80 @@ void ppm_readcolordict(const char * const fileName, int const mustOpen, unsigned int * const nColorsP, - const char *** const colornamesP, + const char *** const colorNamesP, pixel ** const colorsP, colorhash_table * const chtP) { /*---------------------------------------------------------------------------- - Read the color dictionary from the file named 'fileName'. If we can't open - the file (e.g. because it does not exist), and 'mustOpen' is false, return - an empty dictionary (it contains no colors). But if 'mustOpen' is true, - abort the program instead of returning an empty dictionary. + Read the color dictionary from the file named 'fileName' (NULL means + default). If we can't open the file (e.g. because it does not exist), and + 'mustOpen' is false, return an empty dictionary (it contains no colors). + But if 'mustOpen' is true, abort the program instead of returning an empty + dictionary. Return as *nColorsP the number of colors in the dictionary. - Return as *colornamesP the names of those colors. *colornamesP is a - malloced array that Caller must free with ppm_freecolornames(). + Return as *colorNamesP the names of those colors. *colorNamesP is a + malloced array that Caller must free with ppm_freecolorNames(). The first *nColorsP entries are valid; *chtP contains indices into this array. - Return as *colorsP the colors. *colorsP is a malloced array of size - MAXCOLORS with the first elements filled in and the rest undefined. + Return as *colorsP a malloced array of the colors. (*colorsP)[i] is + the color that goes with (*colorNamesP)[i]. Return as *chtP a color hash table mapping each color in the dictionary - to the index into *colornamesP for the name of the color. + to the index into *colorNamesP for the name of the color. - Each of 'nColorsP, 'colornamesP', and 'colorsP' may be null, in which case + Each of 'nColorsP, 'colorNamesP', and 'colorsP' may be null, in which case we do not return the corresponding information (or allocate memory for it). -----------------------------------------------------------------------------*/ - colorhash_table cht; - const char ** colornames; - pixel * colors; - unsigned int nColors; - const char * error; + ppm_ColorDict * colorDictP; - readcolordict(fileName, mustOpen, &nColors, &colornames, &colors, &cht, - &error); + colorDictP = ppm_colorDict_new(fileName, mustOpen); - if (error) { - pm_errormsg("%s", error); - pm_strfree(error); - pm_longjmp(); + if (chtP) + *chtP = colorDictP->cht; + else + ppm_freecolorhash(colorDictP->cht); + + if (colorNamesP) { + /* We have a simplistic, primitive interface where the array must + be exactly MAXCOLORNAMES entries in size with unused entries + set to NULL so that caller can free it with a call to + 'ppm_freecolornames' (which has no size argument). + + So we fail now (as the old interface would) if there are more + than MAXCOLORNAMES colors and expand the array if there are + fewer. + */ + if (colorDictP->count > MAXCOLORNAMES) + pm_error("Too many color names (%u) in color dictionary. " + "Max allowed is %u", + colorDictP->count, MAXCOLORNAMES); + else { + unsigned int i; + + REALLOCARRAY(colorDictP->name, MAXCOLORNAMES); + if (!colorDictP->name) + pm_error("Failed to allocate color name array for " + "maximum colors %u", MAXCOLORNAMES); + for (i = colorDictP->count; i < MAXCOLORNAMES; ++i) + colorDictP->name[i] = NULL; + } + *colorNamesP = colorDictP->name; } else { - if (chtP) - *chtP = cht; - else - ppm_freecolorhash(cht); - if (colornamesP) - *colornamesP = colornames; - else - ppm_freecolornames(colornames); - if (colorsP) - *colorsP = colors; - else - ppm_freerow(colors); - if (nColorsP) - *nColorsP = nColors; + unsigned int i; + for (i = 0; i < colorDictP->count; ++i) + pm_strfree(colorDictP->name[i]); + free(colorDictP->name); } + + if (colorsP) + *colorsP = colorDictP->color; + else + free(colorDictP->color); + + if (nColorsP) + *nColorsP = colorDictP->count; } @@ -433,23 +438,23 @@ void ppm_readcolornamefile(const char * const fileName, int const mustOpen, colorhash_table * const chtP, - const char *** const colornamesP) { + const char *** const colorNamesP) { - ppm_readcolordict(fileName, mustOpen, NULL, colornamesP, NULL, chtP); + ppm_readcolordict(fileName, mustOpen, NULL, colorNamesP, NULL, chtP); } void -ppm_freecolornames(const char ** const colornames) { +ppm_freecolornames(const char ** const colorNames) { unsigned int i; for (i = 0; i < MAXCOLORNAMES; ++i) - if (colornames[i]) - free((char *)colornames[i]); + if (colorNames[i]) + free((char *)colorNames[i]); - free(colornames); + free(colorNames); } diff --git a/lib/ppm.h b/lib/ppm.h index acc70c85..9fa547fe 100644 --- a/lib/ppm.h +++ b/lib/ppm.h @@ -161,6 +161,36 @@ ppm_colorname(const pixel* const colorP, pixval const maxval, int const hexok); +typedef struct { + unsigned int version; + const char ** name; + /* malloced, and each entry malloced. Has space for at least 'size' + entries. May be null if size == 0 + */ + pixel * color; /* malloced */ + /* malloced. Has space for at least 'size' entries. May be null if + size == 0 + */ + unsigned int size; + /* allocated size of 'name' and 'color'. At least 'count' */ + unsigned int count; + /* number of entries used.*/ + colorhash_table cht; + /* Hash table mapping name[] to color[] */ +} ppm_ColorDict; + +ppm_ColorDict * +ppm_colorDict_new(const char * const fileName, + int const mustOpen); + +void +ppm_colorDict_destroy(ppm_ColorDict * colorDictP); + +void +ppm_readcolordict2(const char * const fileName, + int const mustOpen, + ppm_ColorDict ** const colorDictP); + void ppm_readcolordict(const char * const fileName, int const mustOpen, diff --git a/lib/rgb.txt b/lib/rgb.txt index 28231080..90c73024 100644 --- a/lib/rgb.txt +++ b/lib/rgb.txt @@ -2,12 +2,17 @@ # order. Some color names are defined multiple times, and sometimes # with different colors. Many colors have multiple names. -# - Netpbm originals +# When Netpbm interprets this dictionary, it recognizes the first definition +# of a particular color name and the first definition of a particular color +# definition. (That means the function is not reversible). + # - Crayola crayons, as determined by John Thomas at Tektronix # - Hollasch at Microsoft Research # - HTML 4.0 # - Some HTML extension that Internet Explorer understands # - XFree86 rgb.txt ca. 2001, derived from MIT X11 +# - Netpbm originals +# - Resene paint colors, 2010 # More details on the sources are above each group. @@ -35,7 +40,7 @@ 255 255 0 Yellow 255 138 0 Orange 159 211 0 GreenYellow - 0 255 159 Spring Green + 0 255 159 SpringGreen 0 138 255 SkyBlue 148 0 211 Violet 255 0 148 VioletRed @@ -143,7 +148,7 @@ 128 128 105 WarmGrey 0 0 0 Black 41 36 33 IvoryBlack - 46 71 59 Lamp Black + 46 71 59 LampBlack 227 38 54 AlizarinCrimson 156 102 31 Brick 227 23 13 CadmiumRedDeep @@ -335,7 +340,7 @@ 112 128 144 SlateGray 119 136 153 LightSlateGray 119 136 153 LightSlateGrey -211 211 211 light grey +211 211 211 LightGrey 100 149 237 CornflowerBlue 132 112 255 LightSlateBlue 0 191 255 DeepSkyBlue @@ -889,3 +894,1412 @@ # These were more or less invented for use with Netpbm: 255 255 255 D65 + +# The following is from +# http://people.csail.mit.edu/jaffer/Color/Resene-2010-rgb.txt +# on 24.03.31 + +# Resene RGB Values List +# For further information refer to http://www.resene.co.nz +# Copyright Resene Paints Ltd 2001 +# +# Permission to copy this dictionary, to modify it, to redistribute it, +# to distribute modified versions, and to use it for any purpose is +# granted, subject to the following restrictions and understandings. +# +# 1. Any text copy made of this dictionary must include this copyright +# notice in full. +# +# 2. Any redistribution in binary form must reproduce this copyright +# notice in the documentation or other materials provided with the +# distribution. +# +# 3. Resene Paints Ltd makes no warranty or representation that this +# dictionary is error-free, and is under no obligation to provide any +# services, by way of maintenance, update, or otherwise. +# +# 4. There shall be no use of the name of Resene or Resene Paints Ltd +# in any advertising, promotional, or sales literature without prior +# written consent in each case. +# +# 5. These RGB colour formulations may not be used to the detriment of +# Resene Paints Ltd. +# + 36 83 54 kaitokegreen + 27 75 53 countygreen + 23 70 46 zuccini + 29 57 60 nordic + 0 73 78 sherpablue + 37 72 85 tealblue + 53 81 79 bluedianne + 49 70 67 firefly + 44 70 65 gablegreen + 39 63 65 daintree + 24 67 67 tiber + 15 70 69 cyprus + 25 68 60 deepteal + 32 72 63 zydeco + 27 70 54 sherwoodgreen + 39 66 52 englishholly + 38 67 52 everglade + 37 70 54 bottlegreen + 37 70 54 bush + 35 69 55 burnham + 43 63 54 celtic + 50 67 54 timbergreen + 51 66 49 forestgreen + 43 75 64 tepapagreen + 52 83 61 goblin + 58 69 49 mallard + 54 72 47 palmleaf + 55 65 42 seaweed + 53 63 42 olivegreen + 25 57 37 deepfir + 27 52 39 cardingreen + 32 57 44 palmgreen + 37 52 43 holly + 35 46 38 blackbean + 41 51 43 gordonsgreen + 44 50 39 blackforest + 42 47 35 pinetree + 47 49 37 huntergreen + 45 47 40 eternity + 43 46 37 rangoongreen + 43 46 38 marshland + 44 45 36 greenwaterloo + 45 45 36 karaka + 52 50 45 banjul + 53 49 44 acadia + 55 49 43 darkebony + 57 50 39 creole + 56 52 40 graphite + 51 44 34 blackmagic + 51 44 34 cannonblack + 53 40 30 cocoabrown + 60 47 35 cola + 59 46 37 sambuca + 60 52 46 treehouse + 61 50 44 deepoak + 58 47 45 sepia + 54 45 38 coffeebean + 54 45 38 cubantan + 54 45 38 marlin + 48 38 33 woodbark + 42 41 34 asphalt + 42 41 34 maire + 41 41 36 junglegreen + 70 54 35 clinker + 70 54 41 woodburn + 65 54 40 jackobean + 63 55 38 birch + 63 54 35 mikado + 73 63 47 ashbrown + 72 65 43 onion + 71 62 35 madras + 57 61 42 greenkelp + 69 64 43 woodrush + 76 78 49 waiouru + 79 77 50 camouflage + 84 78 49 thatchgreen + 83 73 49 punga + 81 65 45 deepbronze + 75 65 42 tumbleweed + 85 74 60 metallicbronze + 79 64 55 paco + 75 67 59 spaceshuttle + 74 75 70 gravel + 70 71 62 heavymetal + 57 62 46 logcabin + 61 64 49 scrub + 58 65 51 rangitoto + 57 57 44 elpaso + 58 55 46 touchwood + 60 55 49 blackpepper + 63 55 46 blackwood + 68 54 45 tobago + 66 52 43 slugger + 69 54 43 darkrum + 73 59 47 bronze + 71 59 47 englishwalnut + 63 57 57 eclipse + 70 61 62 jon + 52 54 58 shark + 54 56 60 vulcan + 60 61 62 balticsea + 57 59 60 montana + 60 59 60 fuscousgrey + 58 53 50 kilamanjaro + 55 63 67 mirage + 55 62 65 mineshaft + 57 64 67 charade + 59 60 56 zeus + 69 70 66 tuatara + 64 77 73 corduroy + 72 74 70 armadillo + 77 77 75 thunder + 82 75 75 matterhorn + 80 73 74 emperor + 69 70 71 bleachedcedar + 67 70 75 steelgrey + 70 73 78 tuna + 72 71 83 gunpowder + 61 70 83 rhino + 60 67 84 bluezodiac + 58 78 95 cello + 61 75 82 atomic + 58 78 88 deepcove + 51 64 70 bigstone + 37 63 78 nileblue + 35 65 78 greenvogue + 37 60 72 tarawera + 46 55 73 licorice + 53 62 79 cloudburst + 56 55 64 blackmarlin + 55 54 63 revolver + 65 61 75 grape + 44 45 60 blackrock + 44 42 53 haiti + 49 42 41 lividbrown + 50 44 43 diesel + 51 46 46 nightrider + 55 51 50 gondola + 50 49 46 crowshead + 45 48 50 codgrey + 41 44 47 bunker + 38 43 47 bluecharcoal + 44 44 50 bastille + 51 52 58 woodybay + 49 51 55 ebony + 50 52 56 ebonyclay + 44 53 57 gunmetal + 40 53 58 oxfordblue + 37 47 47 swamp + 49 51 48 oil + 43 50 48 woodsmoke + 41 52 50 aztec + 36 46 40 midnightmoss + 35 47 44 racinggreen + 30 52 66 bluewhale + 41 55 65 mosaic + 36 54 64 elephant + 33 48 62 midnight + 30 47 60 tangaroa + 36 42 46 cinder + 30 39 44 blackpearl + 30 39 44 bluebark + 36 37 43 blackrussian + 41 41 47 jaguar + 37 37 37 nero + 42 39 37 bokaragrey + 31 38 59 outerspace + 33 38 58 midnightexpress + 33 38 58 stratos + 25 47 65 prussianblue + 43 52 73 bunting + 42 52 74 downriver + 48 67 106 capri + 38 65 107 bondiblue + 39 60 90 catalinablue + 39 60 90 cobalt + 52 63 92 covegrey + 52 63 92 gulfblue + 47 60 83 biscay + 45 60 84 madison + 33 69 89 astronautblue + 32 63 88 regalblue + 39 74 93 arapawa + 71 88 119 chambray + 68 81 114 astronaut + 71 82 110 eastbay + 37 89 127 bahamablue + 54 92 125 matisse + 44 87 120 veniceblue + 50 84 130 sttropaz + 41 89 139 endeavour + 0 98 111 bluelagoon + 48 92 113 blumine + 44 89 113 chathamsblue + 37 91 119 orient + 31 106 125 allports + 61 113 136 calypso + 68 121 142 jellybean + 55 111 137 astral + 73 136 154 hippieblue + 61 133 184 curiousblue + 49 110 160 lochmara + 78 108 157 sanmarino + 78 105 154 azure + 87 132 193 havelockblue + 91 110 145 waikawagrey + 87 109 142 kashmirblue + 76 107 136 wedgewood +129 124 135 topaz +122 118 121 monsoon +119 118 114 dovegrey +116 120 128 stormgrey +121 132 136 regentgrey +124 129 124 boulder +109 120 118 rollingstone +119 132 142 pigeonpost +105 125 137 lynch +100 125 134 hoki + 98 119 126 bluebayoux +104 118 110 sirocco +102 111 111 nevada + 99 109 112 palesky +102 106 109 midgrey +111 116 123 raven +118 115 111 aluminium +107 106 108 scarpaflow +124 113 115 empress +106 104 115 dolphin +114 114 130 waterloo + 96 93 107 smoky + 99 99 115 comet + 75 90 98 fiord + 68 87 97 sanjuan + 63 84 90 casal + 87 89 93 brightgrey + 88 84 82 tundora + 86 80 81 mortar + 90 79 81 donjuan + 78 78 76 shipgrey + 78 85 82 capecod + 80 85 85 mako + 76 83 86 trout + 70 83 82 darkslate + 79 90 95 pickledbluewood + 85 96 97 riverbed + 78 96 94 limedspruce + 97 102 107 shuttlegrey +105 98 104 saltbox +106 100 102 scorpion +108 94 83 kabul +110 95 86 dorado +105 95 80 makara +101 100 95 stormdust + 91 100 82 pickledaspen + 91 93 86 chicago + 81 87 79 battleshipgrey + 89 86 72 millbrook + 76 85 68 cabbagepont + 79 78 72 merlin + 81 79 74 dune + 87 83 75 masala + 93 89 82 smokeyash + 93 83 70 judgegrey + 93 78 70 saddle + 90 76 66 cork + 90 76 66 mash + 90 77 65 rock + 91 82 68 iroko + 85 77 66 mondo + 84 79 58 lisbonbrown + 84 79 58 panda + 77 80 60 kelp + 78 85 65 lunargreen +105 104 75 hemlock +111 99 75 soyabean +108 91 76 domino +117 101 86 pinecone +114 103 81 coffee +118 109 82 peat +122 113 92 pablo +129 110 92 donkeybrown +133 113 88 cement +143 125 107 squirrel +130 122 103 arrowtown +128 118 97 stonewall +134 118 101 sanddune +138 125 114 americano +139 126 119 hurricane +130 127 121 concord +120 109 95 sandstone +112 110 102 ironsidegrey +113 110 97 flint +103 109 99 limedash +122 124 118 gunsmoke +124 124 114 tapa +120 133 122 bluesmoke +136 128 100 olivehaze +139 130 101 granitegreen +123 120 90 kokoda +117 120 90 finch +112 105 80 crocodile +104 107 80 siam + 91 111 85 cactus + 99 119 90 axolotl + 97 117 91 finlandia +105 117 92 willowgrove +117 135 110 xanadu + 92 129 115 cuttysark + 98 103 70 woodland + 79 99 72 tomthumb + 82 86 54 greygreen + 55 93 79 spectra + 62 89 76 plantation + 78 93 78 nandor + 80 99 85 mineralgreen + 64 99 86 stromboli + 75 95 86 viridiangreen + 57 85 85 oracle + 73 101 105 taxbreak + 73 98 103 smaltblue + 72 108 122 bismark + 64 117 119 ming + 64 114 109 jade + 81 123 120 breakerbay + 83 115 111 william + 72 128 132 paradiso + 0 123 119 surfiegreen + 41 123 118 elm + 49 121 109 genoa + 43 121 122 atoll + 31 99 97 seagreen + 22 100 97 bluestone + 0 95 91 mosque + 38 98 85 eden + 32 89 72 aquamarine + 38 96 79 eveningsea + 48 93 53 parsley + 22 91 49 crusoe + 38 98 66 greenpea + 36 108 70 greenstone + 73 118 79 killarney + 76 120 92 como + 92 138 100 springgreen + 56 123 84 amazon + 27 138 107 elfgreen + 22 126 101 deepsea + 0 143 112 observatory + 23 123 77 salem + 19 104 67 jewel + 21 99 61 fungreen + 0 110 78 watercourse + 0 135 159 easternblue + 37 153 178 pelorous + 48 142 160 scooter + 77 177 200 viking + 91 160 208 pictonblue + 67 142 172 bostonblue + 96 154 184 shakespeare +111 140 159 bermudagrey +121 136 171 shipcove + 91 137 192 danube +122 170 224 jordyblue +147 162 186 rockblue +164 175 205 echoblue +138 167 204 poloblue +102 183 225 malibu +119 183 208 seagull +120 177 191 glacier +140 206 234 anakiwa +165 206 236 sail +174 201 235 tropicalblue +126 205 221 spray +182 236 222 waterleaf +111 210 190 downy +137 217 200 riptide +146 211 202 aqua +134 210 193 bermuda +151 213 179 vistablue +180 225 187 fringyflower +157 211 168 chinook +214 240 205 snowymint +239 245 209 riceflower +223 241 214 hintofgreen +216 240 210 blueromance +197 231 205 grannyapple +192 232 213 aeroblue +215 231 208 peppermint +222 241 221 tara +223 240 226 offgreen +226 242 228 frostedmint +198 234 221 minttulip +194 230 236 onahau +209 234 234 oysterbay +208 234 232 foam +203 232 232 mabel +202 225 217 iceberg +202 231 226 jaggedice +206 239 228 hummingbird +215 238 228 whiteice +233 238 235 lilywhite +221 237 233 tranquil +223 239 234 clearday +230 242 234 bubbles +222 227 227 zircon +216 221 218 mystic +211 229 239 pattensblue +210 218 237 hawkesblue +230 223 231 selago +231 229 232 whitelilac +221 220 219 porcelain +220 221 221 athensgrey +227 225 224 seashell +239 230 230 whisper +238 223 222 softpeach +238 232 235 magnolia +233 236 241 solitude +245 239 235 hintofred +251 238 232 rosewhite +242 240 230 alabaster +244 240 230 romance +244 234 228 sauvignon +249 232 226 wisppink +242 230 221 fantasy +248 234 223 chardon +248 235 221 bridalheath +241 234 215 halfpearllusta +241 235 218 butterywhite +241 235 217 orchidwhite +244 239 224 bianca +242 237 221 quarterpearllusta +248 237 219 islandspice +252 233 215 serenade +253 239 211 varden +248 234 202 ginfizz +247 240 219 apricotwhite +251 242 219 earlydawn +251 240 214 halfdutchwhite +253 239 219 forgetmenot +249 247 222 chileanheath +248 246 223 promenade +250 243 220 offyellow +241 237 212 rumswizzle +251 243 211 chinaivory +245 243 206 moonglow +248 246 216 whitenectar +246 245 215 hintofyellow +235 247 228 panache +232 243 232 aquaspring +238 243 229 saltpan +244 246 236 twilightblue +238 239 223 sugarcane +239 236 222 ricecake +231 242 233 dew +229 242 231 polar +223 230 207 willowbrook +219 229 210 frostee +222 234 220 applegreen +218 230 221 swansdown +219 228 220 aquasqueeze +224 228 220 catskillwhite +229 230 223 blacksqueeze +227 227 220 snowdrift +229 228 219 blackwhite +222 221 203 greenwhite +217 221 213 aquahaze +217 223 205 gin +219 224 208 feta +225 228 197 frost +225 218 187 coconutcream +238 231 200 scotchmist +237 231 200 halfandhalf +234 227 205 orangewhite +226 221 199 travertine +234 218 194 solitaire +230 219 199 halfspanishwhite +234 224 200 pearllusta +245 230 196 pipi +233 220 190 doublepearllusta +249 228 197 eggsour +249 228 198 derby +245 222 196 sazerac +225 218 203 albescentwhite +235 226 210 quarterspanishwhite +235 225 206 bleachwhite +235 229 213 cararra +243 229 220 fairpink +234 228 220 pampas +237 231 224 desertstorm +238 231 220 whitelinen +236 229 218 soapstone +233 230 220 narvik +231 228 222 wildsand +228 226 220 wanwhite +233 225 217 springwood +227 223 217 vistawhite +224 222 215 blackhaze +223 221 214 ceramic +223 221 214 hintofgrey +223 221 214 seafog +220 217 205 milkwhite +225 219 208 merino +230 214 205 dawnpink +230 216 212 ebb +219 208 202 swisscoffee +223 215 210 bonjour +220 215 209 gallery +218 214 204 whitepointer +215 206 197 swirl +212 207 197 westar +217 208 193 blanc +222 209 198 pearlbush +230 214 184 rocksalt +213 203 178 athsspecial +222 209 183 janna +222 209 183 spanishwhite +223 215 189 wheatfield +219 217 194 loafer +212 207 180 whiterock +210 211 179 orinoco +211 219 203 ottoman +209 211 204 greynurse +214 209 192 ecruwhite +214 209 192 joanna +210 210 192 celeste +206 205 184 moonmist +203 206 192 harp +191 205 192 pariswhite +202 199 183 chromewhite +197 195 176 kangaroo +191 192 171 kidnapper +186 192 180 pumice +186 192 179 tasman +188 191 168 berylgreen +208 200 176 parchment +210 195 163 doublespanishwhite +207 190 165 softamber +210 198 182 starkwhite +203 201 192 quillgrey +190 189 182 silversand +194 188 177 cloud +191 189 193 frenchgrey +192 191 199 ghost +195 190 187 paleslate +205 198 197 alto +203 205 205 iron +210 209 205 concrete +213 210 209 mercury +221 214 225 titanwhite +199 205 216 linkwater +189 186 206 bluehaze +179 196 216 spindle +205 213 213 zumthor +203 208 207 geyser +184 198 190 nebula +176 196 196 junglemist +185 195 190 tiara +168 195 188 opal +187 208 201 jetstream +164 210 224 frenchpass +160 205 217 regentstblue +158 209 211 morningglory +164 220 230 charlotte +166 213 208 sinbad +175 227 214 icecold +180 226 213 cruise +173 217 209 scandal +172 201 178 gumleaf +178 198 177 zanah +179 193 177 rainee +195 214 189 surfcrest +194 213 196 seamist +193 216 197 edgewater +184 212 187 surf +187 205 165 pixiegreen +189 202 168 paleleaf +163 189 156 springrain +139 165 143 envy +150 167 147 mantle +143 182 156 summergreen +154 192 182 shadowgreen +138 174 164 seanymph +119 168 171 neptune +129 166 170 ziggurat +140 168 160 cascade +157 180 170 skeptic +174 187 193 heather +179 187 183 loblolly +172 182 178 periglacialblue +172 174 169 silverchalice +170 181 184 casper +160 177 174 conch +156 172 165 towergrey +161 169 168 hitgrey +164 173 176 gullgrey +146 172 180 botticelli +147 170 185 nepal +162 161 172 spunpearl +165 169 178 mischka +159 163 167 greychateau +169 157 157 nobel +160 159 156 mountainmist +179 171 182 chatelle +174 174 173 bombay +191 179 178 pinkswan +190 180 171 tide +191 186 175 cottonseed +189 186 174 greynickel +187 173 161 silk +202 184 162 grainbrown +204 182 155 vanilla +201 181 154 sourdough +197 186 160 sisal +192 176 147 coral +190 178 154 akaroa +191 181 162 tea +186 183 162 linen +186 185 169 mistgrey +190 186 167 ash +184 181 161 tana +169 175 153 greenspring +158 170 158 robinseggblue +167 166 157 foggygrey +160 161 151 stardust +151 164 154 edward +165 168 143 bud +170 165 131 neutralgreen +176 172 148 eagle +181 172 148 bisonhide +183 168 163 martini +176 169 159 cloudy +162 149 137 zorba +165 151 132 malta +167 151 129 bronco +161 153 134 nomad +163 152 129 raincloud +163 154 135 napa +152 145 113 gurkha +161 154 127 greyolive +153 155 149 delta +159 157 145 dawn +153 154 134 lemongrass +135 135 111 schist +136 137 108 bitter +135 132 102 bandicoot +156 141 114 paleoyster +141 132 120 schooner +137 132 120 taupegrey +148 140 126 heatheredgrey +134 131 122 friargrey +139 134 133 suvagrey +135 135 133 jumbo +159 155 157 shadylady +147 145 160 greysuit +153 152 167 santasgrey +132 156 169 balihai +146 159 162 powderblue +140 156 156 submarine +133 136 133 stack +129 137 136 oslogrey +113 143 138 gumbo +123 148 140 grannysmith +116 145 142 juniper +100 136 148 horizon +105 136 144 gothic + 85 143 147 halfbaked + 99 146 131 patina +123 137 118 spanishgreen +145 160 146 pewter +110 141 113 laurel +109 154 120 oxley +123 177 141 bayleaf +126 179 148 padua +117 170 148 acapulco +116 178 168 gulfstream +109 175 167 tradewind +122 197 180 montecarlo +101 173 178 fountainblue + 64 143 144 bluechill + 72 144 132 lochinvar + 37 151 151 java + 95 182 156 keppel + 89 186 163 puertorico +103 190 144 silvertree + 41 169 139 niagara + 57 159 134 gossamer + 50 151 96 eucalyptus + 65 159 89 chateaugreen + 76 169 115 oceangreen +133 202 135 deyork +127 193 92 mantis +102 179 72 apple + 75 163 81 fruitsalad + 95 146 40 vidaloca +136 169 91 chelseacucumber +122 148 97 highland +149 152 107 avocado +152 159 122 sage +125 157 114 amulet +132 145 55 wasabi +146 140 60 highball +146 140 60 sycamore +150 132 40 lemonginger +169 141 54 reefgold +173 138 59 alpine +182 150 66 roti +178 153 75 husk +174 144 65 turmeric +171 141 63 luxorgold +151 151 111 malachitegreen +163 153 119 canvas +163 153 119 tallow +186 171 135 pavlova +167 160 126 hillary +199 184 130 yuma +187 181 141 coriander +184 173 138 chino +205 174 112 putty +198 169 94 laser +210 185 96 tacha +185 173 97 gimblet +175 193 130 caper +185 184 128 peasoup +156 166 100 greensmoke +162 165 128 locust +164 184 143 norway +184 202 157 sprout +191 194 152 greenmist +189 192 126 pineglade +227 212 116 wildrice +204 207 130 deco +222 203 129 sandwisp +222 195 113 chenin +245 205 130 cherokee +235 200 129 marzipan +228 195 133 neworleans +223 194 129 chalky +221 194 131 zombie +218 190 130 straw +220 198 160 raffia +199 189 149 thistle +208 195 131 winterhazel +224 216 167 mintjulep +216 204 155 tahunasands +225 213 166 sapling +233 215 171 beeswax +233 215 171 colonialwhite +237 213 166 astra +235 212 174 givry +237 210 164 dairycream +232 212 162 hampton +228 207 153 doublecolonialwhite +230 204 154 chamois +224 200 141 eggwhite +241 215 158 splash +246 224 164 buttermilk +254 224 165 capehoney +251 229 194 peach +243 215 182 pinklady +238 217 182 champagne +240 223 187 bajawhite +240 223 187 dutchwhite +243 229 192 milkpunch +247 229 183 barleywhite +233 217 169 sidecar +242 229 191 halfcolonialwhite +248 243 196 cornfield +241 241 198 springsun +245 245 204 mimosa +252 237 197 oasis +255 227 155 creambrulee +255 214 123 salomie +249 215 126 goldenglow +249 228 150 visvis +248 234 151 picasso +251 235 155 drover +249 245 159 paleprim +248 246 168 shalimar +244 240 155 portafino +228 222 142 primrose +246 244 147 milan +240 245 144 tidal +238 242 147 jonquil +239 248 170 australianmint +240 245 187 chiffon +227 229 177 tusk +245 249 203 carla +245 244 193 cumulus +234 247 201 snowflurry +183 227 168 madang +159 211 133 gossip +165 215 133 feijoa +198 234 128 sulu +209 239 159 reef +218 234 111 mindaro +177 221 82 conifer +156 208 59 atlantis +183 197 44 lime +183 198 26 riogrande +198 218 54 laspalmas +194 214 46 fuego +210 219 50 bitterlemon +253 227 54 gorse +235 222 49 goldenfizz +226 230 77 canary +251 235 80 parisdaisy +245 241 113 dolly +232 237 105 honeysuckle +236 230 126 texas +251 240 115 witchhaze +249 225 118 sweetcorn +245 204 35 turbo +241 204 43 goldendream +238 204 36 broom +245 215 82 energyyellow +234 204 74 festival +218 192 26 sunflower +240 196 32 moonyellow +236 189 44 brightsun +238 192 81 creamcan +249 208 84 kournikova +224 193 97 cremedebanane +234 206 106 goldensand +240 213 85 portica +221 203 70 confetti +228 219 85 manz +190 202 96 wildwillow +214 202 61 wattle +227 221 57 starship +208 193 23 birdflower +210 198 31 barberry +184 167 34 earlsgreen +196 170 77 sundance +217 178 32 lemon +188 155 27 buddhagold +183 152 38 sahara +158 128 34 hacienda +171 154 28 lucky +142 154 33 citron +186 192 14 larioja +169 192 28 bahia +159 183 10 citrus +137 172 39 limerick +180 192 76 celery +124 159 47 sushi + 95 151 39 limeade +122 172 33 lima +113 169 29 christi + 32 105 55 camarone + 44 110 49 sanfelix + 47 117 50 japaneselaurel + 62 128 39 bilbao + 66 137 41 lapalma + 95 129 81 gladegreen + 96 138 90 hippiegreen + 96 124 71 dingley + 72 101 49 dell + 82 107 45 greenleaf + 62 99 52 greenhouse + 54 92 52 fern + 72 83 26 verdungreen + 87 94 46 fernfrond + 71 86 47 clover + 85 91 44 saratoga + 90 110 65 chaletgreen + 99 111 34 fijigreen +102 112 40 pacifika +102 112 40 rainforest +116 112 40 olivetone +126 132 36 trendygreen +103 105 39 pistachio +130 106 33 yukongold +122 114 41 grasshopper +122 114 41 pesto +119 113 43 crete +124 103 32 mustard +141 112 42 cornharvest +141 112 42 stinger +137 126 89 claycreek +130 133 98 flax +120 110 76 goben +107 91 61 limedgum +115 99 62 yellowmetal +117 91 39 kumera +115 99 48 acorn +115 99 48 himalaya + 98 93 42 costadelsol + 98 93 42 planter + 98 96 62 verdigris +109 86 44 horsesneck + 92 81 47 westcoast + 88 76 37 bronzeolive + 67 76 40 bronzetone + 54 62 29 turtlegreen +110 51 38 pueblo +115 61 31 perutan +112 65 40 darkrimu +109 59 36 newamber + 91 58 36 carnabytan + 83 51 30 brownbramble + 80 56 30 saddlebrown + 91 61 39 bracken + 98 66 43 irishcoffee +102 74 45 dallas +109 77 44 ironbark +106 73 40 caferoyale +108 70 31 antiquebrass +117 72 47 capepalliser +125 78 56 cigar +121 77 46 walnut +132 92 64 pottersclay +136 89 49 natural +116 89 55 shinglefawn +140 114 84 limedoak +140 99 56 mckenzie +143 111 72 driftwood +141 95 44 rustynail +144 94 38 afghantan +157 112 46 butteredrum +167 117 44 hottoddy +129 91 40 brazil +129 91 40 hotcurry +153 82 43 hawaiiantan +178 110 51 renosand +186 111 63 bamboo +175 108 62 bourbon +177 108 57 oregon +171 107 53 pumpkin +165 101 49 maitai +161 82 38 richgold +157 84 50 piper +156 91 52 indochine +161 95 59 desert +161 98 59 redbeech +173 98 66 tuscany +169 106 80 santefe +149 78 44 alerttan +149 83 47 chelseagem +142 89 60 rope +134 75 54 paarl +136 79 64 mulefawn +134 80 64 ironstone +119 66 44 coppercanyon +122 68 52 peanut +120 68 48 cumin +117 68 43 bullshot +123 72 43 cinnamon +128 78 44 korma +136 60 50 prairiesand +135 56 47 crabapple +136 53 49 totempole +142 58 54 tabasco +140 63 48 embers +143 63 42 fire +142 53 55 wellread +146 56 48 thunderbird +155 61 61 mexicanred +161 71 67 roofterracotta +151 66 45 tiamaria +157 68 45 rockspray +154 70 61 cognac +151 70 60 mojo +166 86 72 crail +169 82 73 appleblossom +199 97 85 sunglo +190 92 72 flamepea +168 83 53 orangeroughy +168 85 51 vesuvius +177 89 47 fieryorange +173 82 46 redstage +172 81 45 roseofsharon +201 97 56 ecstasy +187 95 52 smoketree +191 101 46 christine +205 93 52 tangerine +208 94 52 chileanfire +193 77 54 grenadier +197 79 51 trinidad +193 79 59 clementine +192 81 74 sunset +212 87 78 valencia +205 82 91 mandy +168 50 57 punch +158 51 50 milanored +146 42 49 brightred +149 46 49 guardsmanred +134 40 46 flamered +134 40 46 monza +213 108 48 golddrop +220 114 42 tahitigold +212 111 49 tango +229 127 61 pizazz +229 130 58 westside +226 129 59 treepoppy +234 134 69 flamenco +239 142 56 sun +186 120 42 pirategold +197 131 46 geebung +202 129 54 goldenbell +205 132 49 dixie +209 144 51 fuelyellow +187 142 52 hokeypokey +188 146 41 nugget +226 178 39 goldtips +216 167 35 galliano +223 170 40 corn +227 172 61 tuliptree +221 173 86 robroy +220 159 69 saffron +224 157 55 candlelight +244 159 53 yellowsea +218 148 41 buttercup +224 152 66 firebush +250 157 73 sunshade +239 149 72 seabuckthorn +233 140 58 california +247 162 51 lightningyellow +252 174 96 rajah +252 176 87 texasrose +253 174 69 mysin +254 181 82 koromiko +255 193 82 goldentainoi +240 178 83 casablanca +234 184 82 ronchi +255 205 115 grandis +255 180 55 supernova +255 213 154 caramel +254 219 183 sandybeach +255 215 160 frangipani +244 208 164 tequila +238 199 162 negroni +255 198 158 romantic +223 185 146 pancho +220 182 138 brandy +227 185 130 maize +233 186 129 corvette +255 200 120 chardonnay +234 183 106 harvestgold +246 174 120 tacao +245 183 153 mandyspink +238 179 158 waxflower +254 171 154 rosebud +231 158 136 tonyspink +253 164 112 hitpink +228 143 103 apricot +223 157 91 porsche +212 145 93 diserria +212 145 93 whiskeysour +210 144 98 whiskey +211 169 92 apache +218 177 96 equator +213 177 133 calico +226 175 128 manhattan +204 164 131 cameo +199 163 132 rodeodust +182 147 92 barleycorn +157 127 97 sorrellbrown +163 135 106 sandal +165 139 111 mongoose +158 126 83 muesli +169 132 79 muddywaters +171 137 83 teak +191 145 75 tussock +191 141 60 pizza +184 138 61 marigold +181 123 46 mandalay +198 142 63 anzac +193 145 86 twine +192 124 64 brandypunch +187 116 49 meteor +198 114 59 zest +198 128 89 peachschnapps +208 131 99 burningsand +206 114 89 japonica +231 123 117 geraldine +221 131 116 newyorkpink +255 152 137 monalisa +243 134 83 crusta +203 111 74 reddamask +221 107 56 sorbus +226 121 69 jaffa +225 99 79 flamingo +239 115 94 persimmon +216 98 91 roman +229 109 117 froly +227 111 138 deepblush +205 109 147 hopbush +232 153 190 shocking +239 149 174 illusion +224 147 171 kobi +230 128 149 carissma +241 145 154 wewak +238 145 141 sweetpink +219 129 126 seapink +208 116 139 charm +193 111 104 contessa +194 142 136 orientalpink +179 112 132 tapestry +208 138 155 cancan +167 129 153 bouquet +197 143 157 viola +164 135 139 wisteria +174 148 171 londonhue +149 135 156 amethystsmoke +157 156 180 logan +152 126 126 opium +154 134 120 almondfrost +152 125 115 hemp +182 133 122 brandyrose +175 147 125 sandrift +177 148 143 thatch +181 153 142 delrio +195 152 139 quicksand +211 161 148 rose +205 165 156 eunry +209 179 153 cashmere +210 179 169 clamshell +202 181 178 coldturkey +200 177 192 maverick +172 155 155 dustygrey +185 172 187 lola +193 159 179 lily +201 154 160 careyspink +218 151 144 petiteorchid +214 139 128 mypink +255 171 160 cornflower +248 175 169 sundown +255 197 187 yourpink +249 192 196 azalea +223 177 182 blossom +245 178 197 cupid +222 183 217 frenchlilac +244 200 219 classicrose +237 184 199 chantilly +224 183 194 melanie +218 192 205 twilight +246 204 215 pinklace +226 205 213 prim +212 181 176 oysterpink +212 187 177 wafer +220 191 172 justright +219 194 171 bone +230 178 166 shilo +216 180 182 pinkflare +224 184 177 cavernpink +235 185 179 beautybush +245 208 201 coralcandy +242 205 187 watusi +231 210 200 bizarre +229 202 192 duststorm +235 210 209 vanillaice +239 220 212 potpourri +246 222 218 remy +246 227 218 provincialpink +252 219 210 pippin +251 215 204 cinderella +254 220 193 karry +249 211 190 tuftbush +253 215 216 wepeep +252 213 207 cosmos +253 233 224 chablis +250 230 223 bridesmaid +248 228 227 tutu +245 230 234 amour +248 219 224 carouselpink +239 214 218 palerose +228 215 229 snuff +227 214 233 bluechalk +245 215 220 cherub +213 199 232 fog +195 185 221 melrose +202 180 212 prelude +174 153 210 bilobaflower +194 169 219 perfume +162 158 205 wistful +192 178 215 moonraker +172 185 232 perano +139 152 216 portage +157 138 191 coldpurple +170 140 188 eastside +159 144 208 lavender +148 112 196 lilacbush +123 92 183 fuchsia +114 74 161 studio + 91 62 144 daisybush +181 75 115 royalheath +138 45 82 rosebudcherry +137 45 79 disco +150 44 84 lipstick +169 64 100 rouge +180 56 100 cranberry +162 61 84 nightshadz +179 54 84 hibiscus +205 82 108 cabaret +181 80 103 blush +171 73 92 hippiepink +138 51 53 oldbrick +133 53 52 tallpoppy +143 62 63 rosewood +131 61 62 stiletto +128 58 75 camelot +149 82 100 vinrouge +152 73 97 cadillac +148 106 129 strikemaster +105 69 84 finn +121 77 96 cosmic +142 81 100 cannonpink +116 64 66 tosca +133 73 76 solidpink +125 65 56 redrobin +126 74 59 nutmeg +143 78 69 elsalva +142 77 69 matrix +139 80 75 lotus +149 82 76 copperrust +165 110 117 turkishrose +171 110 103 coraltree +158 103 89 auchico +139 95 77 spicymix +144 106 84 leather +159 113 95 toast +135 106 104 ferra +130 102 99 pharlap +125 101 92 russett +143 119 119 bazaar +125 103 87 romancoffee +109 88 67 tobaccobrown +115 85 62 pickledbean +115 80 59 oldcopper +103 72 52 jambalaya +108 79 63 spice +106 84 69 quincy +101 77 73 congobrown +110 81 80 buccaneer +107 90 90 zambezi +110 90 91 falcon + 82 77 91 mulledwine + 98 86 101 fedora + 96 90 103 mobster +118 109 124 mamba +113 102 117 rum +137 117 120 spicypink +139 125 130 venus +130 114 164 deluge +102 111 180 chetwodeblue +111 99 160 scampi +131 120 199 moodyblue +142 114 199 truev +106 91 177 bluemarguerite +146 113 167 cesoir +128 93 128 trendypink +116 80 133 affair +104 87 140 butterflybush + 81 85 155 governorbay + 86 71 134 gigas + 86 73 133 victoria + 66 99 159 mariner + 55 78 136 toryblue + 51 80 131 funblue + 63 82 129 sapphire +105 93 135 kimberly + 53 62 100 bayofmany + 61 50 93 jacarta + 59 67 108 portgore + 52 52 103 deepkoamaru + 53 61 117 toreabay + 50 63 117 resolutionblue + 61 63 125 jacksonspurple + 62 50 103 minsk + 75 60 142 bluegem + 57 45 115 bluebell + 75 45 114 bluediamond + 92 60 109 honeyflower + 74 59 106 meteorite + 78 46 83 hotpurple + 74 45 87 scarletgum + 46 24 59 blackcurrant + 56 26 56 plum + 56 33 97 christalle + 49 39 96 parism + 46 34 73 violentviolet + 42 37 81 paua + 55 45 82 cherrypie + 41 45 79 luckypoint + 42 43 65 valhalla + 63 46 76 jagger + 45 37 65 tolopea + 55 37 40 aubergine + 60 33 38 temptress + 53 34 53 mardigras + 61 35 39 chocolate + 62 38 49 toledo + 69 46 57 barossa + 59 43 44 havana + 59 43 44 jarrah + 52 41 49 melanzane + 54 45 56 jacaranda + 56 44 56 valentino + 47 38 60 violet + 60 55 72 martinique + 68 50 64 voodoo + 76 51 71 loulou + 76 61 78 bossanova + 85 69 69 woodybrown + 69 52 48 rebel + 70 52 48 cedar + 68 55 54 cowboy + 77 62 60 craterbrown + 79 56 53 cocoabean + 82 57 54 vancleef + 74 53 49 bean + 72 50 48 mahogany + 74 46 50 cabsav + 78 49 45 espresso + 78 49 46 cherrywood + 89 69 55 brownderby + 93 59 46 cioccolato + 85 52 43 darkoak + 91 52 46 redwood + 79 48 31 indiantan + 68 45 33 moroccobrown + 60 36 27 brownpod + 62 47 46 tamarind + 64 35 39 maroon + 58 24 26 rusticred + 72 36 39 bulgarianrose + 79 42 44 heath + 78 39 40 volcano + 82 36 38 lonestar + 79 33 42 persianred + 76 28 36 bordeaux + 88 33 36 burntcrimson + 91 31 34 venetianred + 93 31 30 redoxide +101 37 37 burgundy +102 42 44 reddevil + 97 45 45 darktan +103 47 48 japanesemaple + 88 47 43 moccaccino + 99 53 40 hairyheath +107 52 42 meranti +108 55 54 sanguinebrown +102 54 45 oiledcedar +110 61 52 metalliccopper +118 60 51 crownofthorns +111 55 45 mocha +108 50 46 kenyancopper +104 51 50 persianplum +115 52 58 merlot +113 51 60 ribbon + 95 44 47 jazz + 94 42 64 mulberry + 83 41 52 blackrose + 82 44 53 wineberry +100 58 72 tawnyport + 68 35 47 castro + 67 24 47 blackberry +122 46 77 flirt +106 31 68 nightclub +106 31 68 pompadour +105 41 59 siren +110 34 51 claret +124 45 55 paprika +117 43 47 tamarillo +120 46 44 lusty +130 42 50 sangria +132 40 51 shiraz +126 37 48 scarlett +112 31 40 redberry +101 28 38 pohutukawa +107 37 44 hotchile +107 37 44 monarch +107 37 44 westernred +138 36 78 cardinal +105 50 110 seance +110 57 116 eminence +104 59 125 clairvoyant + 88 53 128 kingfisherdaisy + 70 44 119 windsor diff --git a/lib/util/mallocvar.h b/lib/util/mallocvar.h index 23b28c40..73498357 100644 --- a/lib/util/mallocvar.h +++ b/lib/util/mallocvar.h @@ -67,7 +67,18 @@ static __inline__ void reallocProduct(void ** const blockP, size_t const factor1, unsigned int const factor2) { +/*---------------------------------------------------------------------------- + Reallocate the block at *blockPP to size 'factor1' * 'factor2'. + (Reallocate means make *blockPP point to a block of that size that + contains the same data as the block to which *blockP points now, with + additional space as needed at the end). + + If *blockPP is null, make *blockPP point to a new block of memory of + the desired size with no contents. + If the reallocation fails, release any memory pointed by *blockP and + make *blockP null. +-----------------------------------------------------------------------------*/ size_t const sizeMax = #if defined(SIZE_MAX) SIZE_MAX @@ -109,8 +120,6 @@ reallocProduct(void ** const blockP, void * array; \ array = arrayName; \ reallocProduct(&array, nElements, sizeof(arrayName[0])); \ - if (!array && arrayName) \ - free(arrayName); \ arrayName = array; \ } while (0) diff --git a/test/pamcut.ok b/test/pamcut.ok index 61db6a97..18ed88e8 100644 --- a/test/pamcut.ok +++ b/test/pamcut.ok @@ -37,7 +37,51 @@ Test 6a. Should print 5 34 5 34 50 50 30 30 5 34 5 34 50 50 30 30 Test 6b. Should print 3412257956 129 3412257956 129 -Test 7. Should print 1576602925 8 four times +Test 7. Should print 284857390 12 sixteen times +284857390 12 +284857390 12 +284857390 12 +284857390 12 +284857390 12 +284857390 12 +284857390 12 +284857390 12 +284857390 12 +284857390 12 +284857390 12 +284857390 12 +284857390 12 +284857390 12 +284857390 12 +284857390 12 +Test 8. Should print 3125257619 29 four times +3125257619 29 +3125257619 29 +3125257619 29 +3125257619 29 +Test 9. Should print 3338453023 36 sixteen times +3338453023 36 +3338453023 36 +3338453023 36 +3338453023 36 +3338453023 36 +3338453023 36 +3338453023 36 +3338453023 36 +3338453023 36 +3338453023 36 +3338453023 36 +3338453023 36 +3338453023 36 +3338453023 36 +3338453023 36 +3338453023 36 +Test 10. Should print 3957742883 302 four times +3957742883 302 +3957742883 302 +3957742883 302 +3957742883 302 +Test 11. Should print 1576602925 8 four times 1576602925 8 1576602925 8 1576602925 8 diff --git a/test/pamcut.test b/test/pamcut.test index fce61ea8..7d60e1cd 100755 --- a/test/pamcut.test +++ b/test/pamcut.test @@ -1,34 +1,36 @@ #! /bin/sh -# This script tests: pamcut pbmmake -# Also requires: pamfile pnmpad +# This script tests: pamcut +# Also requires: pbmmake pgmmake pamfile pnmpad pamflip + +tmpdir=${tmpdir:-/tmp} echo "Test 1a. Should print 0 259 0 159 227 149 260 160 twice" pamcut -left 0 -right 259 -top 0 -bottom 159 \ - -pad -reportonly testimg.ppm + -pad -reportonly testimg.ppm pamcut -left 0 -top 0 -width 260 -height 160 \ - -pad -reportonly testimg.ppm + -pad -reportonly testimg.ppm echo "Test 1b. Should print 2958909756 124815" pamcut -left 0 -top 0 -width 260 -height 160 \ - -pad testimg.ppm | cksum + -pad testimg.ppm | cksum echo "Test 2a. Should print 120 159 120 159 227 149 40 40 three times" pamcut -left 120 -right 159 -top 120 -bottom 159 \ - -pad -reportonly testimg.ppm + -pad -reportonly testimg.ppm pamcut -right 159 -bottom 159 -width 40 -height 40 \ - -pad -reportonly testimg.ppm + -pad -reportonly testimg.ppm pamcut -left 120 -top 120 -width 40 -height 40 \ - -pad -reportonly testimg.ppm + -pad -reportonly testimg.ppm echo "Test 2b. Should print 3876978825 4813 twice" pamcut -left 120 -right 159 -top 120 -bottom 159 \ - -pad testimg.ppm | cksum + -pad testimg.ppm | cksum pamcut -left 120 -top 120 -width 40 \ - -pad testimg.ppm | pnmpad -black -bottom 11 | cksum + -pad testimg.ppm | pnmpad -black -bottom 11 | cksum echo "Test 3a. Should print 5 5 5 5 227 149 1 1 three times" @@ -43,9 +45,9 @@ pamcut -top 5 -left 5 -bottom 5 -right 5 testimg.ppm | cksum echo "Test 4a. Should print 10 216 10 138 227 149 207 129 five times" pamcut -croptop 10 -cropleft 10 -cropbottom 10 -cropright 10 \ - -reportonly testimg.ppm + -reportonly testimg.ppm pamcut -cropbottom 10 -cropright 10 -width 207 -height 129 \ - -reportonly testimg.ppm + -reportonly testimg.ppm pamcut -top 10 -left 10 -bottom 138 -right 216 -reportonly testimg.ppm pamcut -top 10 -left 10 -bottom -11 -right -11 -reportonly testimg.ppm pamcut -top 10 -left 10 -width 207 -height 129 -reportonly testimg.ppm @@ -61,36 +63,138 @@ width=$(echo ${mazesize} | cut -d " " -f 1) height=$(echo ${mazesize} | cut -d " " -f 2) pamcut -croptop 0 -cropleft 0 -cropbottom 0 -cropright 0 \ - -reportonly maze.pbm + -reportonly maze.pbm pamcut -top 0 -left 0 \ - -bottom $((${height} -1)) -right $((${width} -1)) \ - -reportonly maze.pbm + -bottom $((${height} -1)) -right $((${width} -1)) \ + -reportonly maze.pbm pamcut -top 0 -left 0 -bottom -1 -right -1 -reportonly maze.pbm pamcut -top 0 -left 0 -width ${width} -height ${height} \ - -reportonly maze.pbm + -reportonly maze.pbm pamcut -reportonly maze.pbm echo "Test 5b. Should print 281226646 481 twice" pamcut -croptop 0 -cropleft 0 -cropbottom 0 -cropright 0 maze.pbm | \ - cksum + cksum pamcut maze.pbm | cksum +test50_pbm=${tmpdir}/test50.pbm echo "Test 6a. Should print 5 34 5 34 50 50 30 30" -pbmmake -g 50 50 | pamcut -reportonly 5 5 30 30 +pbmmake -g 50 50 | tee ${test50_pbm} | pamcut -reportonly 5 5 30 30 echo "Test 6b. Should print 3412257956 129" -pbmmake -g 50 50 | pamcut 5 5 30 30 | cksum +pamcut 5 5 30 30 ${test50_pbm} | cksum + +rm ${test50_pbm} + +echo "Test 7. Should print 284857390 12 sixteen times" + +test1_pbm=${tmpdir}/test1.pbm + +pbmmake -b 1 1 > ${test1_pbm} + +# pbmmake -b 5 5 | cksum + +pamcut -pad -cropleft=6 -croptop=6 -width=5 -height=5 ${test1_pbm} | cksum +pamcut -pad -cropright=6 -croptop=6 -width=5 -height=5 ${test1_pbm} | cksum +pamcut -pad -cropleft=6 -cropbottom=6 -width=5 -height=5 ${test1_pbm} | cksum +pamcut -pad -cropright=6 -cropbottom=6 -width=5 -height=5 ${test1_pbm} | cksum + +pamcut -pad -cropleft=6 -width=5 -height=5 ${test1_pbm} | cksum +pamcut -pad -croptop=6 -width=5 -height=5 ${test1_pbm} | cksum +pamcut -pad -cropbottom=6 -width=5 -height=5 ${test1_pbm} | cksum +pamcut -pad -cropright=6 -width=5 -height=5 ${test1_pbm} | cksum + +pamcut -pad -cropleft=7 -croptop=7 -width=5 -height=5 ${test1_pbm} | cksum +pamcut -pad -cropright=7 -croptop=7 -width=5 -height=5 ${test1_pbm} | cksum +pamcut -pad -cropleft=7 -cropbottom=7 -width=5 -height=5 ${test1_pbm} | cksum +pamcut -pad -cropright=7 -cropbottom=7 -width=5 -height=5 ${test1_pbm} | cksum + +pamcut -pad -cropleft=17 -width=5 -height=5 ${test1_pbm} | cksum +pamcut -pad -croptop=17 -width=5 -height=5 ${test1_pbm} | cksum +pamcut -pad -cropbottom=17 -width=5 -height=5 ${test1_pbm} | cksum +pamcut -pad -cropright=17 -width=5 -height=5 ${test1_pbm} | cksum + + +echo "Test 8. Should print 3125257619 29 four times" + +test3_pbm=${tmpdir}/test3.pbm + +pbmmake -g 3 3 > ${test3_pbm} + +pamcut -pad -cropleft=10 -croptop=10 -width=10 -height=10 ${test3_pbm} | cksum +pamcut -pad -cropright=10 -croptop=10 -width=10 -height=10 ${test3_pbm} |\ + pamflip -lr | cksum +pamcut -pad -cropleft=10 -cropbottom=10 -width=10 -height=10 ${test3_pbm} |\ + pamflip -tb | cksum +pamcut -pad -cropright=10 -cropbottom=10 -width=10 -height=10 ${test3_pbm} |\ + pamflip -r180 | cksum + +rm ${test3_pbm} + +echo "Test 9. Should print 3338453023 36 sixteen times" + +testb_pgm=${tmpdir}/testb.pgm + +pgmmake 0.0 1 1 > ${testb_pgm} + +# pgmmake 0.0 5 5 | cksum + +pamcut -pad -cropleft=6 -croptop=6 -width=5 -height=5 ${testb_pgm} | cksum +pamcut -pad -cropright=6 -croptop=6 -width=5 -height=5 ${testb_pgm} | cksum +pamcut -pad -cropleft=6 -cropbottom=6 -width=5 -height=5 ${testb_pgm} | cksum +pamcut -pad -cropright=6 -cropbottom=6 -width=5 -height=5 ${testb_pgm} | cksum + +pamcut -pad -cropleft=6 -width=5 -height=5 ${testb_pgm} | cksum +pamcut -pad -croptop=6 -width=5 -height=5 ${testb_pgm} | cksum +pamcut -pad -cropbottom=6 -width=5 -height=5 ${testb_pgm} | cksum +pamcut -pad -cropright=6 -width=5 -height=5 ${testb_pgm} | cksum + +pamcut -pad -cropleft=7 -croptop=7 -width=5 -height=5 ${testb_pgm} | cksum +pamcut -pad -cropright=7 -croptop=7 -width=5 -height=5 ${testb_pgm} | cksum +pamcut -pad -cropleft=7 -cropbottom=7 -width=5 -height=5 ${testb_pgm} | cksum +pamcut -pad -cropright=7 -cropbottom=7 -width=5 -height=5 ${testb_pgm} | cksum + +pamcut -pad -cropleft=17 -width=5 -height=5 ${testb_pgm} | cksum +pamcut -pad -croptop=17 -width=5 -height=5 ${testb_pgm} | cksum +pamcut -pad -cropbottom=17 -width=5 -height=5 ${testb_pgm} | cksum +pamcut -pad -cropright=17 -width=5 -height=5 ${testb_pgm} | cksum + +rm ${testb_pgm} + +echo "Test 10. Should print 3957742883 302 four times" + +testg_pgm=${tmpdir}/testg.pgm + +pgmmake 0.5 2 2 > ${testg_pgm} + +# pgmmake 0.0 17 17 | cksum + +pamcut -pad -cropleft=17 -croptop=17 -width=17 -height=17 ${testg_pgm} | cksum +pamcut -pad -cropright=17 -croptop=17 -width=17 -height=17 ${testg_pgm} | \ + pamflip -lr | cksum +pamcut -pad -cropleft=17 -cropbottom=17 -width=17 -height=17 ${testg_pgm} | \ + pamflip -tb | cksum +pamcut -pad -cropright=17 -cropbottom=17 -width=17 -height=17 ${testg_pgm} |\ + pamflip -r180 | cksum + +rm ${testg_pgm} + +echo "Test 11. Should print 1576602925 8 four times" + +test5_pbm=${tmpdir}/test5.pbm + +pbmmake -g 5 5 > ${test5_pbm} -echo "Test 7. Should print 1576602925 8 four times" +cat ${test1_pbm} | cksum +pamcut -pad -left=6 -right=6 -top=6 -bottom 6 ${test5_pbm} | cksum +pamcut -pad -left=-6 -right=-6 -top=-6 -bottom -6 ${test5_pbm} | cksum +pamcut -pad -left=101 -right=101 -top=1001 -bottom 1001 ${test5_pbm} | cksum -pbmmake -b 1 1 | cksum -pbmmake -g 5 5 | pamcut -pad -left=6 -right=6 -top=6 -bottom 6 | cksum -pbmmake -g 5 5 | pamcut -pad -left=-6 -right=-6 -top=-6 -bottom -6 | cksum -pbmmake -g 5 5 | pamcut -pad -left=101 -right=101 -top=1001 -bottom 1001 | cksum +rm ${test1_pbm} ${test5_pbm} echo "Test Invalid" diff --git a/test/test1.info b/test/test1.info new file mode 100644 index 00000000..5510d8e8 --- /dev/null +++ b/test/test1.info Binary files differdiff --git a/test/test2.info b/test/test2.info new file mode 100644 index 00000000..7ddb5a6b --- /dev/null +++ b/test/test2.info Binary files differdiff --git a/version.mk b/version.mk index b8bcfbb6..0b74eb8c 100644 --- a/version.mk +++ b/version.mk @@ -1,3 +1,3 @@ NETPBM_MAJOR_RELEASE = 11 -NETPBM_MINOR_RELEASE = 5 +NETPBM_MINOR_RELEASE = 6 NETPBM_POINT_RELEASE = 99 |