about summary refs log tree commit diff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2015-05-24 16:37:23 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2015-05-24 16:37:23 +0000
commitde87c6e86a9639fb0558a20d7d92134017e97965 (patch)
tree72717534dd62a25758b70250fd811274ec6aa725
parent55f66bca6c5221859ee2f5a1c68beaa94ec3025f (diff)
downloadnetpbm-mirror-de87c6e86a9639fb0558a20d7d92134017e97965.tar.gz
netpbm-mirror-de87c6e86a9639fb0558a20d7d92134017e97965.tar.xz
netpbm-mirror-de87c6e86a9639fb0558a20d7d92134017e97965.zip
Release 10.47.56
git-svn-id: http://svn.code.sf.net/p/netpbm/code/stable@2521 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--GNUmakefile4
-rw-r--r--common.mk2
-rw-r--r--converter/other/cameratopam/ljpeg.c31
-rw-r--r--converter/other/pnmtorle.c5
-rw-r--r--converter/pbm/pbmtoatk.c8
-rw-r--r--converter/pbm/pbmtog3.c2
-rw-r--r--converter/pbm/pbmtomacp.c19
-rw-r--r--converter/pbm/pbmtomgr.c13
-rw-r--r--converter/pbm/pbmtopi3.c31
-rw-r--r--converter/pbm/pbmtopk.c12
-rw-r--r--converter/pbm/pbmtoxbm.c19
-rw-r--r--converter/pbm/pktopbm.c5
-rw-r--r--converter/pgm/sbigtopgm.c5
-rw-r--r--converter/ppm/ppmtorgb3.c197
-rw-r--r--converter/ppm/ppmtoyuvsplit.c49
-rw-r--r--doc/HISTORY56
-rw-r--r--doc/USERDOC23
-rw-r--r--lib/util/nstring.c2
-rw-r--r--version.mk2
19 files changed, 322 insertions, 163 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 38564e98..c1c2d0a3 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -344,9 +344,9 @@ install.lib:
 endif
 
 .PHONY: install.manweb
-install.manweb: $(PKGDIR)/man/web/netpbm.url $(PKGDIR)/bin/doc.url
+install.manweb: $(PKGDIR)/$(PKGMANDIR)/web/netpbm.url $(PKGDIR)/bin/doc.url
 
-$(PKGDIR)/man/web/netpbm.url: $(PKGDIR)/man/web
+$(PKGDIR)/$(PKGMANDIR)/web/netpbm.url: $(PKGDIR)/$(PKGMANDIR)/web
 	echo "$(NETPBM_DOCURL)" > $@
 	chmod $(INSTALL_PERM_MAN) $@
 
diff --git a/common.mk b/common.mk
index 379b387b..ed4f68bb 100644
--- a/common.mk
+++ b/common.mk
@@ -452,8 +452,6 @@ install.man: install.man1 install.man3 install.man5 \
 
 MANUALS1 = $(BINARIES) $(SCRIPTS)
 
-PKGMANDIR = man
-
 install.man1: $(PKGDIR)/$(PKGMANDIR)/man1 $(MANUALS1:%=%_installman1)
 
 install.man3: $(PKGDIR)/$(PKGMANDIR)/man3 $(MANUALS3:%=%_installman3)
