diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2019-06-28 23:45:11 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2019-06-28 23:45:11 +0000 |
commit | cdf6e0151411d887fef61245cb303ef190b29335 (patch) | |
tree | 678c2212e125e66e0a868773e2b4ec460794da4e /converter/ppm/ppmtobmp.c | |
parent | de1311e820dc892f1a3c5c9ae70dbc56868030d8 (diff) | |
download | netpbm-mirror-cdf6e0151411d887fef61245cb303ef190b29335.tar.gz netpbm-mirror-cdf6e0151411d887fef61245cb303ef190b29335.tar.xz netpbm-mirror-cdf6e0151411d887fef61245cb303ef190b29335.zip |
Promote Advanced to Stable
git-svn-id: http://svn.code.sf.net/p/netpbm/code/stable@3641 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/ppm/ppmtobmp.c')
-rw-r--r-- | converter/ppm/ppmtobmp.c | 447 |
1 files changed, 240 insertions, 207 deletions
diff --git a/converter/ppm/ppmtobmp.c b/converter/ppm/ppmtobmp.c index 6d65d744..f89cec8d 100644 --- a/converter/ppm/ppmtobmp.c +++ b/converter/ppm/ppmtobmp.c @@ -13,6 +13,7 @@ * */ +#define _DEFAULT_SOURCE 1 /* New name for SVID & BSD source defines */ #define _BSD_SOURCE 1 /* Make sure strdup() is in string.h */ #define _XOPEN_SOURCE 500 /* Make sure strdup() is in string.h */ @@ -29,9 +30,9 @@ #define MAXCOLORS 256 -enum colortype {TRUECOLOR, PALETTE}; +typedef enum {TRUECOLOR, PALETTE} Colortype; -struct rgb { +struct Rgb { unsigned char red; unsigned char grn; unsigned char blu; @@ -50,13 +51,13 @@ typedef struct { colorhash_table cht; /* Indices in the following array are the same as in 'cht', above. */ - struct rgb bmpMap[MAXCOLORS]; -} colorMap; + struct Rgb bmpMap[MAXCOLORS]; +} ColorMap; static void -freeColorMap(const colorMap * const colorMapP) { +freeColorMap(const ColorMap * const colorMapP) { if (colorMapP->cht) ppm_freecolorhash(colorMapP->cht); @@ -68,11 +69,11 @@ struct CmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. */ - const char * inputFilename; - int class; /* C_WIN or C_OS2 */ - unsigned int bppSpec; - unsigned int bpp; - const char * mapfile; + const char * inputFilename; + enum bmpClass class; + unsigned int bppSpec; + unsigned int bpp; + const char * mapfile; }; @@ -93,15 +94,15 @@ parseCommandLine(int argc, const char ** argv, unsigned int windowsSpec, os2Spec, mapfileSpec; unsigned int option_def_index; - + MALLOCARRAY(option_def, 100); option_def_index = 0; /* incremented by OPTENTRY */ OPTENT3('w', "windows", OPT_FLAG, NULL, &windowsSpec, 0); OPTENT3('o', "os2", OPT_FLAG, NULL, &os2Spec, 0); - OPTENT3(0, "bpp", OPT_UINT, &cmdlineP->bpp, + OPTENT3(0, "bpp", OPT_UINT, &cmdlineP->bpp, &cmdlineP->bppSpec, 0); - OPTENT3(0, "mapfile", OPT_STRING, &cmdlineP->mapfile, + OPTENT3(0, "mapfile", OPT_STRING, &cmdlineP->mapfile, &mapfileSpec, 0); opt.opt_table = option_def; @@ -110,18 +111,18 @@ parseCommandLine(int argc, const char ** argv, pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); - if (windowsSpec && os2Spec) + if (windowsSpec && os2Spec) pm_error("Can't specify both -windows and -os2 options."); - else if (windowsSpec) - cmdlineP->class = C_WIN; + else if (windowsSpec) + cmdlineP->class = BMP_C_WIN_V1; else if (os2Spec) - cmdlineP->class = C_OS2; - else - cmdlineP->class = C_WIN; + cmdlineP->class = BMP_C_OS2_1x; + else + cmdlineP->class = BMP_C_WIN_V1; if (cmdlineP->bppSpec) { - if (cmdlineP->bpp != 1 && cmdlineP->bpp != 4 && + if (cmdlineP->bpp != 1 && cmdlineP->bpp != 4 && cmdlineP->bpp != 8 && cmdlineP->bpp != 24) pm_error("Invalid -bpp value specified: %u. The only values valid " "in the BMP format are 1, 4, 8, and 24 bits per pixel", @@ -135,7 +136,7 @@ parseCommandLine(int argc, const char ** argv, cmdlineP->inputFilename = pm_strdup("-"); /* he wants stdin */ else if (argc - 1 == 1) cmdlineP->inputFilename = pm_strdup(argv[1]); - else + else pm_error("Too many arguments. The only argument accepted " "is the input file specificaton"); @@ -153,8 +154,8 @@ freeCommandLine(struct CmdlineInfo const cmdline) { static void -PutByte(FILE * const fp, unsigned char const v) { - if (putc(v, fp) == EOF) +putByte(FILE * const fp, unsigned char const v) { + if (putc(v, fp) == EOF) pm_error("Write of a byte to a file failed."); /* Note: a Solaris/SPARC user reported on 2003.09.29 that the above @@ -168,139 +169,166 @@ PutByte(FILE * const fp, unsigned char const v) { static void -PutShort(FILE * const fp, short const v) { - if (pm_writelittleshort(fp, v) == -1) +putShort(FILE * const fp, short const v) { + if (pm_writelittleshort(fp, v) == -1) pm_error("Write of a halfword to a file failed."); } static void -PutLong(FILE * const fp, long const v) { +putLong(FILE * const fp, long const v) { if (pm_writelittlelong(fp, v) == -1) pm_error("Write of a word to a file failed."); } - -/* - * BMP writing - */ +/*---------------------------------------------------------------------------- + BMP writing +-----------------------------------------------------------------------------*/ static unsigned int -BMPwritefileheader(FILE * const fp, +bmpWriteFileHeader(FILE * const fp, unsigned int const cbSize, unsigned int const offBits) { /*---------------------------------------------------------------------------- Return the number of bytes written. -----------------------------------------------------------------------------*/ - PutByte(fp, 'B'); - PutByte(fp, 'M'); + putByte(fp, 'B'); + putByte(fp, 'M'); /* cbSize */ - PutLong(fp, cbSize); - + putLong(fp, cbSize); + /* xHotSpot */ - PutShort(fp, 0); - + putShort(fp, 0); + /* yHotSpot */ - PutShort(fp, 0); - + putShort(fp, 0); + /* offBits */ - PutLong(fp, offBits); - + putLong(fp, offBits); + + assert(BMPlenfileheader() == 14); + return 14; } -static int -BMPwriteinfoheader(FILE * const fp, - int const class, - unsigned long const bitcount, - unsigned long const x, +static unsigned int +bmpWriteInfoHeader(FILE * const fp, + enum bmpClass const class, + unsigned long const bitcount, + unsigned long const x, unsigned long const y) { /*---------------------------------------------------------------------------- + Write the INFO header. + Return the number of bytes written. ----------------------------------------------------------------------------*/ unsigned int cbFix; switch (class) { - case C_WIN: { - cbFix = 40; - PutLong(fp, cbFix); - - PutLong(fp, x); /* cx */ - PutLong(fp, y); /* cy */ - PutShort(fp, 1); /* cPlanes */ - PutShort(fp, bitcount); /* cBitCount */ + case BMP_C_WIN_V1: + case BMP_C_WIN_V2: + case BMP_C_WIN_V3: + case BMP_C_WIN_V4: + case BMP_C_WIN_V5: + { + cbFix = BMP_HDRLEN_WIN_V1; + putLong(fp, cbFix); + + putLong(fp, x); /* cx */ + putLong(fp, y); /* cy */ + putShort(fp, 1); /* cPlanes */ + putShort(fp, bitcount); /* cBitCount */ /* * We've written 16 bytes so far, need to write 24 more * for the required total of 40. */ - PutLong(fp, 0); /* Compression */ - PutLong(fp, 0); /* ImageSize */ - PutLong(fp, 0); /* XpixelsPerMeter */ - PutLong(fp, 0); /* YpixelsPerMeter */ - PutLong(fp, 0); /* ColorsUsed */ - PutLong(fp, 0); /* ColorsImportant */ + putLong(fp, 0); /* Compression */ + putLong(fp, 0); /* ImageSize */ + putLong(fp, 0); /* XpixelsPerMeter */ + putLong(fp, 0); /* YpixelsPerMeter */ + putLong(fp, 0); /* ColorsUsed */ + putLong(fp, 0); /* ColorsImportant */ + + assert(BMP_HDRLEN_WIN_V1 == 40); /* We wrote 40 bytes */ + + if (class != BMP_C_WIN_V1) { + /* Invalid call to this function - we don't know how to write + these header extensions. + */ + assert(false); + } } break; - case C_OS2: { - cbFix = 12; - PutLong(fp, cbFix); - - PutShort(fp, x); /* cx */ - PutShort(fp, y); /* cy */ - PutShort(fp, 1); /* cPlanes */ - PutShort(fp, bitcount); /* cBitCount */ + case BMP_C_OS2_1x: { + cbFix = BMP_HDRLEN_OS2_1x; + putLong(fp, cbFix); + + putShort(fp, x); /* cx */ + putShort(fp, y); /* cy */ + putShort(fp, 1); /* cPlanes */ + putShort(fp, bitcount); /* cBitCount */ + + assert(BMP_HDRLEN_OS2_1x == 12); /* We wrote 12 bytes */ } break; - default: - pm_error(er_internal, "BMPwriteinfoheader"); + case BMP_C_OS2_2x: + /* Invalid call to this function */ + assert(false); + break; } - return cbFix; } -static int -BMPwriteRgb(FILE * const fp, - int const class, - pixval const R, - pixval const G, - pixval const B) { +static unsigned int +bmpWriteRgb(FILE * const fp, + enum bmpClass const class, + pixval const R, + pixval const G, + pixval const B) { /*---------------------------------------------------------------------------- Return the number of bytes written. -----------------------------------------------------------------------------*/ + unsigned int retval; + switch (class) { - case C_WIN: - PutByte(fp, B); - PutByte(fp, G); - PutByte(fp, R); - PutByte(fp, 0); - return 4; - case C_OS2: - PutByte(fp, B); - PutByte(fp, G); - PutByte(fp, R); - return 3; - default: - pm_error(er_internal, "BMPwriteRgb"); - return -1; /* avoid compiler warning. */ + case BMP_C_WIN_V1: + case BMP_C_WIN_V2: + case BMP_C_WIN_V3: + case BMP_C_WIN_V4: + case BMP_C_WIN_V5: + putByte(fp, B); + putByte(fp, G); + putByte(fp, R); + putByte(fp, 0); + retval = 4; + break; + case BMP_C_OS2_1x: + case BMP_C_OS2_2x: + putByte(fp, B); + putByte(fp, G); + putByte(fp, R); + retval = 3; + break; } + return retval; } -static int -BMPwriteColormap(FILE * const ifP, - int const class, +static unsigned int +bmpWriteColormap(FILE * const ifP, + enum bmpClass const class, int const bpp, - const colorMap * const colorMapP) { + const ColorMap * const colorMapP) { /*---------------------------------------------------------------------------- Return the number of bytes written. -----------------------------------------------------------------------------*/ @@ -314,12 +342,12 @@ BMPwriteColormap(FILE * const ifP, nbyte = 0; for (i = 0; i < colorMapP->count; ++i) { - const struct rgb * const mapEntryP = &colorMapP->bmpMap[i]; - nbyte += BMPwriteRgb(ifP, class, + const struct Rgb * const mapEntryP = &colorMapP->bmpMap[i]; + nbyte += bmpWriteRgb(ifP, class, mapEntryP->red, mapEntryP->grn, mapEntryP->blu); } for (; i < ncolors; ++i) - nbyte += BMPwriteRgb(ifP, class, 0, 0, 0); + nbyte += bmpWriteRgb(ifP, class, 0, 0, 0); return nbyte; } @@ -345,10 +373,10 @@ lookupColor(colorhash_table const cht, static void -bmpWriteRow_palette(FILE * const fp, - const pixel * const row, +bmpWriteRow_palette(FILE * const fp, + const pixel * const row, unsigned int const cols, - unsigned short const bpp, + unsigned short const bpp, colorhash_table const cht, unsigned int * const nBytesP) { /*---------------------------------------------------------------------------- @@ -357,7 +385,7 @@ bmpWriteRow_palette(FILE * const fp, Return the number of bytes written as *nBytesP. -----------------------------------------------------------------------------*/ BITSTREAM b; - + b = pm_bitinit(fp, "w"); if (b == NULL) pm_error("Failed to initialize output file for output"); @@ -365,9 +393,9 @@ bmpWriteRow_palette(FILE * const fp, int rc; unsigned int nbyte; unsigned int col; - + nbyte = 0; /* initial value */ - + for (col = 0; col < cols; ++col) { unsigned int colorIndex; int rc; @@ -385,10 +413,10 @@ bmpWriteRow_palette(FILE * const fp, rc = pm_bitfini(b); nbyte += rc; - + /* Make sure we write a multiple of 4 bytes. */ while (nbyte % 4 != 0) { - PutByte(fp, 0); + putByte(fp, 0); ++nbyte; } *nBytesP = nbyte; @@ -398,13 +426,13 @@ bmpWriteRow_palette(FILE * const fp, static void -bmpWriteRow_truecolor(FILE * const fp, - const pixel * const row, +bmpWriteRow_truecolor(FILE * const fp, + const pixel * const row, unsigned long const cols, pixval const maxval, unsigned int * const nBytesP) { /*---------------------------------------------------------------------------- - Write a row of a truecolor BMP image to the file 'fp'. The row is + Write a row of a truecolor BMP image to the file 'fp'. The row is 'row', which is 'cols' columns long. @@ -413,20 +441,20 @@ bmpWriteRow_truecolor(FILE * const fp, /* This works only for 24 bits per pixel. To implement this for the general case (which is only hypothetical -- this program doesn't write any truecolor images except 24 bit and apparently no one - else does either), you would move this function into + else does either), you would move this function into BMPwriterow_palette, which writes arbitrary bit strings. But that would be a lot slower and less robust. */ int nbyte; /* Number of bytes we have written to file so far */ - int col; - + int col; + nbyte = 0; /* initial value */ for (col = 0; col < cols; ++col) { /* We scale to the BMP maxval, which is always 255. */ - PutByte(fp, PPM_GETB(row[col]) * 255 / maxval); - PutByte(fp, PPM_GETG(row[col]) * 255 / maxval); - PutByte(fp, PPM_GETR(row[col]) * 255 / maxval); + putByte(fp, PPM_GETB(row[col]) * 255 / maxval); + putByte(fp, PPM_GETG(row[col]) * 255 / maxval); + putByte(fp, PPM_GETR(row[col]) * 255 / maxval); nbyte += 3; } @@ -434,25 +462,27 @@ bmpWriteRow_truecolor(FILE * const fp, * Make sure we write a multiple of 4 bytes. */ while (nbyte % 4) { - PutByte(fp, 0); + putByte(fp, 0); ++nbyte; } - + *nBytesP = nbyte; } -static int -BMPwritebits(FILE * const fp, - unsigned long const cols, - unsigned long const rows, - enum colortype const colortype, - unsigned short const cBitCount, - const pixel ** const pixels, - pixval const maxval, - colorhash_table const cht) { +static unsigned int +bmpWriteRaster(FILE * const fp, + unsigned long const cols, + unsigned long const rows, + Colortype const colortype, + unsigned short const cBitCount, + const pixel ** const pixels, + pixval const maxval, + colorhash_table const cht) { /*---------------------------------------------------------------------------- + Write the raster. + Return the number of bytes written. -----------------------------------------------------------------------------*/ unsigned int nbyte; @@ -469,9 +499,9 @@ BMPwritebits(FILE * const fp, unsigned int nBytesThisRow; if (colortype == PALETTE) - bmpWriteRow_palette(fp, pixels[row], cols, + bmpWriteRow_palette(fp, pixels[row], cols, cBitCount, cht, &nBytesThisRow); - else + else bmpWriteRow_truecolor(fp, pixels[row], cols, maxval, &nBytesThisRow); @@ -486,15 +516,15 @@ BMPwritebits(FILE * const fp, static void -bmpEncode(FILE * const ifP, - int const class, - enum colortype const colortype, +bmpEncode(FILE * const ifP, + enum bmpClass const class, + Colortype const colortype, unsigned int const bpp, - int const x, - int const y, - const pixel ** const pixels, + int const x, + int const y, + const pixel ** const pixels, pixval const maxval, - const colorMap * const colorMapP) { + const ColorMap * const colorMapP) { /*---------------------------------------------------------------------------- Write a BMP file of the given class. -----------------------------------------------------------------------------*/ @@ -509,16 +539,16 @@ bmpEncode(FILE * const ifP, pm_message("Writing %u bits per pixel truecolor (no palette)", bpp); nbyte = 0; /* initial value */ - nbyte += BMPwritefileheader(ifP, cbSize, offbits); - nbyte += BMPwriteinfoheader(ifP, class, bpp, x, y); + nbyte += bmpWriteFileHeader(ifP, cbSize, offbits); + nbyte += bmpWriteInfoHeader(ifP, class, bpp, x, y); if (colortype == PALETTE) - nbyte += BMPwriteColormap(ifP, class, bpp, colorMapP); + nbyte += bmpWriteColormap(ifP, class, bpp, colorMapP); if (nbyte != offbits) pm_error(er_internal, "BmpEncode 1"); - nbyte += BMPwritebits(ifP, x, y, colortype, bpp, pixels, maxval, - colorMapP->cht); + nbyte += bmpWriteRaster(ifP, x, y, colortype, bpp, pixels, maxval, + colorMapP->cht); if (nbyte != cbSize) pm_error(er_internal, "BmpEncode 2"); } @@ -526,7 +556,7 @@ bmpEncode(FILE * const ifP, static void -makeBilevelColorMap(colorMap * const colorMapP) { +makeBilevelColorMap(ColorMap * const colorMapP) { colorMapP->count = 2; colorMapP->cht = NULL; @@ -541,10 +571,10 @@ makeBilevelColorMap(colorMap * const colorMapP) { static void -bmpEncodePbm(FILE * const ifP, - int const class, - int const cols, - int const rows, +bmpEncodePbm(FILE * const ifP, + enum bmpClass const class, + int const cols, + int const rows, unsigned char ** const bitrow) { /*---------------------------------------------------------------------------- Write a bi-level BMP file of the given class. @@ -559,19 +589,19 @@ bmpEncodePbm(FILE * const ifP, unsigned int const packedBytes = adjustedCols / 8; unsigned long nbyte; - colorMap bilevelColorMap; + ColorMap bilevelColorMap; unsigned int row; - + /* colortype == PALETTE */ pm_message("Writing 1 bit per pixel with a black-white palette"); nbyte = 0; /* initial value */ - nbyte += BMPwritefileheader(ifP, cbSize, offbits); - nbyte += BMPwriteinfoheader(ifP, class, 1, cols, rows); + nbyte += bmpWriteFileHeader(ifP, cbSize, offbits); + nbyte += bmpWriteInfoHeader(ifP, class, 1, cols, rows); makeBilevelColorMap(&bilevelColorMap); - nbyte += BMPwriteColormap(ifP, class, 1, &bilevelColorMap); + nbyte += bmpWriteColormap(ifP, class, 1, &bilevelColorMap); if (nbyte != offbits) pm_error(er_internal, "bmpEncodePbm 1"); @@ -583,7 +613,7 @@ bmpEncodePbm(FILE * const ifP, if (bytesWritten != packedBytes){ if (feof(ifP)) pm_error("End of file writing row %u of BMP raster.", row); - else + else pm_error("Error writing BMP raster. Errno=%d (%s)", errno, strerror(errno)); } else @@ -597,7 +627,7 @@ bmpEncodePbm(FILE * const ifP, static void -makeHashFromBmpMap(const struct rgb * const bmpMap, +makeHashFromBmpMap(const struct Rgb * const bmpMap, unsigned int const nColors, colorhash_table * const chtP) { @@ -607,7 +637,7 @@ makeHashFromBmpMap(const struct rgb * const bmpMap, MALLOCARRAY_NOFAIL(chv, nColors); for (i = 0; i < nColors; ++i) { - const struct rgb * const mapEntryP = &bmpMap[i]; + const struct Rgb * const mapEntryP = &bmpMap[i]; PPM_ASSIGN(chv[i].color, mapEntryP->red, mapEntryP->grn, mapEntryP->blu); @@ -629,7 +659,7 @@ minBmpBitsForColorCount(unsigned int const colorCount) { implement and other bpp's have in fact been seen to confuse viewers. There is an extended BMP format that has 16 bpp too, but this program doesn't know how to generate that - (see Bmptopnm.c, though). + (see Bmptopnm.c, though). */ if (minbits == 1) return 1; @@ -646,7 +676,7 @@ minBmpBitsForColorCount(unsigned int const colorCount) { static void getMapFile(const char * const mapFileName, unsigned int * const minimumBppP, - colorMap * const colorMapP) { + ColorMap * const colorMapP) { /*---------------------------------------------------------------------------- Get the color map (palette) for the BMP from file 'mapFileName'. @@ -655,7 +685,6 @@ getMapFile(const char * const mapFileName, Return as *minimumBppP the minimum number of bits per pixel it will take to represent all the colors in the map in the BMP format. -----------------------------------------------------------------------------*/ - FILE * mapFileP; int cols, rows; pixval maxval; @@ -675,12 +704,12 @@ getMapFile(const char * const mapFileName, MAXCOLORS, cols * rows); count = 0; /* initial value */ - + for (row = 0; row < rows; ++row) { unsigned int col; for (col = 0; col < cols; ++col) { pixel const color = pixels[row][col]; - struct rgb * const mapEntryP = &colorMapP->bmpMap[count++]; + struct Rgb * const mapEntryP = &colorMapP->bmpMap[count++]; assert(count <= ARRAY_SIZE(colorMapP->bmpMap)); @@ -703,15 +732,15 @@ getMapFile(const char * const mapFileName, static void -analyzeColors(const pixel ** const pixels, - int const cols, - int const rows, - pixval const maxval, +analyzeColors(const pixel ** const pixels, + int const cols, + int const rows, + pixval const maxval, unsigned int * const minimumBppP, - colorMap * const colorMapP) { + ColorMap * const colorMapP) { /*---------------------------------------------------------------------------- Look at the colors in the image 'pixels' and compute values to use in - representing those colors in a BMP image. + representing those colors in a BMP image. First of all, count the distinct colors. Return as *minimumBppP the minimum number of bits per pixel it will take to represent all @@ -733,7 +762,7 @@ analyzeColors(const pixel ** const pixels, int colorCount; pm_message("analyzing colors..."); - chv = ppm_computecolorhist((pixel**)pixels, cols, rows, MAXCOLORS, + chv = ppm_computecolorhist((pixel**)pixels, cols, rows, MAXCOLORS, &colorCount); colorMapP->count = colorCount; if (chv == NULL) { @@ -751,12 +780,12 @@ analyzeColors(const pixel ** const pixels, * Now scale the maxval to 255 as required by BMP format. */ for (i = 0; i < colorMapP->count; ++i) { - struct rgb * const mapEntryP = &colorMapP->bmpMap[i]; + struct Rgb * const mapEntryP = &colorMapP->bmpMap[i]; mapEntryP->red = (pixval) PPM_GETR(chv[i].color) * 255 / maxval; mapEntryP->grn = (pixval) PPM_GETG(chv[i].color) * 255 / maxval; mapEntryP->blu = (pixval) PPM_GETB(chv[i].color) * 255 / maxval; } - + /* And make a hash table for fast lookup. */ colorMapP->cht = ppm_colorhisttocolorhash(chv, colorMapP->count); ppm_freecolorhist(chv); @@ -769,7 +798,7 @@ static void chooseColortypeBpp(bool const userRequestsBpp, unsigned int const requestedBpp, unsigned int const minimumBpp, - enum colortype * const colortypeP, + Colortype * const colortypeP, unsigned int * const bitsPerPixelP) { /*---------------------------------------------------------------------------- Determine whether the BMP raster should contain RGB values or palette @@ -803,12 +832,12 @@ chooseColortypeBpp(bool const userRequestsBpp, *bitsPerPixelP = requestedBpp; } - assert(*bitsPerPixelP == 1 || - *bitsPerPixelP == 4 || - *bitsPerPixelP == 8 || + assert(*bitsPerPixelP == 1 || + *bitsPerPixelP == 4 || + *bitsPerPixelP == 8 || *bitsPerPixelP == 24); - if (*bitsPerPixelP > 8) + if (*bitsPerPixelP > 8) *colortypeP = TRUECOLOR; else { *colortypeP = PALETTE; @@ -818,13 +847,13 @@ chooseColortypeBpp(bool const userRequestsBpp, static void -doPbm(FILE * const ifP, - unsigned int const cols, - unsigned int const rows, - int const format, - int const class, - FILE * const ofP) { - +doPbm(FILE * const ifP, + unsigned int const cols, + unsigned int const rows, + int const format, + enum bmpClass const class, + FILE * const ofP) { + /* We read the raster directly from the input with pbm_readpbmrow_packed(). The raster format is almost identical, except that BMP specifies rows to be zero-filled to @@ -835,7 +864,7 @@ doPbm(FILE * const ifP, int const adjustedCols = (cols+31) /32 * 32; int const packedBytes = adjustedCols /8; - unsigned char ** bitrow; + unsigned char ** bitrow; unsigned int row; bitrow = pbm_allocarray_packed(adjustedCols, rows); @@ -848,15 +877,15 @@ doPbm(FILE * const ifP, thisRow[packedBytes-2] = 0x00; thisRow[packedBytes-3] = 0x00; thisRow[packedBytes-4] = 0x00; - + pbm_readpbmrow_packed(ifP, thisRow, cols, format); { unsigned int i; - for (i = 0; i < colChars; ++i) + for (i = 0; i < colChars; ++i) thisRow[i] = ~thisRow[i]; /* flip all pixels */ } - /* This may seem unnecessary, because the color palette + /* This may seem unnecessary, because the color palette (RGB[] in bmpEncodePbm) can be inverted for the same effect. However we take this precaution, for there is indication that some BMP viewers may get confused with that. @@ -867,21 +896,21 @@ doPbm(FILE * const ifP, } bmpEncodePbm(ofP, class, cols, rows, bitrow); -} +} static void -doPgmPpm(FILE * const ifP, - unsigned int const cols, - unsigned int const rows, - pixval const maxval, - int const ppmFormat, - int const class, - bool const userRequestsBpp, - unsigned int const requestedBpp, - const char * const mapFileName, - FILE * const ofP) { +doPgmPpm(FILE * const ifP, + unsigned int const cols, + unsigned int const rows, + pixval const maxval, + int const ppmFormat, + enum bmpClass const class, + bool const userRequestsBpp, + unsigned int const requestedBpp, + const char * const mapFileName, + FILE * const ofP) { /* PGM and PPM. We read the input image into a PPM array, scan it to analyze the colors, and convert it to a BMP raster. Logic @@ -889,29 +918,29 @@ doPgmPpm(FILE * const ifP, */ unsigned int minimumBpp; unsigned int bitsPerPixel; - enum colortype colortype; + Colortype colortype; unsigned int row; - + pixel ** pixels; - colorMap colorMap; - + ColorMap colorMap; + pixels = ppm_allocarray(cols, rows); - + for (row = 0; row < rows; ++row) ppm_readppmrow(ifP, pixels[row], cols, maxval, ppmFormat); - + if (mapFileName) getMapFile(mapFileName, &minimumBpp, &colorMap); else - analyzeColors((const pixel**)pixels, cols, rows, maxval, + analyzeColors((const pixel**)pixels, cols, rows, maxval, &minimumBpp, &colorMap); - + chooseColortypeBpp(userRequestsBpp, requestedBpp, minimumBpp, &colortype, &bitsPerPixel); - + bmpEncode(ofP, class, colortype, bitsPerPixel, cols, rows, (const pixel**)pixels, maxval, &colorMap); - + freeColorMap(&colorMap); ppm_freearray(pixels, rows); @@ -935,10 +964,11 @@ main(int argc, parseCommandLine(argc, argv, &cmdline); ifP = pm_openr(cmdline.inputFilename); - + ppm_readppminit(ifP, &cols, &rows, &maxval, &ppmFormat); - - if (PPM_FORMAT_TYPE(ppmFormat) == PBM_TYPE) + + if ((PPM_FORMAT_TYPE(ppmFormat) == PBM_TYPE) && + (!cmdline.bppSpec || cmdline.bpp == 1)) doPbm(ifP, cols, rows, ppmFormat, cmdline.class, stdout); else doPgmPpm(ifP, cols, rows, maxval, ppmFormat, @@ -952,3 +982,6 @@ main(int argc, return 0; } + + + |