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/ipdb.c222
-rw-r--r--converter/other/ipdb.h23
-rw-r--r--converter/other/pamtopdbimg.c76
-rw-r--r--converter/other/pamtoxvmini.c77
-rw-r--r--converter/other/pdbimgtopam.c127
-rw-r--r--converter/other/pnmtorle.c276
-rw-r--r--converter/other/pnmtosir.c35
7 files changed, 482 insertions, 354 deletions
diff --git a/converter/other/ipdb.c b/converter/other/ipdb.c
index 5e4dc82e..d524c7e9 100644
--- a/converter/other/ipdb.c
+++ b/converter/other/ipdb.c
@@ -23,15 +23,12 @@
 #define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */
 #define _BSD_SOURCE   /* Ensure strdup() is in <string.h> */
 #include <assert.h>
-#include <time.h>
 #include <string.h>
 
 #include "mallocvar.h"
 #include "nstring.h"
-#include "ipdb.h"
-
-typedef uint32_t pilot_time_t;
 
+#include "ipdb.h"
 
 
 
@@ -49,7 +46,7 @@ imgPpb(IMAGE * const imgP) {
 
 
 unsigned int
-ipdb_img_ppb(IMAGE * const imgP) {
+ipdb_imgPpb(IMAGE * const imgP) {
 /*----------------------------------------------------------------------------
    Pixels per byte
 -----------------------------------------------------------------------------*/
@@ -59,7 +56,7 @@ ipdb_img_ppb(IMAGE * const imgP) {
 
 
 size_t
-ipdb_img_size(IMAGE * const imgP) {
+ipdb_imgSize(IMAGE * const imgP) {
 /*----------------------------------------------------------------------------
   Size (in bytes) of an image's data.
 -----------------------------------------------------------------------------*/
@@ -71,115 +68,97 @@ ipdb_img_size(IMAGE * const imgP) {
 /*
  * Return the start of row `r'.
  */
- uint8_t *
- ipdb_img_row(IMAGE *      const imgP,
-              unsigned int const row) {
-
-     return &imgP->data[(row) * imgP->width / imgPpb(imgP)];
- }
-
-
+uint8_t *
+ipdb_imgRow(IMAGE *      const imgP,
+            unsigned int const row) {
 
- #define img_row(i, r)   
-
- static pilot_time_t const unixepoch = (66*365+17)*24*3600;
-     /* The unix epoch in Mac time (the Mac epoch is 00:00 UTC 1904.01.01).
-        The 17 is the number of leap years.
-     */
-
- static const char * const errorDesc[] = {
-     /* E_BADCOLORS      */
-     "Invalid palette, only {0x00, 0x55, 0xAA, 0xFF} allowed.",
+    return &imgP->data[(row) * imgP->width / imgPpb(imgP)];
+}
 
-     /* E_NOTIMAGE       */
-     "Not an image file.",
 
-     /* E_IMAGETHERE     */
-     "Image record already present, logic error.",
 
-     /* E_IMAGENOTTHERE  */
-     "Image record required before text record, logic error.",
+static const char * const errorDesc[] = {
+    /* E_BADCOLORS      */
+    "Invalid palette, only {0x00, 0x55, 0xAA, 0xFF} allowed.",
 
-     /* E_TEXTTHERE      */
-     "Text record already present, logic error.",
+    /* E_NOTIMAGE       */
+    "Not an image file.",
 
-     /* E_NOTRECHDR      */
-     "Invalid record header encountered.",
+    /* E_IMAGETHERE     */
+    "Image record already present, logic error.",
 
-     /* E_UNKNOWNRECHDR  */
-     "Unknown record header.",
+    /* E_IMAGENOTTHERE  */
+    "Image record required before text record, logic error.",
 
-     /* E_TOOBIGG        */
-     "Image too big, maximum size approx. 640*400 gray pixels.",
+    /* E_TEXTTHERE      */
+    "Text record already present, logic error.",
 
-     /* E_TOOBIGM        */
-     "Image too big, maximum size approx. 640*800 monochrome pixels.",
- };
+    /* E_NOTRECHDR      */
+    "Invalid record header encountered.",
 
+    /* E_UNKNOWNRECHDR  */
+    "Unknown record header.",
 
+    /* E_TOOBIGG        */
+    "Image too big, maximum size approx. 640*400 gray pixels.",
 
- const char *
- ipdb_err(int const e) {
+    /* E_TOOBIGM        */
+    "Image too big, maximum size approx. 640*800 monochrome pixels.",
+};
 
-     if (e < 0)
-         return e >= E_LAST ? errorDesc[-e - 1] : "unknown error";
-     else
-         return strerror(e);
- }
 
 
+const char *
+ipdb_err(int const e) {
 
- static void
- rechdr_free(RECHDR * const recP) {
+    if (e < 0)
+        return e >= E_LAST ? errorDesc[-e - 1] : "unknown error";
+    else
+        return strerror(e);
+}
 
-     if (recP) {
-         free(recP->extra);
-         free(recP);
-     }
- }
 
 
+static void
+rechdr_free(RECHDR * const recP) {
 
- void
- ipdb_image_free(IMAGE * const imgP) {
+    if (recP) {
+        free(recP->extra);
+        free(recP);
+    }
+}
 
-     if (imgP) {
-         rechdr_free(imgP->r);
-         free(imgP->data);
-         free(imgP);
-     }
- }
 
 
+void
+ipdb_imageFree(IMAGE * const imgP) {
 
- void
- ipdb_text_free(TEXT * const textP) {
+    if (imgP) {
+        rechdr_free(imgP->r);
+        free(imgP->data);
+        free(imgP);
+    }
+}
 
-     if (textP) {
-         rechdr_free(textP->r);
-         free(textP->data);
-         free(textP);
-     }
- }
 
 
+void
+ipdb_textFree(TEXT * const textP) {
 
- void
- ipdb_pdbhead_free(PDBHEAD * const headP) {
+    if (textP) {
+        rechdr_free(textP->r);
+        if (textP->data)
+            free(textP->data);
+        free(textP);
+    }
+}
 
-     free(headP);
- }
 
 
+void
+ipdb_pdbheadFree(PDBHEAD * const headP) {
 
- void
- ipdb_clear(IPDB * const pdbP) {
-     
-     if (pdbP) {
-         ipdb_image_free(pdbP->i);
-         ipdb_text_free(pdbP->t);
-         ipdb_pdbhead_free(pdbP->p);
-    }
+    free(headP);
 }
 
 
@@ -187,14 +166,22 @@ ipdb_img_size(IMAGE * const imgP) {
 void
 ipdb_free(IPDB * const pdbP) {
 
-    ipdb_clear(pdbP);
+    if (pdbP->i)
+        ipdb_imageFree(pdbP->i);
+
+    if (pdbP->t)
+        ipdb_textFree(pdbP->t);
+
+    if (pdbP->p)
+        ipdb_pdbheadFree(pdbP->p);
+
     free(pdbP);
 }
 
 
 
 PDBHEAD *
-ipdb_pdbhead_alloc(const char * const name) {
+ipdb_pdbheadAlloc() {
 
     PDBHEAD * pdbHeadP;
 
@@ -202,20 +189,6 @@ ipdb_pdbhead_alloc(const char * const name) {
 
     if (pdbHeadP) {
         MEMSZERO(pdbHeadP);
-
-        STRSCPY(pdbHeadP->name, name == NULL ? "unnamed" : name);
-
-        /*
-         * All of the Image Viewer pdb files that I've come across have
-         * 3510939142U (1997.08.16 14:38:22 UTC) here.  I don't know where
-         * this bizarre date comes from but the real date works fine so
-         * I'm using it.
-         */
-        pdbHeadP->ctime =
-            pdbHeadP->mtime = (pilot_time_t)time(NULL) + unixepoch;
-        
-        MEMSCPY(&pdbHeadP->type, IPDB_vIMG);
-        MEMSCPY(&pdbHeadP->id,   IPDB_View);
     }
     return pdbHeadP;
 }
@@ -223,7 +196,7 @@ ipdb_pdbhead_alloc(const char * const name) {
 
 
 static RECHDR *
-rechdr_alloc(int      const type,
+rechdrCreate(int      const type,
              uint32_t const offset) {
 
     /*
@@ -234,7 +207,7 @@ rechdr_alloc(int      const type,
     RECHDR  * recHdrP;
 
     MALLOCVAR(recHdrP);
-    
+
     if (recHdrP) {
         MEMSSET(recHdrP, 0);
 
@@ -255,10 +228,10 @@ rechdr_alloc(int      const type,
 
 
 IMAGE *
-ipdb_image_alloc(const char * const name,
-            int          const type,
-            int          const w,
-            int          const h) {
+ipdb_imageCreate(const char * const name,
+                 int          const type,
+                 int          const w,
+                 int          const h) {
 
     bool failed;
     IMAGE * imgP;
@@ -277,7 +250,7 @@ ipdb_image_alloc(const char * const name,
         imgP->width    = w;
         imgP->height   = h;
 
-        imgP->r = rechdr_alloc(IMG_REC, IMGOFFSET);
+        imgP->r = rechdrCreate(IMG_REC, IMGOFFSET);
 
         if (imgP->r) {
             if (w != 0 && h != 0) {
@@ -292,10 +265,10 @@ ipdb_image_alloc(const char * const name,
                 rechdr_free(imgP->r);
         } else
             failed = true;
-        
+
         if (failed)
-            ipdb_image_free(imgP);
-    } else 
+            ipdb_imageFree(imgP);
+    } else
         failed = true;
 
     return failed ? NULL : imgP;
@@ -304,7 +277,7 @@ ipdb_image_alloc(const char * const name,
 
 
 TEXT *
-ipdb_text_alloc(const char * const content) {
+ipdb_textAlloc(void) {
 
     TEXT * textP;
     bool failed;
@@ -320,22 +293,13 @@ ipdb_text_alloc(const char * const content) {
     if (textP) {
         MEMSZERO(textP);
 
-        textP->r = rechdr_alloc(TEXT_REC, 0);
+        textP->r = rechdrCreate(TEXT_REC, 0);
 
-        if (textP->r) {
-            if (content) {
-                textP->data = strdup(content);
-
-                if (!textP->data)
-                    failed = true;
-            }
-            if (failed)
-                rechdr_free(textP->r);
-        } else
+        if (textP->r == NULL)
             failed = true;
 
         if (failed)
-            ipdb_text_free(textP);
+            free(textP);
     } else
         failed = true;
 
@@ -345,7 +309,7 @@ ipdb_text_alloc(const char * const content) {
 
 
 IPDB *
-ipdb_alloc(const char * const name) {
+ipdb_alloc(void) {
 
     IPDB * pdbP;
     bool failed;
@@ -357,12 +321,11 @@ ipdb_alloc(const char * const name) {
     if (pdbP) {
         MEMSZERO(pdbP);
 
-        if (name) {
-            pdbP->p = ipdb_pdbhead_alloc(name);
+        pdbP->p = ipdb_pdbheadAlloc();
+
+        if (!pdbP->p)
+            failed = true;
 
-            if (!pdbP->p)
-                failed = true;
-        }
         if (failed)
             ipdb_free(pdbP);
     } else
@@ -383,3 +346,6 @@ ipdb_typeName(uint8_t const type) {
     default: return "???";
     }
 }
+
+
+
diff --git a/converter/other/ipdb.h b/converter/other/ipdb.h
index 6af5fc44..59e5d266 100644
--- a/converter/other/ipdb.h
+++ b/converter/other/ipdb.h
@@ -201,43 +201,40 @@ const char *
 ipdb_err(int error);
 
 size_t
-ipdb_img_size(IMAGE * const imgP);
+ipdb_imgSize(IMAGE * const imgP);
 
 unsigned int
-ipdb_img_ppb(IMAGE * const imgP);
+ipdb_imgPpb(IMAGE * const imgP);
 
 uint8_t *
-ipdb_img_row(IMAGE *      const imgP,
+ipdb_imgRow(IMAGE *      const imgP,
              unsigned int const row);
 
 void
 ipdb_free(IPDB *);
 
 IPDB *
-ipdb_alloc(const char *);
-
-void
-ipdb_clear(IPDB * const pdbP);
+ipdb_alloc(void);
 
 PDBHEAD *
-ipdb_pdbhead_alloc(const char * const name);
+ipdb_pdbheadAlloc(void);
 
 void
-ipdb_pdbhead_free(PDBHEAD * const headP);
+ipdb_pdbheadFree(PDBHEAD * const headP);
 
 IMAGE *
-ipdb_image_alloc(const char * const name,
+ipdb_imageCreate(const char * const name,
                  int          const type,
                  int          const w,
                  int          const h);
 
 void
-ipdb_image_free(IMAGE * const imgP);
+ipdb_imageFree(IMAGE * const imgP);
 
 void
-ipdb_text_free(TEXT * const textP);
+ipdb_textFree(TEXT * const textP);
 
 TEXT *
-ipdb_text_alloc(const char * const content);
+ipdb_textAlloc(void);
 
 #endif
diff --git a/converter/other/pamtopdbimg.c b/converter/other/pamtopdbimg.c
index 4823686f..da0f5064 100644
--- a/converter/other/pamtopdbimg.c
+++ b/converter/other/pamtopdbimg.c
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #include <assert.h>
 #include <string.h>
+#include <time.h>
 #include <sys/stat.h>
 
 #include "pm_c_util.h"
@@ -45,7 +46,7 @@
 
 enum CompMode {COMPRESSED, MAYBE, UNCOMPRESSED};
 
-struct cmdlineInfo {
+struct CmdlineInfo {
     /* All the information the user supplied in the command line,
        in a form easy for the program to use.
     */
@@ -54,13 +55,14 @@ struct cmdlineInfo {
     const char * notefile;  /* NULL if not specified */
     enum CompMode compMode;
     unsigned int depth4;
+    unsigned int fixedtime;
 };
 
 
 
 static void
 parseCommandLine(int argc, const char ** argv,
-                 struct cmdlineInfo * const cmdlineP) {
+                 struct CmdlineInfo * const cmdlineP) {
 /*----------------------------------------------------------------------------
    parse program command line described in Unix standard form by argc
    and argv.  Return the information in the options as *cmdlineP.
@@ -96,6 +98,8 @@ parseCommandLine(int argc, const char ** argv,
             &uncompressed,            0);
     OPTENT3(0, "4depth",              OPT_FLAG,      NULL,
             &cmdlineP->depth4,        0);
+    OPTENT3(0, "fixedtime",           OPT_FLAG,      NULL,
+            &cmdlineP->fixedtime,     0);
 
     opt.opt_table = option_def;
     opt.short_allowed = false;  /* We have no short (old-fashioned) options */
@@ -144,6 +148,42 @@ parseCommandLine(int argc, const char ** argv,
 
 
 
+static uint32_t const unixepoch = (66*365+17)*24*3600;
+    /* The unix epoch in Mac time (the Mac epoch is 00:00 UTC 1904.01.01).
+       The 17 is the number of leap years.
+    */
+
+
+
+static void
+setPdbHeader(PDBHEAD *    const pdbHeadP,
+             const char * const name,
+             bool         const wantFixedTime) {
+
+    STRSCPY(pdbHeadP->name, name);
+
+    {
+        /*
+         * All of the Image Viewer pdb files that I've come across have
+         * 3510939142U (1997.08.16 14:38:22 UTC) here.  I don't know where
+         * this bizarre datetime comes from but the real date works fine so
+         * I'm using it unless user asked for a fixed time (probably just so he
+         * gets repeatable output).
+         */
+
+        uint32_t const stdTime = 3510939142U;
+
+        uint32_t const hdrDt =
+            wantFixedTime ? stdTime : (uint32_t)time(NULL) + unixepoch;
+
+        pdbHeadP->ctime = pdbHeadP->mtime = hdrDt;
+    }
+    MEMSCPY(&pdbHeadP->type, IPDB_vIMG);
+    MEMSCPY(&pdbHeadP->id,   IPDB_View);
+}
+
+
+
 static int
 pdbheadWrite(PDBHEAD * const pdbheadP,
              FILE *    const fileP) {
@@ -249,9 +289,9 @@ compressIfRequired(IPDB *     const pdbP,
 
     if (comp == IPDB_NOCOMPRESS) {
         *compressedDataP = pdbP->i->data;
-        *compressedSizeP = ipdb_img_size(pdbP->i);
+        *compressedSizeP = ipdb_imgSize(pdbP->i);
     } else {
-        int const uncompressedSz = ipdb_img_size(pdbP->i);
+        int const uncompressedSz = ipdb_imgSize(pdbP->i);
 
         unsigned char * outbuf;
         size_t          compressedSz;
@@ -475,7 +515,7 @@ imageInsertInit(IPDB * const pdbP,
                      ipdb_typeName(type), MAX_SIZE(type));
         else {
             pdbP->i =
-                ipdb_image_alloc(name, type, adjustedWidth, adjustedHeight);
+                ipdb_imageCreate(name, type, adjustedWidth, adjustedHeight);
             if (pdbP->i == NULL)
                 pm_message("Could not get memory for %u x %u image",
                            adjustedWidth, adjustedHeight);
@@ -582,7 +622,7 @@ insertMimage(IPDB *          const pdbP,
 
 static int
 insertText(IPDB *       const pdbP,
-           const char * const s) {
+           const char * const content) {
 
     int retval;
 
@@ -591,17 +631,23 @@ insertText(IPDB *       const pdbP,
     else if (pdbP->p->num_recs == 2)
         retval = E_TEXTTHERE;
     else {
-        pdbP->t = ipdb_text_alloc(s);
+        pdbP->t = ipdb_textAlloc();
         if (pdbP->t == NULL)
             retval = ENOMEM;
         else {
-            pdbP->p->num_recs = 2;
+            pdbP->t->data = strdup(content);
 
-            pdbP->i->r->offset += 8;
-            pdbP->t->r->offset =
-                pdbP->i->r->offset + IMAGESIZE + ipdb_img_size(pdbP->i);
+            if (pdbP->t->data == NULL)
+                retval = ENOMEM;
+            else {
+                pdbP->p->num_recs = 2;
 
-            retval = 0;
+                pdbP->i->r->offset += 8;
+                pdbP->t->r->offset =
+                    pdbP->i->r->offset + IMAGESIZE + ipdb_imgSize(pdbP->i);
+
+                retval = 0;
+            }
         }
     }
     return retval;
@@ -689,7 +735,7 @@ readtxt(IPDB *       const pdbP,
 int
 main(int argc, const char **argv) {
 
-    struct cmdlineInfo cmdline;
+    struct CmdlineInfo cmdline;
     IPDB * pdbP;
     FILE * ifP;
     int comp;
@@ -709,11 +755,13 @@ main(int argc, const char **argv) {
     if (strlen(cmdline.title) > 31)
         pm_error("Title too long.  Max length is 31 characters.");
 
-    pdbP = ipdb_alloc(cmdline.title);
+    pdbP = ipdb_alloc();
 
     if (pdbP == NULL)
         pm_error("Failed to allocate IPDB structure");
 
+    setPdbHeader(pdbP->p, cmdline.title, cmdline.fixedtime);
+
     readimg(pdbP, ifP, cmdline.depth4);
 
     if (cmdline.notefile)
diff --git a/converter/other/pamtoxvmini.c b/converter/other/pamtoxvmini.c
index b57bcc74..047de75a 100644
--- a/converter/other/pamtoxvmini.c
+++ b/converter/other/pamtoxvmini.c
@@ -23,16 +23,16 @@ typedef struct xvPalette {
 } xvPalette;
 
 
-struct cmdlineInfo {
+struct CmdlineInfo {
     const char * inputFileName;
 };
 
 
 
 static void
-parseCommandLine(int const argc,
-                 char *    argv[],
-                 struct cmdlineInfo * const cmdlineP) {
+parseCommandLine(int const                  argc,
+                 const char *               argv[],
+                 struct CmdlineInfo * const cmdlineP) {
 
     if (argc-1 < 1)
         cmdlineP->inputFileName = "-";
@@ -75,7 +75,7 @@ static void
 writeXvHeader(FILE *       const ofP,
               unsigned int const cols,
               unsigned int const rows) {
-           
+
     fprintf(ofP, "P7 332\n");
 
     fprintf(ofP, "# Created by Pamtoxvmini\n");
@@ -94,12 +94,14 @@ writeXvHeader(FILE *       const ofP,
 
 static void
 findClosestColor(struct pam *      const pamP,
-                 tuple             const tuple, 
+                 tuple             const tuple,
                  const xvPalette * const xvPaletteP,
                  unsigned int *    const paletteIndexP) {
 /*----------------------------------------------------------------------------
    Find the color in the palette *xvPaletteP that is closest to the color
    'tuple' and return its index in the palette.
+
+   *pamP gives the format of 'tuple', which must be RGB with maxval 255.
 -----------------------------------------------------------------------------*/
     unsigned int paletteIndex;
     unsigned int bestPaletteIndex;
@@ -118,12 +120,12 @@ findClosestColor(struct pam *      const pamP,
         unsigned int const tupleRed = tuple[PAM_RED_PLANE];
         unsigned int const tupleGrn = tuple[PAM_GRN_PLANE];
         unsigned int const tupleBlu = tuple[PAM_BLU_PLANE];
-        
+
         unsigned int const paletteRed = xvPaletteP->red[paletteIndex];
         unsigned int const paletteGrn = xvPaletteP->grn[paletteIndex];
         unsigned int const paletteBlu = xvPaletteP->blu[paletteIndex];
 
-        unsigned int const distance = 
+        unsigned int const distance =
             SQR((int)tupleRed - (int)paletteRed) +
             SQR((int)tupleGrn - (int)paletteGrn) +
             SQR((int)tupleBlu - (int)paletteBlu);
@@ -155,24 +157,29 @@ getPaletteIndexThroughCache(struct pam *      const pamP,
     int found;
     int paletteIndex;
 
+    /* As required by findClosestColor(): */
+    assert(pamP->depth >= 3);
+    assert(pamP->maxval == 255);
+
     pnm_lookuptuple(pamP, paletteHash, tuple, &found, &paletteIndex);
     if (found)
         *paletteIndexP = paletteIndex;
     else {
         int fits;
+
         findClosestColor(pamP, tuple, xvPaletteP, paletteIndexP);
-        
+
         pnm_addtotuplehash(pamP, paletteHash, tuple, *paletteIndexP, &fits);
-        
+
         if (!fits)
             pm_error("Can't get memory for palette hash.");
     }
 }
 
-    
+
 
 static void
-writeXvRaster(struct pam * const pamP,
+writeXvRaster(struct pam * const inpamP,
               xvPalette *  const xvPaletteP,
               FILE *       const ofP) {
 /*----------------------------------------------------------------------------
@@ -190,33 +197,40 @@ writeXvRaster(struct pam * const pamP,
     unsigned int row;
     unsigned char * xvrow;
     struct pam scaledPam;
+    struct pam scaledRgbPam;
+
+    pnm_setminallocationdepth(inpamP, 3);
 
     paletteHash = pnm_createtuplehash();
 
-    tuplerow = pnm_allocpamrow(pamP);
-    xvrow = (unsigned char*)pm_allocrow(pamP->width, 1);
+    tuplerow = pnm_allocpamrow(inpamP);
+    xvrow = (unsigned char*)pm_allocrow(inpamP->width, 1);
 
-    scaledPam = *pamP;
+    scaledPam = *inpamP;  /* initial value */
     scaledPam.maxval = 255;
 
-    for (row = 0; row < pamP->height; ++row) {
+    scaledRgbPam = scaledPam;  /* initial value */
+    scaledRgbPam.depth = MAX(3, scaledPam.depth);
+
+    for (row = 0; row < inpamP->height; ++row) {
         unsigned int col;
 
-        pnm_readpamrow(pamP, tuplerow);
-        pnm_scaletuplerow(pamP, tuplerow, tuplerow, scaledPam.maxval);
+        pnm_readpamrow(inpamP, tuplerow);
+        pnm_scaletuplerow(inpamP, tuplerow, tuplerow, scaledPam.maxval);
         pnm_makerowrgb(&scaledPam, tuplerow);
 
-        for (col = 0; col < scaledPam.width; ++col) {
+        for (col = 0; col < scaledRgbPam.width; ++col) {
             unsigned int paletteIndex;
 
-            getPaletteIndexThroughCache(&scaledPam, tuplerow[col], xvPaletteP,
-                                        paletteHash, &paletteIndex);
+            getPaletteIndexThroughCache(&scaledRgbPam, tuplerow[col],
+                                        xvPaletteP, paletteHash,
+                                        &paletteIndex);
 
             assert(paletteIndex < 256);
 
             xvrow[col] = paletteIndex;
         }
-        fwrite(xvrow, 1, scaledPam.width, ofP);
+        fwrite(xvrow, 1, scaledRgbPam.width, ofP);
     }
 
     pm_freerow((char*)xvrow);
@@ -227,16 +241,16 @@ writeXvRaster(struct pam * const pamP,
 
 
 
-int 
-main(int    argc,
-     char * argv[]) {
+int
+main(int          argc,
+     const char * argv[]) {
 
-    struct cmdlineInfo cmdline;
+    struct CmdlineInfo cmdline;
     FILE * ifP;
     struct pam pam;
     xvPalette xvPalette;
- 
-    pnm_init(&argc, argv);
+
+    pm_proginit(&argc, argv);
 
     parseCommandLine(argc, argv, &cmdline);
 
@@ -246,13 +260,14 @@ main(int    argc,
 
     pnm_readpaminit(ifP, &pam, PAM_STRUCT_SIZE(allocation_depth));
 
-    pnm_setminallocationdepth(&pam, 3);
-
     writeXvHeader(stdout, pam.width, pam.height);
-    
+
     writeXvRaster(&pam, &xvPalette, stdout);
 
     pm_close(ifP);
 
     return 0;
 }
+
+
+
diff --git a/converter/other/pdbimgtopam.c b/converter/other/pdbimgtopam.c
index 67044109..b191644f 100644
--- a/converter/other/pdbimgtopam.c
+++ b/converter/other/pdbimgtopam.c
@@ -56,7 +56,7 @@ parseCommandLine(int argc, const char ** argv,
                  struct cmdlineInfo * const cmdlineP) {
 /*----------------------------------------------------------------------------
    parse program command line described in Unix standard form by argc
-   and argv.  Return the information in the options as *cmdlineP.  
+   and argv.  Return the information in the options as *cmdlineP.
 
    If command line is internally inconsistent (invalid options, etc.),
    issue error message to stderr and abort program.
@@ -90,7 +90,7 @@ parseCommandLine(int argc, const char ** argv,
 
     if (!notefileSpec)
         cmdlineP->notefile = NULL;
-    
+
     if (argc-1 < 1)
         cmdlineP->inputFileName = "-";
     else if (argc-1 == 1)
@@ -152,7 +152,7 @@ decompress(const uint8_t * const compressed,
         const uint8_t * inP;
         uint8_t *       outP;
         size_t          bytesLeft;
-        
+
         for (bytesLeft = imageSize,
                  inP  = &compressed[0], outP = &uncompressed[0];
              bytesLeft > 0;
@@ -224,7 +224,7 @@ readCompressed(IMAGE *    const imgP,
          * this extra byte and ignore it by paying attention to
          * the image dimensions.
          */
-       size_t const maxCompressedSizeWithBloat = ipdb_img_size(imgP) * 2;
+       size_t const maxCompressedSizeWithBloat = ipdb_imgSize(imgP) * 2;
          /*
           * Provide a buffer large enough for the worst case.
           * See note in lib/util/runlength.c .
@@ -251,7 +251,7 @@ readCompressed(IMAGE *    const imgP,
          * Read to the indicated offset.
          */
         dataSize = end_offset - ftell(fP) + 1;
-        
+
         MALLOCARRAY(buffer, dataSize);
 
         if (buffer == NULL)
@@ -306,9 +306,9 @@ imageReadHeader(FILE *  const fileP,
         pm_message("  Y_anchor: %u", imgP->y_anchor);
         pm_message("  Width: %u", imgP->width);
         pm_message("  Height: %u", imgP->height);
-        pm_message("Pixels per byte: %u", ipdb_img_ppb(imgP));
+        pm_message("Pixels per byte: %u", ipdb_imgPpb(imgP));
         pm_message("Image size: %lu bytes",
-                   (unsigned long)ipdb_img_size(imgP));
+                   (unsigned long)ipdb_imgSize(imgP));
     }
 }
 
@@ -318,7 +318,7 @@ imageReadData(FILE *   const fileP,
               IMAGE *  const imgP,
               uint32_t const end_offset) {
 
-    size_t const imageSize = ipdb_img_size(imgP);  
+    size_t const imageSize = ipdb_imgSize(imgP);
 
     int retval;
     size_t dataSize;
@@ -390,7 +390,7 @@ textRead(TEXT * const textP,
         return 0;
 
     textP->r->offset = (uint32_t)ftell(fileP);
-    
+
     /*
      * What a pain in the ass!  Why the hell isn't there a length
      * attached to the text record?  I suppose the designer wasn't
@@ -453,7 +453,7 @@ pdbheadRead(PDBHEAD * const pdbHeadP,
     pm_readbiglongu2(fileP, &pdbHeadP->next_rec);
     pm_readbigshortu(fileP, &pdbHeadP->num_recs);
 
-    if (!memeq(pdbHeadP->type, IPDB_vIMG, 4) 
+    if (!memeq(pdbHeadP->type, IPDB_vIMG, 4)
         || !memeq(pdbHeadP->id, IPDB_View, 4))
         retval = E_NOTIMAGE;
     else
@@ -531,62 +531,54 @@ ipdbRead(IPDB * const pdbP,
 
     int retval;
 
-    ipdb_clear(pdbP);
+    int status;
 
-    pdbP->p = ipdb_pdbhead_alloc(NULL);
+    status = pdbheadRead(pdbP->p, fileP);
 
-    if (pdbP->p == NULL)
-        retval = ENOMEM;
+    if (status != 0)
+        retval = status;
     else {
-        int status;
-
-        status = pdbheadRead(pdbP->p, fileP);
-
-        if (status != 0)
-            retval = status;
+        pdbP->i = ipdb_imageCreate(pdbP->p->name, IMG_GRAY, 0, 0);
+        if (pdbP->i == NULL)
+            retval = ENOMEM;
         else {
-            pdbP->i = ipdb_image_alloc(pdbP->p->name, IMG_GRAY, 0, 0);
-            if (pdbP->i == NULL)
-                retval = ENOMEM;
+            int status;
+            status = rechdrRead(pdbP->i->r, fileP);
+            if (status != 0)
+                retval = status;
             else {
-                int status;
-                status = rechdrRead(pdbP->i->r, fileP);
-                if (status != 0)
-                    retval = status;
-                else {
-                    if (pdbP->p->num_recs > 1) {
-                        pdbP->t = ipdb_text_alloc(NULL);
-                        if (pdbP->t == NULL)
-                            retval = ENOMEM;
-                        else {
-                            int status;
-                            status = rechdrRead(pdbP->t->r, fileP);
-                            if (status != 0)
-                                retval = status;
-                            else
-                                retval = 0;
-                        }
-                    } else
-                        retval = 0;
-                    
-                    if (retval == 0) {
-                        uint32_t const offset =
-                            pdbP->t == NULL ?
-                            UNKNOWN_OFFSET : pdbP->t->r->offset - 1;
-
+                if (pdbP->p->num_recs > 1) {
+                    pdbP->t = ipdb_textAlloc();
+                    if (pdbP->t == NULL)
+                        retval = ENOMEM;
+                    else {
                         int status;
-
-                        status = imageRead(pdbP->i, offset, fileP, verbose);
+                        status = rechdrRead(pdbP->t->r, fileP);
                         if (status != 0)
                             retval = status;
-                        else {
-                            if (pdbP->t != NULL) {
-                                int status;
-                                
-                                status = textRead(pdbP->t, fileP);
-                                if (status != 0)
-                                    retval = status;
-                            }
+                        else
+                            retval = 0;
+                    }
+                } else
+                    retval = 0;
+
+                if (retval == 0) {
+                    uint32_t const offset =
+                        pdbP->t == NULL ?
+                        UNKNOWN_OFFSET : pdbP->t->r->offset - 1;
+
+                    int status;
+
+                    status = imageRead(pdbP->i, offset, fileP, verbose);
+                    if (status != 0)
+                        retval = status;
+                    else {
+                        if (pdbP->t != NULL) {
+                            int status;
+
+                            status = textRead(pdbP->t, fileP);
+                            if (status != 0)
+                                retval = status;
                         }
                     }
                 }
@@ -663,8 +655,8 @@ static void
 g16row(IPDB *       const pdbP,
        unsigned int const row,
        uint8_t *    const buffer) {
-    
-    g16unpack(ipdb_img_row(pdbP->i, row), buffer, ipdb_width(pdbP));
+
+    g16unpack(ipdb_imgRow(pdbP->i, row), buffer, ipdb_width(pdbP));
 }
 
 
@@ -674,7 +666,7 @@ grow(IPDB *       const pdbP,
      unsigned int const row,
      uint8_t *    const buffer) {
 
-    gunpack(ipdb_img_row(pdbP->i, row), buffer, ipdb_width(pdbP));
+    gunpack(ipdb_imgRow(pdbP->i, row), buffer, ipdb_width(pdbP));
 }
 
 
@@ -684,7 +676,7 @@ mrow(IPDB *       const pdbP,
      unsigned int const row,
      uint8_t *    const buffer) {
 
-    munpack(ipdb_img_row(pdbP->i, row), buffer, ipdb_width(pdbP));
+    munpack(ipdb_imgRow(pdbP->i, row), buffer, ipdb_width(pdbP));
 }
 
 
@@ -715,7 +707,7 @@ writeImgPam(IPDB * const pdbP,
            PAM_PBM_TUPLETYPE : PAM_PGM_TUPLETYPE);
 
     pnm_writepaminit(&pam);
-    
+
     tupleRow = pnm_allocpamrow(&pam);
 
     for (row = 0; row < pam.height; ++row) {
@@ -731,7 +723,7 @@ writeImgPam(IPDB * const pdbP,
 
         for (col = 0; col < pam.width; ++col)
             tupleRow[col][0] = imgRow[col];
-        
+
         pnm_writepamrow(&pam, tupleRow);
     }
     pnm_freepamrow(tupleRow);
@@ -754,7 +746,7 @@ writeText(IPDB *       const pdbP,
         fP = pm_openw(name);
         if (fP == NULL)
             pm_error("Could not open note file '%s' for output", name);
-        
+
         fprintf(fP, "%s\n", note);
 
         pm_close(fP);
@@ -777,7 +769,7 @@ main(int argc, const char ** argv) {
 
     ifP = pm_openr(cmdline.inputFileName);
 
-    pdbP = ipdb_alloc(NULL);
+    pdbP = ipdb_alloc();
     if (pdbP == NULL)
         pm_error("Could not allocate IPDB structure.");
 
@@ -795,3 +787,6 @@ main(int argc, const char ** argv) {
 
     return EXIT_SUCCESS;
 }
+
+
+
diff --git a/converter/other/pnmtorle.c b/converter/other/pnmtorle.c
index d61884dd..17c9cfbc 100644
--- a/converter/other/pnmtorle.c
+++ b/converter/other/pnmtorle.c
@@ -33,71 +33,157 @@
  * 2000.04.13 adapted for Netpbm by Bryan Henderson.  Quieted compiler
  *            warnings.
  *
+ * 2022.03.06 revision by Akira F Urushibata
+ *            use shhopt instead of scanargs
+ *            proper handling of multiple image files with -h
+ *
  */
 /*-----------------------------------------------------
  * System includes.
  */
 #include <string.h>
 #include <stdio.h>
+#include <assert.h>
 #include "pnm.h"
 #include "mallocvar.h"
 #include "rle.h"
+#include "shhopt.h"
+#include "pm_c_util.h"
+
+
+struct CmdlineInfo {
+    /* All the information the user supplied in the command line,
+       in a form easy for the program to use.
+    */
+    const char * inFileName;
+    const char * outfile;
+    unsigned int verbose;
+    unsigned int header;
+    unsigned int alpha;
+};
+
+
+
+static void
+parseCommandLine(int argc, const char ** argv,
+                 struct CmdlineInfo * const cmdlineP) {
+/*----------------------------------------------------------------------------
+   Note that the file spec array we return is stored in the storage that
+   was passed to us as the argv array.
+-----------------------------------------------------------------------------*/
+    optEntry * option_def;
+    /* Instructions to pm_optParseOptions3 on how to parse our options. */
+
+    optStruct3 opt;
+
+    unsigned int option_def_index;
+    unsigned int outfileSpec;
+
+    MALLOCARRAY_NOFAIL(option_def, 100);
+
+    option_def_index = 0;   /* incremented by OPTENTRY */
+    OPTENT3(0, "alpha",    OPT_FLAG,   NULL,  &cmdlineP->alpha,     0);
+    OPTENT3(0, "header",   OPT_FLAG,   NULL,  &cmdlineP->header,    0);
+    OPTENT3(0, "verbose",  OPT_FLAG,   NULL,  &cmdlineP->verbose,   0);
+    OPTENT3(0, "outfile",  OPT_STRING, &cmdlineP->outfile,
+                                              &outfileSpec,         0);
+
+    opt.opt_table = option_def;
+    opt.short_allowed = false;  /* We have no short (old-fashioned) options */
+    opt.allowNegNum = false;  /* We have no parms that are negative numbers */
+
+    pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
+        /* Uses and sets argc, argv, and some of *cmdlineP and others. */
+
+    free(option_def);
+
+    if (argc-1 == 0)
+        cmdlineP->inFileName = "-";
+    else if (argc-1 != 1) {
+        pm_error("Program takes zero or one argument (filename).  You "
+                 "specified %d", argc-1);
+    }
+    else
+        cmdlineP->inFileName = argv[1];
+
+    if (!outfileSpec)
+        cmdlineP->outfile = "-";
+}
+
 
-#define VPRINTF if (verbose || header) fprintf
 
-typedef unsigned char U_CHAR;
-/*
- * Global variables.
- */
-static FILE    *fp;
-static rle_hdr hdr;
-static int  format;
-static int width, height;
-static int verbose = 0, header = 0, do_alpha = 0;
-static gray    maxval;
-/*-----------------------------------------------------------------------------
- *                                        Read the pnm image file header.
- */
 static void
-read_pnm_header(void) {
+readPnmHeader(bool      const verbose,
+              bool      const wantAlpha,
+              FILE    * const ifP,
+              int     * const widthP,
+              int     * const heightP,
+              gray    * const maxvalP,
+              int     * const formatP) {
+/*-----------------------------------------------------------------------------
+  Read the pnm image file header.
+---------------------------------------------------------------------------- */
+    int   width;
+    int   height;
+    gray  maxval;
+    int   format;
+    const char * type;
+
+    pnm_readpnminit(ifP, &width, &height, &maxval, &format);
 
-    pnm_readpnminit(fp, &width, &height, &maxval, &format);
     switch (format) {
     case PBM_FORMAT:
-        VPRINTF(stderr, "Image type: plain pbm format\n");
+        type="plain pbm";
         break;
     case RPBM_FORMAT:
-        VPRINTF(stderr, "Image type: raw pbm format\n");
+        type="raw pbm";
         break;
     case PGM_FORMAT:
-        VPRINTF(stderr, "Image type: plain pgm format\n");
+        type="plain pgm";
         break;
     case RPGM_FORMAT:
-        VPRINTF(stderr, "Image type: raw pgm format\n");
+        type="raw pgm";
         break;
     case PPM_FORMAT:
-        VPRINTF(stderr, "Image type: plain ppm format\n");
+        type="plain ppm";
         break;
     case RPPM_FORMAT:
-        VPRINTF(stderr, "Image type: raw ppm format\n");
+        type="raw ppm";
         break;
     }
-    VPRINTF(stderr, "Full image: %dx%d\n", width, height);
-    VPRINTF(stderr, "Maxval:     %d\n", maxval);
-    if (do_alpha)
-        VPRINTF(stderr, "Computing alpha channel...\n");
+    if (verbose) {
+        pm_message("Image type: %s format", type);
+        pm_message("Full image: %dx%d", width, height);
+        pm_message("Maxval:     %d", maxval);
+
+        if (wantAlpha)
+            pm_message("Computing alpha channel...");
+    }
+    *widthP  = width;
+    *heightP = height;
+    *maxvalP = maxval;
+    *formatP = format;
 }
 
 
 
 static void
-write_rle_header(void) {
+writeRleHeader(bool         const wantAlpha,
+               int          const format,
+               unsigned int const width,
+               unsigned int const height,
+               rle_hdr *    const hdrP) {
+
+    rle_hdr hdr;
+
+    hdr = *hdrP;  /* initial value */
 
     hdr.xmin    = 0;
     hdr.xmax    = width-1;
     hdr.ymin    = 0;
     hdr.ymax    = height-1;
     hdr.background = 0;
+
     switch (format) {
     case PBM_FORMAT:
     case RPBM_FORMAT:
@@ -114,31 +200,42 @@ write_rle_header(void) {
         RLE_SET_BIT(hdr, RLE_BLUE);
         break;
     }
-    if (do_alpha) {
+    if (wantAlpha) {
         hdr.alpha = 1;
         RLE_SET_BIT(hdr, RLE_ALPHA);
     }
     rle_put_setup(&hdr);
+
+    *hdrP = hdr;
 }
 
 
 
 static void
-write_rle_data(void) {
+writeRleData(bool         const verbose,
+             bool         const wantAlpha,
+             FILE      *  const ifP,
+             rle_hdr   *  const hdrP,
+             unsigned int const width,
+             unsigned int const height,
+             gray         const maxval,
+             int          const format) {
 
     unsigned int scan;
     xel * xelrow;
     rle_pixel *** scanlines;
 
     MALLOCARRAY(xelrow, width);
-    MALLOCARRAY(scanlines, height);
+    if (xelrow == NULL)
+        pm_error("Failed to allocate memory for row of %u pixels", width);
 
-    if (!scanlines)
+    MALLOCARRAY(scanlines, height);
+    if (scanlines == NULL)
         pm_error("Failed to allocate memory for %u scanline pointers", height);
 
     for (scan = 0; scan < height; ++scan) {
         int rc;
-        rc = rle_row_alloc(&hdr, &scanlines[scan]);
+        rc = rle_row_alloc(hdrP, &scanlines[scan]);
         if (rc < 0)
             pm_error("Failed to allocate memory for a scanline");
     }
@@ -151,10 +248,10 @@ write_rle_data(void) {
         for (scan = 0; scan < height; ++scan) {
             rle_pixel ** const scanline = scanlines[height - scan - 1];
             unsigned int col;
-            pnm_readpnmrow(fp, xelrow, width, maxval, format);
+            pnm_readpnmrow(ifP, xelrow, width, maxval, format);
             for (col = 0; col < width; ++col) {
                 scanline[RLE_RED][col] = PNM_GET1(xelrow[col]) ? 255 : 0;
-                if (do_alpha)
+                if (wantAlpha)
                     scanline[RLE_ALPHA][col] = scanline[RLE_RED][col];
             }
         }
@@ -165,10 +262,10 @@ write_rle_data(void) {
         for (scan = 0; scan < height; ++scan) {
             rle_pixel ** const scanline = scanlines[height - scan - 1];
             unsigned int col;
-            pnm_readpnmrow(fp, xelrow, width, maxval, format);
+            pnm_readpnmrow(ifP, xelrow, width, maxval, format);
             for (col = 0; col < width; ++col) {
                 scanline[RLE_RED][col] = PNM_GET1(xelrow[col]);
-                if (do_alpha)
+                if (wantAlpha)
                     scanline[RLE_ALPHA][col] =
                         scanline[RLE_RED][col] ? 255 : 0;
             }
@@ -179,13 +276,16 @@ write_rle_data(void) {
         unsigned int scan;
         for (scan = 0; scan < height; scan++) {
             rle_pixel ** const scanline = scanlines[height - scan - 1];
+
             unsigned int col;
-            pnm_readpnmrow(fp, xelrow, width, maxval, format);
+
+            pnm_readpnmrow(ifP, xelrow, width, maxval, format);
+
             for (col = 0; col < width; ++col) {
                 scanline[RLE_RED][col]   = PPM_GETR(xelrow[col]);
                 scanline[RLE_GREEN][col] = PPM_GETG(xelrow[col]);
                 scanline[RLE_BLUE][col]  = PPM_GETB(xelrow[col]);
-                if (do_alpha)
+                if (wantAlpha)
                     scanline[RLE_ALPHA][col] =
                         (scanline[RLE_RED][col] ||
                          scanline[RLE_GREEN][col] ||
@@ -196,25 +296,27 @@ write_rle_data(void) {
     }
     /* Write out data in URT order (bottom to top). */
     for (scan = 0; scan < height; ++scan)
-        rle_putrow(scanlines[scan], width, &hdr);
+        rle_putrow(scanlines[scan], width, hdrP);
 
     for (scan = 0; scan < height; ++scan)
-        rle_row_free(&hdr, scanlines[scan]);
+        rle_row_free(hdrP, scanlines[scan]);
     free(scanlines);
     free(xelrow);
 
-    VPRINTF(stderr, "Done -- write eof to RLE data.\n");
-    rle_puteof(&hdr);
+    if (verbose)
+        pm_message("Done -- write eof to RLE data.");
+
+    rle_puteof(hdrP);
 }
 
 
 
 static void
-skip_data(FILE      * const fp,
-          int         const width,
-          int         const height,
-          gray        const maxval,
-          int         const format) {
+skipData(FILE      *  const ifP,
+         unsigned int const width,
+         unsigned int const height,
+         gray         const maxval,
+         int          const format) {
 
     xel * xelrow;
     unsigned int scan;
@@ -223,8 +325,8 @@ skip_data(FILE      * const fp,
     if (xelrow == NULL)
         pm_error("Failed to allocate memory for row of %u pixels", width);
 
-    for(scan=0; scan < height; ++scan)
-        pnm_readpnmrow(fp, xelrow, width, maxval, format);
+    for (scan=0; scan < height; ++scan)
+        pnm_readpnmrow(ifP, xelrow, width, maxval, format);
 
     free(xelrow);
 }
@@ -232,57 +334,57 @@ skip_data(FILE      * const fp,
 
 
 int
-main(int argc, char **  argv) {
-
-    const char * pnmname;
-    const char * outname;
-    int oflag;
+main(int argc, char ** argv) {
+
+    struct CmdlineInfo cmdline;
+
+    FILE   * ifP;
+    rle_hdr hdr;
+    int  format;
+    int  width, height;
+    gray maxval;
+    bool verbose;
+    const char ** argvWork;
+    unsigned int i;
     int eof;
 
-    pnm_init(&argc, argv);
-
-    pnmname = NULL;  /* initial value */
-    outname = NULL;  /* initial value */
-
-    /* Get those options. */
-    if (!scanargs(argc,argv,
-                  "% v%- h%- a%- o%-outfile!s pnmfile%s\n(\
-\tConvert a PNM file to URT RLE format.\n\
-\t-a\tFake an alpha channel.  Alpha=0 when input=0, 255 otherwise.\n\
-\t-h\tPrint header of PNM file and exit.\n\
-\t-v\tVerbose mode.)",
-                  &verbose,
-                  &header,
-                  &do_alpha,
-                  &oflag, &outname,
-                  &pnmname))
-        exit(-1);
+    MALLOCARRAY_NOFAIL(argvWork, argc + 1);
+
+    for (i = 0; i < argc; ++i)  /* Make a copy of argv */
+        argvWork[i] = argv[i];
+
+    pm_proginit(&argc, argvWork);
+
+    parseCommandLine(argc, argvWork, &cmdline);
+
+    verbose = cmdline.verbose || cmdline.header;
 
     hdr = *rle_hdr_init(NULL);
-    rle_names(&hdr, cmd_name(argv), outname, 0);
+
+    rle_names(&hdr, "pnmtorle", cmdline.outfile, 0);
 
     /* Open the file. */
-    if (pnmname == NULL) {
-        fp = pm_openr("-");
-    } else {
-        fp = pm_openr(pnmname);
-    }
+    assert(cmdline.inFileName != NULL);
+    ifP = pm_openr(cmdline.inFileName);
 
-    hdr.rle_file = rle_open_f( hdr.cmd, outname, "wb" );
+    hdr.rle_file = rle_open_f(hdr.cmd, cmdline.outfile, "wb");
 
     for (eof = 0; !eof; ) {
-        read_pnm_header();
+        readPnmHeader(verbose, cmdline.alpha, ifP,
+                      &width, &height, &maxval, &format);
 
-        if (header)
-            skip_data(fp, width, height, maxval, format);
-        else {
+        if (cmdline.header) {
+            skipData(ifP, width, height, maxval, format);
+        } else {
             rle_addhist(argv, NULL, &hdr);
-            write_rle_header();
-            write_rle_data();
+            writeRleHeader(cmdline.alpha, format, width, height, &hdr);
+            writeRleData(verbose, cmdline.alpha, ifP, &hdr,
+                         width, height, maxval, format);
         }
-        pnm_nextimage(fp, &eof);
+        pnm_nextimage(ifP, &eof);
     }
-    pm_close(fp);
+
+    pm_close(ifP);
 
     return 0;
 }
diff --git a/converter/other/pnmtosir.c b/converter/other/pnmtosir.c
index 20bb6178..7b7650fe 100644
--- a/converter/other/pnmtosir.c
+++ b/converter/other/pnmtosir.c
@@ -20,16 +20,16 @@
 
 int
 main(int argc, const char * argv[]) {
-    
+
     FILE * ifP;
     xel ** xels;
     int rows, cols, format;
     unsigned int n;
     bool isGrayscale;
     xelval maxval;
-    unsigned short Header[16];
-    unsigned short LutHeader[16];
-    unsigned short Lut[2048];
+    unsigned short Header[10];
+    unsigned short LutHeader[5];
+    unsigned short Lut[1024];
 
     pm_proginit(&argc, argv);
 
@@ -43,9 +43,9 @@ main(int argc, const char * argv[]) {
     }  else {
         ifP = stdin;
     }
-    
+
     xels = pnm_readpnm(ifP, &cols, &rows, &maxval, &format);
-    
+
     /* Figure out the colormap. */
     switch (PNM_FORMAT_TYPE(format) ) {
     case PPM_TYPE:
@@ -93,15 +93,19 @@ main(int argc, const char * argv[]) {
         pm_writelittleshort(stdout,LutHeader[n]);
     for (n = 5; n < 256; ++n)
         pm_writelittleshort(stdout,0);
- 
-    for (n = 0; n < 3; ++n) {
+
+    for (n = 0; n < 256; ++n) {
         unsigned int m;
-        for (m = 0; m < 256; ++m)
-            Lut[m * 4 + n] = m << 8;
+        for (m = 0; m < 3; ++m)
+            Lut[n * 4 + m] = n << 8;
+
+        Lut[n * 4 + 3] = 0;
+            /* Clear to ensure repeatable output, suppress Valgrind error */
     }
+
     for (n = 0; n < 1024; ++n)
         pm_writelittleshort(stdout,Lut[n]);
- 
+
     /* Finally, write out the data. */
     switch (PNM_FORMAT_TYPE(format)) {
     case PPM_TYPE: {
@@ -110,13 +114,13 @@ main(int argc, const char * argv[]) {
             unsigned int col;
             for (col = 0; col < cols; ++col) {
                 unsigned char const ub =
-                    (char) (PPM_GETR(xels[row][col]) * (255 / maxval)); 
+                    (char) (PPM_GETR(xels[row][col]) * (255 / maxval));
                 fputc(ub, stdout);
             }
         }
         for (row = 0; row < rows; ++row) {
             unsigned int col;
-            for (col = 0; col < cols; ++col) {  
+            for (col = 0; col < cols; ++col) {
                 unsigned const char ub =
                     (char) (PPM_GETG(xels[row][col]) * (255 / maxval));
                 fputc(ub, stdout);
@@ -124,7 +128,7 @@ main(int argc, const char * argv[]) {
         }
         for (row = 0; row < rows; ++row) {
             unsigned int col;
-            for (col = 0; col < cols; ++col) {  
+            for (col = 0; col < cols; ++col) {
                 unsigned const char ub =
                     (char) (PPM_GETB(xels[row][col]) * (255 / maxval));
                 fputc(ub, stdout);
@@ -144,10 +148,11 @@ main(int argc, const char * argv[]) {
         }
     } break;
     }
-    
+
     pm_close(ifP);
 
     return 0;
 }
 
 
+