diff options
Diffstat (limited to 'converter/other/pnmtopalm')
-rw-r--r-- | converter/other/pnmtopalm/palm.h | 30 | ||||
-rw-r--r-- | converter/other/pnmtopalm/palmcolormap.c | 134 | ||||
-rw-r--r-- | converter/other/pnmtopalm/palmcolormap.h | 25 | ||||
-rw-r--r-- | converter/other/pnmtopalm/palmtopnm.c | 398 | ||||
-rw-r--r-- | converter/other/pnmtopalm/pnmtopalm.c | 567 |
5 files changed, 689 insertions, 465 deletions
diff --git a/converter/other/pnmtopalm/palm.h b/converter/other/pnmtopalm/palm.h index 718a66cf..0edf9a28 100644 --- a/converter/other/pnmtopalm/palm.h +++ b/converter/other/pnmtopalm/palm.h @@ -28,9 +28,18 @@ #define PALM_FORMAT_565LE 0x02 /* Palm says internal use only */ #define PALM_FORMAT_INDEXEDLE 0x03 /* Palm says internal use only */ -typedef unsigned long Color_s; +typedef unsigned long ColormapEntry; + /* A entry in a Colormap. It is an encoding of 4 bytes as the integer + that those 4 bytes would represent in pure binary: -typedef Color_s * Color; + MSB 0: the color index + 1: red intensity + 2: green intensity + LSB 3: blue intensity + + The intensities are on a scale with a certain maxval (that must be + specified to interpret a ColormapEntry). + */ typedef struct { unsigned int nentries; @@ -39,24 +48,11 @@ typedef struct { /* number of colors actually in 'color_entries' -- entries are filled from 0 consecutively, one color per entry. */ - Color_s * color_entries; /* Array of colors */ -} Colormap_s; - -typedef Colormap_s * Colormap; + ColormapEntry * color_entries; /* Array of colors */ +} Colormap; qsort_comparison_fn palmcolor_compare_indices; qsort_comparison_fn palmcolor_compare_colors; -Colormap -palmcolor_build_custom_8bit_colormap(unsigned int const rows, - unsigned int const cols, - pixel ** const pixels); - -Colormap -palmcolor_build_default_8bit_colormap(void); - -Colormap -palmcolor_read_colormap (FILE * const ifP); - #endif diff --git a/converter/other/pnmtopalm/palmcolormap.c b/converter/other/pnmtopalm/palmcolormap.c index 0f47558c..1341ca2b 100644 --- a/converter/other/pnmtopalm/palmcolormap.c +++ b/converter/other/pnmtopalm/palmcolormap.c @@ -4,18 +4,46 @@ #include "pm_c_util.h" #include "mallocvar.h" #include "pnm.h" - #include "palm.h" +#include "palmcolormap.h" + + + +static pixval +scaleSample(pixval const arg, + pixval const oldMaxval, + pixval const newMaxval) { + + return (arg * newMaxval + oldMaxval/2) / oldMaxval; +} + + + +ColormapEntry +palmcolor_mapEntryColorFmPixel(pixel const color, + pixval const maxval, + pixval const newMaxval) { + + + return + 0 + | (scaleSample(PPM_GETR(color), maxval, newMaxval) << 16) + | (scaleSample(PPM_GETG(color), maxval, newMaxval) << 8) + | (scaleSample(PPM_GETB(color), maxval, newMaxval) << 0); +} + + + int palmcolor_compare_indices(const void * const p1, const void * const p2) { /*---------------------------------------------------------------------------- This is a 'qsort' collation function. -----------------------------------------------------------------------------*/ - if ((*((Color) p1) & 0xFF000000) < (*((Color) p2) & 0xFF000000)) + if ((*((ColormapEntry *) p1) & 0xFF000000) < (*((ColormapEntry *) p2) & 0xFF000000)) return -1; - else if ((*((Color) p1) & 0xFF000000) > (*((Color) p2) & 0xFF000000)) + else if ((*((ColormapEntry *) p1) & 0xFF000000) > (*((ColormapEntry *) p2) & 0xFF000000)) return 1; else return 0; @@ -165,86 +193,88 @@ static int PalmPalette8bpp[256][3] = -Colormap +Colormap * palmcolor_build_default_8bit_colormap(void) { unsigned int i; - Colormap cm; + Colormap * cmP; - MALLOCVAR_NOFAIL(cm); - cm->nentries = 232; - MALLOCARRAY_NOFAIL(cm->color_entries, cm->nentries); + MALLOCVAR_NOFAIL(cmP); + cmP->nentries = 232; + MALLOCARRAY_NOFAIL(cmP->color_entries, cmP->nentries); /* Fill in the colors */ for (i = 0; i < 231; ++i) { - cm->color_entries[i] = ((i << 24) | + cmP->color_entries[i] = ((i << 24) | (PalmPalette8bpp[i][0] << 16) | (PalmPalette8bpp[i][1] << 8) | (PalmPalette8bpp[i][2])); } - cm->color_entries[231] = 0xFF000000; - cm->ncolors = 232; + cmP->color_entries[231] = 0xFF000000; + cmP->ncolors = 232; /* now sort the table */ - qsort (cm->color_entries, cm->ncolors, sizeof(Color_s), - palmcolor_compare_colors); - return cm; + qsort(cmP->color_entries, cmP->ncolors, sizeof(ColormapEntry), + palmcolor_compare_colors); + return cmP; } -Colormap -palmcolor_build_custom_8bit_colormap(unsigned int const rows, +Colormap * +palmcolor_build_custom_8bit_colormap(pixel ** const pixels, + unsigned int const rows, unsigned int const cols, - pixel ** const pixels) { + pixval const maxval) { + unsigned int row; - Colormap colormap; + Colormap * colormapP; - MALLOCVAR_NOFAIL(colormap); - colormap->nentries = 256; - MALLOCARRAY_NOFAIL(colormap->color_entries, colormap->nentries); - colormap->ncolors = 0; /* initial value */ + MALLOCVAR_NOFAIL(colormapP); + colormapP->nentries = 256; + MALLOCARRAY_NOFAIL(colormapP->color_entries, colormapP->nentries); + colormapP->ncolors = 0; /* initial value */ for (row = 0; row < rows; ++row) { unsigned int col; for (col = 0; col < cols; ++col) { - Color found; - Color_s temp; - - temp = ((PPM_GETR(pixels[row][col]) << 16) | - (PPM_GETG(pixels[row][col]) << 8) | - PPM_GETB(pixels[row][col])); - found = (bsearch (&temp, - colormap->color_entries, colormap->ncolors, - sizeof(Color_s), palmcolor_compare_colors)); - if (!found) { - if (colormap->ncolors >= colormap->nentries) + ColormapEntry * foundEntryP; + ColormapEntry const searchTarget = + palmcolor_mapEntryColorFmPixel(pixels[row][col], maxval, 255); + + foundEntryP = + bsearch(&searchTarget, + colormapP->color_entries, colormapP->ncolors, + sizeof(ColormapEntry), palmcolor_compare_colors); + if (!foundEntryP) { + if (colormapP->ncolors >= colormapP->nentries) pm_error("Too many colors for custom colormap " - "(max 256). " + "(max %u). " "Try using pnmquant to reduce the number " - "of colors."); + "of colors.", colormapP->nentries); else { /* add the new color, and re-sort */ - temp |= ((colormap->ncolors) << 24); - colormap->color_entries[colormap->ncolors] = temp; - colormap->ncolors += 1; - qsort(colormap->color_entries, colormap->ncolors, - sizeof(Color_s), palmcolor_compare_colors); + unsigned int const colorIndex = colormapP->ncolors++; + ColormapEntry const newEntry = + searchTarget | (colorIndex << 24); + colormapP->color_entries[colorIndex] = newEntry; + qsort(colormapP->color_entries, colormapP->ncolors, + sizeof(ColormapEntry), palmcolor_compare_colors); } } } } - return colormap; + return colormapP; } -Colormap +Colormap * palmcolor_read_colormap (FILE * const ifP) { unsigned short ncolors; - Colormap retval; + Colormap * retval; int rc; rc = pm_readbigshort(ifP, (short *) &ncolors); @@ -252,13 +282,13 @@ palmcolor_read_colormap (FILE * const ifP) { retval = NULL; else { long colorentry; - Colormap colormap; + Colormap * colormapP; unsigned int i; bool error; - MALLOCVAR_NOFAIL(colormap); - colormap->nentries = ncolors; - MALLOCARRAY_NOFAIL(colormap->color_entries, colormap->nentries); + MALLOCVAR_NOFAIL(colormapP); + colormapP->nentries = ncolors; + MALLOCARRAY_NOFAIL(colormapP->color_entries, colormapP->nentries); for (i = 0, error = FALSE; i < ncolors && !error; ++i) { int rc; @@ -266,15 +296,15 @@ palmcolor_read_colormap (FILE * const ifP) { if (rc != 0) error = TRUE; else - colormap->color_entries[i] = (colorentry & 0xFFFFFFFF); + colormapP->color_entries[i] = (colorentry & 0xFFFFFFFF); } if (error) { - free (colormap->color_entries); - free (colormap); + free (colormapP->color_entries); + free (colormapP); retval = NULL; } else { - colormap->ncolors = ncolors; - retval = colormap; + colormapP->ncolors = ncolors; + retval = colormapP; } } return retval; diff --git a/converter/other/pnmtopalm/palmcolormap.h b/converter/other/pnmtopalm/palmcolormap.h new file mode 100644 index 00000000..cbdb2031 --- /dev/null +++ b/converter/other/pnmtopalm/palmcolormap.h @@ -0,0 +1,25 @@ +#ifndef PALMCOLORMAP_H_INCLUDED +#define PALMCOLORMAP_H_INCLUDED + +#include <stdio.h> +#include "ppm.h" +#include "palm.h" + +ColormapEntry +palmcolor_mapEntryColorFmPixel(pixel const color, + pixval const maxval, + pixval const newMaxval); + +Colormap * +palmcolor_build_custom_8bit_colormap(pixel ** const pixels, + unsigned int const rows, + unsigned int const cols, + pixval const maxval); + +Colormap * +palmcolor_build_default_8bit_colormap(void); + +Colormap * +palmcolor_read_colormap (FILE * const ifP); + +#endif diff --git a/converter/other/pnmtopalm/palmtopnm.c b/converter/other/pnmtopalm/palmtopnm.c index d701a7e5..0666141d 100644 --- a/converter/other/pnmtopalm/palmtopnm.c +++ b/converter/other/pnmtopalm/palmtopnm.c @@ -21,17 +21,18 @@ #include "mallocvar.h" #include "palm.h" +#include "palmcolormap.h" -enum palmCompressionType { - COMPRESSION_NONE, - COMPRESSION_RLE, +enum PalmCompressionType { + COMPRESSION_NONE, + COMPRESSION_RLE, COMPRESSION_SCANLINE, COMPRESSION_PACKBITS }; -struct palmHeader { +struct PalmHeader { unsigned short cols; unsigned short rows; unsigned short bytesPerRow; @@ -46,7 +47,7 @@ struct palmHeader { unsigned int pixelSize; unsigned char version; unsigned int transparentIndex; - enum palmCompressionType compressionType; + enum PalmCompressionType compressionType; /* version 3 encoding specific */ unsigned char size; unsigned char pixelFormat; @@ -56,7 +57,7 @@ struct palmHeader { -struct directPixelFormat { +struct DirectPixelFormat { unsigned int redbits; unsigned int greenbits; unsigned int bluebits; @@ -64,15 +65,15 @@ struct directPixelFormat { -struct directColorInfo { - struct directPixelFormat pixelFormat; - Color_s transparentColor; +struct DirectColorInfo { + struct DirectPixelFormat pixelFormat; + ColormapEntry transparentColor; }; -struct cmdlineInfo { +struct CmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. */ @@ -85,13 +86,13 @@ struct cmdlineInfo { static void -parseCommandLine(int argc, char ** argv, - struct cmdlineInfo *cmdlineP) { +parseCommandLine(int argc, const char ** argv, + struct CmdlineInfo *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 ) ); + optEntry * option_def; /* Instructions to pm_optParseOptions3 on how to parse our options. */ optStruct3 opt; @@ -100,6 +101,8 @@ parseCommandLine(int argc, char ** argv, unsigned int option_def_index; + MALLOCARRAY_NOFAIL(option_def, 100); + option_def_index = 0; /* incremented by OPTENTRY */ OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); @@ -107,23 +110,23 @@ parseCommandLine(int argc, char ** argv, &cmdlineP->showhist, 0); OPTENT3(0, "transparent", OPT_FLAG, NULL, &cmdlineP->transparent, 0); - OPTENT3(0, "rendition", OPT_UINT, &cmdlineP->rendition, + OPTENT3(0, "rendition", OPT_UINT, &cmdlineP->rendition, &renditionSpec, 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 */ - pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (renditionSpec) { if (cmdlineP->rendition < 1) pm_error("The -rendition value must be at least 1"); - } else + } else cmdlineP->rendition = 1; - + if (cmdlineP->transparent && cmdlineP->showhist) pm_error("You can't specify -showhist with -transparent"); @@ -135,12 +138,13 @@ parseCommandLine(int argc, char ** argv, pm_error("Too many arguments (%d). The only non-option " "argument is the file name", argc-1); } + free(option_def); } static xelval * -createGraymap(unsigned int const ncolors, +createGraymap(unsigned int const ncolors, xelval const maxval) { int i; xelval *map; @@ -154,8 +158,8 @@ createGraymap(unsigned int const ncolors, -static void -skipbytes(FILE * const ifP, +static void +skipbytes(FILE * const ifP, unsigned int const nbytes) { unsigned char buf[256]; @@ -176,15 +180,15 @@ skipbytes(FILE * const ifP, pm_error("Error reading Palm file. Short read."); n = 0; } - } + } } static void interpretCompression(unsigned char const compressionValue, - enum palmCompressionType * const compressionTypeP) { - + enum PalmCompressionType * const compressionTypeP) { + switch (compressionValue) { case PALM_COMPRESSION_RLE: *compressionTypeP = COMPRESSION_RLE; @@ -220,17 +224,18 @@ readRestOfHeaderVersion3(FILE * const ifP, short * const nextDepthOffsetP) { unsigned char unused; - + pm_readcharu(ifP, sizeP); /* should be 0x18, but I can't see why we should really care */ if (*sizeP != 0x18) - pm_message("Strange value for Palm bitmap header size: %hu", *sizeP); + pm_message("Strange value for Palm bitmap header size: %u", + (unsigned)*sizeP); pm_readcharu(ifP, pixelFormatP); if (*pixelFormatP != PALM_FORMAT_INDEXED && *pixelFormatP != PALM_FORMAT_565) pm_error("Unrecognized pixelformat type: %u", *pixelFormatP); - + pm_readcharu(ifP, &unused); @@ -244,15 +249,15 @@ readRestOfHeaderVersion3(FILE * const ifP, *densityP != PALM_DENSITY_TRIPLE && *densityP != PALM_DENSITY_QUADRUPLE) pm_error("Invalid value for -density: %d.", *densityP); - + pm_readbiglong(ifP, transparentValueP); if (pixelSize < 16) *transparentIndexP = *transparentValueP; else *transparentIndexP = 0; - + pm_readbiglong(ifP, nextBitmapOffsetP); - + /* version < 3 specific */ *nextDepthOffsetP = 0; } @@ -269,18 +274,18 @@ readRestOfHeaderOld(FILE * const ifP, long * const transparentValueP, long * const nextBitmapOffsetP, short * const nextDepthOffsetP) { - + short pad; unsigned char transparentIndex; - + pm_readbigshort(ifP, nextDepthOffsetP); pm_readcharu(ifP, &transparentIndex); *transparentIndexP = transparentIndex; - + pm_readcharu(ifP,compressionTypeP); - + pm_readbigshort(ifP, &pad); /* reserved by Palm as of 8/9/00 */ - + /* version 3 specific */ *sizeP = 0; *pixelFormatP = 0; @@ -292,7 +297,7 @@ readRestOfHeaderOld(FILE * const ifP, static void -interpretHeader(struct palmHeader * const palmHeaderP, +interpretHeader(struct PalmHeader * const palmHeaderP, short const cols, short const rows, short const bytesPerRow, @@ -306,7 +311,7 @@ interpretHeader(struct palmHeader * const palmHeaderP, long const transparentValue, unsigned int const transparentIndex, unsigned char const compressionType) { - + palmHeaderP->cols = cols; palmHeaderP->rows = rows; palmHeaderP->bytesPerRow = bytesPerRow; @@ -329,11 +334,11 @@ interpretHeader(struct palmHeader * const palmHeaderP, */ pm_error("PALM_DIRECT_COLOR_FLAG is set but pixelFormat is not" "PALM_FORMAT_565."); - - palmHeaderP->directColor = ((flags & PALM_DIRECT_COLOR_FLAG) || + + palmHeaderP->directColor = ((flags & PALM_DIRECT_COLOR_FLAG) || palmHeaderP->pixelFormat == PALM_FORMAT_565); - - if (flags & PALM_IS_COMPRESSED_FLAG) + + if (flags & PALM_IS_COMPRESSED_FLAG) interpretCompression(compressionType, &palmHeaderP->compressionType); else @@ -345,7 +350,7 @@ interpretHeader(struct palmHeader * const palmHeaderP, static void readHeader(FILE * const ifP, unsigned int const requestedRendition, - struct palmHeader * const palmHeaderP) { + struct PalmHeader * const palmHeaderP) { /*---------------------------------------------------------------------------- Read the Palm Bitmap header from the file 'ifP'. Read past all renditions up to 'requestedRendition' and read the header of that @@ -358,7 +363,7 @@ readHeader(FILE * const ifP, currentRendition = 1; while (!gotHeader) { short cols, rows, bytesPerRow, flags, nextDepthOffset, density; - unsigned char pixelSizeCode, version, compressionType, + unsigned char pixelSizeCode, version, compressionType, size, pixelFormat; long transparentValue, nextBitmapOffset; unsigned int pixelSize, transparentIndex; @@ -367,7 +372,7 @@ readHeader(FILE * const ifP, pm_readbigshort(ifP, &rows); pm_readbigshort(ifP, &bytesPerRow); pm_readbigshort(ifP, &flags); - + pm_readcharu(ifP, &pixelSizeCode); pixelSize = pixelSizeCode == 0 ? 1 : pixelSizeCode; if (pixelSizeCode != 0x00 && @@ -384,12 +389,12 @@ readHeader(FILE * const ifP, "bits per pixel.", bytesPerRow, cols, pixelSize); pm_readcharu(ifP, &version); - if (version > 3) + if (version > 3) pm_error("Unknown encoding version type: %d", version); else if (version == 3) readRestOfHeaderVersion3(ifP, pixelSize, &size, &pixelFormat, &compressionType, - &density, &transparentIndex, + &density, &transparentIndex, &transparentValue, &nextBitmapOffset, &nextDepthOffset); else @@ -400,29 +405,29 @@ readHeader(FILE * const ifP, &nextDepthOffset); if (currentRendition < requestedRendition) { - if (version < 3 && nextDepthOffset == 0 && pixelSizeCode != 0xFF) + if (version < 3 && nextDepthOffset == 0 && pixelSizeCode != 0xFF) pm_error("Not enough renditions in the input Palm Bitmap " "to extract the %dth", requestedRendition); - if (version == 3 && nextBitmapOffset == 0) + if (version == 3 && nextBitmapOffset == 0) pm_error("Not enough renditions in the input Palm Bitmap " "to extract the %dth", requestedRendition); /* nextDepthOffset is calculated in 4 byte words - from the beginning of this bitmap (so it equals its size) + from the beginning of this bitmap (so it equals its size) */ if (version < 3 && pixelSizeCode != 0xFF ) skipbytes(ifP, (nextDepthOffset*4)-16); else if (version == 3) /* FIXME rewrite skipbytes to accept longs? */ - skipbytes(ifP, (short) nextBitmapOffset-24); + skipbytes(ifP, (short) nextBitmapOffset-24); if (pixelSizeCode != 0xFF) ++currentRendition; } else if (pixelSizeCode != 0xFF) { gotHeader = TRUE; - + interpretHeader(palmHeaderP, cols, rows, bytesPerRow, flags, pixelSizeCode, pixelSize, version, size, pixelFormat, density, - transparentValue, transparentIndex, + transparentValue, transparentIndex, compressionType); } } @@ -441,8 +446,8 @@ yesno(bool const arg) { static void -reportPalmHeader(struct palmHeader const palmHeader, - struct directColorInfo const directColorInfo) { +reportPalmHeader(struct PalmHeader const palmHeader, + struct DirectColorInfo const directColorInfo) { const char *ctype; @@ -462,9 +467,9 @@ reportPalmHeader(struct palmHeader const palmHeader, } pm_message("Dimensions: %hu columns x %hu rows", palmHeader.cols, palmHeader.rows); - pm_message("Row layout: %hu bytes per row, %hu bits per pixel", + pm_message("Row layout: %hu bytes per row, %u bits per pixel", palmHeader.bytesPerRow, palmHeader.pixelSize); - pm_message("Pixel Size code: %hu", palmHeader.pixelSizeCode); + pm_message("Pixel Size code: %u", (unsigned)palmHeader.pixelSizeCode); pm_message("Flags: 0x%04hx", palmHeader.flags); pm_message(" Direct Color: %s", yesno(palmHeader.directColor)); pm_message(" Colormap: %s", yesno(palmHeader.hasColormap)); @@ -473,10 +478,10 @@ reportPalmHeader(struct palmHeader const palmHeader, if (palmHeader.hasTransparency) { if (palmHeader.directColor) { /* Copied from doTransparent(...) */ - Color_s const color = directColorInfo.transparentColor; - pm_message("Transparent value: #%02x%02x%02x", - (unsigned int)((color >> 16) & 0xFF), - (unsigned int)((color >> 8) & 0xFF), + ColormapEntry const color = directColorInfo.transparentColor; + pm_message("Transparent value: #%02x%02x%02x", + (unsigned int)((color >> 16) & 0xFF), + (unsigned int)((color >> 8) & 0xFF), (unsigned int)((color >> 0) & 0xFF)); } else pm_message("Transparent index: %u", palmHeader.transparentIndex); @@ -489,7 +494,7 @@ reportPalmHeader(struct palmHeader const palmHeader, static void -determineOutputFormat(struct palmHeader const palmHeader, +determineOutputFormat(struct PalmHeader const palmHeader, int * const formatP, xelval * const maxvalP) { @@ -515,14 +520,14 @@ determineOutputFormat(struct palmHeader const palmHeader, static void readRgbFormat(FILE * const ifP, - struct directPixelFormat * const pixelFormatP) { + struct DirectPixelFormat * const pixelFormatP) { unsigned char r, g, b; pm_readcharu(ifP, &r); pm_readcharu(ifP, &g); pm_readcharu(ifP, &b); - + if (r != 5 || g != 6 || b != 5) pm_error("This image has a direct color pixel format of " "%u red, %u green, %u blue bits. This program " @@ -537,8 +542,8 @@ readRgbFormat(FILE * const ifP, static void -readDirectTransparentColor(FILE * const ifP, - Color_s * const colorP) { +readDirectTransparentColor(FILE * const ifP, + ColormapEntry * const colorP) { unsigned char r, g, b; @@ -553,8 +558,8 @@ readDirectTransparentColor(FILE * const ifP, static void readDirectInfoType(FILE * const ifP, - struct palmHeader const palmHeader, - struct directColorInfo * const directInfoTypeP) { + struct PalmHeader const palmHeader, + struct DirectColorInfo * const directInfoTypeP) { /*---------------------------------------------------------------------------- Read the Palm Bitmap Direct Info Type section, if any. @@ -568,12 +573,12 @@ readDirectInfoType(FILE * const ifP, if ((palmHeader.directColor) && palmHeader.pixelSize != 16) pm_error("The image is of the direct color type, but has %u " "bits per pixel. The only kind of direct color images " - "this program understands are 16 bit ones.", + "this program understands are 16 bit ones.", palmHeader.pixelSize); if (palmHeader.version == 3) { /* All direct color info is in the header, because it'sversion - 3 encoding. No Direct Info Type section. + 3 encoding. No Direct Info Type section. */ } else { if (palmHeader.directColor) { @@ -584,7 +589,7 @@ readDirectInfoType(FILE * const ifP, pm_readcharu(ifP, &padding); pm_readcharu(ifP, &padding); - readDirectTransparentColor(ifP, + readDirectTransparentColor(ifP, &directInfoTypeP->transparentColor); } else { /* Not a direct color image; no Direct Info Type section. */ @@ -596,8 +601,8 @@ readDirectInfoType(FILE * const ifP, static void readColormap(FILE * const ifP, - struct palmHeader const palmHeader, - Colormap * const colormapP) { + struct PalmHeader const palmHeader, + Colormap ** const colormapPP) { /*---------------------------------------------------------------------------- Read the colormap, if any from the Palm Bitmap. @@ -605,18 +610,18 @@ readColormap(FILE * const ifP, return an undefined value as *colormapP. -----------------------------------------------------------------------------*/ if (palmHeader.hasColormap) - *colormapP = palmcolor_read_colormap(ifP); + *colormapPP = palmcolor_read_colormap(ifP); } static void -getColorInfo(struct palmHeader const palmHeader, - struct directColorInfo const directInfoType, - Colormap const colormapFromImage, - Colormap * const colormapP, +getColorInfo(struct PalmHeader const palmHeader, + struct DirectColorInfo const directInfoType, + Colormap * const colormapFromImageP, + Colormap ** const colormapPP, unsigned int * const ncolorsP, - struct directColorInfo * const directColorInfoP) { + struct DirectColorInfo * const directColorInfoP) { /*---------------------------------------------------------------------------- Gather color encoding information from the various sources. @@ -626,14 +631,14 @@ getColorInfo(struct palmHeader const palmHeader, If it's a version 3 direct color, the pixel format must be "565". -----------------------------------------------------------------------------*/ if (palmHeader.version == 3 && palmHeader.directColor) { - *colormapP = NULL; + *colormapPP = NULL; assert(palmHeader.pixelFormat == PALM_FORMAT_565); directColorInfoP->pixelFormat.redbits = 5; directColorInfoP->pixelFormat.greenbits = 6; directColorInfoP->pixelFormat.bluebits = 5; - directColorInfoP->transparentColor = + directColorInfoP->transparentColor = /* See convertRowToPnmDirect for this trick This will break once maxval isn't always set 255 for @@ -646,18 +651,18 @@ getColorInfo(struct palmHeader const palmHeader, ((((palmHeader.transparentValue >> 0) & 0x1F) * 255 / 0x1F) << 0); } else if (palmHeader.directColor) { - *colormapP = NULL; + *colormapPP = NULL; *directColorInfoP = directInfoType; } else if (palmHeader.hasColormap) - *colormapP = colormapFromImage; + *colormapPP = colormapFromImageP; else if (palmHeader.pixelSize >= 8) { - Colormap colormap; - colormap = palmcolor_build_default_8bit_colormap(); - qsort(colormap->color_entries, colormap->ncolors, - sizeof(Color_s), palmcolor_compare_indices); - *colormapP = colormap; + Colormap * const colormapP = + palmcolor_build_default_8bit_colormap(); + qsort(colormapP->color_entries, colormapP->ncolors, + sizeof(ColormapEntry), palmcolor_compare_indices); + *colormapPP = colormapP; } else - *colormapP = NULL; + *colormapPP = NULL; *ncolorsP = 1 << palmHeader.pixelSize; } @@ -670,8 +675,8 @@ doTransparent(FILE * const ofP, bool const directColor, unsigned char const transparentIndex, unsigned char const pixelSize, - Colormap const colormap, - struct directColorInfo const directColorInfo) { + Colormap * const colormapP, + struct DirectColorInfo const directColorInfo) { /*---------------------------------------------------------------------------- Generate a PNM comment on *ofP telling what color in the raster is supposed to be transparent. @@ -681,31 +686,32 @@ doTransparent(FILE * const ofP, RGB_ALPHA and GRAYSCALE_ALPHA tuple types). -----------------------------------------------------------------------------*/ if (hasTransparency) { - if (colormap) { - Color_s const color = transparentIndex << 24; - Color const actualColor = (bsearch(&color, - colormap->color_entries, - colormap->ncolors, - sizeof(color), - palmcolor_compare_indices)); - if (!actualColor) + if (colormapP) { + ColormapEntry const searchTarget = transparentIndex << 24; + ColormapEntry * const foundEntryP = + bsearch(&searchTarget, + colormapP->color_entries, + colormapP->ncolors, + sizeof(searchTarget), + palmcolor_compare_indices); + if (!foundEntryP) pm_error("Invalid input; transparent index %u " "is not among the %u colors in the image's colormap", - transparentIndex, colormap->ncolors); + transparentIndex, colormapP->ncolors); - fprintf(ofP, "#%02x%02x%02x\n", - (unsigned int) ((*actualColor >> 16) & 0xFF), - (unsigned int) ((*actualColor >> 8) & 0xFF), - (unsigned int) ((*actualColor >> 0) & 0xFF)); + fprintf(ofP, "#%02x%02x%02x\n", + (unsigned int) ((*foundEntryP >> 16) & 0xFF), + (unsigned int) ((*foundEntryP >> 8) & 0xFF), + (unsigned int) ((*foundEntryP >> 0) & 0xFF)); } else if (directColor) { - Color_s const color = directColorInfo.transparentColor; - fprintf(ofP, "#%02x%02x%02x\n", - (unsigned int)((color >> 16) & 0xFF), - (unsigned int)((color >> 8) & 0xFF), + ColormapEntry const color = directColorInfo.transparentColor; + fprintf(ofP, "#%02x%02x%02x\n", + (unsigned int)((color >> 16) & 0xFF), + (unsigned int)((color >> 8) & 0xFF), (unsigned int)((color >> 0) & 0xFF)); } else { unsigned int const maxval = pm_bitstomaxval(pixelSize); - unsigned int const grayval = + unsigned int const grayval = ((maxval - transparentIndex) * 256) / maxval; fprintf(ofP, "#%02x%02x%02x\n", grayval, grayval, grayval); } @@ -723,10 +729,10 @@ createHistogram(unsigned int const ncolors, MALLOCARRAY(seen, ncolors); if (!seen) pm_error("Can't allocate array for keeping track of " - "how many pixels of each of %u colors are in the image.", + "how many pixels of each of %u colors are in the image.", ncolors); - { + { /* Initialize the counter for each color to zero */ unsigned int i; for (i = 0; i < ncolors; ++i) @@ -761,7 +767,7 @@ readScanlineRow(FILE * const ifP, pm_readcharu(ifP, &diffmask); byteCount = MIN(bytesPerRow - j, 8); - + for (k = 0; k < byteCount; ++k) { /* the first row cannot be compressed */ if (firstRow || ((diffmask & (1 << (7 - k))) != 0)) { @@ -800,7 +806,7 @@ readRleRow(FILE * const ifP, memset(palmrow + j, inval, incount); j += incount; } -} +} @@ -810,7 +816,7 @@ readPackBitsRow16(FILE * const ifP, unsigned int const bytesPerRow) { /* From the Palm OS Programmer's API Reference: - + Although the [...] spec is byte-oriented, the 16-bit algorithm is identical [to the 8-bit algorithm]: just substitute "word" for "byte". @@ -860,13 +866,13 @@ readPackBitsRow16(FILE * const ifP, } j += nonrunlength; } - if (j > bytesPerRow) + if (j > bytesPerRow) pm_error("Bytes in PackBits compressed row exceed bytes per row. " "Bytes per row is %u. " "The bytes in this row were pushed up to %u bytes " "(and then we gave up).", bytesPerRow, j); } -} +} @@ -908,13 +914,13 @@ readPackBitsRow(FILE * const ifP, } j += nonrunlength; } - if (j > bytesPerRow) + if (j > bytesPerRow) pm_error("Bytes in PackBits compressed row exceed bytes per row. " "Bytes per row is %u. " "The bytes in this row were pushed up to %u bytes " "(and then we gave up).", bytesPerRow, j); } -} +} @@ -924,7 +930,7 @@ readUncompressedRow(FILE * const ifP, unsigned int const bytesPerRow) { int bytesRead; - + bytesRead = fread(palmrow, 1, bytesPerRow, ifP); if (bytesRead != bytesPerRow) pm_error("Error reading Palm file. Short read."); @@ -936,7 +942,7 @@ static void readDecompressedRow(FILE * const ifP, unsigned char * const palmrow, unsigned char * const lastrow, - enum palmCompressionType const compressionType, + enum PalmCompressionType const compressionType, unsigned int const bytesPerRow, unsigned int const pixelSize, bool const firstRow) { @@ -997,27 +1003,27 @@ convertRowToPnmDirect(const unsigned char * const palmrow, blue=0x1F. How do we promote those colors? Simple shift would give us R=248,G=252,B=248; which is slightly green. Hardly seems right. - + So I've perverted the math a bit. Each color value is multiplied by 255, then divided by either 31 (red or blue) or 63 (green). That's the right way to do it - anyway. + anyway. */ const unsigned char *inbyte; unsigned int j; - + for (inbyte = palmrow, j = 0; j < cols; ++j) { unsigned int inval; inval = *inbyte++ << 8; inval |= *inbyte++; - + if (seen) ++seen[inval]; - - PPM_ASSIGN(xelrow[j], - (((inval >> 11) & 0x1F) * maxval) / 0x1F, - (((inval >> 5) & 0x3F) * maxval) / 0x3F, + + PPM_ASSIGN(xelrow[j], + (((inval >> 11) & 0x1F) * maxval) / 0x1F, + (((inval >> 5) & 0x3F) * maxval) / 0x3F, (((inval >> 0) & 0x1F) * maxval) / 0x1F ); } @@ -1029,46 +1035,50 @@ static void convertRowToPnmNotDirect(const unsigned char * const palmrow, xel * const xelrow, unsigned int const cols, - Colormap const colormap, + Colormap * const colormapP, xelval * const graymap, unsigned int * const seen, unsigned int const pixelSize) { unsigned int const mask = (1 << pixelSize) - 1; - const unsigned char *inbyte; + const unsigned char * inbyteP; unsigned int inbit; unsigned int j; - + + assert(pixelSize <= 8); + inbit = 8 - pixelSize; - inbyte = palmrow; + inbyteP = &palmrow[0]; for (j = 0; j < cols; ++j) { - short const color = ((*inbyte) & (mask << inbit)) >> inbit; + short const color = (*inbyteP & (mask << inbit)) >> inbit; if (seen) ++seen[color]; - - if (colormap) { - Color_s const color2 = color << 24; - Color const actualColor = (bsearch (&color2, - colormap->color_entries, - colormap->ncolors, - sizeof(color2), - palmcolor_compare_indices)); - if (!actualColor) + + if (colormapP) { + ColormapEntry const searchTarget = color << 24; + ColormapEntry * const foundEntryP = + bsearch(&searchTarget, + colormapP->color_entries, + colormapP->ncolors, + sizeof(searchTarget), + palmcolor_compare_indices); + + if (!foundEntryP) pm_error("Invalid input. A color index in column %u " "is %u, which is not among the %u colors " "in the colormap", - j, color, colormap->ncolors); + j, color, colormapP->ncolors); - PPM_ASSIGN(xelrow[j], - (*actualColor >> 16) & 0xFF, - (*actualColor >> 8) & 0xFF, - (*actualColor >> 0) & 0xFF); + PPM_ASSIGN(xelrow[j], + (*foundEntryP >> 16) & 0xFF, + (*foundEntryP >> 8) & 0xFF, + (*foundEntryP >> 0) & 0xFF); } else PNM_ASSIGN1(xelrow[j], graymap[color]); - + if (!inbit) { - ++inbyte; + ++inbyteP; inbit = 8 - pixelSize; } else inbit -= pixelSize; @@ -1079,9 +1089,9 @@ convertRowToPnmNotDirect(const unsigned char * const palmrow, static void writePnm(FILE * const ofP, - struct palmHeader const palmHeader, + struct PalmHeader const palmHeader, FILE * const ifP, - Colormap const colormap, + Colormap * const colormapP, xelval * const graymap, unsigned int const nColors, int const format, @@ -1096,22 +1106,22 @@ writePnm(FILE * const ofP, xel * xelrow; unsigned int * seen; unsigned int row; - + pnm_writepnminit(ofP, cols, rows, maxval, format, 0); xelrow = pnm_allocrow(cols); /* Read the picture data, one row at a time */ MALLOCARRAY_NOFAIL(palmrow, palmHeader.bytesPerRow); - MALLOCARRAY_NOFAIL(lastrow, palmHeader.bytesPerRow); - + MALLOCARRAY_NOFAIL(lastrow, palmHeader.bytesPerRow); + if (seenP) { createHistogram(nColors, &seen); *seenP = seen; } else seen = NULL; - /* We should actually use compressedDataSizeNN for checking the sanity - of the data we're reading ... + /* We should actually use compressedDataSizeNN for checking the sanity + of the data we're reading ... */ if (palmHeader.compressionType != COMPRESSION_NONE) { if (palmHeader.version < 3) { @@ -1124,8 +1134,8 @@ writePnm(FILE * const ofP, } for (row = 0; row < rows; ++row) { - readDecompressedRow(ifP, palmrow, lastrow, - palmHeader.compressionType, + readDecompressedRow(ifP, palmrow, lastrow, + palmHeader.compressionType, palmHeader.bytesPerRow, palmHeader.pixelSize, row == 0); @@ -1134,7 +1144,7 @@ writePnm(FILE * const ofP, assert(palmHeader.pixelSize == 16); convertRowToPnmDirect(palmrow, xelrow, cols, maxval, seen); } else - convertRowToPnmNotDirect(palmrow, xelrow, cols, colormap, graymap, + convertRowToPnmNotDirect(palmrow, xelrow, cols, colormapP, graymap, seen, palmHeader.pixelSize); pnm_writepnmrow(ofP, xelrow, cols, maxval, format, 0); @@ -1148,28 +1158,29 @@ writePnm(FILE * const ofP, static void showHistogram(unsigned int * const seen, - Colormap const colormap, + Colormap * const colormapP, const xelval * const graymap, unsigned int const ncolors) { unsigned int colorIndex; - + for (colorIndex = 0; colorIndex < ncolors; ++colorIndex) { - if (!colormap) - pm_message("%.3d -> %.3d: %d", + if (!colormapP) + pm_message("%.3d -> %.3d: %d", colorIndex, graymap[colorIndex], seen[colorIndex]); else { - Color_s const color = colorIndex << 24; - Color const actualColor = (bsearch(&color, - colormap->color_entries, - colormap->ncolors, - sizeof(color), - palmcolor_compare_indices)); - if (actualColor) + ColormapEntry const searchTarget = colorIndex << 24; + ColormapEntry * const foundEntryP = + bsearch(&searchTarget, + colormapP->color_entries, + colormapP->ncolors, + sizeof(searchTarget), + palmcolor_compare_indices); + if (foundEntryP) pm_message("%.3d -> %ld,%ld,%ld: %d", colorIndex, - (*actualColor >> 16) & 0xFF, - (*actualColor >> 8) & 0xFF, - (*actualColor & 0xFF), seen[colorIndex]); + (*foundEntryP >> 16) & 0xFF, + (*foundEntryP >> 8) & 0xFF, + (*foundEntryP & 0xFF), seen[colorIndex]); } } } @@ -1177,22 +1188,21 @@ showHistogram(unsigned int * const seen, int -main(int argc, char **argv) { +main(int argc, const char **argv) { - struct cmdlineInfo cmdline; + struct CmdlineInfo cmdline; - FILE* ifP; - struct palmHeader palmHeader; - struct directColorInfo directInfoType; - Colormap colormapFromImage; - Colormap colormap; - struct directColorInfo directColorInfo; + FILE * ifP; + struct PalmHeader palmHeader; + struct DirectColorInfo directInfoType; + Colormap * colormapFromImageP; + Colormap * colormapP; + struct DirectColorInfo directColorInfo; int format; xelval maxval; unsigned int nColors; - /* Parse default params */ - pnm_init(&argc, argv); + pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); @@ -1201,22 +1211,22 @@ main(int argc, char **argv) { readHeader(ifP, cmdline.rendition, &palmHeader); readDirectInfoType(ifP, palmHeader, &directInfoType); - - readColormap(ifP, palmHeader, &colormapFromImage); - + + readColormap(ifP, palmHeader, &colormapFromImageP); + determineOutputFormat(palmHeader, &format, &maxval); - - getColorInfo(palmHeader, directInfoType, colormapFromImage, - &colormap, &nColors, &directColorInfo); + + getColorInfo(palmHeader, directInfoType, colormapFromImageP, + &colormapP, &nColors, &directColorInfo); if (cmdline.verbose) reportPalmHeader(palmHeader, directColorInfo); if (cmdline.transparent) - doTransparent(stdout, + doTransparent(stdout, palmHeader.hasTransparency, palmHeader.directColor, - palmHeader.transparentIndex, - palmHeader.pixelSize, colormap, directColorInfo); + palmHeader.transparentIndex, + palmHeader.pixelSize, colormapP, directColorInfo); else { unsigned int * seen; xelval * graymap; @@ -1224,12 +1234,12 @@ main(int argc, char **argv) { graymap = createGraymap(nColors, maxval); writePnm(stdout, - palmHeader, ifP, colormap, graymap, nColors, format, maxval, + palmHeader, ifP, colormapP, graymap, nColors, format, maxval, cmdline.showhist ? &seen : NULL); - + if (cmdline.showhist) - showHistogram(seen, colormap, graymap, nColors); - + showHistogram(seen, colormapP, graymap, nColors); + free(graymap); } pm_close(ifP); diff --git a/converter/other/pnmtopalm/pnmtopalm.c b/converter/other/pnmtopalm/pnmtopalm.c index a7d1fd46..25c8af2e 100644 --- a/converter/other/pnmtopalm/pnmtopalm.c +++ b/converter/other/pnmtopalm/pnmtopalm.c @@ -29,33 +29,37 @@ #include "pm_c_util.h" #include "pnm.h" -#include "palm.h" #include "shhopt.h" #include "mallocvar.h" #include "runlength.h" -enum compressionType {COMP_NONE, COMP_SCANLINE, COMP_RLE, COMP_PACKBITS}; +#include "palm.h" +#include "palmcolormap.h" + +enum CompressionType {COMP_NONE, COMP_SCANLINE, COMP_RLE, COMP_PACKBITS}; -struct cmdline_info { +struct CmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. */ const char * inputFilespec; /* Filespecs of input files */ - const char * transparent; /* -transparent value. Null if unspec */ - unsigned int depth; /* -depth value. 0 if unspec */ - unsigned int maxdepth; /* -maxdepth value. 0 if unspec */ - enum compressionType compression; + const char * transparent; + unsigned int depthSpec; + unsigned int depth; + unsigned int maxdepthSpec; + unsigned int maxdepth; + enum CompressionType compression; unsigned int verbose; unsigned int colormap; - unsigned int offset; /* -offset specified */ - unsigned int density; /* screen density */ + unsigned int offset; + unsigned int density; unsigned int withdummy; }; static void -parseCommandLine(int argc, char ** argv, struct cmdline_info *cmdlineP) { +parseCommandLine(int argc, const char ** argv, struct CmdlineInfo *cmdlineP) { /*---------------------------------------------------------------------------- Note that the file spec array we return is stored in the storage that was passed to us as the argv array. @@ -64,7 +68,7 @@ parseCommandLine(int argc, char ** argv, struct cmdline_info *cmdlineP) { optEntry *option_def; unsigned int option_def_index; - unsigned int transSpec, depthSpec, maxdepthSpec, densitySpec; + unsigned int transSpec, densitySpec; unsigned int scanline_compression, rle_compression, packbits_compression; MALLOCARRAY_NOFAIL(option_def, 100); @@ -73,9 +77,9 @@ parseCommandLine(int argc, char ** argv, struct cmdline_info *cmdlineP) { OPTENT3(0, "transparent", OPT_STRING, &cmdlineP->transparent, &transSpec, 0); OPTENT3(0, "depth", OPT_UINT, - &cmdlineP->depth, &depthSpec, 0); + &cmdlineP->depth, &cmdlineP->depthSpec, 0); OPTENT3(0, "maxdepth", OPT_UINT, - &cmdlineP->maxdepth, &maxdepthSpec, 0); + &cmdlineP->maxdepth, &cmdlineP->maxdepthSpec, 0); OPTENT3(0, "scanline_compression", OPT_FLAG, NULL, &scanline_compression, 0); OPTENT3(0, "rle_compression", OPT_FLAG, @@ -97,28 +101,26 @@ parseCommandLine(int argc, char ** argv, struct cmdline_info *cmdlineP) { opt.short_allowed = FALSE; /* We have some short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ - pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdline_p and others. */ - if (depthSpec) { + if (cmdlineP->depthSpec) { if (cmdlineP->depth != 1 && cmdlineP->depth != 2 && cmdlineP->depth != 4 && cmdlineP->depth != 8 && cmdlineP->depth != 16) pm_error("invalid value for -depth: %u. Valid values are " "1, 2, 4, 8, and 16", cmdlineP->depth); - } else - cmdlineP->depth = 0; + } - if (maxdepthSpec) { + if (cmdlineP->maxdepthSpec) { if (cmdlineP->maxdepth != 1 && cmdlineP->maxdepth != 2 && cmdlineP->maxdepth != 4 && cmdlineP->maxdepth != 8 && cmdlineP->maxdepth != 16) pm_error("invalid value for -maxdepth: %u. Valid values are " "1, 2, 4, 8, and 16", cmdlineP->maxdepth); - } else - cmdlineP->maxdepth = 0; + } - if (depthSpec && maxdepthSpec && + if (cmdlineP->depthSpec && cmdlineP->maxdepthSpec && cmdlineP->depth > cmdlineP->maxdepth) pm_error("-depth value (%u) is greater than -maxdepth (%u) value.", cmdlineP->depth, cmdlineP->maxdepth); @@ -132,8 +134,8 @@ parseCommandLine(int argc, char ** argv, struct cmdline_info *cmdlineP) { cmdlineP->density != PALM_DENSITY_DOUBLE && cmdlineP->density != PALM_DENSITY_TRIPLE && cmdlineP->density != PALM_DENSITY_QUADRUPLE) - pm_error("Invalid value for -density: %d. Valid values are " - "%d, %d, %d, %d and %d.", cmdlineP->density, + pm_error("Invalid value for -density: %u. Valid values are " + "%u, %u, %u, %u and %u.", cmdlineP->density, PALM_DENSITY_LOW, PALM_DENSITY_ONEANDAHALF, PALM_DENSITY_DOUBLE, PALM_DENSITY_TRIPLE, PALM_DENSITY_QUADRUPLE); @@ -164,7 +166,7 @@ parseCommandLine(int argc, char ** argv, struct cmdline_info *cmdlineP) { if (argc-1 > 1) pm_error("This program takes at most 1 argument: the file name. " - "You specified %d", argc-1); + "You specified %u", argc-1); else if (argc-1 > 0) cmdlineP->inputFilespec = argv[1]; else @@ -173,108 +175,241 @@ parseCommandLine(int argc, char ** argv, struct cmdline_info *cmdlineP) { +static xelval +scaleSample(pixval const arg, + pixval const oldMaxval, + pixval const newMaxval) { + + return (arg * newMaxval + oldMaxval/2) / oldMaxval; +} + + + +static void +determinePalmFormatPgm(xelval const maxval, + bool const bppSpecified, + unsigned int const bpp, + bool const maxBppSpecified, + unsigned int const maxBpp, + bool const wantCustomColormap, + enum CompressionType const compression, + bool const verbose, + unsigned int * const bppP) { + + /* We can usually handle this one, but may not have enough pixels. So + check. + */ + + if (wantCustomColormap) + pm_error("You specified -colormap with a black and white input" + "image. -colormap is valid only with color."); + if (bppSpecified) + *bppP = bpp; + else if (maxBppSpecified && (maxval >= (1 << maxBpp))) + *bppP = maxBpp; + else if (compression != COMP_NONE && maxval > 255) + *bppP = 8; + else if (maxval > 16) + *bppP = 4; + else { + /* scale to minimum number of bpp needed */ + unsigned int bpp; + for (bpp = 1; (1 << bpp) < maxval; bpp *= 2) + ; + *bppP = bpp; + } + if (verbose) + pm_message("output is grayscale %u bits-per-pixel", *bppP); +} + + + +static void +validateImageAgainstStandardColormap(const Colormap * const colormapP, + xel ** const xels, + unsigned int const cols, + unsigned int const rows, + xelval const maxval) { +/*---------------------------------------------------------------------------- + Abort program if the image xels[][] (which is 'cols' x 'rows') contains a + color not in the colormap *colormapP, giving an error message assuming the + user chose the standard Palm colormap. +-----------------------------------------------------------------------------*/ + unsigned int row; + + for (row = 0; row < rows; ++row) { + unsigned int col; + + for (col = 0; col < cols; ++col) { + ColormapEntry const searchTarget = + palmcolor_mapEntryColorFmPixel(xels[row][col], maxval, 255); + + ColormapEntry * const foundEntryP = + (bsearch(&searchTarget, + colormapP->color_entries, colormapP->ncolors, + sizeof(ColormapEntry), palmcolor_compare_colors)); + if (!foundEntryP) + pm_error( + "A color in the input image is not in the standard Palm " + "8-bit color palette. Either adjust the colors in the " + "input with 'pnmremap' and the 'palmcolor8.map' file " + "(see manual) or specify -colormap or -depth=16"); + } + } +} + + + +static void +determinePalmFormatPpm(unsigned int const cols, + unsigned int const rows, + xelval const maxval, + xel ** const xels, + bool const bppSpecified, + unsigned int const bpp, + bool const maxBppSpecified, + unsigned int const maxBpp, + bool const wantCustomColormap, + enum CompressionType const compression, + bool const verbose, + unsigned int * const bppP, + bool * const directColorP, + Colormap ** const colormapPP) { + + /* We don't attempt to identify PPM files that are actually + monochrome. So there are two options here: either 8-bit with a + colormap, either the standard one or a custom one, or 16-bit direct + color. In the colormap case, if 'wantCustomColormap' is true (not + recommended by Palm) we will put in our own colormap that has the + colors of the input image; otherwise we will select the default + Palm colormap and will fail if the input image has any colors that + are not in that map (user should use Pnmremap and the + palmcolor8.map file that comes with Netpbm to avoid this). We try + for colormapped first, since it works on more PalmOS devices. + */ + if ((bppSpecified && bpp == 16) || + (!bppSpecified && maxBppSpecified && maxBpp == 16)) { + /* we do the 16-bit direct color */ + *directColorP = TRUE; + *colormapPP = NULL; + *bppP = 16; + } else if (!wantCustomColormap) { + /* colormapped with the standard colormap */ + Colormap * colormapP; + + if ((bppSpecified && bpp != 8) || (maxBppSpecified && maxBpp < 8)) + pm_error("Must use depth of 8 for color Palm Bitmap without " + "custom color table."); + colormapP = palmcolor_build_default_8bit_colormap(); + validateImageAgainstStandardColormap(colormapP, + xels, cols, rows, maxval); + + *colormapPP = colormapP; + *bppP = 8; + *directColorP = FALSE; + if (verbose) + pm_message("Output is color with default colormap at 8 bpp"); + } else { + /* colormapped with a custom colormap */ + *colormapPP = + palmcolor_build_custom_8bit_colormap(xels, rows, cols, maxval); + for (*bppP = 1; (1 << *bppP) < (*colormapPP)->ncolors; *bppP *= 2); + if (bppSpecified) { + if (bpp >= *bppP) + *bppP = bpp; + else + pm_error("Too many colors for specified depth. " + "Specified depth is %u bits; would need %u to " + "represent the %u colors in the image. " + "Use pnmquant to reduce.", + maxBpp, *bppP, (*colormapPP)->ncolors); + } else if (maxBppSpecified && maxBpp < *bppP) { + pm_error("Too many colors for specified max depth. " + "Specified maximum is %u bits; would need %u to " + "represent the %u colors in the image. " + "Use pnmquant to reduce.", + maxBpp, *bppP, (*colormapPP)->ncolors); + } else if (compression != COMP_NONE && *bppP > 8) { + pm_error("Too many colors for a compressed image. " + "Maximum is 256; the image has %u", + (*colormapPP)->ncolors); + } + *directColorP = FALSE; + if (verbose) + pm_message("Output is color with custom colormap " + "with %u colors at %u bpp", + (*colormapPP)->ncolors, *bppP); + } +} + + + static void -determinePalmFormat(unsigned int const cols, - unsigned int const rows, - xelval const maxval, - int const format, - xel ** const xels, - unsigned int const specified_bpp, - unsigned int const max_bpp, - bool const custom_colormap, - bool const verbose, - unsigned int * const bppP, - bool * const directColorP, - Colormap * const colormapP) { +determinePalmFormat(unsigned int const cols, + unsigned int const rows, + xelval const maxval, + int const format, + xel ** const xels, + bool const bppSpecified, + unsigned int const bpp, + bool const maxBppSpecified, + unsigned int const maxBpp, + bool const wantCustomColormap, + enum CompressionType const compression, + bool const verbose, + unsigned int * const bppP, + bool * const directColorP, + Colormap ** const colormapPP) { +/*---------------------------------------------------------------------------- + Determine what kind of Palm output file to make. + Also compute the colormap, if there is to be one. This could be either one + we make up, that needs to go into the image, or a standard one. +-----------------------------------------------------------------------------*/ + if (compression != COMP_NONE) { + if (bppSpecified && bpp > 8) + pm_error("You requested %u bits per pixel and compression. " + "This program does not know how to generate a " + "compressed image with more than 8 bits per pixel", + bpp); + if (maxBppSpecified && maxBpp > 8) + pm_error("You requested %u max bits per pixel and compression. " + "This program does not know how to generate a " + "compressed image with more than 8 bits per pixel", + maxBpp); + } if (PNM_FORMAT_TYPE(format) == PBM_TYPE) { - if (custom_colormap) + if (wantCustomColormap) pm_error("You specified -colormap with a black and white input " "image. -colormap is valid only with color."); - if (specified_bpp) - *bppP = specified_bpp; + if (bppSpecified) + *bppP = bpp; else *bppP = 1; /* no point in wasting bits */ *directColorP = FALSE; - *colormapP = NULL; + *colormapPP = NULL; if (verbose) pm_message("output is black and white"); } else if (PNM_FORMAT_TYPE(format) == PGM_TYPE) { - /* we can usually handle this one, but may not have enough - pixels. So check... */ - if (custom_colormap) - pm_error("You specified -colormap with a black and white input" - "image. -colormap is valid only with color."); - if (specified_bpp) - *bppP = specified_bpp; - else if (max_bpp && (maxval >= (1 << max_bpp))) - *bppP = max_bpp; - else if (maxval > 16) - *bppP = 4; - else { - /* scale to minimum number of bpp needed */ - for (*bppP = 1; (1 << *bppP) < maxval; *bppP *= 2) - ; - } - if (*bppP > 4) - *bppP = 4; - if (verbose) - pm_message("output is grayscale %d bits-per-pixel", *bppP); + determinePalmFormatPgm(maxval, + bppSpecified, bpp, maxBppSpecified, maxBpp, + wantCustomColormap, compression, + verbose, + bppP); + *directColorP = FALSE; - *colormapP = NULL; + *colormapPP = NULL; } else if (PNM_FORMAT_TYPE(format) == PPM_TYPE) { - - /* We assume that we only get a PPM if the image cannot be - represented as PBM or PGM. There are two options here: either - 8-bit with a colormap, either the standard one or a custom one, - or 16-bit direct color. In the 8-bit case, if "custom_colormap" - is specified (not recommended by Palm) we will put in our own - colormap; otherwise we will assume that the colors have been - mapped to the default Palm colormap by appropriate use of - pnmquant. We try for 8-bit color first, since it works on - more PalmOS devices. - */ - if ((specified_bpp == 16) || - (specified_bpp == 0 && max_bpp == 16)) { - /* we do the 16-bit direct color */ - *directColorP = TRUE; - *colormapP = NULL; - *bppP = 16; - } else if (!custom_colormap) { - /* standard indexed 8-bit color */ - *colormapP = palmcolor_build_default_8bit_colormap(); - *bppP = 8; - if (((specified_bpp != 0) && (specified_bpp != 8)) || - ((max_bpp != 0) && (max_bpp < 8))) - pm_error("Must use depth of 8 for color Palm Bitmap without " - "custom color table."); - *directColorP = FALSE; - if (verbose) - pm_message("Output is color with default colormap at 8 bpp"); - } else { - /* indexed 8-bit color with a custom colormap */ - *colormapP = - palmcolor_build_custom_8bit_colormap(rows, cols, xels); - for (*bppP = 1; (1 << *bppP) < (*colormapP)->ncolors; *bppP *= 2); - if (specified_bpp != 0) { - if (specified_bpp >= *bppP) - *bppP = specified_bpp; - else - pm_error("Too many colors for specified depth. " - "Use pnmquant to reduce."); - } else if ((max_bpp != 0) && (max_bpp < *bppP)) { - pm_error("Too many colors for specified max depth. " - "Use pnmquant to reduce."); - } - *directColorP = FALSE; - if (verbose) - pm_message("Output is color with custom colormap " - "with %d colors at %d bpp", - (*colormapP)->ncolors, *bppP); - } + determinePalmFormatPpm(cols, rows, maxval, xels, bppSpecified, bpp, + maxBppSpecified, maxBpp, + wantCustomColormap, compression, verbose, + bppP, directColorP, colormapPP); } else { pm_error("unknown format 0x%x on input file", (unsigned) format); } + + if (compression != COMP_NONE) + assert(*bppP <= 8); } @@ -300,25 +435,23 @@ findTransparentColor(const char * const colorSpec, pixval const newMaxval, bool const directColor, pixval const maxval, - Colormap const colormap, + Colormap * const colormapP, xel * const transcolorP, unsigned int * const transindexP) { *transcolorP = ppm_parsecolor(colorSpec, maxval); if (!directColor) { - Color_s const temp_color = - ((((PPM_GETR(*transcolorP)*newMaxval) / maxval) << 16) - | (((PPM_GETG(*transcolorP)*newMaxval) / maxval) << 8) - | ((PPM_GETB(*transcolorP)*newMaxval) / maxval)); - Color const found = - (bsearch(&temp_color, - colormap->color_entries, colormap->ncolors, - sizeof(Color_s), palmcolor_compare_colors)); - if (!found) { + ColormapEntry const searchTarget = + palmcolor_mapEntryColorFmPixel(*transcolorP, maxval, newMaxval); + ColormapEntry * const foundEntryP = + (bsearch(&searchTarget, + colormapP->color_entries, colormapP->ncolors, + sizeof(ColormapEntry), palmcolor_compare_colors)); + if (!foundEntryP) { pm_error("Specified transparent color %s not found " "in colormap.", colorSpec); } else - *transindexP = (*found >> 24) & 0xFF; + *transindexP = (*foundEntryP >> 24) & 0xFF; } } @@ -326,9 +459,9 @@ findTransparentColor(const char * const colorSpec, static unsigned int bitmapVersion(unsigned int const bpp, - bool const colormap, + bool const colormapped, bool const transparent, - enum compressionType const compression, + enum CompressionType const compression, unsigned int const density) { /*---------------------------------------------------------------------------- Return the version number of the oldest version that can represent @@ -343,7 +476,7 @@ bitmapVersion(unsigned int const bpp, version = 3; else if (transparent || compression != COMP_NONE) version = 2; - else if (bpp > 1 || colormap) + else if (bpp > 1 || colormapped) version = 1; else version = 0; @@ -357,8 +490,8 @@ static void writeCommonHeader(unsigned int const cols, unsigned int const rows, unsigned int const rowbytes, - enum compressionType const compression, - bool const colormap, + enum CompressionType const compression, + bool const colormapped, bool const transparent, bool const directColor, unsigned int const bpp, @@ -382,7 +515,7 @@ writeCommonHeader(unsigned int const cols, flags = 0; /* initial value */ if (compression != COMP_NONE) flags |= PALM_IS_COMPRESSED_FLAG; - if (colormap) + if (colormapped) flags |= PALM_HAS_COLORMAP_FLAG; if (transparent) flags |= PALM_HAS_TRANSPARENCY_FLAG; @@ -398,7 +531,7 @@ writeCommonHeader(unsigned int const cols, static unsigned char -compressionFieldValue(enum compressionType const compression) { +compressionFieldValue(enum CompressionType const compression) { unsigned char retval; @@ -424,7 +557,7 @@ compressionFieldValue(enum compressionType const compression) { static void writeRemainingHeaderLow(unsigned int const nextDepthOffset, unsigned int const transindex, - enum compressionType const compression, + enum CompressionType const compression, unsigned int const bpp) { /*---------------------------------------------------------------------------- Write last 6 bytes of a low density Palm Bitmap header. @@ -449,7 +582,7 @@ writeRemainingHeaderLow(unsigned int const nextDepthOffset, static void writeRemainingHeaderHigh(unsigned int const bpp, - enum compressionType const compression, + enum CompressionType const compression, unsigned int const density, xelval const maxval, bool const transparent, @@ -480,9 +613,9 @@ writeRemainingHeaderHigh(unsigned int const bpp, if (bpp == 16) { /* Blind guess here */ fputc(0, stdout); - fputc((PPM_GETR(transcolor) * 255) / maxval, stdout); - fputc((PPM_GETG(transcolor) * 255) / maxval, stdout); - fputc((PPM_GETB(transcolor) * 255) / maxval, stdout); + fputc(scaleSample(PPM_GETR(transcolor), maxval, 255), stdout); + fputc(scaleSample(PPM_GETG(transcolor), maxval, 255), stdout); + fputc(scaleSample(PPM_GETB(transcolor), maxval, 255), stdout); } else { assert(transindex <= UCHAR_MAX); fputc(0, stdout); @@ -523,7 +656,7 @@ writeDummy() { static void writeColormap(bool const explicitColormap, - Colormap const colormap, + Colormap * const colormapP, bool const directColor, unsigned int const bpp, bool const transparent, @@ -534,14 +667,14 @@ writeColormap(bool const explicitColormap, /* if there's a colormap, write it out */ if (explicitColormap) { unsigned int row; - if (!colormap) + if (!colormapP) pm_error("Internal error: user specified -colormap, but we did " "not generate a colormap."); - qsort (colormap->color_entries, colormap->ncolors, - sizeof(Color_s), palmcolor_compare_indices); - pm_writebigshort( stdout, colormap->ncolors ); - for (row = 0; row < colormap->ncolors; ++row) - pm_writebiglong (stdout, colormap->color_entries[row]); + qsort(colormapP->color_entries, colormapP->ncolors, + sizeof(ColormapEntry), palmcolor_compare_indices); + pm_writebigshort( stdout, colormapP->ncolors ); + for (row = 0; row < colormapP->ncolors; ++row) + pm_writebiglong (stdout, colormapP->color_entries[row]); } if (directColor && (version < 3)) { @@ -552,13 +685,13 @@ writeColormap(bool const explicitColormap, fputc(5, stdout); /* # of bits of blue */ fputc(0, stdout); /* reserved by Palm */ } else - pm_error("Don't know how to create %d bit DirectColor bitmaps.", + pm_error("Don't know how to create %u bit DirectColor bitmaps.", bpp); if (transparent) { fputc(0, stdout); - fputc((PPM_GETR(transcolor) * 255) / maxval, stdout); - fputc((PPM_GETG(transcolor) * 255) / maxval, stdout); - fputc((PPM_GETB(transcolor) * 255) / maxval, stdout); + fputc(scaleSample(PPM_GETR(transcolor) , maxval, 255), stdout); + fputc(scaleSample(PPM_GETG(transcolor) , maxval, 255), stdout); + fputc(scaleSample(PPM_GETB(transcolor) , maxval, 255), stdout); } else pm_writebiglong(stdout, 0); /* no transparent color */ } @@ -571,17 +704,29 @@ computeRawRowDirectColor(const xel * const xelrow, unsigned int const cols, xelval const maxval, unsigned char * const rowdata) { +/*---------------------------------------------------------------------------- + Compute a row of Palm data in raw (uncompressed) form for an image that + uses direct color (really, true color: each pixel contains RGB intensities + as distinct R, G, and B numbers). + In this format, each pixel is 16 bits: 5 red, 6 green, 5 blue. + + 'xelrow' is the image contents of row. It is 'cols' columns wide and + samples are based on maxval 'maxval'. + + Put the output data at 'rowdata'. +-----------------------------------------------------------------------------*/ unsigned int col; - unsigned char *outptr; + unsigned char * outCursor; - for (col = 0, outptr = rowdata; col < cols; ++col) { + for (col = 0, outCursor = &rowdata[0]; col < cols; ++col) { unsigned int const color = - ((((PPM_GETR(xelrow[col])*31)/maxval) << 11) | - (((PPM_GETG(xelrow[col])*63)/maxval) << 5) | - ((PPM_GETB(xelrow[col])*31)/maxval)); - *outptr++ = (color >> 8) & 0xFF; - *outptr++ = color & 0xFF; + (scaleSample(PPM_GETR(xelrow[col]), maxval, 31) << 11) | + (scaleSample(PPM_GETG(xelrow[col]), maxval, 63) << 5) | + (scaleSample(PPM_GETB(xelrow[col]), maxval, 31) << 0); + + *outCursor++ = (color >> 8) & 0xFF; + *outCursor++ = color & 0xFF; } } @@ -592,23 +737,40 @@ computeRawRowNonDirect(const xel * const xelrow, unsigned int const cols, xelval const maxval, unsigned int const bpp, - Colormap const colormap, + Colormap * const colormapP, unsigned int const newMaxval, unsigned char * const rowdata) { +/*---------------------------------------------------------------------------- + Compute a row of Palm data in raw (uncompressed) form for an image that + does not have a raster whose elements are explicit R, G, and B + intensities. + If 'colormapP' is non-null, the pixel is an index into that colormap. + 'newMaxval' is meaningless. + + If 'colormapP' is null, the pixel is a grayscale intensity, on a scale with + maximum value 'newMaxval'. (N.B. this is really direct color, but for some + reason it's historically lumped in with the paletted formats). + + 'xelrow' is the image contents of row. It is 'cols' columns wide and + samples are based on maxval 'maxval'. + + Put the output data at 'rowdata', using 'bpp' bits per pixel. +-----------------------------------------------------------------------------*/ unsigned int col; - unsigned char *outptr; + unsigned char * outCursor; + /* Points to next slot in 'rowdata' we will fill */ unsigned char outbyte; /* Accumulated bits to be output */ unsigned char outbit; /* The lowest bit number we want to access for this pixel */ - outbyte = 0x00; - outptr = rowdata; + outbyte = 0x00; /* initial value */ + outCursor = &rowdata[0]; /* Start at the beginning of the row */ for (outbit = 8 - bpp, col = 0; col < cols; ++col) { unsigned int color; - if (!colormap) { + if (!colormapP) { /* we assume grayscale, and use simple scaling */ color = (PNM_GET1(xelrow[col]) * newMaxval)/maxval; if (color > newMaxval) @@ -616,24 +778,23 @@ computeRawRowNonDirect(const xel * const xelrow, "color of %u.", color); color = newMaxval - color; /* note grayscale maps are inverted */ } else { - Color_s const temp_color = - ((((PPM_GETR(xelrow[col])*newMaxval)/maxval)<<16) - | (((PPM_GETG(xelrow[col])*newMaxval)/maxval)<<8) - | (((PPM_GETB(xelrow[col])*newMaxval)/maxval))); - Color const found = (bsearch (&temp_color, - colormap->color_entries, - colormap->ncolors, - sizeof(Color_s), - palmcolor_compare_colors)); - if (!found) { - pm_error("Color %d:%d:%d not found in colormap. " - "Try using pnmquant to reduce the " - "number of colors.", + ColormapEntry const searchTarget = + palmcolor_mapEntryColorFmPixel(xelrow[col], maxval, 255); + ColormapEntry * const foundEntryP = + bsearch(&searchTarget, + colormapP->color_entries, + colormapP->ncolors, + sizeof(ColormapEntry), + palmcolor_compare_colors); + if (!foundEntryP) { + pm_error("INERNAL ERROR: " + "Color (%u,%u,%u) not found in colormap, " + "though it was supposedly there before", PPM_GETR(xelrow[col]), PPM_GETG(xelrow[col]), PPM_GETB(xelrow[col])); } - color = (*found >> 24) & 0xFF; + color = (*foundEntryP >> 24) & 0xFF; } if (color > newMaxval) @@ -642,7 +803,7 @@ computeRawRowNonDirect(const xel * const xelrow, outbyte |= (color << outbit); if (outbit == 0) { /* Bit buffer is full. Flush to to rowdata. */ - *outptr++ = outbyte; + *outCursor++ = outbyte; outbyte = 0x00; outbit = 8 - bpp; } else @@ -650,7 +811,7 @@ computeRawRowNonDirect(const xel * const xelrow, } if ((cols % (8 / bpp)) != 0) { /* Flush bits remaining in the bit buffer to rowdata */ - *outptr++ = outbyte; + *outCursor++ = outbyte; } } @@ -830,7 +991,7 @@ rleCompressAndBufferRow(const unsigned char * const rowdata, unsigned int repeatcount; for (repeatcount = 1; repeatcount < (rowbytes - pos) && repeatcount < 255; - ++repeatcount) + ++repeatcount) if (rowdata[pos + repeatcount] != rowdata[pos]) break; @@ -870,7 +1031,7 @@ packbitsCompressAndBufferRow(const unsigned char * const rowdata, static void bufferRowFromRawRowdata(const unsigned char * const rowdata, unsigned int const rowbytes, - enum compressionType const compression, + enum CompressionType const compression, const unsigned char * const lastrow, struct seqBuffer * const rasterBufferP) { /*---------------------------------------------------------------------------- @@ -909,16 +1070,17 @@ bufferRow(const xel * const xelrow, unsigned int const rowbytes, unsigned int const bpp, unsigned int const newMaxval, - enum compressionType const compression, + enum CompressionType const compression, bool const directColor, - Colormap const colormap, + Colormap * const colormapP, unsigned char * const rowdata, unsigned char * const lastrow, struct seqBuffer * const rasterBufferP) { /*---------------------------------------------------------------------------- Add a row of the Palm Bitmap raster to buffer 'rasterBufferP'. - 'xelrow' is the image contents of row. It is 'cols' columns wide. + 'xelrow' is the image contents of row. It is 'cols' columns wide and + samples are based on maxval 'maxval'. If 'compression' indicates scanline compression, 'lastrow' is the row immediately preceding this one in the image (and this function @@ -930,7 +1092,7 @@ bufferRow(const xel * const xelrow, if (directColor) computeRawRowDirectColor(xelrow, cols, maxval, rowdata); else - computeRawRowNonDirect(xelrow, cols, maxval, bpp, colormap, newMaxval, + computeRawRowNonDirect(xelrow, cols, maxval, bpp, colormapP, newMaxval, rowdata); bufferRowFromRawRowdata(rowdata, rowbytes, compression, @@ -947,9 +1109,9 @@ bufferRaster(xel ** const xels, unsigned int const rowbytes, unsigned int const bpp, unsigned int const newMaxval, - enum compressionType const compression, + enum CompressionType const compression, bool const directColor, - Colormap const colormap, + Colormap * const colormapP, struct seqBuffer ** const rasterBufferPP) { unsigned char * rowdata; @@ -971,7 +1133,7 @@ bufferRaster(xel ** const xels, for (row = 0; row < rows; ++row) { bufferRow(xels[row], cols, maxval, rowbytes, bpp, newMaxval, compression, - directColor, colormap, rowdata, row > 0 ? lastrow : NULL, + directColor, colormapP, rowdata, row > 0 ? lastrow : NULL, *rasterBufferPP); if (compression == COMP_SCANLINE) @@ -988,8 +1150,8 @@ static void computeOffsetStuff(bool const offsetWanted, unsigned int const version, bool const directColor, - enum compressionType const compression, - bool const colormap, + enum CompressionType const compression, + bool const colormapped, unsigned int const colormapColorCount, unsigned int const sizePlusRasterSize, unsigned int * const nextDepthOffsetP, @@ -1003,7 +1165,7 @@ computeOffsetStuff(bool const offsetWanted, */ unsigned int const headerSize = ((version < 3) ? 16 : 24); unsigned int const colormapSize = - (colormap ? (2 + colormapColorCount * 4) : 0); + (colormapped ? (2 + colormapColorCount * 4) : 0); if (version < 3) { unsigned int const directSize = (directColor && version < 3) ? 8 : 0; @@ -1058,12 +1220,12 @@ writeBitmap(xel ** const xels, unsigned int const rowbytes, unsigned int const bpp, unsigned int const newMaxval, - enum compressionType const compression, + enum CompressionType const compression, bool const transparent, bool const directColor, bool const offsetWanted, - bool const hasColormap, - Colormap const colormap, + bool const colormapped, + Colormap * const colormapP, unsigned int const transindex, xel const transcolor, unsigned int const version, @@ -1086,11 +1248,11 @@ writeBitmap(xel ** const xels, */ struct seqBuffer * rasterBufferP; - writeCommonHeader(cols, rows, rowbytes, compression, hasColormap, + writeCommonHeader(cols, rows, rowbytes, compression, colormapped, transparent, directColor, bpp, version); bufferRaster(xels, cols, rows, maxval, rowbytes, bpp, newMaxval, - compression, directColor, colormap, &rasterBufferP); + compression, directColor, colormapP, &rasterBufferP); /* rasterSize itself takes 2 or 4 bytes */ if (version < 3) @@ -1099,7 +1261,7 @@ writeBitmap(xel ** const xels, sizePlusRasterSize = 4 + bufferLength(rasterBufferP); computeOffsetStuff(offsetWanted, version, directColor, compression, - hasColormap, hasColormap ? colormap->ncolors : 0, + colormapped, colormapped ? colormapP->ncolors : 0, sizePlusRasterSize, &nextDepthOffset, &nextBitmapOffset, &padBytesRequired); @@ -1111,7 +1273,7 @@ writeBitmap(xel ** const xels, maxval, transparent, transcolor, transindex, nextBitmapOffset); - writeColormap(hasColormap, colormap, directColor, bpp, + writeColormap(colormapped, colormapP, directColor, bpp, transparent, transcolor, maxval, version); if (compression != COMP_NONE) @@ -1134,8 +1296,8 @@ writeBitmap(xel ** const xels, int -main( int argc, char **argv ) { - struct cmdline_info cmdline; +main( int argc, const char **argv ) { + struct CmdlineInfo cmdline; unsigned int version; FILE* ifP; xel** xels; @@ -1148,10 +1310,9 @@ main( int argc, char **argv ) { unsigned int bpp; bool directColor; unsigned int newMaxval; - Colormap colormap; + Colormap * colormapP; - /* Parse default params */ - pnm_init(&argc, argv); + pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); @@ -1161,18 +1322,20 @@ main( int argc, char **argv ) { pm_close(ifP); if (cmdline.verbose) - pm_message("Input is %dx%d %s, maxval %d", + pm_message("Input is %ux%u %s, maxval %u", cols, rows, formatName(format), maxval); - determinePalmFormat(cols, rows, maxval, format, xels, cmdline.depth, - cmdline.maxdepth, cmdline.colormap, cmdline.verbose, - &bpp, &directColor, &colormap); + determinePalmFormat(cols, rows, maxval, format, xels, + cmdline.depthSpec, cmdline.depth, + cmdline.maxdepthSpec, cmdline.maxdepth, + cmdline.colormap, cmdline.compression, cmdline.verbose, + &bpp, &directColor, &colormapP); newMaxval = (1 << bpp) - 1; if (cmdline.transparent) findTransparentColor(cmdline.transparent, newMaxval, directColor, - maxval, colormap, &transcolor, &transindex); + maxval, colormapP, &transcolor, &transindex); else transindex = 0; @@ -1185,7 +1348,7 @@ main( int argc, char **argv ) { writeBitmap(xels, cols, rows, maxval, rowbytes, bpp, newMaxval, cmdline.compression, !!cmdline.transparent, directColor, cmdline.offset, - cmdline.colormap, colormap, transindex, transcolor, + cmdline.colormap, colormapP, transindex, transcolor, version, cmdline.density, cmdline.withdummy); return 0; |