diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2016-06-26 18:15:09 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2016-06-26 18:15:09 +0000 |
commit | aab4792db8e0adcaf63cf57a1f5e0b18666dae47 (patch) | |
tree | bbfa9c4e12783d2dfd785c4e10964366550e9a60 /converter/ppm/ppmtobmp.c | |
parent | fe14f983ade44baa0794e4ce58a1a5334e46cf68 (diff) | |
download | netpbm-mirror-aab4792db8e0adcaf63cf57a1f5e0b18666dae47.tar.gz netpbm-mirror-aab4792db8e0adcaf63cf57a1f5e0b18666dae47.tar.xz netpbm-mirror-aab4792db8e0adcaf63cf57a1f5e0b18666dae47.zip |
Promote Development to Advanced as Release 10.75.00
git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@2803 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/ppm/ppmtobmp.c')
-rw-r--r-- | converter/ppm/ppmtobmp.c | 303 |
1 files changed, 167 insertions, 136 deletions
diff --git a/converter/ppm/ppmtobmp.c b/converter/ppm/ppmtobmp.c index 6d65d744..6bdec8c3 100644 --- a/converter/ppm/ppmtobmp.c +++ b/converter/ppm/ppmtobmp.c @@ -29,9 +29,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 +50,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 +68,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; }; @@ -113,11 +113,11 @@ parseCommandLine(int argc, const char ** argv, if (windowsSpec && os2Spec) pm_error("Can't specify both -windows and -os2 options."); else if (windowsSpec) - cmdlineP->class = C_WIN; + cmdlineP->class = BMP_C_WIN_V1; else if (os2Spec) - cmdlineP->class = C_OS2; + cmdlineP->class = BMP_C_OS2_1x; else - cmdlineP->class = C_WIN; + cmdlineP->class = BMP_C_WIN_V1; if (cmdlineP->bppSpec) { @@ -153,7 +153,7 @@ freeCommandLine(struct CmdlineInfo const cmdline) { static void -PutByte(FILE * const fp, unsigned char const v) { +putByte(FILE * const fp, unsigned char const v) { if (putc(v, fp) == EOF) pm_error("Write of a byte to a file failed."); @@ -168,7 +168,7 @@ PutByte(FILE * const fp, unsigned char const v) { static void -PutShort(FILE * const fp, short const v) { +putShort(FILE * const fp, short const v) { if (pm_writelittleshort(fp, v) == -1) pm_error("Write of a halfword to a file failed."); } @@ -176,131 +176,158 @@ PutShort(FILE * const fp, short const v) { 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, +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 +341,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; } @@ -388,7 +415,7 @@ bmpWriteRow_palette(FILE * const fp, /* Make sure we write a multiple of 4 bytes. */ while (nbyte % 4 != 0) { - PutByte(fp, 0); + putByte(fp, 0); ++nbyte; } *nBytesP = nbyte; @@ -424,9 +451,9 @@ bmpWriteRow_truecolor(FILE * const fp, 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,7 +461,7 @@ bmpWriteRow_truecolor(FILE * const fp, * Make sure we write a multiple of 4 bytes. */ while (nbyte % 4) { - PutByte(fp, 0); + putByte(fp, 0); ++nbyte; } @@ -443,16 +470,18 @@ bmpWriteRow_truecolor(FILE * const fp, -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; @@ -487,14 +516,14 @@ BMPwritebits(FILE * const fp, static void bmpEncode(FILE * const ifP, - int const class, - enum colortype const colortype, + enum bmpClass const class, + Colortype const colortype, unsigned int const bpp, 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 +538,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 +555,7 @@ bmpEncode(FILE * const ifP, static void -makeBilevelColorMap(colorMap * const colorMapP) { +makeBilevelColorMap(ColorMap * const colorMapP) { colorMapP->count = 2; colorMapP->cht = NULL; @@ -542,7 +571,7 @@ makeBilevelColorMap(colorMap * const colorMapP) { static void bmpEncodePbm(FILE * const ifP, - int const class, + enum bmpClass const class, int const cols, int const rows, unsigned char ** const bitrow) { @@ -559,19 +588,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"); @@ -597,7 +626,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 +636,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); @@ -646,7 +675,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 +684,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; @@ -680,7 +708,7 @@ getMapFile(const char * const mapFileName, 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)); @@ -708,7 +736,7 @@ analyzeColors(const pixel ** const pixels, 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. @@ -751,7 +779,7 @@ 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; @@ -769,7 +797,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 @@ -818,12 +846,12 @@ 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 @@ -872,16 +900,16 @@ doPbm(FILE * const ifP, 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,11 +917,11 @@ 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); @@ -952,3 +980,6 @@ main(int argc, return 0; } + + + |