about summary refs log tree commit diff
path: root/converter/ppm/ppmtobmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/ppm/ppmtobmp.c')
-rw-r--r--converter/ppm/ppmtobmp.c447
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;
 }
+
+
+