about summary refs log tree commit diff
path: root/converter/ppm
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2008-03-26 17:12:57 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2008-03-26 17:12:57 +0000
commitd1888145c840aff23c816de708e28b14c74d2976 (patch)
tree3ab3306e05156665f756cb6fe2de11c38b6bf962 /converter/ppm
parent9c6fe598ae9fff42dd705caa656d5dc4d712f667 (diff)
downloadnetpbm-mirror-d1888145c840aff23c816de708e28b14c74d2976.tar.gz
netpbm-mirror-d1888145c840aff23c816de708e28b14c74d2976.tar.xz
netpbm-mirror-d1888145c840aff23c816de708e28b14c74d2976.zip
Rebase to Release 10.42
git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@603 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/ppm')
-rw-r--r--converter/ppm/ppmtoarbtxt.c495
-rw-r--r--converter/ppm/ppmtompeg/combine.c6
-rw-r--r--converter/ppm/ppmtompeg/gethostname_win32.c96
-rw-r--r--converter/ppm/ppmtompeg/headers/byteorder.h2
-rw-r--r--converter/ppm/ppmtompeg/headers/frames.h2
-rw-r--r--converter/ppm/ppmtompeg/headers/parallel.h2
-rw-r--r--converter/ppm/ppmtompeg/iframe.c16
-rw-r--r--converter/ppm/ppmtompeg/mpeg.c4
-rw-r--r--converter/ppm/ppmtompeg/noparallel.c3
-rw-r--r--converter/ppm/ppmtompeg/parallel.c10
-rw-r--r--converter/ppm/ppmtompeg/ppmtompeg.c1
-rw-r--r--converter/ppm/ppmtompeg/rate.c1
-rw-r--r--converter/ppm/rawtoppm.c418
13 files changed, 569 insertions, 487 deletions
diff --git a/converter/ppm/ppmtoarbtxt.c b/converter/ppm/ppmtoarbtxt.c
index be78040e..9817f183 100644
--- a/converter/ppm/ppmtoarbtxt.c
+++ b/converter/ppm/ppmtoarbtxt.c
@@ -24,6 +24,10 @@ typedef enum {
     WIDTH, HEIGHT, POSX, POSY
 } SKL_OBJ_TYP;
 
+typedef enum {
+    OBJTYP_ICOLOR, OBJTYP_FCOLOR, OBJTYP_INT, OBJTYP_BDATA
+} SKL_OBJ_CLASS;
+
 /* Maximum size for a format string ("%d" etc.) */
 #define MAXFORMAT 16
 