diff --git a/converter/other/cameratopam/ljpeg.c b/converter/other/cameratopam/ljpeg.c
index 18423f4f..4b092933 100644
--- a/converter/other/cameratopam/ljpeg.c
+++ b/converter/other/cameratopam/ljpeg.c
@@ -33,21 +33,26 @@ ljpeg_start (FILE * ifp, struct jhead *jh)
   do {
     fread (data, 2, 2, ifp);
     tag =  data[0] << 8 | data[1];
-    len = (data[2] << 8 | data[3]) - 2;
-    if (tag <= 0xff00 || len > 255) return 0;
-    fread (data, 1, len, ifp);
-    switch (tag) {
+    len = (data[2] << 8 | data[3]);
+    if (len < 2)
+      pm_error("Length field is %u; must be at least 2", len);
+    else {
+      unsigned int const dataLen = len - 2;
+      if (tag <= 0xff00 || dataLen > 255) return 0;
+      fread (data, 1, dataLen, ifp);
+      switch (tag) {
       case 0xffc3:
-    jh->bits = data[0];
-    jh->high = data[1] << 8 | data[2];
-    jh->wide = data[3] << 8 | data[4];
-    jh->clrs = data[5];
-    break;
+        jh->bits = data[0];
+        jh->high = data[1] << 8 | data[2];
+        jh->wide = data[3] << 8 | data[4];
+        jh->clrs = data[5];
+        break;
       case 0xffc4:
-    for (dp = data; dp < data+len && *dp < 4; ) {
-      jh->huff[*dp] = free_decode;
-      dp = make_decoder (++dp, 0);
-    }
+        for (dp = data; dp < data+dataLen && *dp < 4; ) {
+          jh->huff[*dp] = free_decode;
+          dp = make_decoder (++dp, 0);
+        }
+      }
     }
   } while (tag != 0xffda);
   jh->row = calloc (jh->wide*jh->clrs, 2);
diff --git a/converter/other/pnmtorle.c b/converter/other/pnmtorle.c
index 180b144f..8908c356 100644
--- a/converter/other/pnmtorle.c
+++ b/converter/other/pnmtorle.c
@@ -212,7 +212,6 @@ main(int argc, char **  argv) {
 
     const char * pnmname;
     const char * outname;
-    static char filename[BUFSIZ];
     int oflag;
 
     pnm_init(&argc, argv);
@@ -239,11 +238,9 @@ main(int argc, char **  argv) {
 
     /* Open the file. */
     if (pnmname == NULL) {
-        strcpy(filename, "stdin");
         fp = pm_openr("-");
     } else {
-        strcpy(filename, pnmname);
-        fp = pm_openr(filename);
+        fp = pm_openr(pnmname);
     }
 
     hdr.rle_file = rle_open_f( hdr.cmd, outname, "wb" );
diff --git a/converter/pbm/pbmtoatk.c b/converter/pbm/pbmtoatk.c
index dd829776..9399f602 100644
--- a/converter/pbm/pbmtoatk.c
+++ b/converter/pbm/pbmtoatk.c
@@ -125,7 +125,6 @@ main(int argc, char *argv[]) {
     register bit *bP;
     int rows, cols, format, row;
     int col;
-    char name[100], *cp;
     unsigned char curbyte, newbyte;
     int curcount, gather;
 
@@ -136,15 +135,8 @@ main(int argc, char *argv[]) {
 
     else if (argc-1 == 1) {
         ifd = pm_openr( argv[1] );
-        strcpy(name, argv[1]);
-        if (streq( name, "-"))
-            strcpy(name, "noname");
-        
-        if ((cp = strchr(name, '.')) != 0)
-            *cp = '\0';
     } else {
         ifd = stdin;
-        strcpy( name, "noname" );
     }
 
     pbm_readpbminit(ifd, &cols, &rows, &format);
diff --git a/converter/pbm/pbmtog3.c b/converter/pbm/pbmtog3.c
index f53bfaa0..c0dd8c64 100644
--- a/converter/pbm/pbmtog3.c
+++ b/converter/pbm/pbmtog3.c
@@ -440,7 +440,7 @@ main(int    argc,
 
     MALLOCARRAY_NOFAIL(bitrow, pbm_packed_bytes(cols) + sizeof(wordint));
 
-    MALLOCARRAY_NOFAIL(milepost, readcols + 1);
+    MALLOCARRAY_NOFAIL(milepost, readcols + 2);
 
     initOutStream(cmdline.reversebits);
     puteol();
diff --git a/converter/pbm/pbmtomacp.c b/converter/pbm/pbmtomacp.c
index ad0b22b1..9dc700e6 100644
--- a/converter/pbm/pbmtomacp.c
+++ b/converter/pbm/pbmtomacp.c
@@ -20,6 +20,8 @@
 #define EQUAL		1
 #define UNEQUAL		0
 
+#define MIN3(a,b,c)     (MIN((MIN((a),(b))),(c)))
+
 static void fillbits ARGS(( bit **bits, bit **bitsr, int top, int left, int bottom, int right ));
 static void writemacp ARGS(( bit **bits ));
 static int packit ARGS(( bit *pb, bit *bits ));
@@ -102,23 +104,18 @@ char *argv[];
     left = 0;
 
   if( rflg )
-  { if( right - left >= MAX_COLS )
-      right = left + MAX_COLS - 1;
-  }
+    right = MIN3( right, cols - 1, left + MAX_COLS - 1 );
   else
-    right = ( left + MAX_COLS > cols ) ? ( cols - 1 ) : ( left + MAX_COLS - 1 );
+    right = MIN( cols - 1,  left + MAX_COLS - 1 );
 
   if( !tflg )
     top = 0;
 
   if( bflg )
-  { if( bottom - top >= MAX_LINES )
-      bottom = top + MAX_LINES - 1;
-  }
+    bottom = MIN3( bottom, rows - 1, top + MAX_LINES - 1);
   else
-    bottom = ( top + MAX_LINES > rows ) ?
-		   ( rows - 1 ) : ( top + MAX_LINES - 1 );
-  
+    bottom = MIN( rows - 1, top + MAX_LINES - 1 );
+
     if( right <= left || left < 0 || right - left + 1 > MAX_COLS )
       pm_error("error in right (= %d) and/or left (=%d)",right,left );
     if( bottom <= top || top < 0 || bottom - top + 1 > MAX_LINES )
@@ -220,7 +217,7 @@ packit( pb, bits )
       save = *srcb++;
       charcount--;
       newcount = 1;
-      while( (*srcb == save) && charcount ) { 
+      while( charcount && (*srcb == save) ) { 
           srcb++;
           newcount++;
           charcount--;
diff --git a/converter/pbm/pbmtomgr.c b/converter/pbm/pbmtomgr.c
index 2ca7c7d0..d12e6635 100644
--- a/converter/pbm/pbmtomgr.c
+++ b/converter/pbm/pbmtomgr.c
@@ -6,9 +6,12 @@
    ftp://sunsite.unc.edu/pub/Linux/apps/MGR/!INDEX.html
 */
 
+#include <assert.h>
 #include "pbm.h"
 #include "mgr.h"
 
+
+
 static void
 putinit(unsigned int const rows,
         unsigned int const cols) {
@@ -16,6 +19,10 @@ putinit(unsigned int const rows,
     struct b_header head;
     size_t writtenCount;
 
+    /* Because of argument restrictions: maximum dimensions: */
+    assert((rows & 0xfff) == rows);
+    assert((cols & 0xfff) == cols);
+
     head.magic[0] = 'y';
     head.magic[1] = 'z';
     head.h_wide = ((cols >> 6) & 0x3f) + ' ';
@@ -48,6 +55,8 @@ main(int argc,
            a multiple of 8, i.e. an integral number of packed bytes.
         */
     const char * inputFileName;
+    unsigned int const maxDimension = 4095;
+        /* Dimensions are 2 characters of the header -- 12 bits */
 
     pbm_init(&argc, argv);
 
@@ -62,6 +71,10 @@ main(int argc,
     ifP = pm_openr(inputFileName);
 
     pbm_readpbminit(ifP, &cols, &rows, &format);
+    if (cols > maxDimension)
+        pm_error("Image width too large: %u (max: %u)", cols, maxDimension);
+    if (rows > maxDimension)
+        pm_error("Image height too large: %u (max: %u)", rows, maxDimension);
     
     bitrow = pbm_allocrow_packed(cols);
     bytesPerRow = pbm_packed_bytes(cols);
diff --git a/converter/pbm/pbmtopi3.c b/converter/pbm/pbmtopi3.c
index 6a60af62..1dbf1a71 100644
--- a/converter/pbm/pbmtopi3.c
+++ b/converter/pbm/pbmtopi3.c
@@ -14,6 +14,7 @@
 
 #include <stdio.h>
 #include "pbm.h"
+#include "pm_c_util.h"
 
 static void putinit ARGS(( void ));
 static void putbit ARGS(( bit b ));
@@ -28,8 +29,9 @@ main( argc, argv )
     FILE* ifp;
     bit* bitrow;
     register bit* bP;
-    int rows, cols, format, padright, row, col;
-
+    int inrows, incols, format, padright, row, col;
+    int const outcols = 640;
+    int const outrows = 400;
 
     pbm_init( &argc, argv );
 
@@ -41,27 +43,26 @@ main( argc, argv )
     else
 	ifp = stdin;
 
-    pbm_readpbminit( ifp, &cols, &rows, &format );
-    if (cols > 640)
-	cols = 640;
-    if (rows > 400)
-	rows = 400;
-    bitrow = pbm_allocrow( cols );
-    
+    pbm_readpbminit( ifp, &incols, &inrows, &format );
+    bitrow = pbm_allocrow( MAX(incols, outcols) );
+
     /* Compute padding to round cols up to 640 */
-    padright = 640 - cols;
+    if(incols < outcols)
+        padright = outcols - incols;
+    else 
+        padright = 0;
 
     putinit( );
-    for ( row = 0; row < rows; ++row )
+    for ( row = 0; row < MIN(inrows, outrows); ++row )
 	{
-	pbm_readpbmrow( ifp, bitrow, cols, format );
-        for ( col = 0, bP = bitrow; col < cols; ++col, ++bP )
+	pbm_readpbmrow( ifp, bitrow, incols, format );
+        for ( col = 0, bP = bitrow; col < MIN(incols, outcols); ++col, ++bP )
 	    putbit( *bP );
 	for ( col = 0; col < padright; ++col )
 	    putbit( 0 );
         }
-    while (row++ < 400)
-	for ( col = 0; col < 640; ++col)
+    while (row++ < outrows)
+	for ( col = 0; col < outcols; ++col)
 	    putbit( 0 );
 
     pm_close( ifp );
diff --git a/converter/pbm/pbmtopk.c b/converter/pbm/pbmtopk.c
index a9683190..fc94f855 100644
--- a/converter/pbm/pbmtopk.c
+++ b/converter/pbm/pbmtopk.c
@@ -854,11 +854,17 @@ main(int argc, char *argv[]) {
     initialize_pk() ;
    
     if (--argc < 1) pm_usage(usage) ;
-    strcpy(pkname, *++argv) ;
+    ++argv;
+    if(strlen(*argv) + 4 > NAMELENGTH)
+        pm_error("pkname is too long");
+    strcpy(pkname, *argv) ;
     pbmtopk_add_suffix(pkname, ".pk") ;
    
-    if (--argc < 1) pm_usage(usage) ;
-    strcpy(tfmname, *++argv) ;
+    if (--argc < 1) pm_usage(usage);
+    ++argv;
+    if(strlen(*argv) + 4 > NAMELENGTH)
+        pm_error("tfmname is too long");
+    strcpy(tfmname, *argv) ;
     pbmtopk_add_suffix(tfmname, ".tfm") ;
    
     if (--argc < 1) pm_usage(usage) ;
diff --git a/converter/pbm/pbmtoxbm.c b/converter/pbm/pbmtoxbm.c
index 937e56c5..340642ce 100644
--- a/converter/pbm/pbmtoxbm.c
+++ b/converter/pbm/pbmtoxbm.c
@@ -249,7 +249,7 @@ puttermX10(void) {
                     (i == 0) ? " " : "",
                     itemBuff[i+1],
                     itemBuff[i], 
-                    (i == itemCnt - 2) ? "};\n" : ",");
+                    (i == itemCnt - 2) ? "" : ",");
         if (rc < 0)        
             pm_error("Error writing end of X10 bitmap raster.  "
                      "printf() failed with errno %d (%s)",
@@ -270,7 +270,7 @@ puttermX11(void) {
         rc = printf("%s0x%02x%s",
                     (i == 0)  ? " " : "",
                     itemBuff[i],
-                    (i == itemCnt - 1) ? "};\n" : ",");
+                    (i == itemCnt - 1) ? "" : ",");
 
         if (rc < 0)        
             pm_error("Error writing end of X11 bitmap raster.  "
@@ -297,6 +297,17 @@ putterm(void) {
     case X10: puttermX10(); break;
     case X11: puttermX11(); break;
     }
+
+    {
+        int rc;
+
+        rc = printf("};\n");
+
+        if (rc < 0)        
+            pm_error("Error writing end of X11 bitmap raster.  "
+                     "printf() failed with errno %d (%s)",
+                     errno, strerror(errno));
+    }
 }
 
 
@@ -339,7 +350,6 @@ convertRaster(FILE *          const ifP,
     putinit(xbmVersion);
 
     bitrow = pbm_allocrow_packed(cols + padright);
-    bitrow[bitrowBytes-1] = 0;
     
     for (row = 0; row < rows; ++row) {
         int const bitrowInBytes = pbm_packed_bytes(cols);
@@ -354,6 +364,9 @@ convertRaster(FILE *          const ifP,
             bitrow[bitrowInBytes - 1] <<= padrightIn;
         }
 
+        if (padright >= 8)
+            bitrow[bitrowBytes-1] = 0x00;
+
         for (i = 0; i < bitrowBytes; ++i)
             putitem(bitrow[i]);
     }
diff --git a/converter/pbm/pktopbm.c b/converter/pbm/pktopbm.c
index a3584ee5..712f339f 100644
--- a/converter/pbm/pktopbm.c
+++ b/converter/pbm/pktopbm.c
@@ -214,7 +214,10 @@ main(int argc, char *argv[]) {
 
     if (--argc < 1) pm_usage(usage) ;
 
-    strcpy(pkname, *++argv) ;
+    ++argv;
+    if(strlen(*argv) + 4 > NAMELENGTH)
+        pm_error("pkname is too long");
+    strcpy(pkname, *argv) ;
     pktopbm_add_suffix(pkname, ".pk") ;
 
     car = 0 ;
diff --git a/converter/pgm/sbigtopgm.c b/converter/pgm/sbigtopgm.c
index 17e1e01e..8e933752 100644
--- a/converter/pgm/sbigtopgm.c
+++ b/converter/pgm/sbigtopgm.c
@@ -61,7 +61,7 @@ int main(argc, argv)
     register int col;
     int maxval;
     int comp, rows, cols;
-    char header[SBIG_HEADER_LENGTH];
+    char header[SBIG_HEADER_LENGTH+1];
     char *hdr;
     static char camera[80] = "ST-?";
 
@@ -82,6 +82,7 @@ int main(argc, argv)
     if (fread(header, SBIG_HEADER_LENGTH, 1, ifp) < 1) {
         pm_error("error reading SBIG file header");
     }
+    header[SBIG_HEADER_LENGTH] = '\0';
 
     /*	Walk through the header and parse relevant parameters.	*/
 
@@ -127,7 +128,7 @@ int main(argc, argv)
 
 	    if (ep != NULL) {
 		*ep = 0;
-		strcpy(camera, hdr);
+		STRSCPY(camera, hdr);
                 *ep = ' ';
 	    }
 	}
diff --git a/converter/ppm/ppmtorgb3.c b/converter/ppm/ppmtorgb3.c
index 21d3346a..b1ac8087 100644
--- a/converter/ppm/ppmtorgb3.c
+++ b/converter/ppm/ppmtorgb3.c
@@ -1,4 +1,4 @@
-/* ppmtorgb3.c - separate a portable pixmap into three portable graymaps
+/* ppmtorgb3.c - separate a PPM image into 3 PGM images.
 **
 ** Copyright (C) 1991 by Jef Poskanzer.
 **
@@ -11,89 +11,134 @@
 */
 
 #include <string.h>
+#include "pm_c_util.h"
+#include "mallocvar.h"
+#include "nstring.h"
 #include "ppm.h"
 #include "pgm.h"
 
-int
-main( argc, argv )
-    int argc;
-    char* argv[];
+
+
+struct Cmdline {
+    const char * inputFileName;
+};
+
+
+
+static const char *
+strippedOfExtension(const char * const arg) {
+
+    char * buffer;
+
+    MALLOCARRAY(buffer, strlen(arg) + 1);
+
+    strcpy(buffer, arg);
+
     {
-    FILE* ifp;
-    FILE* redfile;
-    FILE* grnfile;
-    FILE* blufile;
-    const char* basename;
-    char filename[100];
-    char* cp;
-    pixel* pixelrow;
-    register pixel* pP;
-    gray* grayrow;
-    register gray* gP;
-    int rows, cols, format, row;
-    register int col;
+        char * const dotPos = strrchr(buffer, '.');
+        if (dotPos)
+            *dotPos = '\0';
+    }
+    return buffer;
+}
+
+
+
+static void
+openComponentOut(const char * const suffix,
+                 const char * const baseName,
+                 FILE **      const fpP) {
+
+    const char * fileName;
+
+    asprintfN(&fileName, "%s.%s", baseName, suffix);
+
+    *fpP = pm_openw(fileName);
+
+    strfree(fileName);
+}
+
+
+
+int
+main(int argc, const char ** argv) {
+
+    FILE * ifP;
+    FILE * redfP;
+    FILE * grnfP;
+    FILE * blufP;
+    pixel * pixelrow;
+    gray * grayrow;
+    int rows, cols;
+    int format;
+    unsigned int row;
     pixval maxval;
+    struct Cmdline cmdline;
+    const char * baseFileName;
+
+    pm_proginit(&argc, argv);
 
+    if (argc-1 > 1)
+        pm_error("Too many arguments (%u).  The only possible argument "
+                 "is the input file name", argc-1);
 
-    ppm_init( &argc, argv );
+    if (argc-1 < 1)
+        cmdline.inputFileName = "-";
+    else
+        cmdline.inputFileName = argv[1];
 
-    if ( argc > 2 )
-	pm_usage( "[ppmfile]" );
+    ifP = pm_openr(cmdline.inputFileName);
 
-    if ( argc == 2 )
-	{
-	ifp = pm_openr( argv[1] );
-	basename = argv[1];
-	cp = strrchr( basename, '.' );
-	if ( cp != NULL )
-	    *cp = '\0';
-	}
+    if (streq(cmdline.inputFileName, "-"))
+        asprintfN(&baseFileName, "noname");
     else
-	{
-	ifp = stdin;
-	basename = "noname";
-	}
-
-    ppm_readppminit( ifp, &cols, &rows, &maxval, &format );
-    pixelrow = ppm_allocrow( cols );
-    (void) strcpy( filename, basename );
-    (void) strcat( filename, ".red" );
-    redfile = pm_openw( filename );
-    pgm_writepgminit( redfile, cols, rows, (gray) maxval, 0 );
-    (void) strcpy( filename, basename );
-    (void) strcat( filename, ".grn" );
-    grnfile = pm_openw( filename );
-    pgm_writepgminit( grnfile, cols, rows, (gray) maxval, 0 );
-    (void) strcpy( filename, basename );
-    (void) strcat( filename, ".blu" );
-    blufile = pm_openw( filename );
-    pgm_writepgminit( blufile, cols, rows, (gray) maxval, 0 );
-    grayrow = pgm_allocrow( cols );
-
-    for ( row = 0; row < rows; ++row )
-	{
-	ppm_readppmrow( ifp, pixelrow, cols, maxval, format );
-
-	for ( col = 0, pP = pixelrow, gP = grayrow; col < cols;
-	      ++col, ++pP, ++gP )
-	    *gP = (gray) PPM_GETR( *pP );
-	pgm_writepgmrow( redfile, grayrow, cols, maxval, 0 );
-
-	for ( col = 0, pP = pixelrow, gP = grayrow; col < cols;
-	      ++col, ++pP, ++gP )
-	    *gP = (gray) PPM_GETG( *pP );
-	pgm_writepgmrow( grnfile, grayrow, cols, maxval, 0 );
-
-	for ( col = 0, pP = pixelrow, gP = grayrow; col < cols;
-	      ++col, ++pP, ++gP )
-	    *gP = (gray) PPM_GETB( *pP );
-	pgm_writepgmrow( blufile, grayrow, cols, maxval, 0 );
-	}
-
-    pm_close( ifp );
-    pm_close( redfile );
-    pm_close( blufile );
-    pm_close( grnfile );
-
-    exit( 0 );
+        baseFileName = strippedOfExtension(cmdline.inputFileName);
+
+    ppm_readppminit(ifP, &cols, &rows, &maxval, &format);
+
+    pixelrow = ppm_allocrow(cols);
+
+    openComponentOut("red", baseFileName, &redfP);
+    openComponentOut("grn", baseFileName, &grnfP);
+    openComponentOut("blu", baseFileName, &blufP);
+
+    pgm_writepgminit(redfP, cols, rows, maxval, 0);
+    pgm_writepgminit(grnfP, cols, rows, maxval, 0);
+    pgm_writepgminit(blufP, cols, rows, maxval, 0);
+
+    grayrow = pgm_allocrow(cols);
+
+    for (row = 0; row < rows; ++row) {
+        unsigned int col;
+
+        ppm_readppmrow(ifP, pixelrow, cols, maxval, format);
+
+        for (col = 0; col < cols; ++col)
+            grayrow[col] = PPM_GETR(pixelrow[col]);
+
+        pgm_writepgmrow(redfP, grayrow, cols, maxval, 0);
+
+        for (col = 0; col < cols; ++col)
+            grayrow[col] = PPM_GETG(pixelrow[col]);
+
+        pgm_writepgmrow(grnfP, grayrow, cols, maxval, 0);
+
+        for (col = 0; col < cols; ++col)
+            grayrow[col] = PPM_GETB(pixelrow[col]);
+
+        pgm_writepgmrow(blufP, grayrow, cols, maxval, 0);
     }
+
+    pgm_freerow(grayrow);
+    ppm_freerow(pixelrow);
+    strfree(baseFileName);
+    pm_close(ifP);
+    pm_close(blufP);
+    pm_close(grnfP);
+    pm_close(redfP);
+
+    return 0;
+}
+
+
+
diff --git a/converter/ppm/ppmtoyuvsplit.c b/converter/ppm/ppmtoyuvsplit.c
index e4ffaa3a..eb89ad29 100644
--- a/converter/ppm/ppmtoyuvsplit.c
+++ b/converter/ppm/ppmtoyuvsplit.c
@@ -29,8 +29,40 @@
 #endif
 
 #include <string.h>
+#include "nstring.h"
 #include "ppm.h"
 
+
+
+struct FileNameSet {
+    const char * u;
+    const char * v;
+    const char * y;
+};
+
+
+
+static void
+makeOutputFileName(const char *         const baseName,
+                   struct FileNameSet * const fnameP) {
+
+    pm_asprintf(&fnameP->u, "%s.U", baseName);
+    pm_asprintf(&fnameP->v, "%s.V", baseName);
+    pm_asprintf(&fnameP->y, "%s.Y", baseName);
+}
+
+
+
+static void
+termFileNameSet(struct FileNameSet const fname) {
+
+    pm_strfree(fname.u);
+    pm_strfree(fname.v);
+    pm_strfree(fname.y);
+}
+
+
+
 int
 main(int argc, const char ** argv) {
 
@@ -42,7 +74,8 @@ main(int argc, const char ** argv) {
     unsigned int row;
     pixval maxval;
     unsigned char *y1buf, *y2buf, *ubuf, *vbuf;
-    char ufname[256], vfname[256], yfname[256];
+    struct FileNameSet fname;
+        /* Output file names - .U, .V, .Y */
 
     pm_proginit(&argc, argv);
 
@@ -56,17 +89,13 @@ main(int argc, const char ** argv) {
     else
         ifP = stdin;
 
-    strcpy(ufname,argv[1]);
-    strcpy(vfname,argv[1]);
-    strcpy(yfname,argv[1]);
+    makeOutputFileName(argv[1], &fname);
 
-    strcat(ufname,".U");
-    strcat(vfname,".V");
-    strcat(yfname,".Y");
+    uf = pm_openw(fname.u);
+    vf = pm_openw(fname.v);
+    yf = pm_openw(fname.y);
 
-    uf = pm_openw(ufname);
-    vf = pm_openw(vfname);
-    yf = pm_openw(yfname);
+    termFileNameSet(fname);
 
     ppm_readppminit(ifP, &cols, &rows, &maxval, &format);
 
diff --git a/doc/HISTORY b/doc/HISTORY
index 584a50dc..a45cdb69 100644
--- a/doc/HISTORY
+++ b/doc/HISTORY
@@ -4,6 +4,62 @@ Netpbm.
 CHANGE HISTORY 
 --------------
 
+15.05.24 BJH  Release 10.47.56
+
+              libnetpbm: pm_stripeq: fix bug: wild pointer access when
+              comparator is shorter than comparand.  Doesn't affect function,
+              but could cause crash or privacy exposure.  Affects reading of a
+              PAM file by any program.  Introduced in one of Netpbm 10.27
+              (March 2005) through 10.35 (August 2006).
+
+              pbmtog3: Fix buffer overrun.  Introduced in Netpbm 10.23
+              (July 2004).
+
+              pbmtog3: Fix buffer overrun.  Introduced in Netpbm 10.23
+              (July 2004).
+
+              cameratopam: Fix arithmetic underflow in JPEG processing;
+              unknown effect.
+
+              pbmtoxbm: Fix bug: crash with zero width input.  Broken in
+              Netpbm 10.37 (December 2006).
+
+              sbigtopgm: fix buffer overrun with invalid input image.  Always
+              present (sbigtopgm was new in Netpbm 8.3 (March 2000)).
+
+              pnmtorle: Fix buffer overrun with long file name.  Always
+              present.  (pnmtorle was new to Netpbm in Netpbm 9.0 (April
+              2000)).
+
+              pbmtopk: Fix buffer overrun with long file name.  Always
+              present.  (pbmtopk was new in Netpbm 1 (March 1991)).
+
+              pktopbm: Fix buffer overrun with long file name.  Always
+              present.  (pbmtopk was new in Netpbm 1 (March 1991)).
+
+              ppmtoyuvsplit: Fix buffer overrun with long file name.  Always
+              present.  (New in Netpbm 1 (March 1991)).
+
+              pbmtopi3: Fix bug: wrong output when input is higher or wider
+              than 640 pixels.  Always broken (pbmtopi3 was new in September
+              1991).
+
+              pbmtomgr: Fix incorrect output when input is too large (must be
+              at most 4095 pixels high or wide).
+
+              pbmtomacp: fix wild pointer dereference with -b larger than
+              image height.  Always broken.  (pbmtomacp was new in X.V11R3
+              (March 1988).
+
+              ppmtorgb3: Fix buffer overflow with long input file name.
+              Always present.  (ppmtorgb3 was new in X.V11R4 (November 1989).
+
+              pbmtoatk: Fix crash with very long input file name argument.
+              Always broken (pbmtoatk was new in 1991).
+
+              Build: fix 'make package' where config.mk sets a subdirectory
+              other than 'man' for the manual.
+
 15.03.29 BJH  Release 10.47.55
 
               pamtosvg: fix use of unset variable; probably results in a
diff --git a/doc/USERDOC b/doc/USERDOC
index 0eec24b4..d1da64e1 100644
--- a/doc/USERDOC
+++ b/doc/USERDOC
@@ -18,24 +18,27 @@ so you can use the current manual with old Netpbm code.
 INSTALLING A LOCAL COPY OF DOCUMENTATION
 ----------------------------------------
 
-If accessing the manual on the World Wide Web is not convenient for
-you (for example, if you want to access it from a computer that is not
-always connected to the Internet), just make a local copy of the web
-site files.  An obvious way to do that is just to copy the web site
-with GNU Wget:
+If accessing the manual on the World Wide Web is not convenient for you (for
+example, if you want to access it from a computer that is not always connected
+to the Internet), just make a local copy of the HTML files.
 
-  wget --recursive --relative http://netpbm.sourceforge.net/doc/
-
-However, a somewhat cleaner way is to get the files from the
-Subversion repository using the Subversion client program 'svn':
+You can get the files from the Subversion repository using the Subversion
+client program 'svn':
 
-  URL=https://netpbm.svn.sourceforge.net/svnroot/netpbm/userguide
+  URL=https://svn.code.sf.net/p/netpbm/code/userguide
   svn export $URL
 
 This creates a directory "userguide" in your current directory containing
 all the same files that are on the web site.
 
 
+An apparent alternative is just to copy the web site with something like GNU
+Wget.  However, the Sourceforge web server has limitations on how much you can
+download.  In a February 2012 experiment, Sourceforge started refusing HTTP
+requests (with an Internal Server Error indication and a message saying there
+had been too many requests) before all the files could be fetched.
+
+
 GETTING COMMAND HELP WITH A "MAN" COMMAND
 -----------------------------------------
 
diff --git a/lib/util/nstring.c b/lib/util/nstring.c
index 0fa78c7a..8842aa05 100644
--- a/lib/util/nstring.c
+++ b/lib/util/nstring.c
@@ -868,7 +868,7 @@ stripeq(const char * const comparand,
      */
     if (px - p != qx - q) equal = 0;
 
-
+    else
     while (p <= px) {
         if (*p != *q) equal = 0;
         p++; q++;
diff --git a/version.mk b/version.mk
index b25513f6..a687c653 100644
--- a/version.mk
+++ b/version.mk
@@ -1,3 +1,3 @@
 NETPBM_MAJOR_RELEASE = 10
 NETPBM_MINOR_RELEASE = 47
-NETPBM_POINT_RELEASE = 55
+NETPBM_POINT_RELEASE = 56