about summary refs log tree commit diff
path: root/converter/other
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2015-03-29 23:07:03 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2015-03-29 23:07:03 +0000
commitdd2bedb00517b296115cc56a66300194ab9a25d9 (patch)
tree7a68e60481770e1d0dd7d03c229d96d42cd93e13 /converter/other
parent04c4c8a3ce3ccb391877c25039c52a1a9cc07bd4 (diff)
downloadnetpbm-mirror-dd2bedb00517b296115cc56a66300194ab9a25d9.tar.gz
netpbm-mirror-dd2bedb00517b296115cc56a66300194ab9a25d9.tar.xz
netpbm-mirror-dd2bedb00517b296115cc56a66300194ab9a25d9.zip
Release 10.70.00
git-svn-id: http://svn.code.sf.net/p/netpbm/code/advanced@2442 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/other')
-rw-r--r--converter/other/Makefile2
-rw-r--r--converter/other/cameratopam/Makefile4
-rw-r--r--converter/other/cameratopam/cameratopam.c2
-rw-r--r--converter/other/giftopnm.c214
-rw-r--r--converter/other/jbig/Makefile2
-rw-r--r--converter/other/jpeg2000/libjasper/base/jas_stream.c2
-rw-r--r--converter/other/pamtotiff.c10
-rw-r--r--converter/other/pamtowinicon.c12
-rw-r--r--converter/other/rletopnm.c152
-rw-r--r--converter/other/tifftopnm.c41
-rw-r--r--converter/other/winicontopam.c20
-rw-r--r--converter/other/yuy2topam.c266
12 files changed, 525 insertions, 202 deletions
diff --git a/converter/other/Makefile b/converter/other/Makefile
index db185faf..e76373ef 100644
--- a/converter/other/Makefile
+++ b/converter/other/Makefile
@@ -124,7 +124,7 @@ PORTBINARIES =  avstopam bmptopnm fitstopnm \
 		pnmtopclxl pnmtorast \
 		pnmtosgi pnmtosir pamtotga pnmtoxwd \
 		rasttopnm rlatopam sgitopnm sirtopnm srftopam sunicontopnm \
-		winicontopam xwdtopnm zeisstopnm
+		winicontopam xwdtopnm yuy2topam zeisstopnm
 
 ifneq ($(DONT_HAVE_PROCESS_MGMT),Y)
   PORTBINARIES += pstopnm pnmtops
diff --git a/converter/other/cameratopam/Makefile b/converter/other/cameratopam/Makefile
index 11ca4e1d..d6207aea 100644
--- a/converter/other/cameratopam/Makefile
+++ b/converter/other/cameratopam/Makefile
@@ -26,11 +26,11 @@ OBJECTS = cameratopam.o $(ADDL_OBJECTS)
 
 camera.o camera.o2: CFLAGS_TARGET = $(HAVE_JPEG_DEFINE)
 
-MERGE_OBJECTS =
+MERGE_OBJECTS = cameratopam.o2 $(ADDL_OBJECTS)
 
 PORTBINARIES = cameratopam
 BINARIES = $(PORTBINARIES)
-MERGEBINARIES = 
+MERGEBINARIES = cameratopam
 SCRIPTS = 
 
 include $(SRCDIR)/common.mk
diff --git a/converter/other/cameratopam/cameratopam.c b/converter/other/cameratopam/cameratopam.c
index 40d8207f..ec33dd31 100644
--- a/converter/other/cameratopam/cameratopam.c
+++ b/converter/other/cameratopam/cameratopam.c
@@ -26,7 +26,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#ifdef __CYGWIN__
+#ifdef HAVE_IO_H
   #include <io.h>
 #endif
 #if !MSVCRT
diff --git a/converter/other/giftopnm.c b/converter/other/giftopnm.c
index 239e5100..2e6ae1d9 100644
--- a/converter/other/giftopnm.c
+++ b/converter/other/giftopnm.c
@@ -39,10 +39,6 @@
 
 #define MAX_LZW_BITS  12
 
-#define INTERLACE      0x40
-#define LOCALCOLORMAP  0x80
-#define BitSet(byte, bit)      (((byte) & (bit)) == (bit))
-
 #if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN)
   /* make sure (BYTE_ORDER == LITTLE_ENDIAN) is FALSE */ 
   #define BYTE_ORDER    0