@@ -158,257 +162,330 @@ save_bin_data(int    const ndat,
 
 
 
+static SKL_OBJ *
+save_icol_data(SKL_OBJ_TYP  const ctyp,
+               const char * const format,
+               int          const icolmin,
+               int          const icolmax) {
 /* Save integer color data in Object */
-static SKL_OBJ *save_icol_data (ctyp,format,icolmin,icolmax)
-SKL_OBJ_TYP ctyp;
-char *format;
-int icolmin, icolmax;
 
-{SKL_OBJ *obj;
+    SKL_OBJ * objP;
 
- obj = (SKL_OBJ *)malloc (sizeof (SKL_OBJ));
- if (obj != NULL)
- {
-   obj->otyp = ctyp;
-   strcpy (obj->odata.icol_data.icformat,format);
-   obj->odata.icol_data.icolmin = icolmin;
-   obj->odata.icol_data.icolmax = icolmax;
- }
- return (obj);
+    MALLOCVAR(objP);
+
+    if (objP) {
+        objP->otyp = ctyp;
+        strcpy(objP->odata.icol_data.icformat, format);
+        objP->odata.icol_data.icolmin = icolmin;
+        objP->odata.icol_data.icolmax = icolmax;
+    }
+    return objP;
 }
 
 
+
+static SKL_OBJ *
+save_fcol_data(SKL_OBJ_TYP  const ctyp,
+               const char * const format,
+               double       const fcolmin,
+               double       const fcolmax) {
 /* Save float color data in Object */
-static SKL_OBJ *save_fcol_data (ctyp,format,fcolmin,fcolmax)
-SKL_OBJ_TYP ctyp;
-char *format;
-double fcolmin, fcolmax;
 
-{SKL_OBJ *obj;
+    SKL_OBJ * objP;
 
- obj = (SKL_OBJ *)malloc (sizeof (SKL_OBJ));
- if (obj != NULL)
- {
-   obj->otyp = ctyp;
-   strcpy (obj->odata.fcol_data.fcformat,format);
-   obj->odata.fcol_data.fcolmin = fcolmin;
-   obj->odata.fcol_data.fcolmax = fcolmax;
- }
- return (obj);
+    MALLOCVAR(objP);
+
+    if (objP) {
+        objP->otyp = ctyp;
+        strcpy(objP->odata.fcol_data.fcformat, format);
+        objP->odata.fcol_data.fcolmin = fcolmin;
+        objP->odata.fcol_data.fcolmax = fcolmax;
+    }
+    return objP;
 }
 
 
+
+static SKL_OBJ *
+save_i_data(SKL_OBJ_TYP  const ctyp,
+            const char * const format) {
+
 /* Save universal data in Object */
-static SKL_OBJ *save_i_data (ctyp,format)
-SKL_OBJ_TYP ctyp;
-char *format;
 
-{SKL_OBJ *obj;
+    SKL_OBJ * objP;
 
- obj = (SKL_OBJ *)malloc (sizeof (SKL_OBJ));
- if (obj != NULL)
- {
-   obj->otyp = ctyp;
-   strcpy (obj->odata.i_data.iformat,format);
- }
- return (obj);
+    MALLOCVAR(objP);
+    if (objP) {
+        objP->otyp = ctyp;
+        strcpy(objP->odata.i_data.iformat, format);
+    }
+    return objP;
 }
 
 
-/* Read skeleton file */
-static int read_skeleton (filename,maxskl,nskl,skl)
-char *filename;
-int maxskl,*nskl;
-SKL_OBJ **skl;
 
-{FILE *sklfile;
- int slen, objlen, chr, n_odata;
- int icolmin,icolmax;
- double fcolmin,fcolmax;
- SKL_OBJ_TYP otyp;
- char line[MAX_LINE_BUF+MAX_OBJ_BUF+16];
- char objstr[MAX_OBJ_BUF],typstr[MAX_OBJ_BUF];
- char formstr[MAX_OBJ_BUF];
- char meta1 = '#', meta2 = '(', meta3 = ')';
+static char const escape = '#';
 
-#define SAVE_BIN(slen,line) \
- { if ((skl[*nskl] = save_bin_data (slen,line)) != NULL) (*nskl)++; \
-   slen = 0; }
 
-#define ADD_STR(slen,line,addlen,addstr) \
- {int count=0; line[slen++] = meta1; line[slen++] = meta2; \
-  while (count++ < addlen) line[slen++] = addstr[count]; }
 
- if ((sklfile = fopen (filename,"r")) == NULL)
-   return (-1);
+static SKL_OBJ_TYP
+interpretObjType(const char * const typstr) {
 
- /* Parse skeleton file */
- *nskl = 0;
+    SKL_OBJ_TYP otyp;
 
- slen = 0;
- while ((chr = getc (sklfile)) != EOF)   /* Up to end of skeleton file */
- {
-   if (*nskl >= maxskl) return (-1);
+    /* Check for integer colors */
+    if      (streq(typstr, "ired")  ) otyp = IRED;
+    else if (streq(typstr, "igreen")) otyp = IGREEN;
+    else if (streq(typstr, "iblue") ) otyp = IBLUE;
+    else if (streq(typstr, "ilum")  ) otyp = ILUM;
+    /* Check for real colors */
+    else if (streq(typstr, "fred")  ) otyp = FRED;
+    else if (streq(typstr, "fgreen")) otyp = FGREEN;
+    else if (streq(typstr, "fblue") ) otyp = FBLUE;
+    else if (streq(typstr, "flum")  ) otyp = FLUM;
+    /* Check for integer data */
+    else if (streq(typstr, "width") ) otyp = WIDTH;
+    else if (streq(typstr, "height")) otyp = HEIGHT;
+    else if (streq(typstr, "posx")  ) otyp = POSX;
+    else if (streq(typstr, "posy")  ) otyp = POSY;
+    else                              otyp = BDATA;
 
-   if (slen+1 >= MAX_LINE_BUF)   /* Buffer finished ? Save as binary object */
-   {
-     SAVE_BIN (slen,line);
-   }
+    return otyp;
+}
 
-   if (chr != meta1)      /* Look for start of replacement string */
-   {
-     line[slen++] = chr;
-     continue;
-   }
 
-   if ((chr = getc (sklfile)) == EOF)
-   {
-     line[slen++] = meta1;
-     break;
-   }
-   if (chr != meta2) /* '(' ? Otherwise no replacement */
-   {
-     line[slen++] = meta1;
-     line[slen++] = chr;
-     continue;
-   }
 
-   objlen = 0;
-   for (;;)   /* Read replacement string up to ')' */
-   {
-     if (objlen == sizeof (objstr)-1) break; /* ')' not found */
-     if ((chr = getc (sklfile)) == EOF) break;
-     if (chr == meta3) break;
-     objstr[objlen++] = chr;
-   }
-   objstr[objlen] = '\0'; /* Now objstr keeps data without metas */
+static SKL_OBJ_CLASS
+objClass(SKL_OBJ_TYP const otyp) {
 
-   if (chr != meta3)    /* Object not found ? */
-   {
-     ADD_STR (slen,line,objlen,objstr);   /* Save what we already read */
-     if (chr == EOF) break;
-     continue;
-   }
+    switch (otyp) {
+    case IRED:
+    case IGREEN:
+    case IBLUE:
+    case ILUM:
+        return OBJTYP_ICOLOR;
 
-   typstr[0] = '\0';           /* Get typ of data */
-   sscanf (objstr,"%s",typstr);
-
-                   /* Check for integer colors */
-   if      (streq(typstr,"ired")  ) otyp = IRED;
-   else if (streq(typstr,"igreen")) otyp = IGREEN;
-   else if (streq(typstr,"iblue") ) otyp = IBLUE;
-   else if (streq(typstr,"ilum")  ) otyp = ILUM;
-                   /* Check for real colors */
-   else if (streq(typstr,"fred")  ) otyp = FRED;
-   else if (streq(typstr,"fgreen")) otyp = FGREEN;
-   else if (streq(typstr,"fblue") ) otyp = FBLUE;
-   else if (streq(typstr,"flum")  ) otyp = FLUM;
-                   /* Check for integer data */
-   else if (streq(typstr,"width") ) otyp = WIDTH;
-   else if (streq(typstr,"height")) otyp = HEIGHT;
-   else if (streq(typstr,"posx")  ) otyp = POSX;
-   else if (streq(typstr,"posy")  ) otyp = POSY;
-   else                                    otyp = BDATA;
-
-   if ((otyp == IRED) || (otyp == IGREEN) || (otyp == IBLUE) || (otyp == ILUM))
-   {
-     n_odata = sscanf (objstr,"%*s%s%d%d",formstr,&icolmin,&icolmax);
-
-     if (n_odata == EOF)  /* No arguments specified ? Use defaults */
-     {
-       strcpy (formstr,"%d"); icolmin = 0; icolmax = 255;
-     }
-     else if (n_odata != 3)  /* Wrong specification */
-     {
-       otyp = BDATA;
-     }
-   }
+    case FRED:
+    case FGREEN:
+    case FBLUE:
+    case FLUM:
+        return OBJTYP_FCOLOR;
 
-   if ((otyp == FRED) || (otyp == FGREEN) || (otyp == FBLUE) || (otyp == FLUM))
-   {
-     n_odata = sscanf (objstr,"%*s%s%lf%lf",formstr,&fcolmin,&fcolmax);
-
-     if (n_odata == EOF)  /* No arguments specified ? Use defaults */
-     {
-       strcpy (formstr,"%f"); fcolmin = 0.0; fcolmax = 1.0;
-     }
-     else if (n_odata != 3)  /* Wrong specification */
-     {
-       otyp = BDATA;
-     }
-   }
+    case WIDTH:
+    case HEIGHT:
+    case POSX:
+    case POSY:
+        return OBJTYP_INT;
+    case BDATA:
+        return OBJTYP_BDATA;
+    }
+    return 999; /* quiet compiler warning */
+}
 
-   if (   (otyp == WIDTH) || (otyp == HEIGHT)
-       || (otyp == POSX) || (otyp == POSY))
-   {
-     n_odata = sscanf (objstr,"%*s%s",formstr);
-
-     if (n_odata == EOF)  /* No arguments specified ? Use defaults */
-     {
-       strcpy (formstr,"%d");
-     }
-     else if (n_odata != 1)  /* Wrong specification */
-     {
-       otyp = BDATA;
-     }
-   }
 
-   if (otyp != BDATA)   /* Got an object definition ? */
-   {
-     if (slen > 0)      /* Save what we already found */
-     {
-       SAVE_BIN (slen,line);
-     }
-   }
 
-   /* Now process the object in objstr */
-   switch (otyp)
-   {
-     case BDATA:   /* Bad object definition ? Save as text */
-       ADD_STR (slen,line,objlen,objstr);
-       break;
+static void
+addImpostorReplacementSeq(char *         const line,
+                          unsigned int   const startCursor,
+                          const char *   const seqContents,
+                          unsigned int   const seqContentsLen,
+                          unsigned int * const newCursorP) {
+/*----------------------------------------------------------------------------
+   Add to line line[], at position 'startCursor', text that looks like a
+   replacement sequence but doesn't have the proper contents (the
+   stuff between the parentheses) to be one.  For example,
 
-     case IRED:
-     case IGREEN:
-     case IBLUE:
-     case ILUM:
-       skl[*nskl] = save_icol_data (otyp,formstr,icolmin,icolmax);
-       if (skl[*nskl] != NULL) (*nskl)++;
-       break;
+     "#(fread x)"
 
-     case FRED:
-     case FGREEN:
-     case FBLUE:
-     case FLUM:
-       skl[*nskl] = save_fcol_data (otyp,formstr,fcolmin,fcolmax);
-       if (skl[*nskl] != NULL) (*nskl)++;
-       break;
+   seqContents[] is the contents; 'seqContentsLen' its length.
 
-     case WIDTH:
-     case HEIGHT:
-     case POSX:
-     case POSY:
-       skl[*nskl] = save_i_data (otyp,formstr);
-       if (skl[*nskl] != NULL) (*nskl)++;
-       break;
-   }
- } /* EOF of skeleton file */
+   Return as *newCursorP where the line[] cursor ends up after adding
+   the sequence.
+-----------------------------------------------------------------------------*/
+    unsigned int cursor;
+    unsigned int i;
 
- if (slen > 0)      /* Drop finishing newline character */
- {
-   if (line[slen-1] == '\n') slen--;
- }
+    cursor = startCursor;
 
- if (slen > 0)      /* Something left ? */
- {
-   SAVE_BIN (slen,line);   /* Save it */
- }
+    line[cursor++] = escape;
+    line[cursor++] = '(';
 
- fclose (sklfile);
- return (0);
+    for (i = 0; i < seqContentsLen; ++i)
+        line[cursor++] = seqContents[i];
+
+    line[cursor++] = ')';
+
+    *newCursorP = cursor;
 }
 
 
+
+static int
+read_skeleton(const char *   const filename,
+              unsigned int   const maxskl,
+              unsigned int * const nsklP,
+              SKL_OBJ **     const skl) {
+/*----------------------------------------------------------------------------
+  Read skeleton file
+-----------------------------------------------------------------------------*/
+    FILE * sklfile;
+    unsigned int slen;
+    unsigned int objlen;
+    int chr;
+    SKL_OBJ_TYP otyp;
+    char line[MAX_LINE_BUF+MAX_OBJ_BUF+16];
+    char objstr[MAX_OBJ_BUF],typstr[MAX_OBJ_BUF];
+    unsigned int nskl;
+
+#define SAVE_BIN(slen,line) \
+    { if (slen > 0 && (skl[nskl] = save_bin_data(slen,line)) != NULL) ++nskl; \
+      slen = 0; }
+
+    sklfile = fopen(filename,"r");
+    if (sklfile == NULL)
+        return -1;
+
+    /* Parse skeleton file */
+    nskl = 0;  /* initial value */
+
+    slen = 0;
+    while ((chr = getc (sklfile)) != EOF) {  /* Up to end of skeleton file */
+        if (nskl >= maxskl)
+            return -1;
+
+        if (slen+1 >= MAX_LINE_BUF) {
+            /* Buffer finished.  Save as binary object */
+            SAVE_BIN(slen,line);
+        }
+
+        if (chr != escape) {
+            /* Not a replacement sequence; just a literal character */
+            line[slen++] = chr;
+            continue;
+        }
+
+        chr = getc(sklfile);
+        if (chr == EOF) {
+            /* Not a valid replacement sequence */
+            line[slen++] = escape;
+            break;
+        }
+        if (chr != '(') {
+            /* Not a valid replacement sequence */
+            line[slen++] = escape;
+            line[slen++] = chr;
+            continue;
+        }
+        /* Read replacement string up through ')'.  Put contents of
+           parentheses in objstr[].
+        */
+        for (objlen = 0; objlen < sizeof(objstr)-1; ++objlen) {
+            chr = getc(sklfile);
+            if (chr == EOF) break;
+            if (chr == ')') break;
+            objstr[objlen] = chr;
+        }
+        objstr[objlen] = '\0';
+
+        if (chr != ')') {
+            /* Not valid replacement sequence */
+            unsigned int i;
+            line[slen++] = escape;
+            line[slen++] = chr;
+            for (i = 0; i < objlen; ++i)
+                line[slen++] = objstr[i];
+            if (chr == EOF)
+                break;
+            continue;
+        }
+
+        typstr[0] = '\0';           /* Get typ of data */
+        sscanf(objstr, "%s", typstr);
+
+        otyp = interpretObjType(typstr);
+
+        switch (objClass(otyp)) {
+        case OBJTYP_ICOLOR: {
+            int icolmin, icolmax;
+            char formstr[MAX_OBJ_BUF];
+            int n_odata;
+
+            n_odata = sscanf(objstr, "%*s%s%d%d", formstr, &icolmin, &icolmax);
+
+            if (n_odata == 3) {
+                SAVE_BIN(slen, line);
+                skl[nskl] = save_icol_data(otyp, formstr, icolmin, icolmax);
+                if (skl[nskl] != NULL)
+                    ++nskl;
+            } else if (n_odata == EOF) {
+                /* No arguments specified.  Use defaults */
+                SAVE_BIN(slen, line);
+                skl[nskl] = save_icol_data(otyp, "%d", 0, 255);
+                if (skl[nskl] != NULL)
+                    ++nskl;
+            } else
+                addImpostorReplacementSeq(line, slen, objstr, objlen, &slen);
+        } break;
+        case OBJTYP_FCOLOR: {
+            double fcolmin, fcolmax;
+            char formstr[MAX_OBJ_BUF];
+            int n_odata;
+
+            n_odata = sscanf(objstr, "%*s%s%lf%lf", formstr,
+                             &fcolmin, &fcolmax);
+
+            if (n_odata == 3) {
+                SAVE_BIN(slen, line);
+                skl[nskl] = save_fcol_data(otyp, formstr, fcolmin, fcolmax);
+                if (skl[nskl] != NULL)
+                    ++nskl;
+            } else if (n_odata == EOF) {
+                /* No arguments specified.  Use defaults */
+                SAVE_BIN(slen, line);
+                skl[nskl] = save_fcol_data(otyp, "%f", 0.0, 1.0);
+                if (skl[nskl] != NULL)
+                    ++nskl;
+            } else
+                addImpostorReplacementSeq(line, slen, objstr, objlen, &slen);
+        } break;
+
+        case OBJTYP_INT: {
+            char formstr[MAX_OBJ_BUF];
+            int const n_odata = sscanf(objstr, "%*s%s", formstr);
+
+            if (n_odata == 1) {
+                SAVE_BIN(slen, line);
+                skl[nskl] = save_i_data(otyp, formstr);
+                if (skl[nskl] != NULL)
+                    ++nskl;
+            } else if (n_odata == EOF) {
+                /* No arguments specified.  Use defaults */
+                SAVE_BIN(slen, line);
+                skl[nskl] = save_i_data(otyp, "%d");
+                if (skl[nskl] != NULL)
+                    ++nskl;
+            } else
+                addImpostorReplacementSeq(line, slen, objstr, objlen, &slen);
+        } break;
+        case OBJTYP_BDATA:
+            addImpostorReplacementSeq(line, slen, objstr, objlen, &slen);
+        }
+    } /* EOF of skeleton file */
+
+    if (slen >= 1 && line[slen-1] == '\n')
+        /* Drop finishing newline character */
+        --slen;
+
+    SAVE_BIN(slen, line);  /* Save whatever is left */
+
+    *nsklP = nskl;
+
+    fclose(sklfile);
+    return 0;
+}
+
+
+
 int main( argc, argv )
 int argc;
 char* argv[];
@@ -419,7 +496,7 @@ char* argv[];
  pixval maxval,red,green,blue;
  double dmaxval;
  int argn, rows, cols, format, row;
- int head_nskl,body_nskl,tail_nskl;
+ unsigned int head_nskl,body_nskl,tail_nskl;
  SKL_OBJ *head_skl[MAX_SKL_HEAD_OBJ];
  SKL_OBJ *body_skl[MAX_SKL_BODY_OBJ];
  SKL_OBJ *tail_skl[MAX_SKL_TAIL_OBJ];
diff --git a/converter/ppm/ppmtompeg/combine.c b/converter/ppm/ppmtompeg/combine.c
index 52cc646d..8e0d3281 100644
--- a/converter/ppm/ppmtompeg/combine.c
+++ b/converter/ppm/ppmtompeg/combine.c
@@ -35,8 +35,8 @@
 #include <errno.h>
 #include <unistd.h>
 
-#include "ppm.h"
 #include "nstring.h"
+#include "nsleep.h"
 
 #include "mtypes.h"
 #include "frames.h"
@@ -111,11 +111,9 @@ appendSpecifiedGopFiles(struct inputSource * const inputSourceP,
              ++nAttempts) {
 
             ifP = fopen(fileName, "rb");
-            if (ifP == NULL) {
+            if (ifP == NULL)
                 pm_message("ERROR:  Couldn't read file '%s'.  retry %u", 
                            fileName, nAttempts);
-                sleep(1);
-            }
         }
         if (ifP) {
             if (!realQuiet)
diff --git a/converter/ppm/ppmtompeg/gethostname_win32.c b/converter/ppm/ppmtompeg/gethostname_win32.c
index 56a8dbfc..383f4e55 100644
--- a/converter/ppm/ppmtompeg/gethostname_win32.c
+++ b/converter/ppm/ppmtompeg/gethostname_win32.c
@@ -1,5 +1,5 @@
-// define this macro for activating debugging version
-//#define GETHOSTNAME_LOCAL_DEBUG     1
+/* define this macro for activating debugging version */
+/* #define GETHOSTNAME_LOCAL_DEBUG     1*/
 
 #include <windows.h>
 #include <tchar.h>
@@ -21,7 +21,7 @@ typedef struct {
 } push_string_t;
 
 static void
-pushString(push_string_t *p, char *fmt, ...)
+pushString(push_string_t *p, const char *fmt, ...)
 {
     va_list args;
 
@@ -37,36 +37,36 @@ pushString(push_string_t *p, char *fmt, ...)
  * GetProductInfo() Function
  * http://msdn2.microsoft.com/en-us/library/ms724358.aspx
  */
-#define PRODUCT_BUSINESS                        0x00000006  // Business Edition
-#define PRODUCT_BUSINESS_N                      0x00000010  // Business Edition
-#define PRODUCT_CLUSTER_SERVER                  0x00000012  // Cluster Server Edition
-#define PRODUCT_DATACENTER_SERVER               0x00000008  // Server Datacenter Edition (full installation)
-#define PRODUCT_DATACENTER_SERVER_CORE          0x0000000C  // Server Datacenter Edition (core installation)
-#define PRODUCT_ENTERPRISE                      0x00000004  // Enterprise Edition
-#define PRODUCT_ENTERPRISE_N                    0x0000001B  // Enterprise Edition
-#define PRODUCT_ENTERPRISE_SERVER               0x0000000A  // Server Enterprise Edition (full installation)
-#define PRODUCT_ENTERPRISE_SERVER_CORE          0x0000000E  // Server Enterprise Edition (core installation)
-#define PRODUCT_ENTERPRISE_SERVER_IA64          0x0000000F  // Server Enterprise Edition for Itanium-based Systems
-#define PRODUCT_HOME_BASIC                      0x00000002  // Home Basic Edition
-#define PRODUCT_HOME_BASIC_N                    0x00000005  // Home Basic Edition
-#define PRODUCT_HOME_PREMIUM                    0x00000003  // Home Premium Edition
-#define PRODUCT_HOME_PREMIUM_N                  0x0000001A  // Home Premium Edition
-#define PRODUCT_HOME_SERVER                     0x00000013  // Home Server Edition
-#define PRODUCT_SERVER_FOR_SMALLBUSINESS        0x00000018  // Server for Small Business Edition
-#define PRODUCT_SMALLBUSINESS_SERVER            0x00000009  // Small Business Server
-#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM    0x00000019  // Small Business Server Premium Edition
-#define PRODUCT_STANDARD_SERVER                 0x00000007  // Server Standard Edition (full installation)
-#define PRODUCT_STANDARD_SERVER_CORE            0x0000000D  // Server Standard Edition (core installation)
-#define PRODUCT_STARTER                         0x0000000B  // Starter Edition
-#define PRODUCT_STORAGE_ENTERPRISE_SERVER       0x00000017  // Storage Server Enterprise Edition
-#define PRODUCT_STORAGE_EXPRESS_SERVER          0x00000014  // Storage Server Express Edition
-#define PRODUCT_STORAGE_STANDARD_SERVER         0x00000015  // Storage Server Standard Edition
-#define PRODUCT_STORAGE_WORKGROUP_SERVER        0x00000016  // Storage Server Workgroup Edition
-#define PRODUCT_UNDEFINED                       0x00000000  // An unknown product
-#define PRODUCT_ULTIMATE                        0x00000001  // Ultimate Edition
-#define PRODUCT_ULTIMATE_N                      0x0000001C  // Ultimate Edition
-#define PRODUCT_WEB_SERVER                      0x00000011  // Web Server Edition (full installation)
-#define PRODUCT_WEB_SERVER_CORE                 0x0000001D  // Web Server Edition (core installation)
+#define PRODUCT_BUSINESS                        0x00000006  /* Business Edition */
+#define PRODUCT_BUSINESS_N                      0x00000010  /* Business Edition */
+#define PRODUCT_CLUSTER_SERVER                  0x00000012  /* Cluster Server Edition */
+#define PRODUCT_DATACENTER_SERVER               0x00000008  /* Server Datacenter Edition (full installation) */
+#define PRODUCT_DATACENTER_SERVER_CORE          0x0000000C  /* Server Datacenter Edition (core installation) */
+#define PRODUCT_ENTERPRISE                      0x00000004  /* Enterprise Edition */
+#define PRODUCT_ENTERPRISE_N                    0x0000001B  /* Enterprise Edition */
+#define PRODUCT_ENTERPRISE_SERVER               0x0000000A  /* Server Enterprise Edition (full installation) */
+#define PRODUCT_ENTERPRISE_SERVER_CORE          0x0000000E  /* Server Enterprise Edition (core installation) */
+#define PRODUCT_ENTERPRISE_SERVER_IA64          0x0000000F  /* Server Enterprise Edition for Itanium-based Systems */
+#define PRODUCT_HOME_BASIC                      0x00000002  /* Home Basic Edition */
+#define PRODUCT_HOME_BASIC_N                    0x00000005  /* Home Basic Edition */
+#define PRODUCT_HOME_PREMIUM                    0x00000003  /* Home Premium Edition */
+#define PRODUCT_HOME_PREMIUM_N                  0x0000001A  /* Home Premium Edition */
+#define PRODUCT_HOME_SERVER                     0x00000013  /* Home Server Edition */
+#define PRODUCT_SERVER_FOR_SMALLBUSINESS        0x00000018  /* Server for Small Business Edition */
+#define PRODUCT_SMALLBUSINESS_SERVER            0x00000009  /* Small Business Server */
+#define PRODUCT_SMALLBUSINESS_SERVER_PREMIUM    0x00000019  /* Small Business Server Premium Edition */
+#define PRODUCT_STANDARD_SERVER                 0x00000007  /* Server Standard Edition (full installation) */
+#define PRODUCT_STANDARD_SERVER_CORE            0x0000000D  /* Server Standard Edition (core installation) */
+#define PRODUCT_STARTER                         0x0000000B  /* Starter Edition */
+#define PRODUCT_STORAGE_ENTERPRISE_SERVER       0x00000017  /* Storage Server Enterprise Edition */
+#define PRODUCT_STORAGE_EXPRESS_SERVER          0x00000014  /* Storage Server Express Edition */
+#define PRODUCT_STORAGE_STANDARD_SERVER         0x00000015  /* Storage Server Standard Edition */
+#define PRODUCT_STORAGE_WORKGROUP_SERVER        0x00000016  /* Storage Server Workgroup Edition */
+#define PRODUCT_UNDEFINED                       0x00000000  /* An unknown product */
+#define PRODUCT_ULTIMATE                        0x00000001  /* Ultimate Edition */
+#define PRODUCT_ULTIMATE_N                      0x0000001C  /* Ultimate Edition */
+#define PRODUCT_WEB_SERVER                      0x00000011  /* Web Server Edition (full installation) */
+#define PRODUCT_WEB_SERVER_CORE                 0x0000001D  /* Web Server Edition (core installation) */
 #endif
 
 static BOOL
@@ -82,8 +82,10 @@ get_string_version(push_string_t *str)
     ZeroMemory(&si, sizeof(SYSTEM_INFO));
     ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
 
-    // Try calling GetVersionEx using the OSVERSIONINFOEX structure.
-    // If that fails, try using the OSVERSIONINFO structure.
+    /*
+     * Try calling GetVersionEx using the OSVERSIONINFOEX structure.
+     * If that fails, try using the OSVERSIONINFO structure.
+     */
     osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
     if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
     {
@@ -92,7 +94,7 @@ get_string_version(push_string_t *str)
             return FALSE;
     }
 
-    // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
+    /* Call GetNativeSystemInfo if supported or GetSystemInfo otherwise. */
     pGNSI = (PGNSI)
             GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), 
             "GetNativeSystemInfo");
@@ -103,9 +105,9 @@ get_string_version(push_string_t *str)
 
     switch (osvi.dwPlatformId)
     {
-    // Test for the Windows NT product family.
+    /* Test for the Windows NT product family. */
     case VER_PLATFORM_WIN32_NT:
-        // Test for the specific product.
+        /* Test for the specific product. */
         if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0)
         {
             if (osvi.wProductType == VER_NT_WORKSTATION)
@@ -196,7 +198,7 @@ get_string_version(push_string_t *str)
             else
                 pushString(str, "Microsoft Windows Server 2003, ");
 
-            // Test for the server type.
+            /* Test for the server type. */
             if ( osvi.wProductType != VER_NT_WORKSTATION )
             {
                 switch (si.wProcessorArchitecture)
@@ -264,10 +266,10 @@ get_string_version(push_string_t *str)
         if ( osvi.dwMajorVersion <= 4 )
             pushString(str, "Microsoft Windows NT ");
 
-        // Test for specific product on Windows NT 4.0 SP6 and later.
+        /* Test for specific product on Windows NT 4.0 SP6 and later. */
         if (bOsVersionInfoEx)
         {
-            // Test for the workstation type.
+            /* Test for the workstation type. */
             switch (osvi.wProductType)
             {
             case VER_NT_WORKSTATION:
@@ -285,7 +287,7 @@ get_string_version(push_string_t *str)
                 break;
             }
         }
-        // Test for specific product on Windows NT 4.0 SP5 and earlier
+        /* Test for specific product on Windows NT 4.0 SP5 and earlier */
         else  
         {
             HKEY hKey;
@@ -318,31 +320,31 @@ get_string_version(push_string_t *str)
                 pushString(str, "%d.%d ", osvi.dwMajorVersion, osvi.dwMinorVersion);
         }
 
-        // Display service pack (if any) and build number.
+        /* Display service pack (if any) and build number. */
         if (osvi.dwMajorVersion == 4 && 
             lstrcmpi(osvi.szCSDVersion, TEXT("Service Pack 6")) == 0)
         { 
             HKEY hKey;
             LONG lRet;
 
-            // Test for SP6 versus SP6a.
+            /* Test for SP6 versus SP6a. */
             lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
                 TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009"),
                 0, KEY_QUERY_VALUE, &hKey );
             if( lRet == ERROR_SUCCESS )
                 pushString(str, "Service Pack 6a (Build %d)\n", osvi.dwBuildNumber & 0xFFFF );         
             else
-                // Windows NT 4.0 prior to SP6a
+                /* Windows NT 4.0 prior to SP6a */
                 pushString(str, "%s (Build %d)\n", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF);
 
              RegCloseKey( hKey );
         }
-        else // not Windows NT 4.0 
+        else /* not Windows NT 4.0 */
             pushString(str, "%s (Build %d)\n", osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF);
 
         break;
 
-    // Test for the Windows Me/98/95.
+    /* Test for the Windows Me/98/95. */
     case VER_PLATFORM_WIN32_WINDOWS:
         if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
         {
diff --git a/converter/ppm/ppmtompeg/headers/byteorder.h b/converter/ppm/ppmtompeg/headers/byteorder.h
index 0070252a..e2d8030c 100644
--- a/converter/ppm/ppmtompeg/headers/byteorder.h
+++ b/converter/ppm/ppmtompeg/headers/byteorder.h
@@ -72,6 +72,8 @@
 #else
     /* let in.h handle it, if possible */		   
 #include <sys/types.h>
+#if !defined(WIN32) || defined(__CYGWIN__)
 #include <netinet/in.h>
+#endif
 #endif /* FORCE_LITTLE_ENDIAN */
 #endif /* FORCE_BIG_ENDIAN */
diff --git a/converter/ppm/ppmtompeg/headers/frames.h b/converter/ppm/ppmtompeg/headers/frames.h
index 17820127..f2bcf6ae 100644
--- a/converter/ppm/ppmtompeg/headers/frames.h
+++ b/converter/ppm/ppmtompeg/headers/frames.h
@@ -255,7 +255,7 @@ extern int gopSize;
 extern int slicesPerFrame;
 extern int blocksPerSlice;
 extern int referenceFrame;
-extern int specificsOn;
+extern boolean specificsOn;
 extern int quietTime;       /* shut up for at least quietTime seconds;
                  * negative means shut up forever
                  */
diff --git a/converter/ppm/ppmtompeg/headers/parallel.h b/converter/ppm/ppmtompeg/headers/parallel.h
index cf27ce66..90edd874 100644
--- a/converter/ppm/ppmtompeg/headers/parallel.h
+++ b/converter/ppm/ppmtompeg/headers/parallel.h
@@ -87,7 +87,7 @@ void
 NoteFrameDone(int frameStart, int frameEnd);
 
 void
-SetIOConvert(bool const separate);
+SetIOConvert(boolean const separate);
 
 void
 SetRemoteShell(const char * const shell);
diff --git a/converter/ppm/ppmtompeg/iframe.c b/converter/ppm/ppmtompeg/iframe.c
index c6735505..7552f413 100644
--- a/converter/ppm/ppmtompeg/iframe.c
+++ b/converter/ppm/ppmtompeg/iframe.c
@@ -42,11 +42,11 @@
  * HEADER FILES *
  *==============*/
 
+#include <time.h>  /* Defines CLOCKS_PER_SEC, if this system has clock() */
 
-#ifdef CLOCKS_PER_SEC
-#include <times.h>
-#else
-#include <sys/times.h>
+#ifndef CLOCKS_PER_SEC
+  /* System doesn't have clock(); we assume it has times() instead */
+  #include <sys/times.h>
 #endif
 
 #include <sys/types.h>
@@ -72,8 +72,8 @@
  * STATIC VARIABLES *
  *==================*/
 
-static  int lastNumBits = 0;
-static  int lastIFrame = 0;
+static int lastNumBits = 0;
+static int lastIFrame = 0;
 static int numBlocks = 0;
 static int numBits;
 static int numFrames = 0;
@@ -979,7 +979,3 @@ int32 time_elapsed(void) {
     return timeBuffer.tms_utime + timeBuffer.tms_stime;
 #endif
 }
-
-
-
-
diff --git a/converter/ppm/ppmtompeg/mpeg.c b/converter/ppm/ppmtompeg/mpeg.c
index de662e88..6557f377 100644
--- a/converter/ppm/ppmtompeg/mpeg.c
+++ b/converter/ppm/ppmtompeg/mpeg.c
@@ -43,8 +43,8 @@
 #endif
 #include <sys/stat.h>
 
-#include "ppm.h"
 #include "nstring.h"
+#include "nsleep.h"
 
 #include "mtypes.h"
 #include "frames.h"
@@ -1680,7 +1680,7 @@ ReadDecodedRefFrame(MpegFrame *  const frameP,
     }
 
     if ((fpointer = fopen(fileName, "rb")) == NULL) {
-        sleep(1);
+        sleepN(1000);
         if ((fpointer = fopen(fileName, "rb")) == NULL) {
             fprintf(stderr, "Cannot open %s\n", fileName);
             exit(1);
diff --git a/converter/ppm/ppmtompeg/noparallel.c b/converter/ppm/ppmtompeg/noparallel.c
index 016e3c44..6e6449a4 100644
--- a/converter/ppm/ppmtompeg/noparallel.c
+++ b/converter/ppm/ppmtompeg/noparallel.c
@@ -163,7 +163,8 @@ MasterServer(struct inputSource * const inputSourceP,
 void
 CombineServer(int          const numFrames, 
               const char * const masterHostName, 
-              int          const masterPortNum) {
+              int          const masterPortNum,
+              const char*  const outputFileName) {
 
     pm_error("This version of Ppmtompeg cannot run combine server because "
              "it does not have socket capability.");
diff --git a/converter/ppm/ppmtompeg/parallel.c b/converter/ppm/ppmtompeg/parallel.c
index 021e6d2b..e13bf221 100644
--- a/converter/ppm/ppmtompeg/parallel.c
+++ b/converter/ppm/ppmtompeg/parallel.c
@@ -41,6 +41,7 @@
 
 #include "mallocvar.h"
 #include "nstring.h"
+#include "nsleep.h"
 
 #include "pm.h"
 
@@ -128,7 +129,7 @@ boolean niceProcesses = FALSE;
 boolean forceIalign = FALSE;
 int     machineNumber = -1;
 boolean remoteIO = FALSE;
-bool separateConversion;
+boolean separateConversion;
     /* The I/O server will convert from the input format to the base format,
        and the slave will convert from the base format to the YUV internal
        format.  If false, the I/O server assumes the input format is the
@@ -630,7 +631,7 @@ static int safe_fork(command)       /* fork child process and remember its PID *
  *
  *===========================================================================*/
 void
-SetIOConvert(bool const separate) {
+SetIOConvert(boolean const separate) {
     separateConversion = separate;
 }
 
@@ -648,8 +649,7 @@ SetIOConvert(bool const separate) {
  *
  *===========================================================================*/
 void
-SetParallelPerfect(val)
-boolean val;
+SetParallelPerfect(boolean val)
 {
     parallelPerfect = val;
 }
@@ -1209,7 +1209,7 @@ openInputFile(const char * const fileName,
             pm_message("ERROR  Couldn't read frame file '%s' errno = %d (%s)"
                        "attempt %d", 
                        fileName, errno, strerror(errno), attempts);
-            sleep(1);
+            sleepN(1000);
         }
         ++attempts;
     }
diff --git a/converter/ppm/ppmtompeg/ppmtompeg.c b/converter/ppm/ppmtompeg/ppmtompeg.c
index 2296e2cb..f4473e07 100644
--- a/converter/ppm/ppmtompeg/ppmtompeg.c
+++ b/converter/ppm/ppmtompeg/ppmtompeg.c
@@ -33,7 +33,6 @@
 #define _BSD_SOURCE   /* Make sure strdup() is in string.h */
 
 #include <assert.h>
-#include <sys/utsname.h>
 
 #include "all.h"
 #include "mtypes.h"
diff --git a/converter/ppm/ppmtompeg/rate.c b/converter/ppm/ppmtompeg/rate.c
index 3940956c..1a44cb95 100644
--- a/converter/ppm/ppmtompeg/rate.c
+++ b/converter/ppm/ppmtompeg/rate.c
@@ -50,7 +50,6 @@
 
 #include <assert.h>
 #include <sys/types.h>
-#include <sys/times.h>
 
 #include "ppm.h"
 #include "nstring.h"
diff --git a/converter/ppm/rawtoppm.c b/converter/ppm/rawtoppm.c
index 8d6c3b2c..44e856da 100644
--- a/converter/ppm/rawtoppm.c
+++ b/converter/ppm/rawtoppm.c
@@ -13,39 +13,148 @@
 #include <math.h>
 #include "ppm.h"
 
-static void dorowskip ARGS(( FILE* ifp, int rowskip ));
+enum order { ORD_RGB, ORD_RBG, ORD_GRB, ORD_GBR, ORD_BRG, ORD_BGR };
+
+enum interleave { INT_PIX, INT_ROW };
+
+static void
+dorowskip(FILE * const ifP,
+          int    const rowskip) {
+
+    unsigned int i;
+
+    for (i = 0; i < rowskip; ++i) {
+        int const val = getc(ifP);
+        if (val == EOF)
+            pm_error("EOF / read error");
+    }
+}
+
+
+
+static void
+doRowPixInterleave(pixel *      const pixrow,
+                   unsigned int const cols,
+                   FILE *       const ifP,
+                   enum order   const order,
+                   int          const rowskip) {
+
+    unsigned int col;
+
+    for (col = 0; col < cols; ++col) {
+        int const val1 = getc(ifP);
+        int const val2 = getc(ifP);
+        int const val3 = getc(ifP);
+
+        if (val1 == EOF)
+            pm_error("EOF / read error");
+        if (val2 == EOF)
+            pm_error("EOF / read error");
+        if (val3 == EOF)
+            pm_error("EOF / read error");
+
+        switch (order) {
+        case ORD_RGB:
+            PPM_ASSIGN(pixrow[col], val1, val2, val3);
+            break;
+        case ORD_RBG:
+            PPM_ASSIGN(pixrow[col], val1, val3, val2);
+            break;
+        case ORD_GRB:
+            PPM_ASSIGN(pixrow[col], val2, val1, val3);
+            break;
+        case ORD_GBR:
+            PPM_ASSIGN(pixrow[col], val3, val1, val2);
+            break;
+        case ORD_BRG:
+            PPM_ASSIGN(pixrow[col], val2, val3, val1);
+            break;
+        case ORD_BGR:
+            PPM_ASSIGN(pixrow[col], val3, val2, val1);
+            break;
+        }
+    }
+    dorowskip(ifP, rowskip);
+}
+
+
+
+static void
+doRowRowInterleave(pixel *      const pixrow,
+                   unsigned int const cols,
+                   FILE *       const ifP,
+                   enum order   const order,
+                   int          const rowskip,
+                   pixval *     const grow1,
+                   pixval *     const grow2,
+                   pixval *     const grow3) {
+
+    unsigned int col;
+
+    for (col = 0; col < cols; ++col) {
+        int const val1 = getc(ifP);
+        if (val1 == EOF)
+            pm_error("EOF / read error");
+        grow1[col] = val1;
+    }
+    dorowskip(ifP, rowskip);
+    for (col = 0; col < cols; ++col) {
+        int const val2 = getc(ifP);
+        if (val2 == EOF)
+            pm_error( "EOF / read error" );
+        grow2[col] = val2;
+    }
+    dorowskip(ifP, rowskip);
+    for (col = 0; col < cols; ++col) {
+        int const val3 = getc(ifP);
+        if (val3 == EOF)
+            pm_error( "EOF / read error" );
+        grow3[col] = val3;
+    }
+    dorowskip(ifP, rowskip);
+
+    for (col = 0; col < cols; ++col) {
+        switch (order) {
+        case ORD_RGB:
+            PPM_ASSIGN(pixrow[col], grow1[col], grow2[col], grow3[col]);
+            break;
+        case ORD_RBG:
+            PPM_ASSIGN(pixrow[col], grow1[col], grow3[col], grow2[col]);
+            break;
+        case ORD_GRB:
+            PPM_ASSIGN(pixrow[col], grow2[col], grow1[col], grow3[col]);
+            break;
+        case ORD_GBR:
+            PPM_ASSIGN(pixrow[col], grow3[col], grow1[col], grow2[col]);
+            break;
+        case ORD_BRG:
+            PPM_ASSIGN(pixrow[col], grow2[col], grow3[col], grow1[col]);
+            break;
+        case ORD_BGR:
+            PPM_ASSIGN(pixrow[col], grow3[col], grow2[col], grow1[col]);
+            break;
+        }
+    }
+}
+
+
 
 int
-main( argc, argv )
-    int argc;
-    char* argv[];
-    {
-    FILE* ifp;
-    pixel* pixrow;
-    register pixel* pP;
+main(int argc, const char * argv[]) {
+
+    pixval const maxval = 255;
+
+    FILE * ifP;
+    pixel * pixrow;
     int argn, headerskip, rowskip, rows, cols, row, i;
-    register int col;
-    int order;
-#define ORD_RGB 1
-#define ORD_RBG 2
-#define ORD_GRB 3
-#define ORD_GBR 4
-#define ORD_BRG 5
-#define ORD_BGR 6
-int interleave;
-#define INT_PIX 1
-#define INT_ROW 2
-    int val1, val2, val3;
-    gray* grow1;
-    gray* grow2;
-    gray* grow3;
-    register gray* g1P;
-    register gray* g2P;
-    register gray* g3P;
+    enum order order;
+    enum interleave interleave;
+    gray * grow1;
+    gray * grow2;
+    gray * grow3;
     const char* const usage = "[-headerskip N] [-rowskip N] [-rgb|-rbg|-grb|-gbr|-brg|-bgr] [-interpixel|-interrow] <width> <height> [rawfile]";
 
-
-    ppm_init( &argc, argv );
+    pm_proginit(&argc, argv);
 
     argn = 1;
     headerskip = 0;
@@ -54,191 +163,90 @@ int interleave;
     interleave = INT_PIX;
 
     while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
-	{
-	if ( pm_keymatch( argv[argn], "-headerskip", 2 ) )
-	    {
-	    ++argn;
-	    if ( argn >= argc )
-		pm_usage( usage );
-	    headerskip = atoi( argv[argn] );
-	    }
-	else if ( pm_keymatch( argv[argn], "-rowskip", 3 ) )
-	    {
-	    ++argn;
-	    if ( argn >= argc )
-		pm_usage( usage );
-	    rowskip = atoi( argv[argn] );
-	    }
-	else if ( pm_keymatch( argv[argn], "-rgb", 3 ) )
-	    order = ORD_RGB;
-	else if ( pm_keymatch( argv[argn], "-rbg", 3 ) )
-	    order = ORD_RBG;
-	else if ( pm_keymatch( argv[argn], "-grb", 3 ) )
-	    order = ORD_GRB;
-	else if ( pm_keymatch( argv[argn], "-gbr", 3 ) )
-	    order = ORD_GBR;
-	else if ( pm_keymatch( argv[argn], "-brg", 3 ) )
-	    order = ORD_BRG;
-	else if ( pm_keymatch( argv[argn], "-bgr", 3 ) )
-	    order = ORD_BGR;
-	else if ( pm_keymatch( argv[argn], "-interpixel", 7 ) )
-	    interleave = INT_PIX;
-	else if ( pm_keymatch( argv[argn], "-interrow", 7 ) )
-	    interleave = INT_ROW;
-	else
-	    pm_usage( usage );
-	++argn;
-	}
+        {
+        if ( pm_keymatch( argv[argn], "-headerskip", 2 ) )
+            {
+            ++argn;
+            if ( argn >= argc )
+                pm_usage( usage );
+            headerskip = atoi( argv[argn] );
+            }
+        else if ( pm_keymatch( argv[argn], "-rowskip", 3 ) )
+            {
+            ++argn;
+            if ( argn >= argc )
+                pm_usage( usage );
+            rowskip = atoi( argv[argn] );
+            }
+        else if ( pm_keymatch( argv[argn], "-rgb", 3 ) )
+            order = ORD_RGB;
+        else if ( pm_keymatch( argv[argn], "-rbg", 3 ) )
+            order = ORD_RBG;
+        else if ( pm_keymatch( argv[argn], "-grb", 3 ) )
+            order = ORD_GRB;
+        else if ( pm_keymatch( argv[argn], "-gbr", 3 ) )
+            order = ORD_GBR;
+        else if ( pm_keymatch( argv[argn], "-brg", 3 ) )
+            order = ORD_BRG;
+        else if ( pm_keymatch( argv[argn], "-bgr", 3 ) )
+            order = ORD_BGR;
+        else if ( pm_keymatch( argv[argn], "-interpixel", 7 ) )
+            interleave = INT_PIX;
+        else if ( pm_keymatch( argv[argn], "-interrow", 7 ) )
+            interleave = INT_ROW;
+        else
+            pm_usage( usage );
+        ++argn;
+        }
 
     if ( argn + 2 > argc )
-	pm_usage( usage );
-
-    cols = atoi( argv[argn++] );
-    rows = atoi( argv[argn++] );
-    if ( cols <= 0 || rows <= 0 )
-	pm_usage( usage );
+        pm_usage( usage );
+    
+    cols = pm_parse_width(argv[argn++]);
+    rows = pm_parse_height(argv[argn++]);
 
     if ( argn < argc )
-	{
-	ifp = pm_openr( argv[argn] );
-	++argn;
-	}
+        {
+        ifP = pm_openr( argv[argn] );
+        ++argn;
+        }
     else
-	ifp = stdin;
+        ifP = stdin;
 
     if ( argn != argc )
-	pm_usage( usage );
-
-    ppm_writeppminit( stdout, cols, rows, (pixval) 255, 0 );
-    pixrow = ppm_allocrow( cols );
-
-    if ( interleave == INT_ROW )
-	{
-	grow1 = pgm_allocrow( cols );
-	grow2 = pgm_allocrow( cols );
-	grow3 = pgm_allocrow( cols );
-	}
-
-    for ( i = 0; i < headerskip; ++i )
-	{
-	val1 = getc( ifp );
-	if ( val1 == EOF )
-	    pm_error( "EOF / read error" );
-	}
-
-    for ( row = 0; row < rows; ++row)
-	{
-	switch ( interleave )
-	    {
-	    case INT_PIX:
-	    for ( col = 0, pP = pixrow; col < cols; ++col, ++pP )
-		{
-		val1 = getc( ifp );
-		if ( val1 == EOF )
-		    pm_error( "EOF / read error" );
-		val2 = getc( ifp );
-		if ( val2 == EOF )
-		    pm_error( "EOF / read error" );
-		val3 = getc( ifp );
-		if ( val3 == EOF )
-		    pm_error( "EOF / read error" );
-		switch ( order )
-		    {
-		    case ORD_RGB:
-		    PPM_ASSIGN( *pP, val1, val2, val3 );
-		    break;
-		    case ORD_RBG:
-		    PPM_ASSIGN( *pP, val1, val3, val2 );
-		    break;
-		    case ORD_GRB:
-		    PPM_ASSIGN( *pP, val2, val1, val3 );
-		    break;
-		    case ORD_GBR:
-		    PPM_ASSIGN( *pP, val3, val1, val2 );
-		    break;
-		    case ORD_BRG:
-		    PPM_ASSIGN( *pP, val2, val3, val1 );
-		    break;
-		    case ORD_BGR:
-		    PPM_ASSIGN( *pP, val3, val2, val1 );
-		    break;
-		    }
-		}
-	    dorowskip( ifp, rowskip );
-	    break;
-
-	    case INT_ROW:
-	    for ( col = 0, g1P = grow1; col < cols; ++col, ++g1P )
-		{
-		val1 = getc( ifp );
-		if ( val1 == EOF )
-		    pm_error( "EOF / read error" );
-		*g1P = val1;
-		}
-	    dorowskip( ifp, rowskip );
-	    for ( col = 0, g2P = grow2; col < cols; ++col, ++g2P )
-		{
-		val2 = getc( ifp );
-		if ( val2 == EOF )
-		    pm_error( "EOF / read error" );
-		*g2P = val2;
-		}
-	    dorowskip( ifp, rowskip );
-	    for ( col = 0, g3P = grow3; col < cols; ++col, ++g3P )
-		{
-		val3 = getc( ifp );
-		if ( val3 == EOF )
-		    pm_error( "EOF / read error" );
-		*g3P = val3;
-		}
-	    dorowskip( ifp, rowskip );
-	    for ( col = 0, pP = pixrow, g1P = grow1, g2P = grow2, g3P = grow3;
-		  col < cols; ++col, ++pP, ++g1P, ++g2P, ++g3P )
-		{
-		switch ( order )
-		    {
-		    case ORD_RGB:
-		    PPM_ASSIGN( *pP, *g1P, *g2P, *g3P );
-		    break;
-		    case ORD_RBG:
-		    PPM_ASSIGN( *pP, *g1P, *g3P, *g2P );
-		    break;
-		    case ORD_GRB:
-		    PPM_ASSIGN( *pP, *g2P, *g1P, *g3P );
-		    break;
-		    case ORD_GBR:
-		    PPM_ASSIGN( *pP, *g3P, *g1P, *g2P );
-		    break;
-		    case ORD_BRG:
-		    PPM_ASSIGN( *pP, *g2P, *g3P, *g1P );
-		    break;
-		    case ORD_BGR:
-		    PPM_ASSIGN( *pP, *g3P, *g2P, *g1P );
-		    break;
-		    }
-		}
-	    break;
-	    }
-	ppm_writeppmrow( stdout, pixrow, cols, (pixval) 255, 0 );
-	}
-
-    pm_close( ifp );
-    pm_close( stdout );
+        pm_usage( usage );
 
-    exit( 0 );
+    ppm_writeppminit(stdout, cols, rows, (pixval) 255, 0);
+    pixrow = ppm_allocrow(cols);
+
+    if (interleave == INT_ROW) {
+        grow1 = pgm_allocrow(cols);
+        grow2 = pgm_allocrow(cols);
+        grow3 = pgm_allocrow(cols);
     }
 
-static void
-dorowskip( ifp, rowskip )
-    FILE* ifp;
-    int rowskip;
-    {
-    int i, val;
-
-    for ( i = 0; i < rowskip; ++i )
-	{
-	val = getc( ifp );
-	if ( val == EOF )
-	    pm_error( "EOF / read error" );
-	}
+    for (i = 0; i < headerskip; ++i) {
+        int const val = getc(ifP);
+        if (val == EOF)
+            pm_error("EOF / read error");
+    }
+
+    for (row = 0; row < rows; ++row) {
+        switch (interleave) {
+        case INT_PIX:
+            doRowPixInterleave(pixrow, cols, ifP, order, rowskip);
+            break;
+
+        case INT_ROW:
+            doRowRowInterleave(pixrow, cols, ifP, order, rowskip,
+                               grow1, grow2, grow3);
+            break;
+        }
+        ppm_writeppmrow(stdout, pixrow, cols, maxval, 0);
+    }
+
+    pm_close( ifP );
+    pm_close( stdout );
+
+    exit( 0 );
     }