about summary refs log tree commit diff
path: root/converter/other
diff options
context:
space:
mode:
Diffstat (limited to 'converter/other')
-rw-r--r--converter/other/pnmtorast.c501
-rw-r--r--converter/other/rast.h15
-rw-r--r--converter/other/rasttopnm.c295
-rw-r--r--converter/other/tifftopnm.c2
4 files changed, 530 insertions, 283 deletions
diff --git a/converter/other/pnmtorast.c b/converter/other/pnmtorast.c
index 605e815c..e11d3cb7 100644
--- a/converter/other/pnmtorast.c
+++ b/converter/other/pnmtorast.c
@@ -19,103 +19,285 @@
 
 
 static colormap_t *
-alloc_pr_colormap(void) {
-
-    colormap_t* pr_colormapP;
-
-    MALLOCVAR(pr_colormapP);
-    if ( pr_colormapP == NULL )
-        pm_error( "out of memory" );
-    pr_colormapP->type = RMT_EQUAL_RGB;
-    pr_colormapP->length = MAXCOLORS;
-    MALLOCARRAY(pr_colormapP->map[0], MAXCOLORS);
-    MALLOCARRAY(pr_colormapP->map[1], MAXCOLORS);
-    MALLOCARRAY(pr_colormapP->map[2], MAXCOLORS);
-    if ( pr_colormapP->map[0] == NULL || 
-         pr_colormapP->map[1] == NULL ||
-         pr_colormapP->map[2] == NULL )
-        pm_error( "out of memory" );
-
-    return pr_colormapP;
+allocPrColormap(void) {
+
+    colormap_t * prColormapP;
+
+    MALLOCVAR(prColormapP);
+    if (prColormapP == NULL)
+        pm_error("out of memory");
+    prColormapP->type = RMT_EQUAL_RGB;
+    prColormapP->length = MAXCOLORS;
+    MALLOCARRAY(prColormapP->map[0], MAXCOLORS);
+    MALLOCARRAY(prColormapP->map[1], MAXCOLORS);
+    MALLOCARRAY(prColormapP->map[2], MAXCOLORS);
+    if (prColormapP->map[0] == NULL || 
+        prColormapP->map[1] == NULL ||
+        prColormapP->map[2] == NULL)
+        pm_error("out of memory");
+
+    return prColormapP;
 }
 
 
 
-static colormap_t*
-make_pr_colormap(colorhist_vector const chv,
-                 int              const colors) {
+static colormap_t *
+makePrColormap(colorhist_vector const chv,
+               unsigned int     const colors) {
 
-    colormap_t* pr_colormapP;
-    int i;
+    colormap_t * prColormapP;
+    unsigned int i;
 
-    pr_colormapP = alloc_pr_colormap( );
+    prColormapP = allocPrColormap();
 
-    for ( i = 0; i < colors; ++i )
-    {
-        pr_colormapP->map[0][i] = PPM_GETR( chv[i].color );
-        pr_colormapP->map[1][i] = PPM_GETG( chv[i].color );
-        pr_colormapP->map[2][i] = PPM_GETB( chv[i].color );
+    for (i = 0; i < colors; ++i) {
+        prColormapP->map[0][i] = PPM_GETR(chv[i].color);
+        prColormapP->map[1][i] = PPM_GETG(chv[i].color);
+        prColormapP->map[2][i] = PPM_GETB(chv[i].color);
     }
-    for ( ; i < MAXCOLORS; ++i )
-        pr_colormapP->map[0][i] = pr_colormapP->map[1][i] =
-            pr_colormapP->map[2][i] = 0;
-
-    return pr_colormapP;
+    for ( ; i < MAXCOLORS; ++i) {
+        prColormapP->map[0][i] = 0;
+        prColormapP->map[1][i] = 0;
+        prColormapP->map[2][i] = 0;
+    }
+    return prColormapP;
 }
 
 
 
 static colormap_t *
-make_gray_pr_colormap(void) {
+makeGrayPrColormap(void) {
 
-    colormap_t* pr_colormapP;
-    int i;
+    colormap_t * prColormapP;
+    unsigned int i;
 
-    pr_colormapP = alloc_pr_colormap( );
+    prColormapP = allocPrColormap();
 
-    for ( i = 0; i < MAXCOLORS; ++i )
-    {
-        pr_colormapP->map[0][i] = i;
-        pr_colormapP->map[1][i] = i;
-        pr_colormapP->map[2][i] = i;
+    for (i = 0; i < MAXCOLORS; ++i) {
+        prColormapP->map[0][i] = i;
+        prColormapP->map[1][i] = i;
+        prColormapP->map[2][i] = i;
+    }
+
+    return prColormapP;
+}
+
+
+
+static void
+doRowDepth1(const xel *     const xelrow,
+            unsigned char * const rastRow,
+            unsigned int    const cols,
+            int             const format,
+            xelval          const maxval,
+            colorhash_table const cht,
+            unsigned int *  const lenP) {
+                
+    unsigned int col;
+    int bitcount;
+    unsigned int cursor;
+
+    cursor = 0;
+
+    rastRow[cursor] = 0;
+    bitcount = 7;
+
+    for (col = 0; col < cols; ++col) {
+        switch (PNM_FORMAT_TYPE(format)) {
+        case PPM_TYPE: {
+            xel adjustedXel;
+            int color;
+            if (maxval != 255)
+                PPM_DEPTH(adjustedXel, xelrow[col], maxval, 255 );
+            color = ppm_lookupcolor(cht, &adjustedXel);
+            if (color == -1)
+                pm_error("color not found?!?  "
+                         "col=%u  r=%u g=%u b=%u",
+                         col,
+                         PPM_GETR(adjustedXel),
+                         PPM_GETG(adjustedXel),
+                         PPM_GETB(adjustedXel));
+            if (color)
+                rastRow[cursor] |= 1 << bitcount;
+        } break;
+
+        default: {
+            int const color = PNM_GET1(xelrow[col]);
+            if (!color)
+                rastRow[cursor] |= 1 << bitcount;
+            break;
+        }
+        }
+        --bitcount;
+        if (bitcount < 0) {
+            ++cursor;
+            rastRow[cursor] = 0;
+            bitcount = 7;
+        }
+    }
+    *lenP = cursor;
+}
+
+
+
+static void
+doRowDepth8(const xel *     const xelrow,
+            unsigned char * const rastRow,
+            unsigned int    const cols,
+            int             const format,
+            xelval          const maxval,
+            colorhash_table const cht,
+            unsigned int *  const lenP) {
+
+    unsigned int col;
+    unsigned int cursor;
+
+    for (col = 0, cursor = 0; col < cols; ++col) {
+        int color;  /* color index of pixel or -1 if not in 'cht' */
+
+        switch (PNM_FORMAT_TYPE(format)) {
+        case PPM_TYPE: {
+            xel adjustedXel;
+
+            if (maxval == 255)
+                adjustedXel = xelrow[col];
+            else
+                PPM_DEPTH(adjustedXel, xelrow[col], maxval, 255);
+
+            color = ppm_lookupcolor(cht, &adjustedXel);
+            if (color == -1)
+                pm_error("color not found?!?  "
+                         "col=%u  r=%u g=%u b=%u",
+                         col,
+                         PPM_GETR(adjustedXel),
+                         PPM_GETG(adjustedXel),
+                         PPM_GETB(adjustedXel));
+        } break;
+
+        case PGM_TYPE: {
+            int const rawColor = PNM_GET1(xelrow[col]);
+
+            color = maxval == 255 ? rawColor : rawColor * 255 / maxval;
+
+        } break;
+
+        default:
+            color = PNM_GET1(xelrow[col]);
+        }
+        rastRow[cursor++] = color;
     }
+    *lenP = cursor;
+}
+
 
-    return pr_colormapP;
+
+
+static void
+doRowDepth24(const xel *     const xelrow,
+             unsigned char * const rastRow,
+             unsigned int    const cols,
+             int             const format,
+             xelval          const maxval,
+             unsigned int *  const lenP) {
+
+    /* Since depth is 24, we do NOT have a valid cht. */
+
+    unsigned int col;
+    unsigned int cursor;
+
+    for (col = 0, cursor = 0; col < cols; ++col) {
+        xel adjustedXel;
+
+        if (maxval == 255)
+            adjustedXel = xelrow[col];
+        else
+            PPM_DEPTH(adjustedXel, xelrow[col], maxval, 255);
+
+        rastRow[cursor++] = PPM_GETB(adjustedXel);
+        rastRow[cursor++] = PPM_GETG(adjustedXel);
+        rastRow[cursor++] = PPM_GETR(adjustedXel);
+    }
+    *lenP = cursor;
+}
+
+
+
+static void
+computeRaster(unsigned char * const rastRaster,
+              unsigned int    const lineSize,
+              unsigned int    const depth,
+              unsigned int    const cols,
+              unsigned int    const rows,
+              int             const format,
+              xelval          const maxval,
+              xel **          const xels,
+              colorhash_table const cht) {
+                  
+    unsigned int row;
+    unsigned char * rastRow;
+
+    for (row = 0, rastRow = &rastRaster[0]; row < rows; ++row) {
+        xel * const xelrow = xels[row];
+
+        unsigned int len; /* Number of bytes of rast data added to rastRow[] */
+
+        switch (depth) {
+        case 1:
+            doRowDepth1(xelrow, rastRow, cols, format, maxval, cht, &len);
+            break;
+        case 8:
+            doRowDepth8(xelrow, rastRow, cols, format, maxval, cht, &len);
+            break;
+        case 24:
+            doRowDepth24(xelrow, rastRow, cols, format, maxval, &len);
+            break;
+        default:
+            pm_error("INTERNAL ERROR: impossible depth %u", depth);
+        }
+        {
+            /* Pad out the line (which has a rounded size) with zeroes so
+               the resulting file is repeatable.
+            */
+            unsigned int i;
+            for (i = len; i < lineSize; ++i)
+                rastRow[i] = 0;
+        }
+        rastRow += lineSize;
+    }
 }
 
 
 
 int
-main(int argc, char ** argv) {
+main(int argc, const char ** argv) {
 
-    FILE* ifp;
-    xel** xels;
-    xel* xelrow;
+    FILE * ifP;
+    xel ** xels;
     xel p;
-    register xel* xP;
     colorhist_vector chv;
     colorhash_table cht;
-    colormap_t* pr_colormapP;
-    int argn, pr_type, rows, cols, format, i;
-    int depth, colors, linesize, row;
-    register int col, bitcount;
+    colormap_t * prColormapP;
+    int argn;
+    int prType;
+    int rows, cols;
+    int format;
+    unsigned int depth;
+    int colorCt;
     xelval maxval;
-    struct pixrect* pr;
-    unsigned char* data;
-    register unsigned char* byteP;
-    const char* const usage = "[-standard|-rle] [pnmfile]";
+    struct pixrect * prP;
+    const char * const usage = "[-standard|-rle] [pnmfile]";
 
-    pnm_init( &argc, argv );
+    pm_proginit(&argc, argv);
 
     argn = 1;
-    pr_type = RT_BYTE_ENCODED;
+    prType = RT_BYTE_ENCODED;
 
     while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
     {
         if ( pm_keymatch( argv[argn], "-standard", 2 ) )
-            pr_type = RT_STANDARD;
+            prType = RT_STANDARD;
         else if ( pm_keymatch( argv[argn], "-rle", 2 ) )
-            pr_type = RT_BYTE_ENCODED;
+            prType = RT_BYTE_ENCODED;
         else
             pm_usage( usage );
         ++argn;
@@ -123,191 +305,96 @@ main(int argc, char ** argv) {
 
     if ( argn != argc )
     {
-        ifp = pm_openr( argv[argn] );
+        ifP = pm_openr( argv[argn] );
         ++argn;
     }
     else
-        ifp = stdin;
+        ifP = stdin;
 
     if ( argn != argc )
         pm_usage( usage );
 
-    xels = pnm_readpnm( ifp, &cols, &rows, &maxval, &format );
+    xels = pnm_readpnm(ifP, &cols, &rows, &maxval, &format);
 
-    pm_close( ifp );
+    pm_close(ifP);
 
     /* Figure out the proper depth and colormap. */
-    switch ( PNM_FORMAT_TYPE(format) )
-    {
+    switch (PNM_FORMAT_TYPE(format)) {
     case PPM_TYPE:
-        pm_message( "computing colormap..." );
-        chv = ppm_computecolorhist( xels, cols, rows, MAXCOLORS, &colors );
-        if ( chv == (colorhist_vector) 0 )
-        {
+        pm_message("computing colormap...");
+        chv = ppm_computecolorhist(xels, cols, rows, MAXCOLORS, &colorCt);
+        if (!chv) {
             pm_message(
-                "Too many colors - proceeding to write a 24-bit non-mapped" );
+                "Too many colors - proceeding to write a 24-bit non-mapped");
             pm_message(
                 "rasterfile.  If you want 8 bits, try doing a 'pnmquant %d'.",
-                MAXCOLORS );
+                MAXCOLORS);
             depth = 24;
-            pr_type = RT_STANDARD;
-            pr_colormapP = (colormap_t*) 0;
-        }
-        else
-        {
-            pm_message( "%d colors found", colors );
-
-            if ( maxval != 255 )
-                for ( i = 0; i < colors; ++i )
-                    PPM_DEPTH( chv[i].color, chv[i].color, maxval, 255 );
-
+            prType = RT_STANDARD;
+            prColormapP = NULL;
+        } else {
+            pm_message("%u colors found", colorCt);
+
+            if (maxval != 255) {
+                unsigned int i;
+                for (i = 0; i < colorCt; ++i)
+                    PPM_DEPTH(chv[i].color, chv[i].color, maxval, 255);
+            }
             /* Force white to slot 0 and black to slot 1, if possible. */
-            PPM_ASSIGN( p, 255, 255, 255 );
-            ppm_addtocolorhist( chv, &colors, MAXCOLORS, &p, 0, 0 );
-            PPM_ASSIGN( p, 0, 0, 0 );
-            ppm_addtocolorhist( chv, &colors, MAXCOLORS, &p, 0, 1 );
-
-            if ( colors == 2 )
-            {
-                /* Monochrome. */
+            PPM_ASSIGN(p, 255, 255, 255);
+            ppm_addtocolorhist(chv, &colorCt, MAXCOLORS, &p, 0, 0);
+            PPM_ASSIGN(p, 0, 0, 0);
+            ppm_addtocolorhist(chv, &colorCt, MAXCOLORS, &p, 0, 1);
+
+            if (colorCt == 2) {
+                /* Monochrome */
                 depth = 1;
-                pr_colormapP = (colormap_t*) 0;
-            }
-            else
-            {
+                prColormapP = NULL;
+            } else {
                 /* Turn the ppm colormap into the appropriate Sun colormap. */
                 depth = 8;
-                pr_colormapP = make_pr_colormap( chv, colors );
+                prColormapP = makePrColormap(chv, colorCt);
             }
-            cht = ppm_colorhisttocolorhash( chv, colors );
-            ppm_freecolorhist( chv );
+            cht = ppm_colorhisttocolorhash(chv, colorCt);
+            ppm_freecolorhist(chv);
         }
 
         break;
 
     case PGM_TYPE:
         depth = 8;
-        pr_colormapP = make_gray_pr_colormap( );
+        prColormapP = makeGrayPrColormap();
         break;
 
     default:
         depth = 1;
-        pr_colormapP = (colormap_t*) 0;
+        prColormapP = NULL;
         break;
     }
 
-    if ( maxval > 255 && depth != 1 )
+    if (maxval > 255 && depth != 1)
         pm_message(
-            "maxval is not 255 - automatically rescaling colors" );
+            "maxval is not 255 - automatically rescaling colors");
     
     /* Allocate space for the Sun-format image. */
-    if ( (pr = mem_create(cols, rows, depth)) == (struct pixrect*) 0 )
-        pm_error( "unable to create new pixrect" );
-    data = ( (struct mpr_data*) pr->pr_data )->md_image;
-    linesize = ( (struct mpr_data*) pr->pr_data )->md_linebytes;
-
-    /* And compute the Sun image.  The variables at this point are:
-    **   cht is null or not
-    **   depth is 1, 8, or 24
-    */
-    for ( row = 0; row < rows; ++row )
-    {
-        xelrow = xels[row];
-        byteP = data;
-        switch ( depth )
-        {
-        case 1:
-            *byteP = 0;
-            bitcount = 7;
-            for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
-            {
-                register int color;
-
-                switch ( PNM_FORMAT_TYPE(format) )
-                {
-                case PPM_TYPE:
-                    if ( maxval != 255 )
-                        PPM_DEPTH( *xP, *xP, maxval, 255 );
-                    color = ppm_lookupcolor( cht, xP );
-                    if ( color == -1 )
-                        pm_error(
-                            "color not found?!?  row=%d col=%d  r=%d g=%d b=%d",
-                            row, col, PPM_GETR(*xP), PPM_GETG(*xP),
-                            PPM_GETB(*xP) );
-                    if ( color )
-                        *byteP |= 1 << bitcount;
-                    break;
-
-                default:
-                    color = PNM_GET1( *xP );
-                    if ( ! color )
-                        *byteP |= 1 << bitcount;
-                    break;
-                }
-                --bitcount;
-                if ( bitcount < 0 )
-                {
-                    ++byteP;
-                    *byteP = 0;
-                    bitcount = 7;
-                }
-            }
-            break;
-
-        case 8:
-            for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
-            {
-                register int color;
-
-                switch ( PNM_FORMAT_TYPE(format) )
-                {
-                case PPM_TYPE:
-                    if ( maxval != 255 )
-                        PPM_DEPTH( *xP, *xP, maxval, 255 );
-                    color = ppm_lookupcolor( cht, xP );
-                    if ( color == -1 )
-                        pm_error(
-                            "color not found?!?  row=%d col=%d  r=%d g=%d b=%d",
-                            row, col, PPM_GETR(*xP), PPM_GETG(*xP),
-                            PPM_GETB(*xP) );
-                    break;
-
-                case PGM_TYPE:
-                    color = PNM_GET1( *xP );
-                    if ( maxval != 255 )
-                        color = color * 255 / maxval;
-                    break;
-
-                default:
-                    color = PNM_GET1( *xP );
-                }
-                *byteP++ = color;
-            }
-            break;
+    prP = mem_create(cols, rows, depth);
+    if (!prP)
+        pm_error("unable to create new pixrect");
 
-        case 24:
-            /* If depth is 24, we do NOT have a valid cht. */
-            for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
-            {
-                if ( maxval != 255 )
-                    PPM_DEPTH( *xP, *xP, maxval, 255 );
-                *byteP++ = PPM_GETB( *xP );
-                *byteP++ = PPM_GETG( *xP );
-                *byteP++ = PPM_GETR( *xP );
-            }
-            break;
+    computeRaster(prP->pr_data->md_image,
+                  prP->pr_data->md_linebytes,
+                  depth,
+                  cols, rows, format, maxval, xels, cht);
 
-        default:
-            pm_error( "can't happen" );
-        }
-        data += linesize;
-    }
-    pnm_freearray( xels, rows );
+    pnm_freearray(xels, rows);
 
-    /* Finally, write the sucker out. */
-    if ( pr_dump( pr, stdout, pr_colormapP, pr_type, 0 ) == PIX_ERR )
-        pm_error( "error writing rasterfile" );
+    {
+        int rc;
 
-    exit( 0 );
+        rc = pr_dump(prP, stdout, prColormapP, prType, 0);
+        if (rc == PIX_ERR )
+            pm_error("error writing rasterfile");
+    }
+    return 0;
 }
 
diff --git a/converter/other/rast.h b/converter/other/rast.h
index e79896ea..eb6f4ec4 100644
--- a/converter/other/rast.h
+++ b/converter/other/rast.h
@@ -49,7 +49,7 @@ struct rasterfile {
 #define RMT_EQUAL_RGB	1
 #define RMT_RAW		2
     long ras_maplength;
-    };
+};
 
 struct pixrectops {
     int	(*pro_rop)();
@@ -65,21 +65,22 @@ struct pixrectops {
     int	(*pro_getcolormap)();
     int	(*pro_putattributes)();
     int	(*pro_getattributes)();
-    };
+};
 
 struct pr_size {
     int x, y;
-    };
+};
+
 struct pr_pos {
     int x, y;
-    };
+};
 
 struct pixrect {
     struct pixrectops* pr_ops;
     struct pr_size pr_size;
     int pr_depth;
     struct mpr_data* pr_data;	/* work-alike only handles memory pixrects */
-    };
+};
 
 struct mpr_data {
     int md_linebytes;
@@ -87,13 +88,13 @@ struct mpr_data {
     struct pr_pos md_offset;
     short md_primary;
     short md_flags;
-    };
+};
 
 typedef struct {
     int type;
     int length;
     unsigned char* map[3];
-    } colormap_t;
+} colormap_t;
 
 /* And the routine definitions. */
 
diff --git a/converter/other/rasttopnm.c b/converter/other/rasttopnm.c
index 2d081489..285fc5e0 100644
--- a/converter/other/rasttopnm.c
+++ b/converter/other/rasttopnm.c
@@ -24,6 +24,8 @@ struct cmdlineInfo {
     */
     const char * inputFileName;
     unsigned int index;
+    unsigned int dumpheader;
+    unsigned int dumpcolormap;
 };
 
 
@@ -50,7 +52,12 @@ parseCommandLine(int argc, const char ** argv,
     opt.short_allowed = false;  /* We have no short (old-fashioned) options */
     opt.allowNegNum = false;  /* We have no parms that are negative numbers */
 
-    OPTENT3(0,   "index",     OPT_FLAG,   NULL, &cmdlineP->index,   0);
+    OPTENT3(0,   "index",        OPT_FLAG,   NULL,
+            &cmdlineP->index,          0);
+    OPTENT3(0,   "dumpheader",   OPT_FLAG,   NULL,
+            &cmdlineP->dumpheader,     0);
+    OPTENT3(0,   "dumpcolormap", OPT_FLAG,   NULL,
+            &cmdlineP->dumpcolormap,   0);
 
     pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
         /* Uses and sets argc, argv, and some of *cmdlineP and others. */
@@ -67,13 +74,14 @@ parseCommandLine(int argc, const char ** argv,
 
 
 static bool
-colorMapIsGrayscale(colormap_t   const colorMap,
-                    unsigned int const mapLength) {
-
+colorMapIsGrayscale(colormap_t const colorMap) {
+/*----------------------------------------------------------------------------
+   The color map contains only gray.
+-----------------------------------------------------------------------------*/
     unsigned int i;
     bool grayscale;
 
-    for (i = 0, grayscale = true; i < mapLength / 3; ++i) {
+    for (i = 0, grayscale = true; i < colorMap.length; ++i) {
         if (colorMap.map[0][i] != colorMap.map[1][i] ||
             colorMap.map[1][i] != colorMap.map[2][i]) {
             grayscale = false;
@@ -94,8 +102,7 @@ analyzeImage(struct rasterfile const header,
              xel *             const oneP) {
 
     bool const grayscale =
-        header.ras_maplength == 0 ||
-        colorMapIsGrayscale(colorMap, header.ras_maplength);
+        header.ras_maplength == 0 || colorMapIsGrayscale(colorMap);
 
     *grayscaleP = grayscale;
 
@@ -186,6 +193,117 @@ reportOutputType(int const format) {
 
 
 static void
+convertRowDepth1(const unsigned char * const rastLine,
+                 unsigned int          const cols,
+                 xel                   const zeroXel,
+                 xel                   const oneXel,
+                 xel *                 const xelrow) {
+
+    const unsigned char * byteP;
+     unsigned int col;
+    unsigned char mask;
+
+    byteP = rastLine;  /* initial value */
+
+    for (col = 0, mask = 0x80; col < cols; ++col) {
+        if (mask == 0x00) {
+            ++byteP;
+            mask = 0x80;
+        }
+        xelrow[col] = (*byteP & mask) ? oneXel : zeroXel;
+        mask = mask >> 1;
+    }
+}
+
+
+
+static void
+convertRowDepth8(const unsigned char * const lineStart,
+                 unsigned int          const cols,
+                 bool                  const colorMapped,
+                 bool                  const useIndexForColor,
+                 bool                  const grayscale,
+                 colormap_t            const colorMap,
+                 xel *                 const xelrow) {
+/*----------------------------------------------------------------------------
+   Convert a line of raster data from the RAST input to a row of raster
+   data for the PNM output.
+
+   'lineStart' is where the RAST row starts.   'xelrow' is where to put the
+   PNM row.  'cols' is the number of pixels in the row.
+
+   'colorMapped' means the RAST image is colormapped.  If so, 'colorMap'
+   is the color map from the RAST file and 'useIndexForColor' means not
+   to use that map but instead to create a PGM row of the colormap
+   _indices_.
+
+   'grayscale' means it is a grayscale image; the output is PGM.
+-----------------------------------------------------------------------------*/
+    const unsigned char * byteP;
+    unsigned int col;
+
+    byteP = lineStart; /* initial value */
+
+    for (col = 0; col < cols; ++col) {
+        if (colorMapped && !useIndexForColor) {
+            if (grayscale)
+                PNM_ASSIGN1(xelrow[col], colorMap.map[0][*byteP]);
+            else
+                PPM_ASSIGN(xelrow[col],
+                           colorMap.map[0][*byteP],
+                           colorMap.map[1][*byteP],
+                           colorMap.map[2][*byteP]);
+        } else
+            PNM_ASSIGN1(xelrow[col], *byteP);
+
+        ++byteP;
+    }
+} 
+
+
+
+static void
+convertRowRgb(const unsigned char * const lineStart,
+              unsigned int          const cols,
+              unsigned int          const depth,
+              long                  const rastType,
+              bool                  const colorMapped,
+              bool                  const useIndexForColor,
+              colormap_t            const colorMap,
+              xel *                 const xelrow) {
+
+    const unsigned char * byteP;
+    unsigned int col;
+
+    byteP = lineStart; /* initial value */
+
+    for (col = 0; col < cols; ++col) {
+        xelval r, g, b;
+
+        if (depth == 32)
+            ++byteP;
+        if (rastType == RT_FORMAT_RGB) {
+            r = *byteP++;
+            g = *byteP++;
+            b = *byteP++;
+        } else {
+            b = *byteP++;
+            g = *byteP++;
+            r = *byteP++;
+        }
+        if (colorMapped && !useIndexForColor)
+            PPM_ASSIGN(xelrow[col],
+                       colorMap.map[0][r],
+                       colorMap.map[1][g],
+                       colorMap.map[2][b]);
+        else
+            PPM_ASSIGN(xelrow[col], r, g, b);
+    }
+} 
+
+
+
+static void
 writePnm(FILE *                 const ofP,
          const struct pixrect * const pixRectP,
          unsigned int           const cols,
@@ -201,10 +319,7 @@ writePnm(FILE *                 const ofP,
          xel                    const oneXel,
          bool                   const useIndexForColor) {
 
-    unsigned int const lineSize =
-        ((struct mpr_data*) pixRectP->pr_data)->md_linebytes;
-    unsigned char * const data =
-        ((struct mpr_data*) pixRectP->pr_data)->md_image;
+    struct mpr_data const mprData = *pixRectP->pr_data;
 
     xel * xelrow;
     unsigned int row;
@@ -216,66 +331,23 @@ writePnm(FILE *                 const ofP,
 
     reportOutputType(format);
 
-    for (row = 0, lineStart = data; row < rows; ++row, lineStart += lineSize) {
-        unsigned char * byteP;
-
-        byteP = lineStart; /* initial value */
+    for (row = 0, lineStart = mprData.md_image;
+         row < rows;
+         ++row, lineStart += mprData.md_linebytes) {
 
         switch (depth) {
-        case 1: {
-            unsigned int col;
-            unsigned char mask;
-            for (col = 0, mask = 0x80; col < cols; ++col) {
-                if (mask == 0x00) {
-                    ++byteP;
-                    mask = 0x80;
-                }
-                xelrow[col] = (*byteP & mask) ? oneXel : zeroXel;
-                mask = mask >> 1;
-            }
-        } break;
-        case 8: {
-            unsigned int col;
-            for (col = 0; col < cols; ++col) {
-                if (colorMapped && !useIndexForColor)
-                    if (grayscale)
-                        PNM_ASSIGN1(xelrow[col], colorMap.map[0][*byteP]);
-                    else
-                        PPM_ASSIGN(xelrow[col],
-                                   colorMap.map[0][*byteP],
-                                   colorMap.map[1][*byteP],
-                                   colorMap.map[2][*byteP]);
-                else
-                    PNM_ASSIGN1(xelrow[col], *byteP);
-                ++byteP;
-            }
-        } break;
+        case 1:
+            convertRowDepth1(lineStart, cols, zeroXel, oneXel, xelrow);
+            break;
+        case 8:
+            convertRowDepth8(lineStart, cols, colorMapped, useIndexForColor,
+                             grayscale, colorMap, xelrow);
+            break;
         case 24:
-        case 32: {
-            unsigned int col;
-            for (col = 0; col < cols; ++col) {
-                xelval r, g, b;
-
-                if (depth == 32)
-                    ++byteP;
-                if (rastType == RT_FORMAT_RGB) {
-                    r = *byteP++;
-                    g = *byteP++;
-                    b = *byteP++;
-                } else {
-                    b = *byteP++;
-                    g = *byteP++;
-                    r = *byteP++;
-                }
-                if (colorMapped && !useIndexForColor)
-                    PPM_ASSIGN(xelrow[col],
-                               colorMap.map[0][r],
-                               colorMap.map[1][g],
-                               colorMap.map[2][b]);
-                else
-                    PPM_ASSIGN(xelrow[col], r, g, b);
-            }
-        } break;
+        case 32:
+            convertRowRgb(lineStart, cols, depth, rastType, colorMapped,
+                          useIndexForColor, colorMap, xelrow);
+            break;
         default:
             pm_error("Invalid depth value: %u", depth);
         }
@@ -285,6 +357,84 @@ writePnm(FILE *                 const ofP,
 
 
 
+static void
+dumpHeader(struct rasterfile const header) {
+
+    const char * typeName;
+
+    switch (header.ras_type) {
+    case RT_OLD:            typeName = "old";           break;
+    case RT_STANDARD:       typeName = "standard";      break;
+    case RT_BYTE_ENCODED:   typeName = "byte encoded";  break;
+    case RT_FORMAT_RGB:     typeName = "format rgb";    break;
+    case RT_FORMAT_TIFF:    typeName = "format_tiff";   break;
+    case RT_FORMAT_IFF:     typeName = "format_iff";    break;
+    case RT_EXPERIMENTAL:   typeName = "experimental";  break;
+    default:                typeName = "???";
+    }
+
+    pm_message("type: %s (%lu)", typeName, (unsigned long)header.ras_type);
+    pm_message("%luw x %lul x %lud",
+               (unsigned long)header.ras_width,
+               (unsigned long)header.ras_height,
+               (unsigned long)header.ras_depth);
+    pm_message("raster length: %lu", (unsigned long)header.ras_length);
+
+    if (header.ras_maplength)
+        pm_message("Has color map");
+}
+
+
+
+static void
+dumpHeaderAnalysis(bool         const grayscale, 
+                   unsigned int const depth,
+                   xel          const zero, 
+                   xel          const one) {
+
+    pm_message("grayscale: %s", grayscale ? "YES" : "NO");
+
+    if (depth == 1) {
+        pm_message("Zero color: (%u,%u,%u)",
+                   PNM_GETR(zero),
+                   PNM_GETG(zero),
+                   PNM_GETB(zero));
+
+        pm_message("One color: (%u,%u,%u)",
+                   PNM_GETR(one),
+                   PNM_GETG(one),
+                   PNM_GETB(one));
+    }
+}
+
+
+
+static void
+dumpColorMap(colormap_t const colorMap) {
+
+    unsigned int i;
+    const char * typeName;
+
+    switch (colorMap.type) {
+    case RMT_NONE:      typeName = "NONE";      break;
+    case RMT_EQUAL_RGB: typeName = "EQUAL_RGB"; break;
+    case RMT_RAW:       typeName = "RAW";       break;
+    default:            typeName = "???";
+    }
+
+    pm_message("color map type = %s (%u)", typeName, colorMap.type);
+
+    pm_message("color map size = %u", colorMap.length);
+
+    for (i = 0; i < colorMap.length; ++i)
+        pm_message("color %u: (%u, %u, %u)", i,
+                   (unsigned char)colorMap.map[0][i],
+                   (unsigned char)colorMap.map[1][i],
+                   (unsigned char)colorMap.map[2][i]);
+}
+
+
+
 int
 main(int argc, const char ** const argv) {
 
@@ -309,6 +459,9 @@ main(int argc, const char ** const argv) {
     if (rc != 0 )
         pm_error("unable to read in rasterfile header");
 
+    if (cmdline.dumpheader)
+        dumpHeader(header);
+
     if (header.ras_maplength != 0) {
         int rc;
         
@@ -316,10 +469,16 @@ main(int argc, const char ** const argv) {
         
         if (rc != 0 )
             pm_error("unable to read colormap from RAST file");
+
+        if (cmdline.dumpcolormap)
+            dumpColorMap(colorMap);
     }
 
     analyzeImage(header, colorMap, &format, &maxval, &grayscale, &zero, &one);
 
+    if (cmdline.dumpheader)
+        dumpHeaderAnalysis(grayscale, header.ras_depth, zero, one);
+
     pr = pr_load_image(ifP, &header, NULL);
     if (pr == NULL )
         pm_error("unable to read in the image from the rasterfile" );
diff --git a/converter/other/tifftopnm.c b/converter/other/tifftopnm.c
index 679dff71..fcfb03f6 100644
--- a/converter/other/tifftopnm.c
+++ b/converter/other/tifftopnm.c
@@ -1350,7 +1350,7 @@ warnBrokenTiffLibrary(TIFF * const tiffP) {
         case ORIENTATION_RIGHTBOT:
         case ORIENTATION_LEFTBOT:
             pm_message("WARNING: This TIFF image has an orientation that "
-                       "most TIFF libraries converts incorrectly.  "
+                       "most TIFF libraries convert incorrectly.  "
                        "Use -byrow to circumvent.");
             break;
         }