@@ -90,7 +86,7 @@ readFile(FILE *          const ifP,
 
 
 
-struct cmdlineInfo {
+struct CmdlineInfo {
     /* All the information the user supplied in the command line,
        in a form easy for the program to use.
     */
@@ -111,7 +107,7 @@ struct cmdlineInfo {
 
 static void
 parseCommandLine(int argc, char ** argv,
-                 struct cmdlineInfo * const cmdlineP) {
+                 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.
@@ -240,13 +236,21 @@ typedef struct {
 -----------------------------------------------------------------------*/
 
 
-struct gifScreen {
-    unsigned int    Width;
-    unsigned int    Height;
-    GifColorMap     ColorMap;
-    unsigned int    ColorResolution;
-    unsigned int    Background;
-    unsigned int    AspectRatio;
+struct GifScreen {
+    unsigned int    width;
+    unsigned int    height;
+    bool            hasGlobalColorMap;
+        /* The stream has a global color map, to wit 'colorMap'.
+           (If the stream doesn't have a global color map, the individual
+           images must each have a local color map)
+        */
+    GifColorMap     colorMap;
+        /* The global color map for the stream.  Meaningful only if
+           'hasGlobalColorMap' is true.
+        */
+    unsigned int    colorResolution;
+    unsigned int    background;
+    unsigned int    aspectRatio;
         /* Aspect ratio of each pixel, times 64, minus 15.  (i.e. 1 => 1:4).
            But Zero means 1:1.
         */
@@ -260,7 +264,7 @@ struct gifScreen {
         */
 };
 
-struct gif89 {
+struct Gif89 {
     bool         haveTransColor;
         /* The GIF specifies a transparent background color */
     unsigned int transparentIndex;
@@ -278,7 +282,7 @@ struct gif89 {
 };
 
 static void
-initGif89(struct gif89 * const gif89P) {
+initGif89(struct Gif89 * const gif89P) {
     gif89P->haveTransColor = false;
     gif89P->haveDelayTime  = false;
     gif89P->haveInputFlag  = false;
@@ -297,7 +301,16 @@ readColorMap(FILE *        const ifP,
              GifColorMap * const cmapP,
              bool *        const hasGrayP,
              bool *        const hasColorP) {
+/*----------------------------------------------------------------------------
+   Read a color map from a GIF stream, where the stream is on *ifP,
+   which is positioned to a color map, which is 'cmapSize' bytes long.
 
+   Return as *cmapP that color map.
+
+   Furthermore, analyze that color map and return *hasGrayP == true iff it
+   contains any gray (black and white don't count) and *hasColorP == true iff
+   it contains anything that is not gray or black or white.
+-----------------------------------------------------------------------------*/
     unsigned int  i;
     unsigned char rgb[3];
 
@@ -494,7 +507,7 @@ LM_to_uint(unsigned char const a,
 
 static void 
 doGraphicControlExtension(FILE *         const ifP,
-                          struct gif89 * const gif89P) {
+                          struct Gif89 * const gif89P) {
 
     bool eof;
     unsigned int length;
@@ -531,7 +544,7 @@ doGraphicControlExtension(FILE *         const ifP,
 static void
 doExtension(FILE *         const ifP,
             unsigned char  const label,
-            struct gif89 * const gif89P) {
+            struct Gif89 * const gif89P) {
 
     const char * str;
     
@@ -566,7 +579,7 @@ doExtension(FILE *         const ifP,
 
 
 
-struct getCodeState {
+struct GetCodeState {
     unsigned char buf[280];
         /* This is the buffer through which we read the data from the 
            stream.  We must buffer it because we have to read whole data
@@ -592,7 +605,7 @@ struct getCodeState {
 
 static void
 getAnotherBlock(FILE *                const ifP, 
-                struct getCodeState * const gsP,
+                struct GetCodeState * const gsP,
                 const char **         const errorP) {
 
     unsigned int count;
@@ -633,10 +646,10 @@ getAnotherBlock(FILE *                const ifP,
 
 
 
-static struct getCodeState getCodeState;
+static struct GetCodeState getCodeState;
 
 static void
-getCode_init(struct getCodeState * const getCodeStateP) {
+getCode_init(struct GetCodeState * const getCodeStateP) {
     
     /* Fake a previous data block */
     getCodeStateP->buf[0] = 0;
@@ -688,7 +701,7 @@ bitsOfLeBuffer(const unsigned char * const buf,
 
 
 static void
-getCode_get(struct getCodeState * const gsP,
+getCode_get(struct GetCodeState * const gsP,
             FILE *                const ifP, 
             int                   const codeSize,
             bool *                const eofP,
@@ -752,7 +765,7 @@ getCode_get(struct getCodeState * const gsP,
 
 
 
-struct stack {
+struct Stack {
     /* Stack grows from low addresses to high addresses */
     unsigned char * stack;  /* malloc'ed array */
     unsigned char * sp;     /* stack pointer */
@@ -762,7 +775,7 @@ struct stack {
 
 
 static void 
-initStack(struct stack * const stackP, unsigned int const size) {
+initStack(struct Stack * const stackP, unsigned int const size) {
 
     MALLOCARRAY(stackP->stack, size);
     if (stackP->stack == NULL)
@@ -774,7 +787,7 @@ initStack(struct stack * const stackP, unsigned int const size) {
 
 
 static void
-pushStack(struct stack * const stackP, unsigned char const value) {
+pushStack(struct Stack * const stackP, unsigned char const value) {
 
     if (stackP->sp >= stackP->top)
         pm_error("stack overflow");
@@ -785,14 +798,14 @@ pushStack(struct stack * const stackP, unsigned char const value) {
 
 
 static bool
-stackIsEmpty(const struct stack * const stackP) {
+stackIsEmpty(const struct Stack * const stackP) {
     return stackP->sp == stackP->stack;
 }
 
 
 
 static unsigned char
-popStack(struct stack * const stackP) {
+popStack(struct Stack * const stackP) {
 
     if (stackP->sp <= stackP->stack)
         pm_error("stack underflow");
@@ -803,7 +816,7 @@ popStack(struct stack * const stackP) {
 
 
 static void
-termStack(struct stack * const stackP) {
+termStack(struct Stack * const stackP) {
     free(stackP->stack);
     stackP->stack = NULL;
 }
@@ -851,8 +864,8 @@ termStack(struct stack * const stackP) {
 
 static int const maxLzwCodeCt = (1<<MAX_LZW_BITS);
 
-struct decompressor {
-    struct stack stack;
+struct Decompressor {
+    struct Stack stack;
     bool fresh;
         /* The stream is right after a clear code or at the very beginning */
     unsigned int codeSize;
@@ -891,7 +904,7 @@ struct decompressor {
 
 
 static void
-resetDecompressor(struct decompressor * const decompP) {
+resetDecompressor(struct Decompressor * const decompP) {
 
     decompP->codeSize      = decompP->initCodeSize+1;
     decompP->maxCodeCt     = 1 << decompP->codeSize;
@@ -927,7 +940,7 @@ validateTransparentIndex(unsigned int const transparentIndex,
 
 
 static void
-lzwInit(struct decompressor * const decompP, 
+lzwInit(struct Decompressor * const decompP, 
         FILE *                const ifP,
         int                   const initCodeSize,
         unsigned int          const cmapSize,
@@ -988,7 +1001,7 @@ lzwInit(struct decompressor * const decompP,
 
 
 static void
-lzwAdjustForPBM(struct decompressor * const decompP,
+lzwAdjustForPBM(struct Decompressor * const decompP,
                 GifColorMap           const cmap) {
 /*----------------------------------------------------------------------------
   In the PBM case we use the table index value directly instead of looking up
@@ -1006,7 +1019,7 @@ lzwAdjustForPBM(struct decompressor * const decompP,
 
 
 static void
-lzwTerm(struct decompressor * const decompP) {
+lzwTerm(struct Decompressor * const decompP) {
 
     termStack(&decompP->stack);
 }
@@ -1014,7 +1027,7 @@ lzwTerm(struct decompressor * const decompP) {
 
 
 static void
-pushWholeStringOnStack(struct decompressor * const decompP,
+pushWholeStringOnStack(struct Decompressor * const decompP,
                        unsigned int          const code0) {
 /*----------------------------------------------------------------------------
   Get the whole string that compression code 'code0' represents and push
@@ -1038,7 +1051,7 @@ pushWholeStringOnStack(struct decompressor * const decompP,
 
 
 static void
-expandCodeOntoStack(struct decompressor * const decompP,
+expandCodeOntoStack(struct Decompressor * const decompP,
                     unsigned int          const incode,
                     const char **         const errorP) {
 /*----------------------------------------------------------------------------
@@ -1113,8 +1126,8 @@ expandCodeOntoStack(struct decompressor * const decompP,
 
 
 static void
-lzwReadByteFresh(struct getCodeState * const getCodeStateP,
-                 struct decompressor * const decompP,
+lzwReadByteFresh(struct GetCodeState * const getCodeStateP,
+                 struct Decompressor * const decompP,
                  bool *                const endOfImageP,
                  unsigned char *       const dataReadP,
                  const char **         const errorP) {
@@ -1171,7 +1184,7 @@ lzwReadByteFresh(struct getCodeState * const getCodeStateP,
 
 
 static void
-lzwReadByte(struct decompressor * const decompP,
+lzwReadByte(struct Decompressor * const decompP,
             unsigned char *       const dataReadP,
             bool *                const endOfImageP,
             const char **         const errorP) {
@@ -1398,7 +1411,7 @@ pnmFormat(bool const hasGray,
 
 
 static void
-makePnmRow(struct decompressor * const decompP,
+makePnmRow(struct Decompressor * const decompP,
            unsigned int          const cols,
            unsigned int          const rows,
            bool                  const fillWithZero,
@@ -1447,7 +1460,7 @@ makePnmRow(struct decompressor * const decompP,
 
 
 static void
-convertRaster(struct decompressor * const decompP,
+convertRaster(struct Decompressor * const decompP,
               unsigned int          const cols,
               unsigned int          const rows,
               GifColorMap           const cmap, 
@@ -1550,7 +1563,7 @@ convertRaster(struct decompressor * const decompP,
 
 
 static void
-skipExtraneousData(struct decompressor * const decompP) {
+skipExtraneousData(struct Decompressor * const decompP) {
 
     unsigned char byteRead;
     bool endOfImage;
@@ -1638,7 +1651,7 @@ readImageData(FILE *       const ifP,
               bool         const tolerateBadInput) {
 
     unsigned char lzwMinCodeSize;      
-    struct decompressor decomp;
+    struct Decompressor decomp;
     const char * error;
 
     readFile(ifP, &lzwMinCodeSize, sizeof(lzwMinCodeSize), &error);
@@ -1697,12 +1710,14 @@ warnUserNotSquare(unsigned int const aspectRatio) {
 
 static void
 readGifHeader(FILE *             const gifFileP,
-              struct gifScreen * const gifScreenP) {
+              struct GifScreen * const gifScreenP) {
 /*----------------------------------------------------------------------------
    Read the GIF stream header off the file *gifFileP, which is present
    positioned to the beginning of a GIF stream.  Return the info from it
    as *gifScreenP.
 -----------------------------------------------------------------------------*/
+#define GLOBALCOLORMAP  0x80
+
     unsigned char buf[16];
     char version[4];
     unsigned int cmapSize;
@@ -1729,44 +1744,46 @@ readGifHeader(FILE *             const gifFileP,
     if (error)
         pm_error("Failed to read screen descriptor.  %s", error);
     
-    gifScreenP->Width           = LM_to_uint(buf[0],buf[1]);
-    gifScreenP->Height          = LM_to_uint(buf[2],buf[3]);
+    gifScreenP->width           = LM_to_uint(buf[0],buf[1]);
+    gifScreenP->height          = LM_to_uint(buf[2],buf[3]);
     cmapSize                    = 1 << ((buf[4] & 0x07) + 1);
-    gifScreenP->ColorResolution = (buf[4] & 0x70 >> 3) + 1;
-    gifScreenP->Background      = buf[5];
-    gifScreenP->AspectRatio     = buf[6];
+    gifScreenP->colorResolution = (buf[4] & 0x70 >> 3) + 1;
+    gifScreenP->background      = buf[5];
+    gifScreenP->aspectRatio     = buf[6];
 
     if (verbose) {
-        pm_message("GIF Width = %d GIF Height = %d "
-                   "Pixel aspect ratio = %d (%f:1)",
-                   gifScreenP->Width, gifScreenP->Height, 
-                   gifScreenP->AspectRatio, 
-                   gifScreenP->AspectRatio == 0 ? 
-                   1 : (gifScreenP->AspectRatio + 15) / 64.0);
-        pm_message("Colors = %d   Color Resolution = %d",
-                   cmapSize, gifScreenP->ColorResolution);
+        pm_message("GIF Width = %u GIF Height = %u "
+                   "Pixel aspect ratio = %u (%f:1)",
+                   gifScreenP->width, gifScreenP->height, 
+                   gifScreenP->aspectRatio, 
+                   gifScreenP->aspectRatio == 0 ? 
+                   1 : (gifScreenP->aspectRatio + 15) / 64.0);
+        pm_message("Global color count = %u   Color Resolution = %u",
+                   cmapSize, gifScreenP->colorResolution);
     }           
-    if (BitSet(buf[4], LOCALCOLORMAP)) {    /* Global Colormap */
-        readColorMap(gifFileP, cmapSize, &gifScreenP->ColorMap,
+    if (buf[4] & GLOBALCOLORMAP) {
+        gifScreenP->hasGlobalColorMap = true;
+        readColorMap(gifFileP, cmapSize, &gifScreenP->colorMap,
                      &gifScreenP->hasGray, &gifScreenP->hasColor);
         if (verbose) {
-            pm_message("Color map %s grays, %s colors", 
+            pm_message("Global color map %s grays, %s colors", 
                        gifScreenP->hasGray ? "contains" : "doesn't contain",
                        gifScreenP->hasColor ? "contains" : "doesn't contain");
         }
-    } else {
-        gifScreenP->ColorMap.size = 0;
-    }
+    } else
+        gifScreenP->hasGlobalColorMap = false;
     
-    if (gifScreenP->AspectRatio != 0 && gifScreenP->AspectRatio != 49)
-        warnUserNotSquare(gifScreenP->AspectRatio);
+    if (gifScreenP->aspectRatio != 0 && gifScreenP->aspectRatio != 49)
+        warnUserNotSquare(gifScreenP->aspectRatio);
+
+#undef GLOBALCOLORMAP
 }
 
 
 
 static void
 readExtensions(FILE*          const ifP, 
-               struct gif89 * const gif89P,
+               struct Gif89 * const gif89P,
                bool *         const eodP,
                const char **  const errorP) {
 /*----------------------------------------------------------------------------
@@ -1832,7 +1849,13 @@ struct GifImageHeader {
 /*----------------------------------------------------------------------------
    Information in the header (first 9 bytes) of a GIF image.
 -----------------------------------------------------------------------------*/
-    bool useGlobalColormap;
+    bool hasLocalColormap;
+        /* The image has its own color map.  Its size is 'localColorMapSize' */
+        /* (If an image does not have its own color map, the image uses the 
+           global color map for the GIF stream)
+        */
+    unsigned int localColorMapSize;
+        /* Meaningful only if 'hasLocalColormap' is true. */
 
     /* Position of the image (max 65535) */
     unsigned int lpos;
@@ -1841,7 +1864,7 @@ struct GifImageHeader {
     /* Dimensions of the image (max 65535) */
     unsigned int cols;
     unsigned int rows;
-    unsigned int localColorMapSize;
+
     bool interlaced;
 };
 
@@ -1858,11 +1881,11 @@ reportImageHeader(struct GifImageHeader const imageHeader) {
         pm_message("  Image left position: %u top position: %u",
                    imageHeader.lpos, imageHeader.tpos);
     
-    if (imageHeader.useGlobalColormap)
-        pm_message("  Uses global colormap");
-    else
+    if (imageHeader.hasLocalColormap)
         pm_message("  Uses local colormap of %u colors",
                    imageHeader.localColorMapSize);
+    else
+        pm_message("  Uses global colormap");
 }
 
 
@@ -1871,6 +1894,9 @@ static void
 readImageHeader(FILE *                  const ifP,
                 struct GifImageHeader * const imageHeaderP) {
 
+#define LOCALCOLORMAP  0x80
+#define INTERLACE      0x40
+
     unsigned char buf[16];
     const char * error;
 
@@ -1878,34 +1904,37 @@ readImageHeader(FILE *                  const ifP,
     if (error)
         pm_error("couldn't read left/top/width/height.  %s", error);
 
-    imageHeaderP->useGlobalColormap = ! BitSet(buf[8], LOCALCOLORMAP);
+    imageHeaderP->hasLocalColormap  = !!(buf[8] & LOCALCOLORMAP);
     imageHeaderP->localColorMapSize = 1u << ((buf[8] & 0x07) + 1);
     imageHeaderP->lpos              = LM_to_uint(buf[0], buf[1]);
     imageHeaderP->tpos              = LM_to_uint(buf[2], buf[3]);
     imageHeaderP->cols              = LM_to_uint(buf[4], buf[5]);
     imageHeaderP->rows              = LM_to_uint(buf[6], buf[7]);
-    imageHeaderP->interlaced        = !!BitSet(buf[8], INTERLACE);
+    imageHeaderP->interlaced        = !!(buf[8] & INTERLACE);
 
     if (verbose)
         reportImageHeader(*imageHeaderP);
+
+#undef INTERLACE
+#undef LOCALCOLORMAP
 }
 
 
 
 static void
 validateWithinGlobalScreen(struct GifImageHeader const imageHeader,
-                           struct gifScreen      const gifScreen) {
+                           struct GifScreen      const gifScreen) {
 
     unsigned long int const rpos = imageHeader.lpos + imageHeader.cols;
     unsigned long int const bpos = imageHeader.tpos + imageHeader.rows; 
 
-    if (rpos > gifScreen.Width)
+    if (rpos > gifScreen.width)
         pm_error("Image right end (%lu) is outside global screen: %u x %u",
-                 rpos, gifScreen.Width, gifScreen.Height);
-    if (bpos > gifScreen.Height)
+                 rpos, gifScreen.width, gifScreen.height);
+    if (bpos > gifScreen.height)
         pm_error("Image bottom end (%lu) is outside global screen: "
                  "%u x %u",
-                 bpos, gifScreen.Width, gifScreen.Height);
+                 bpos, gifScreen.width, gifScreen.height);
 }
 
 
@@ -1930,8 +1959,8 @@ convertImage(FILE *           const ifP,
              bool             const skipIt, 
              FILE *           const imageoutFileP, 
              FILE *           const alphafileP, 
-             struct gifScreen const gifScreen,
-             struct gif89     const gif89,
+             struct GifScreen const gifScreen,
+             struct Gif89     const gif89,
              bool             const tolerateBadInput) {
 /*----------------------------------------------------------------------------
    Read a single GIF image from the current position of file 'ifP'.
@@ -1949,19 +1978,18 @@ convertImage(FILE *           const ifP,
 
     validateWithinGlobalScreen(imageHeader, gifScreen);
 
-    if (imageHeader.useGlobalColormap) {
-        if (gifScreen.ColorMap.size == 0) {
-            pm_error("Invalid GIF: "
-                     "Image has no local color map and stream has no global "
-                     "color map either.");
-        }
-        currentColorMapP = &gifScreen.ColorMap;
-        hasGray  = gifScreen.hasGray;
-        hasColor = gifScreen.hasColor;
-    } else {
+    if (imageHeader.hasLocalColormap) {
         readColorMap(ifP, imageHeader.localColorMapSize, &localColorMap, 
                      &hasGray, &hasColor);
         currentColorMapP = &localColorMap;
+    } else if (gifScreen.hasGlobalColorMap) {
+        currentColorMapP = &gifScreen.colorMap;
+        hasGray  = gifScreen.hasGray;
+        hasColor = gifScreen.hasColor;
+    } else {
+        pm_error("Invalid GIF: "
+                 "Image has no local color map and stream has no global "
+                 "color map either.");
     }
 
     if (!skipIt) {
@@ -2027,8 +2055,8 @@ convertImages(FILE *       const ifP,
         /* Sequence within GIF stream of image we are currently processing.
            First is 0.
         */
-    struct gifScreen gifScreen;
-    struct gif89 gif89;
+    struct GifScreen gifScreen;
+    struct Gif89 gif89;
     bool eod;
         /* We've read through the GIF terminator character */
 
@@ -2072,7 +2100,7 @@ convertImages(FILE *       const ifP,
 int
 main(int argc, char **argv) {
 
-    struct cmdlineInfo cmdline;
+    struct CmdlineInfo cmdline;
     FILE * ifP;
     FILE * alphaFileP;
     FILE * imageOutFileP;
diff --git a/converter/other/jbig/Makefile b/converter/other/jbig/Makefile
index 0625edd3..946cb732 100644
--- a/converter/other/jbig/Makefile
+++ b/converter/other/jbig/Makefile
@@ -29,6 +29,8 @@ endif
 
 BINARIES = $(PORTBINARIES)
 
+MERGEBINARIES = $(BINARIES)
+
 SCRIPTS =
 
 ifeq ($(JBIGLIB),$(INTERNAL_JBIGLIB))
diff --git a/converter/other/jpeg2000/libjasper/base/jas_stream.c b/converter/other/jpeg2000/libjasper/base/jas_stream.c
index 7c6050fb..16c948eb 100644
--- a/converter/other/jpeg2000/libjasper/base/jas_stream.c
+++ b/converter/other/jpeg2000/libjasper/base/jas_stream.c
@@ -127,7 +127,7 @@
 #if defined(HAVE_UNISTD_H)
 #include <unistd.h>
 #endif
-#if MSVCRT
+#if HAVE_IO_H
 #include <io.h>
 #endif
 
diff --git a/converter/other/pamtotiff.c b/converter/other/pamtotiff.c
index f2cc0e2b..7b645b23 100644
--- a/converter/other/pamtotiff.c
+++ b/converter/other/pamtotiff.c
@@ -960,6 +960,12 @@ copyBufferToStdout(int const tmpfileFd) {
             fwrite(buffer, 1, bytesReadCt, stdout);
     }
 
+    /* POSIX lets us create a FILE from an existing file descriptor, but
+       does not provide a way to destroy the FILE and keep the file
+       descriptor.  The following fclose() closes the file.  Caller
+       must not access the file again, and if he attempts to close it,
+       must ignore the failure of close
+    */
     fclose(tmpfileP);
 }
 
@@ -975,6 +981,10 @@ destroyTiffGenerator(WriteMethod const writeMethod,
     if (writeMethod == TMPFILE)
         copyBufferToStdout(ofd);
 
+    /* If we copied the buffer above, the buffer file is already closed
+       (copyBufferToStdout closes it), TIFFClose appears to tolerate that -
+       all it does is a close() and doesn't mind that it fails.
+    */
     TIFFClose(tifP);
 }
 
diff --git a/converter/other/pamtowinicon.c b/converter/other/pamtowinicon.c
index c67267e4..7e2c9e86 100644
--- a/converter/other/pamtowinicon.c
+++ b/converter/other/pamtowinicon.c
@@ -36,12 +36,12 @@ parseCommandLine(int argc, const char **argv,
 
     option_def_index = 0;
 
-    OPTENT3 (0, "verbose",         OPT_FLAG, NULL,
-             &cmdlineP->verbose,         0);
-    OPTENT3 (0, "pngthreshold",    OPT_UINT, &cmdlineP->pngthreshold,
-             &pngthresholdSpec,          0);
-    OPTENT3 (0, "truetransparent", OPT_FLAG, NULL,
-             &cmdlineP->truetransparent, 0);
+    OPTENT3(0, "verbose",         OPT_FLAG, NULL,
+            &cmdlineP->verbose,         0);
+    OPTENT3(0, "pngthreshold",    OPT_UINT, &cmdlineP->pngthreshold,
+            &pngthresholdSpec,          0);
+    OPTENT3(0, "truetransparent", OPT_FLAG, NULL,
+            &cmdlineP->truetransparent, 0);
 
     opt3.opt_table     = option_def;
     opt3.short_allowed = false;
diff --git a/converter/other/rletopnm.c b/converter/other/rletopnm.c
index 71f4e284..99959141 100644
--- a/converter/other/rletopnm.c
+++ b/converter/other/rletopnm.c
@@ -61,19 +61,19 @@
 /*
  * Utah type declarations.
  */
-rle_hdr     hdr;
-rle_map     *colormap;
+static rle_hdr hdr;
+static rle_map * colormap;
 
 
-struct cmdlineInfo {
+struct CmdlineInfo {
     /* All the information the user supplied in the command line,
        in a form easy for the program to use.
     */
-    char *input_filename;
+    char *       inputFilename;
     unsigned int headerdump;
     unsigned int verbose;
-    char *alpha_filename;
-    bool alpha_stdout;
+    char *       alphaout;
+    bool         alphaStdout;
 };
 
 
@@ -81,15 +81,14 @@ struct cmdlineInfo {
 /*
  * Other declarations.
  */
-int     visual, maplen;
-int     width, height;
-
+static int visual, maplen;
+static int width, height;
 
 
 
 static void
 parseCommandLine(int argc, char ** argv,
-                   struct cmdlineInfo * const cmdlineP) {
+                 struct CmdlineInfo * const cmdlineP) {
 /*----------------------------------------------------------------------------
    Note that many of the strings that this function returns in the
    *cmdlineP structure are actually in the supplied argv array.  And
@@ -110,7 +109,7 @@ parseCommandLine(int argc, char ** argv,
     OPTENT3('v', "verbose",    OPT_FLAG,   
             NULL,                      &cmdlineP->verbose,        0);
     OPTENT3(0,   "alphaout",   OPT_STRING, 
-            &cmdlineP->alpha_filename, &alphaoutSpec,             0);
+            &cmdlineP->alphaout, &alphaoutSpec,                   0);
 
     opt.opt_table = option_def;
     opt.short_allowed = TRUE;  /* We have short (old-fashioned) options */
@@ -120,24 +119,24 @@ parseCommandLine(int argc, char ** argv,
         /* Uses and sets argc, argv, and all of *cmdlineP. */
 
     if (!alphaoutSpec)
-        cmdlineP->alpha_filename = NULL;
+        cmdlineP->alphaout = NULL;
 
     if (argc - 1 == 0)
-        cmdlineP->input_filename = NULL;  /* he wants stdin */
+        cmdlineP->inputFilename = NULL;  /* he wants stdin */
     else if (argc - 1 == 1) {
         if (streq(argv[1], "-"))
-            cmdlineP->input_filename = NULL;  /* he wants stdin */
+            cmdlineP->inputFilename = NULL;  /* he wants stdin */
         else 
-            cmdlineP->input_filename = strdup(argv[1]);
+            cmdlineP->inputFilename = strdup(argv[1]);
     } else 
         pm_error("Too many arguments.  The only argument accepted "
                  "is the input file specification");
 
-    if (cmdlineP->alpha_filename && 
-        streq(cmdlineP->alpha_filename, "-"))
-        cmdlineP->alpha_stdout = TRUE;
+    if (cmdlineP->alphaout && 
+        streq(cmdlineP->alphaout, "-"))
+        cmdlineP->alphaStdout = TRUE;
     else 
-        cmdlineP->alpha_stdout = FALSE;
+        cmdlineP->alphaStdout = FALSE;
 }
 
 
@@ -167,15 +166,14 @@ reportRleGetSetupError(int const rleGetSetupRc) {
 }
 
 
-/*-----------------------------------------------------------------------------
- *                                                         Read the rle header.
- */
+
 static void 
-read_rle_header(FILE * const ifp,
-                bool   const headerDump) {
+readRleHeader(FILE * const ifP,
+              bool   const headerDump) {
+
     int rc;
     int  i;
-    hdr.rle_file = ifp;
+    hdr.rle_file = ifP;
     rc = rle_get_setup(&hdr);
     if (rc != 0)
         reportRleGetSetupError(rc);
@@ -254,12 +252,12 @@ read_rle_header(FILE * const ifp,
         for (i = 0; hdr.comments[i] != NULL; i++)
             HMSG("%s", hdr.comments[i]);
 }
-/*-----------------------------------------------------------------------------
- *                                                    Write the ppm image data.
- */
+
+
+
 static void 
-write_ppm_data(FILE * const imageout_file,
-               FILE * const alpha_file) {
+writePpmRaster(FILE * const imageoutFileP,
+               FILE * const alphaFileP) {
 
     rle_pixel ***scanlines, **scanline;
     pixval r, g, b;
@@ -341,17 +339,17 @@ write_ppm_data(FILE * const imageout_file,
         /*
          * Write the scan line.
          */
-        if (imageout_file ) 
-            ppm_writeppmrow(imageout_file, pixelrow, width, RLE_MAXVAL, 0);
-        if (alpha_file)
-            pgm_writepgmrow(alpha_file, alpharow, width, RLE_MAXVAL, 0);
+        if (imageoutFileP) 
+            ppm_writeppmrow(imageoutFileP, pixelrow, width, RLE_MAXVAL, 0);
+        if (alphaFileP)
+            pgm_writepgmrow(alphaFileP, alpharow, width, RLE_MAXVAL, 0);
 
     } /* end of for scan = 0 to height */
 
     /* Free scanline memory. */
-    for ( scan = 0; scan < height; scan++ )
-        rle_row_free( &hdr, scanlines[scan] );
-    free( scanlines );
+    for (scan = 0; scan < height; ++scan)
+        rle_row_free(&hdr, scanlines[scan]);
+    free (scanlines);
     ppm_freerow(pixelrow);
     pgm_freerow(alpharow);
 }
@@ -359,8 +357,8 @@ write_ppm_data(FILE * const imageout_file,
 
 
 static void 
-write_pgm_data(FILE * const imageout_file,
-               FILE * const alpha_file) {
+writePgmRaster(FILE * const imageoutFileP,
+               FILE * const alphaFileP) {
 /*----------------------------------------------------------------------------
    Write the PGM image data
 -----------------------------------------------------------------------------*/
@@ -397,10 +395,10 @@ write_pgm_data(FILE * const imageout_file,
             else
                 alpharow[x] = 0;
         }
-        if (imageout_file) 
-            pgm_writepgmrow(imageout_file, pixelrow, width, RLE_MAXVAL, 0);
-        if (alpha_file)
-            pgm_writepgmrow(alpha_file, alpharow, width, RLE_MAXVAL, 0);
+        if (imageoutFileP) 
+            pgm_writepgmrow(imageoutFileP, pixelrow, width, RLE_MAXVAL, 0);
+        if (alphaFileP)
+            pgm_writepgmrow(alphaFileP, alpharow, width, RLE_MAXVAL, 0);
 
         }   /* end of for scan = 0 to height */
 
@@ -414,59 +412,59 @@ write_pgm_data(FILE * const imageout_file,
 
 
 
-/*-----------------------------------------------------------------------------
- *                               Convert a Utah rle file to a pbmplus pnm file.
- */
 int
 main(int argc, char ** argv) {
 
-    struct cmdlineInfo cmdline;
-    FILE        *ifp;
-    FILE *imageout_file, *alpha_file;
-    char *fname = NULL;
+    struct CmdlineInfo cmdline;
+    FILE * ifP;
+    FILE * imageoutFileP;
+    FILE * alphaFileP;
+    char * fname;
 
     pnm_init( &argc, argv );
 
     parseCommandLine(argc, argv, &cmdline);
 
-    if ( cmdline.input_filename != NULL ) 
-        ifp = pm_openr( cmdline.input_filename );
+    fname = NULL;  /* initial value */
+
+    if (cmdline.inputFilename != NULL ) 
+        ifP = pm_openr(cmdline.inputFilename);
     else
-        ifp = stdin;
+        ifP = stdin;
 
-    if (cmdline.alpha_stdout)
-        alpha_file = stdout;
-    else if (cmdline.alpha_filename == NULL) 
-        alpha_file = NULL;
+    if (cmdline.alphaStdout)
+        alphaFileP = stdout;
+    else if (cmdline.alphaout == NULL) 
+        alphaFileP = NULL;
     else {
-        alpha_file = pm_openw(cmdline.alpha_filename);
+        alphaFileP = pm_openw(cmdline.alphaout);
     }
 
-    if (cmdline.alpha_stdout) 
-        imageout_file = NULL;
+    if (cmdline.alphaStdout) 
+        imageoutFileP = NULL;
     else
-        imageout_file = stdout;
+        imageoutFileP = stdout;
 
 
     /*
      * Open the file.
      */
     /* Initialize header. */
-    hdr = *rle_hdr_init( (rle_hdr *)NULL );
-    rle_names( &hdr, cmd_name( argv ), fname, 0 );
+    hdr = *rle_hdr_init(NULL);
+    rle_names(&hdr, cmd_name( argv ), fname, 0);
 
     /*
      * Read the rle file header.
      */
-    read_rle_header(ifp, cmdline.headerdump || cmdline.verbose);
+    readRleHeader(ifP, cmdline.headerdump || cmdline.verbose);
     if (cmdline.headerdump)
         exit(0);
 
     /* 
      * Write the alpha file header
      */
-    if (alpha_file)
-        pgm_writepgminit(alpha_file, width, height, RLE_MAXVAL, 0);
+    if (alphaFileP)
+        pgm_writepgminit(alphaFileP, width, height, RLE_MAXVAL, 0);
 
     /*
      * Write the pnm file header.
@@ -475,24 +473,24 @@ main(int argc, char ** argv) {
     case GRAYSCALE:   /* 8 bits without colormap -> pgm */
         if (cmdline.verbose)
             pm_message("Writing pgm file.");
-        if (imageout_file)
-            pgm_writepgminit(imageout_file, width, height, RLE_MAXVAL, 0);
-        write_pgm_data(imageout_file, alpha_file);
+        if (imageoutFileP)
+            pgm_writepgminit(imageoutFileP, width, height, RLE_MAXVAL, 0);
+        writePgmRaster(imageoutFileP, alphaFileP);
         break;
     default:      /* anything else -> ppm */
         if (cmdline.verbose)
             pm_message("Writing ppm file.");
-        if (imageout_file)
-            ppm_writeppminit(imageout_file, width, height, RLE_MAXVAL, 0);
-        write_ppm_data(imageout_file, alpha_file);
+        if (imageoutFileP)
+            ppm_writeppminit(imageoutFileP, width, height, RLE_MAXVAL, 0);
+        writePpmRaster(imageoutFileP, alphaFileP);
         break;
     }
    
-    pm_close(ifp);
-    if (imageout_file) 
-        pm_close( imageout_file );
-    if (alpha_file)
-        pm_close( alpha_file );
+    pm_close(ifP);
+    if (imageoutFileP) 
+        pm_close(imageoutFileP);
+    if (alphaFileP)
+        pm_close(alphaFileP);
 
     return 0;
 }
diff --git a/converter/other/tifftopnm.c b/converter/other/tifftopnm.c
index 595d4937..0d6494f9 100644
--- a/converter/other/tifftopnm.c
+++ b/converter/other/tifftopnm.c
@@ -151,6 +151,31 @@ parseCommandLine(int argc, const char ** const argv,
 
 
 
+static TIFF *
+newTiffImageObject(const char * const inputFileName) {
+/*----------------------------------------------------------------------------
+   Create a TIFF library object for accessing the TIFF input in file
+   named 'inputFileName'.  If 'inputFileName' is "-", that means
+   Standard Input.
+-----------------------------------------------------------------------------*/
+    const char * const tiffSourceName =
+        streq(inputFileName, "-") ? "Standard Input" : inputFileName;
+
+    TIFF * retval;
+
+    retval = TIFFFdOpen(fileno(pm_openr_seekable(inputFileName)),
+                        tiffSourceName,
+                        "r");
+
+    if (retval == NULL)
+        pm_error("Failed to access input file.  The OS opened the file fine, "
+                 "but the TIFF library's TIFFFdOpen rejected the open file.");
+
+    return retval;
+}
+
+
+
 static void
 getBps(TIFF *           const tif,
        unsigned short * const bpsP) {
@@ -1623,7 +1648,7 @@ int
 main(int argc, const char * argv[]) {
 
     struct CmdlineInfo cmdline;
-    TIFF * tif;
+    TIFF * tiffP;
     FILE * alphaFile;
     FILE * imageoutFile;
 
@@ -1631,15 +1656,7 @@ main(int argc, const char * argv[]) {
 
     parseCommandLine(argc, argv, &cmdline);
 
-    if (!streq(cmdline.inputFilename, "-")) {
-        tif = TIFFOpen(cmdline.inputFilename, "r");
-        if (tif == NULL)
-            pm_error("error opening TIFF file %s", cmdline.inputFilename);
-    } else {
-        tif = TIFFFdOpen(0, "Standard Input", "r");
-        if (tif == NULL)
-            pm_error("error opening standard input as TIFF file");
-    }
+    tiffP = newTiffImageObject(cmdline.inputFilename);
 
     if (cmdline.alphaStdout)
         alphaFile = stdout;
@@ -1653,13 +1670,15 @@ main(int argc, const char * argv[]) {
     else
         imageoutFile = stdout;
 
-    convertIt(tif, alphaFile, imageoutFile, cmdline);
+    convertIt(tiffP, alphaFile, imageoutFile, cmdline);
 
     if (imageoutFile != NULL) 
         pm_close( imageoutFile );
     if (alphaFile != NULL)
         pm_close( alphaFile );
 
+    TIFFClose(tiffP);
+
     pm_strfree(cmdline.inputFilename);
 
     /* If the program failed, it previously aborted with nonzero completion
diff --git a/converter/other/winicontopam.c b/converter/other/winicontopam.c
index f41a8db3..664b4ef9 100644
--- a/converter/other/winicontopam.c
+++ b/converter/other/winicontopam.c
@@ -49,16 +49,16 @@ parseCommandLine(int argc, const char **argv,
 
     option_def_index = 0;
 
-    OPTENT3 (0, "allimages",   OPT_FLAG,   NULL,
-             &cmdlineP->allimages,         0);
-    OPTENT3 (0, "image",     OPT_UINT,   &cmdlineP->image,
-             &cmdlineP->imageSpec,         0);
-    OPTENT3 (0, "andmasks",  OPT_FLAG,   NULL,
-             &cmdlineP->andmasks,          0);
-    OPTENT3 (0, "headerdump",   OPT_FLAG,   NULL,
-             &cmdlineP->headerdump,        0);
-    OPTENT3 (0, "verbose",   OPT_FLAG,   NULL,
-             &cmdlineP->verbose,           0);
+    OPTENT3(0, "allimages",   OPT_FLAG,   NULL,
+            &cmdlineP->allimages,         0);
+    OPTENT3(0, "image",     OPT_UINT,   &cmdlineP->image,
+            &cmdlineP->imageSpec,         0);
+    OPTENT3(0, "andmasks",  OPT_FLAG,   NULL,
+            &cmdlineP->andmasks,          0);
+    OPTENT3(0, "headerdump",   OPT_FLAG,   NULL,
+            &cmdlineP->headerdump,        0);
+    OPTENT3(0, "verbose",   OPT_FLAG,   NULL,
+            &cmdlineP->verbose,           0);
 
     opt3.opt_table     = option_def;
     opt3.short_allowed = false;
diff --git a/converter/other/yuy2topam.c b/converter/other/yuy2topam.c
new file mode 100644
index 00000000..40ab98b3
--- /dev/null
+++ b/converter/other/yuy2topam.c
@@ -0,0 +1,266 @@
+/* Convert an YUY2 image to a PAM image
+ *
+ * See
+ * http://msdn.microsoft.com/en-us/library/aa904813%28VS.80%29.aspx#yuvformats_2
+ * and http://www.digitalpreservation.gov/formats/fdd/fdd000364.shtml for
+ * details.
+ *
+ * By Michael Haardt 2014.
+ *
+ * Contributed to the public domain by its author.
+ *
+ * Recoded in Netpbm style by Bryan Henderson
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "pm_c_util.h"
+#include "mallocvar.h"
+#include "pm.h"
+#include "pam.h"
+#include "shhopt.h"
+
+
+
+struct CmdlineInfo {
+    const char * inputFileName;
+    unsigned int width;
+    unsigned int height;
+};
+
+
+
+static void 
+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.  
+
+   If command line is internally inconsistent (invalid options, etc.),
+   issue error message to stderr and abort program.
+
+   Note that the strings we return are stored in the storage that
+   was passed to us as the argv array.  We also trash *argv.
+--------------------------------------------------------------------------*/
+    optEntry * option_def;
+        /* Instructions to pm_optParseOptions3 on how to parse our options. */
+    optStruct3 opt;
+
+    unsigned int widthSpec, heightSpec;
+    unsigned int option_def_index;
+
+    MALLOCARRAY_NOFAIL(option_def, 100);
+
+    option_def_index = 0;   /* incremented by OPTENT3 */
+    OPTENT3(0, "width",    OPT_UINT,
+            &cmdlineP->width,   &widthSpec,                             0);
+    OPTENT3(0, "height",   OPT_UINT,
+            &cmdlineP->height,  &heightSpec,                            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. */
+
+    if (!widthSpec)
+        pm_error("You must specify the image width with -width");
+    if (cmdlineP->width == 0)
+        pm_error("-width cannot be zero");
+
+    if (cmdlineP->width % 2 != 0)
+        pm_error("-width %u is odd, but YUY2 images must have an even width.",
+                 cmdlineP->width);
+
+    if (!heightSpec)
+        pm_error("You must specify the image height with -height");
+    if (cmdlineP->height == 0)
+        pm_error("-height cannot be zero");
+
+    if (argc-1 < 1)
+        cmdlineP->inputFileName = "-";
+    else {
+        cmdlineP->inputFileName = argv[1];
+        
+        if (argc-1 > 1)
+            pm_error("Too many arguments (%u).  The only non-option argument "
+                     "is the input file name.", argc-1);
+    }
+}
+
+
+
+typedef struct {
+    int y0;
+    int y1;
+    int u;
+    int v;
+} Yuy2Pixel;
+
+
+
+static Yuy2Pixel
+readPixel(FILE * const ifP) {
+/*----------------------------------------------------------------------------
+   Read one pixel from the YUY2 input.  YUY2 represents a pixel in 4 bytes.
+-----------------------------------------------------------------------------*/
+    Yuy2Pixel retval;
+    unsigned char c;
+
+    pm_readcharu(ifP, &c); retval.y0 = c -  16;
+    pm_readcharu(ifP, &c); retval.u  = c - 128;
+    pm_readcharu(ifP, &c); retval.y1 = c -  16;
+    pm_readcharu(ifP, &c); retval.v  = c - 128;
+
+    return retval;
+}
+
+
+
+typedef struct {
+    int a1;
+    int a2;
+    int a3;
+    int a4;
+} UvCoeff;
+
+typedef struct {
+    int a0a;
+    int a0b;
+    UvCoeff uv;
+} Coeff;
+
+
+
+static Coeff
+coeffFromYuy2(Yuy2Pixel const yuy2) {
+
+    Coeff retval;
+
+    retval.a0a   = 298 * yuy2.y0;
+    retval.a0b   = 298 * yuy2.y1;
+    retval.uv.a1 = 409 * yuy2.v;
+    retval.uv.a2 = 100 * yuy2.u;
+    retval.uv.a3 = 208 * yuy2.v;
+    retval.uv.a4 = 516 * yuy2.u;
+
+    return retval;
+}
+
+
+
+typedef struct {
+    int r;
+    int g;
+    int b;
+} Rgb;
+
+
+
+static Rgb
+rgbFromCoeff(int     const a0,
+             UvCoeff const uv) {
+
+    Rgb retval;
+
+    retval.r = (a0 + uv.a1 + 128) >> 8;
+    retval.g = (a0 - uv.a2 - uv.a3 + 128) >> 8;
+    retval.b = (a0 + uv.a4 + 128) >> 8;
+
+    return retval;
+}
+
+
+
+static Rgb
+rgbFromCoeff0(Coeff const coeff) {
+
+    return rgbFromCoeff(coeff.a0a, coeff.uv);
+}
+
+
+
+static Rgb
+rgbFromCoeff1(Coeff const coeff) {
+
+    return rgbFromCoeff(coeff.a0b, coeff.uv);
+}
+
+
+
+static void
+rgbToTuple(Rgb   const rgb,
+           tuple const out) {
+
+    out[PAM_RED_PLANE] = MIN(255, MAX(0, rgb.r));
+    out[PAM_GRN_PLANE] = MIN(255, MAX(0, rgb.g));
+    out[PAM_BLU_PLANE] = MIN(255, MAX(0, rgb.b));
+}
+
+
+
+static void
+yuy2topam(const char * const fileName,
+          unsigned int const width,
+          unsigned int const height) {
+
+    FILE * ifP;
+    struct pam outpam;
+    tuple * tuplerow;
+    unsigned int row;
+
+    outpam.size             = sizeof(struct pam);
+    outpam.len              = PAM_STRUCT_SIZE(allocation_depth);
+    outpam.file             = stdout;
+    outpam.format           = PAM_FORMAT;
+    outpam.plainformat      = 0;
+    outpam.width            = width;
+    outpam.height           = height;
+    outpam.depth            = 3;
+    outpam.maxval           = 255;
+    outpam.bytes_per_sample = 1;
+    strcpy(outpam.tuple_type, PAM_PPM_TUPLETYPE);
+    outpam.allocation_depth = 3;
+
+    ifP = pm_openr(fileName);
+
+    pnm_writepaminit(&outpam);
+
+    tuplerow = pnm_allocpamrow(&outpam);
+
+    for (row = 0; row < outpam.height; ++row) {
+        unsigned int col;
+
+        for (col = 0; col < outpam.width; col += 2) {
+            Yuy2Pixel const yuy2 = readPixel(ifP);
+
+            Coeff const coeff = coeffFromYuy2(yuy2);
+
+            rgbToTuple(rgbFromCoeff0(coeff), tuplerow[col]);
+            rgbToTuple(rgbFromCoeff1(coeff), tuplerow[col+1]);
+        }
+        pnm_writepamrow(&outpam, tuplerow);
+    }
+    pnm_freepamrow(tuplerow);
+
+    pm_closer(ifP);
+}
+
+
+
+int
+main(int argc, const char *argv[]) {
+
+    struct CmdlineInfo cmdline;
+
+    pm_proginit(&argc, argv);
+
+    parseCommandLine(argc, argv, &cmdline);
+
+    yuy2topam(cmdline.inputFileName, cmdline.width, cmdline.height);
+
+    return 0;
+}