diff --git a/.gitignore b/.gitignore index 6c496c0..f4510f8 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,15 @@ /netpbm-10.90.00.tar.xz /netpbm-10.92.00.tar.xz /netpbm-10.93.00.tar.xz +/netpbm-10.94.05.tar.xz +/netpbm-10.95.00.tar.xz +/netpbm-10.96.00.tar.xz +/netpbm-10.97.00.tar.xz +/netpbm-10.99.00.tar.xz +/netpbm-11.00.00.tar.xz +/netpbm-11.01.00.tar.xz +/netpbm-11.02.00.tar.xz +/netpbm-11.09.00.tar.xz +/netpbm-11.10.00.tar.xz +/netpbm-11.12.00.tar.xz +/netpbm-11.13.00.tar.xz diff --git a/fix.patch b/fix.patch new file mode 100644 index 0000000..b3c3cb9 --- /dev/null +++ b/fix.patch @@ -0,0 +1,1336 @@ +diff --git a/analyzer/pgmtexture.c b/analyzer/pgmtexture.c +index c69643e..2e09dde 100644 +--- a/analyzer/pgmtexture.c ++++ b/analyzer/pgmtexture.c +@@ -54,6 +54,7 @@ vector(unsigned int const nl, + + assert(nh >= nl); + ++ overflow_add(nh - nl, 1); + MALLOCARRAY(v, (unsigned) (nh - nl + 1)); + + if (v == NULL) +@@ -85,6 +86,7 @@ matrix (unsigned int const nrl, + assert(nrh >= nrl); + + /* allocate pointers to rows */ ++ overflow_add(nrh - nrl, 1); + MALLOCARRAY(m, (unsigned) (nrh - nrl + 1)); + if (m == NULL) + pm_error("Unable to allocate memory for a matrix."); +@@ -93,6 +95,7 @@ matrix (unsigned int const nrl, + + assert (nch >= ncl); + ++ overflow_add(nch - ncl, 1); + /* allocate rows and set pointers to them */ + for (i = nrl; i <= nrh; ++i) { + MALLOCARRAY(m[i], (unsigned) (nch - ncl + 1)); +diff --git a/converter/other/gemtopnm.c b/converter/other/gemtopnm.c +index 6bbfcc0..24199cb 100644 +--- a/converter/other/gemtopnm.c ++++ b/converter/other/gemtopnm.c +@@ -106,6 +106,7 @@ main(argc, argv) + + pnm_writepnminit( stdout, cols, rows, MAXVAL, type, 0 ); + ++ overflow_add(cols, padright); + { + /* allocate input row data structure */ + int plane; +diff --git a/converter/other/jpegtopnm.c b/converter/other/jpegtopnm.c +index 98552c0..311298c 100644 +--- a/converter/other/jpegtopnm.c ++++ b/converter/other/jpegtopnm.c +@@ -862,6 +862,8 @@ convertImage(FILE * const ofP, + /* Calculate output image dimensions so we can allocate space */ + jpeg_calc_output_dimensions(cinfoP); + ++ overflow2(cinfoP->output_width, cinfoP->output_components); ++ + /* Start decompressor */ + jpeg_start_decompress(cinfoP); + +diff --git a/converter/other/pbmtopgm.c b/converter/other/pbmtopgm.c +index 817fb5b..8baaa57 100644 +--- a/converter/other/pbmtopgm.c ++++ b/converter/other/pbmtopgm.c +@@ -60,6 +60,7 @@ main(int argc, char *argv[]) { + + + outrow = pgm_allocrow(cols) ; ++ overflow2(width, height); + maxval = MIN(PGM_OVERALLMAXVAL, width*height); + pgm_writepgminit(stdout, cols, rows, maxval, 0) ; + +diff --git a/converter/other/pnmtoddif.c b/converter/other/pnmtoddif.c +index b7b942b..52be0e4 100644 +--- a/converter/other/pnmtoddif.c ++++ b/converter/other/pnmtoddif.c +@@ -629,6 +629,7 @@ main(int argc, char *argv[]) { + switch (PNM_FORMAT_TYPE(format)) { + case PBM_TYPE: + ip.bits_per_pixel = 1; ++ overflow_add(cols, 7); + ip.bytes_per_line = (cols + 7) / 8; + ip.spectral = 2; + ip.components = 1; +@@ -644,6 +645,7 @@ main(int argc, char *argv[]) { + ip.polarity = 2; + break; + case PPM_TYPE: ++ overflow2(cols, 3); + ip.bytes_per_line = 3 * cols; + ip.bits_per_pixel = 24; + ip.spectral = 5; +diff --git a/converter/other/pnmtojpeg.c b/converter/other/pnmtojpeg.c +index e345831..39038f8 100644 +--- a/converter/other/pnmtojpeg.c ++++ b/converter/other/pnmtojpeg.c +@@ -605,8 +605,10 @@ read_scan_script(j_compress_ptr const cinfo, + data, but if you want to compress multiple images you'd + want JPOOL_PERMANENT. + */ ++ overflow2(nscans, sizeof(jpeg_scan_info)); + const unsigned int scan_info_size = nscans * sizeof(jpeg_scan_info); +- jpeg_scan_info * const scan_info = ++ const jpeg_scan_info * scan_info; ++ scan_info = + (jpeg_scan_info *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + scan_info_size); +@@ -938,6 +940,8 @@ compute_rescaling_array(JSAMPLE ** const rescale_p, const pixval maxval, + const long half_maxval = maxval / 2; + long val; + ++ overflow_add(maxval, 1); ++ overflow2(maxval+1, sizeof(JSAMPLE)); + *rescale_p = (JSAMPLE *) + (cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_IMAGE, + (size_t) (((long) maxval + 1L) * +@@ -1016,6 +1020,7 @@ convert_scanlines(struct jpeg_compress_struct * const cinfo_p, + */ + + /* Allocate the libpnm output and compressor input buffers */ ++ overflow2(cinfo_p->image_width, cinfo_p->input_components); + buffer = (*cinfo_p->mem->alloc_sarray) + ((j_common_ptr) cinfo_p, JPOOL_IMAGE, + (unsigned int) cinfo_p->image_width * cinfo_p->input_components, +diff --git a/converter/other/pnmtops.c b/converter/other/pnmtops.c +index 45d856d..5b04eeb 100644 +--- a/converter/other/pnmtops.c ++++ b/converter/other/pnmtops.c +@@ -294,17 +294,21 @@ parseCommandLine(int argc, const char ** argv, + validateCompDimension(width, 72, "-width value"); + validateCompDimension(height, 72, "-height value"); + ++ overflow2(width, 72); + cmdlineP->width = width * 72; ++ overflow2(height, 72); + cmdlineP->height = height * 72; + + if (imagewidthSpec) { + validateCompDimension(imagewidth, 72, "-imagewidth value"); ++ overflow2(imagewidth, 72); + cmdlineP->imagewidth = imagewidth * 72; + } + else + cmdlineP->imagewidth = 0; + if (imageheightSpec) { +- validateCompDimension(imagewidth, 72, "-imageheight value"); ++ validateCompDimension(imageheight, 72, "-imageheight value"); ++ overflow2(imageheight, 72); + cmdlineP->imageheight = imageheight * 72; + } + else +diff --git a/converter/other/rletopnm.c b/converter/other/rletopnm.c +index 97f271d..72b63d3 100644 +--- a/converter/other/rletopnm.c ++++ b/converter/other/rletopnm.c +@@ -19,6 +19,8 @@ + * If you modify this software, you should include a notice giving the + * name of the person performing the modification, the date of modification, + * and the reason for such modification. ++ * ++ * 2002-12-19: Fix maths wrapping bugs. Alan Cox + */ + /* + * rletopnm - A conversion program to convert from Utah's "rle" image format +diff --git a/converter/other/sirtopnm.c b/converter/other/sirtopnm.c +index fafcc91..9fe49d0 100644 +--- a/converter/other/sirtopnm.c ++++ b/converter/other/sirtopnm.c +@@ -69,6 +69,7 @@ char* argv[]; + } + break; + case PPM_TYPE: ++ overflow3(cols, rows, 3); + picsize = cols * rows * 3; + planesize = cols * rows; + if ( !( sirarray = (unsigned char*) malloc( picsize ) ) ) +diff --git a/converter/other/tifftopnm.c b/converter/other/tifftopnm.c +index 05493e7..7ea59fd 100644 +--- a/converter/other/tifftopnm.c ++++ b/converter/other/tifftopnm.c +@@ -1372,6 +1372,7 @@ convertRasterByRows(pnmOut * const pnmOutP, + if (scanbuf == NULL) + pm_error("can't allocate memory for scanline buffer"); + ++ overflow2(cols,spp); + MALLOCARRAY(samplebuf, cols * spp); + if (samplebuf == NULL) + pm_error("can't allocate memory for row buffer"); +diff --git a/converter/other/xwdtopnm.c b/converter/other/xwdtopnm.c +index a74da34..4d26a31 100644 +--- a/converter/other/xwdtopnm.c ++++ b/converter/other/xwdtopnm.c +@@ -210,6 +210,10 @@ processX10Header(X10WDFileHeader * const h10P, + *colorsP = pnm_allocrow(2); + PNM_ASSIGN1((*colorsP)[0], 0); + PNM_ASSIGN1((*colorsP)[1], *maxvalP); ++ overflow_add(h10P->pixmap_width, 15); ++ if(h10P->pixmap_width < 0) ++ pm_error("assert: negative width"); ++ overflow2((((h10P->pixmap_width + 15) / 16) * 16 - h10P->pixmap_width), 8); + *padrightP = + (((h10P->pixmap_width + 15) / 16) * 16 - h10P->pixmap_width) * 8; + *bits_per_itemP = 16; +@@ -635,6 +639,7 @@ processX11Header(X11WDFileHeader * const h11P, + + *colsP = h11FixedP->pixmap_width; + *rowsP = h11FixedP->pixmap_height; ++ overflow2(h11FixedP->bytes_per_line, 8); + *padrightP = + h11FixedP->bytes_per_line * 8 - + h11FixedP->pixmap_width * h11FixedP->bits_per_pixel; +diff --git a/converter/pbm/mdatopbm.c b/converter/pbm/mdatopbm.c +index 461b3f8..c8bab6c 100644 +--- a/converter/pbm/mdatopbm.c ++++ b/converter/pbm/mdatopbm.c +@@ -245,10 +245,13 @@ main(int argc, char **argv) { + pm_readlittleshort(infile, &yy); nInCols = yy; + } + ++ overflow2(nOutCols, 8); + nOutCols = 8 * nInCols; + nOutRows = nInRows; +- if (bScale) ++ if (bScale) { ++ overflow2(nOutRows, 2); + nOutRows *= 2; ++ } + + data = pbm_allocarray(nOutCols, nOutRows); + +diff --git a/converter/pbm/mgrtopbm.c b/converter/pbm/mgrtopbm.c +index 9f7004a..f2c1590 100644 +--- a/converter/pbm/mgrtopbm.c ++++ b/converter/pbm/mgrtopbm.c +@@ -67,6 +67,7 @@ readMgrHeader(FILE * const ifP, + + *colsP = (((int)head.h_wide - ' ') << 6) + ((int)head.l_wide - ' '); + *rowsP = (((int)head.h_high - ' ') << 6) + ((int) head.l_high - ' '); ++ overflow_add(*colsP, pad); + *padrightP = ( ( *colsP + pad - 1 ) / pad ) * pad - *colsP; + } + +diff --git a/converter/pbm/pbmto4425.c b/converter/pbm/pbmto4425.c +index 1d97ac6..c4c8cbb 100644 +--- a/converter/pbm/pbmto4425.c ++++ b/converter/pbm/pbmto4425.c +@@ -2,6 +2,7 @@ + + #include "nstring.h" + #include "pbm.h" ++#include + + static char bit_table[2][3] = { + {1, 4, 0x10}, +@@ -160,7 +161,7 @@ main(int argc, char * argv[]) { + xres = vmap_width * 2; + yres = vmap_height * 3; + +- vmap = malloc(vmap_width * vmap_height * sizeof(char)); ++ vmap = malloc3(vmap_width, vmap_height, sizeof(char)); + if(vmap == NULL) + { + pm_error( "Cannot allocate memory" ); +diff --git a/converter/pbm/pbmtogem.c b/converter/pbm/pbmtogem.c +index 4fd30e9..c82757d 100644 +--- a/converter/pbm/pbmtogem.c ++++ b/converter/pbm/pbmtogem.c +@@ -79,6 +79,7 @@ putinit (int const rows, int const cols) + bitsperitem = 0; + bitshift = 7; + outcol = 0; ++ overflow_add(cols, 7); + outmax = (cols + 7) / 8; + outrow = (unsigned char *) pm_allocrow (outmax, sizeof (unsigned char)); + lastrow = (unsigned char *) pm_allocrow (outmax, sizeof (unsigned char)); +diff --git a/converter/pbm/pbmtogo.c b/converter/pbm/pbmtogo.c +index 4f84f39..943dc84 100644 +--- a/converter/pbm/pbmtogo.c ++++ b/converter/pbm/pbmtogo.c +@@ -158,6 +158,7 @@ main(int argc, + bitrow = pbm_allocrow(cols); + + /* Round cols up to the nearest multiple of 8. */ ++ overflow_add(cols, 7); + rucols = ( cols + 7 ) / 8; + bytesperrow = rucols; /* GraphOn uses bytes */ + rucols = rucols * 8; +diff --git a/converter/pbm/pbmtolj.c b/converter/pbm/pbmtolj.c +index 3cd7670..0b51932 100644 +--- a/converter/pbm/pbmtolj.c ++++ b/converter/pbm/pbmtolj.c +@@ -120,7 +120,11 @@ parseCommandLine(int argc, char ** argv, + static void + allocateBuffers(unsigned int const cols) { + ++ overflow_add(cols, 8); + rowBufferSize = (cols + 7) / 8; ++ overflow_add(rowBufferSize, 128); ++ overflow_add(rowBufferSize, rowBufferSize+128); ++ overflow_add(rowBufferSize+10, rowBufferSize/8); + packBufferSize = rowBufferSize + (rowBufferSize + 127) / 128 + 1; + deltaBufferSize = rowBufferSize + rowBufferSize / 8 + 10; + +diff --git a/converter/pbm/pbmtomda.c b/converter/pbm/pbmtomda.c +index 3ad5149..9efe5cf 100644 +--- a/converter/pbm/pbmtomda.c ++++ b/converter/pbm/pbmtomda.c +@@ -179,6 +179,7 @@ int main(int argc, char **argv) + + nOutRowsUnrounded = bScale ? nInRows/2 : nInRows; + ++ overflow_add(nOutRowsUnrounded, 3); + nOutRows = ((nOutRowsUnrounded + 3) / 4) * 4; + /* MDA wants rows a multiple of 4 */ + nOutCols = nInCols / 8; +diff --git a/converter/pbm/pbmtoppa/pbm.c b/converter/pbm/pbmtoppa/pbm.c +index ae36e0d..b8c89c9 100644 +--- a/converter/pbm/pbmtoppa/pbm.c ++++ b/converter/pbm/pbmtoppa/pbm.c +@@ -154,6 +154,7 @@ pbm_readline(pbm_stat * const pbmStatP, + break; + case P4: { + int tmp, tmp2; ++ overflow_add(pbmStatP->width, 7); + tmp = (pbmStatP->width+7)/8; + tmp2 = fread(data,1,tmp,pbmStatP->fptr); + if (tmp2 == tmp) { +@@ -186,6 +187,7 @@ pbm_unreadline(pbm_stat * const pbmStatP, + + if (!pbmStatP->unread) { + pbmStatP->unread = 1; ++ overflow_add(pbmStatP->width, 7); + pbmStatP->revdata = malloc ((pbmStatP->width+7)/8); + memcpy(pbmStatP->revdata, data, (pbmStatP->width+7)/8); + --pbmStatP->current_line; +diff --git a/converter/pbm/pbmtoppa/pbmtoppa.c b/converter/pbm/pbmtoppa/pbmtoppa.c +index ff4a599..aa510ec 100644 +--- a/converter/pbm/pbmtoppa/pbmtoppa.c ++++ b/converter/pbm/pbmtoppa/pbmtoppa.c +@@ -453,6 +453,7 @@ main(int argc, char *argv[]) { + pm_error("main(): unrecognized parameter '%s'", argv[argn]); + } + ++ overflow_add(Width, 7); + Pwidth=(Width+7)/8; + printer.fptr=out; + +diff --git a/converter/pbm/pbmtoxbm.c b/converter/pbm/pbmtoxbm.c +index ecb72b3..600461f 100644 +--- a/converter/pbm/pbmtoxbm.c ++++ b/converter/pbm/pbmtoxbm.c +@@ -352,6 +352,7 @@ convertRaster(FILE * const ifP, + + unsigned char * bitrow; + unsigned int row; ++ overflow_add(cols, padright); + + putinit(xbmVersion); + +diff --git a/converter/pbm/pktopbm.c b/converter/pbm/pktopbm.c +index 712f339..b6fcb02 100644 +--- a/converter/pbm/pktopbm.c ++++ b/converter/pbm/pktopbm.c +@@ -280,6 +280,7 @@ main(int argc, char *argv[]) { + if (flagbyte == 7) { /* long form preamble */ + integer packetlength = get32() ; /* character packet length */ + car = get32() ; /* character number */ ++ overflow_add(packetlength, pktopbm_pkloc); + endofpacket = packetlength + pktopbm_pkloc; + /* calculate end of packet */ + if ((car >= MAXPKCHAR) || !filename[car]) { +diff --git a/converter/pbm/thinkjettopbm.l b/converter/pbm/thinkjettopbm.l +index 5de4f2b..cc1810c 100644 +--- a/converter/pbm/thinkjettopbm.l ++++ b/converter/pbm/thinkjettopbm.l +@@ -114,7 +114,9 @@ DIG [0-9] + \033\*b{DIG}+W { + int l; + if (rowCount >= rowCapacity) { ++ overflow_add(rowCapacity, 100); + rowCapacity += 100; ++ overflow2(rowCapacity, sizeof *rows); + rows = realloc (rows, rowCapacity * sizeof *rows); + if (rows == NULL) + pm_error ("Out of memory."); +@@ -226,6 +228,7 @@ yywrap (void) + /* + * Quite simple since ThinkJet bit arrangement matches PBM + */ ++ overflow2(maxRowLength, 8); + pbm_writepbminit(stdout, maxRowLength*8, rowCount, 0); + + packed_bitrow = malloc(maxRowLength); +diff --git a/converter/pbm/ybmtopbm.c b/converter/pbm/ybmtopbm.c +index 2a42908..cf1ff03 100644 +--- a/converter/pbm/ybmtopbm.c ++++ b/converter/pbm/ybmtopbm.c +@@ -43,6 +43,7 @@ getinit(FILE * const ifP, + pm_error("EOF / read error"); + + *depthP = 1; ++ overflow_add(*colsP, 15); + } + + +diff --git a/converter/pgm/lispmtopgm.c b/converter/pgm/lispmtopgm.c +index 40dd3fb..8dd9cae 100644 +--- a/converter/pgm/lispmtopgm.c ++++ b/converter/pgm/lispmtopgm.c +@@ -58,6 +58,7 @@ main( argc, argv ) + pm_error( "depth (%d bits) is too large", depth); + + pgm_writepgminit( stdout, cols, rows, (gray) maxval, 0 ); ++ overflow_add(cols, 7); + grayrow = pgm_allocrow( ( cols + 7 ) / 8 * 8 ); + + for ( row = 0; row < rows; ++row ) +@@ -103,6 +104,7 @@ getinit( file, colsP, rowsP, depthP, padrightP ) + if ( *depthP == 0 ) + *depthP = 1; /* very old file */ + ++ overflow_add((int)colsP, 31); + *padrightP = ( ( *colsP + 31 ) / 32 ) * 32 - *colsP; + + if ( *colsP != (cols_32 - *padrightP) ) { +diff --git a/converter/pgm/psidtopgm.c b/converter/pgm/psidtopgm.c +index 07417d1..25bb311 100644 +--- a/converter/pgm/psidtopgm.c ++++ b/converter/pgm/psidtopgm.c +@@ -78,6 +78,7 @@ main(int argc, + pm_error("bits/sample (%d) is too large.", bitspersample); + + pgm_writepgminit(stdout, cols, rows, maxval, 0); ++ overflow_add(cols, 7); + grayrow = pgm_allocrow((cols + 7) / 8 * 8); + for (row = 0; row < rows; ++row) { + unsigned int col; +diff --git a/converter/ppm/Makefile b/converter/ppm/Makefile +index 003ef8d..b97349d 100644 +--- a/converter/ppm/Makefile ++++ b/converter/ppm/Makefile +@@ -11,7 +11,7 @@ SUBDIRS = hpcdtoppm ppmtompeg + + PORTBINARIES = 411toppm eyuvtoppm gouldtoppm ilbmtoppm imgtoppm \ + leaftoppm mtvtoppm neotoppm \ +- pcxtoppm pc1toppm pi1toppm picttoppm pjtoppm \ ++ pcxtoppm pc1toppm pi1toppm pjtoppm \ + ppmtoacad ppmtoapplevol ppmtoarbtxt ppmtoascii \ + ppmtobmp ppmtoeyuv ppmtogif ppmtoicr ppmtoilbm \ + ppmtoleaf ppmtolj ppmtomitsu ppmtoneo \ +diff --git a/converter/ppm/ilbmtoppm.c b/converter/ppm/ilbmtoppm.c +index b9b8986..f4fe331 100644 +--- a/converter/ppm/ilbmtoppm.c ++++ b/converter/ppm/ilbmtoppm.c +@@ -608,6 +608,7 @@ decode_row(FILE * const ifP, + rawtype *chp; + + cols = bmhdP->w; ++ overflow_add(cols, 15); + bytes = RowBytes(cols); + for( plane = 0; plane < nPlanes; plane++ ) { + int mask; +@@ -695,6 +696,23 @@ decode_mask(FILE * const ifP, + Multipalette handling + ****************************************************************************/ + ++static void * ++xmalloc2(x, y) ++ int x; ++ int y; ++{ ++ void *mem; ++ ++ overflow2(x,y); ++ if( x * y == 0 ) ++ return NULL; ++ ++ mem = malloc2(x,y); ++ if( mem == NULL ) ++ pm_error("out of memory allocating %d bytes", x * y); ++ return mem; ++} ++ + + static void + multi_adjust(ColorMap * const cmapP, +@@ -1363,6 +1381,9 @@ dcol_to_ppm(FILE * const ifP, + if( redmaxval != maxval || greenmaxval != maxval || bluemaxval != maxval ) + pm_message("scaling colors to %d bits", pm_maxvaltobits(maxval)); + ++ overflow_add(redmaxval, 1); ++ overflow_add(greenmaxval, 1); ++ overflow_add(bluemaxval, 1); + MALLOCARRAY_NOFAIL(redtable, redmaxval +1); + MALLOCARRAY_NOFAIL(greentable, greenmaxval +1); + MALLOCARRAY_NOFAIL(bluetable, bluemaxval +1); +@@ -1802,7 +1823,9 @@ PCHG_ConvertSmall(PCHGHeader * const pchgP, + ChangeCount32 = *data++; + remDataSize -= 2; + ++ overflow_add(ChangeCount16, ChangeCount32); + changes = ChangeCount16 + ChangeCount32; ++ overflow_add(changes, 1); + for (i = 0; i < changes; ++i) { + if (totalchanges >= pchgP->TotalChanges) goto fail; + if (remDataSize < 2) goto fail; +@@ -2067,6 +2090,9 @@ read_pchg(FILE * const ifP, + cmap->mp_change[i] = NULL; + if( PCHG.StartLine < 0 ) { + int nch; ++ if(PCHG.MaxReg < PCHG.MinReg) ++ pm_error("assert: MinReg > MaxReg"); ++ overflow_add(PCHG.MaxReg-PCHG.MinReg, 2); + nch = PCHG.MaxReg - PCHG.MinReg +1; + MALLOCARRAY_NOFAIL(cmap->mp_init, nch + 1); + for( i = 0; i < nch; i++ ) +@@ -2143,6 +2169,7 @@ process_body( FILE * const ifP, + if (typeid == ID_ILBM) { + int isdeep; + ++ overflow_add(bmhdP->w, 15); + MALLOCARRAY_NOFAIL(ilbmrow, RowBytes(bmhdP->w)); + *viewportmodesP |= fakeviewport; /* -isham/-isehb */ + +diff --git a/converter/ppm/imgtoppm.c b/converter/ppm/imgtoppm.c +index 7078b88..eb8509e 100644 +--- a/converter/ppm/imgtoppm.c ++++ b/converter/ppm/imgtoppm.c +@@ -84,6 +84,7 @@ main(int argc, char ** argv) { + len = atoi((char*) buf ); + if ( fread( buf, len, 1, ifp ) != 1 ) + pm_error( "bad colormap buf" ); ++ overflow2(cmaplen, 3); + if ( cmaplen * 3 != len ) + { + pm_message( +@@ -105,6 +106,7 @@ main(int argc, char ** argv) { + pm_error( "bad pixel data header" ); + buf[8] = '\0'; + len = atoi((char*) buf ); ++ overflow2(cols, rows); + if ( len != cols * rows ) + pm_message( + "pixel data length (%d) does not match image size (%d)", +diff --git a/converter/ppm/pcxtoppm.c b/converter/ppm/pcxtoppm.c +index e252ba2..270ae3b 100644 +--- a/converter/ppm/pcxtoppm.c ++++ b/converter/ppm/pcxtoppm.c +@@ -409,6 +409,7 @@ pcx_planes_to_pixels(pixels, bitplanes, bytesperline, planes, bitsperpixel) + /* + * clear the pixel buffer + */ ++ overflow2(bytesperline, 8); + npixels = (bytesperline * 8) / bitsperpixel; + p = pixels; + while (--npixels >= 0) +@@ -470,6 +471,7 @@ pcx_16col_to_ppm(FILE * const ifP, + } + + /* BytesPerLine should be >= BitsPerPixel * cols / 8 */ ++ overflow2(BytesPerLine, 8); + rawcols = BytesPerLine * 8 / BitsPerPixel; + if (headerCols > rawcols) { + pm_message("warning - BytesPerLine = %d, " +diff --git a/converter/ppm/picttoppm.c b/converter/ppm/picttoppm.c +index 9cf570e..6020f67 100644 +--- a/converter/ppm/picttoppm.c ++++ b/converter/ppm/picttoppm.c +@@ -1,3 +1,4 @@ ++#error "Unfixable. Don't ship me" + /* + * picttoppm.c -- convert a MacIntosh PICT file to PPM format. + * +diff --git a/converter/ppm/pjtoppm.c b/converter/ppm/pjtoppm.c +index ffb01d0..eb11e8d 100644 +--- a/converter/ppm/pjtoppm.c ++++ b/converter/ppm/pjtoppm.c +@@ -149,12 +149,17 @@ main(int argc, const char ** argv) { + case 'V': /* send plane */ + case 'W': /* send last plane */ + if (rows == -1 || row >= rows || image == NULL) { +- if (rows == -1 || row >= rows) ++ if (rows == -1 || row >= rows) { ++ overflow_add(rows, 100); + rows += 100; ++ } ++ + if (image == NULL) { ++ overflow2(rows,planes); + MALLOCARRAY(image, uintProduct(rows, planes)); + MALLOCARRAY(imlen, uintProduct(rows, planes)); + } else { ++ overflow2(rows,planes); + REALLOCARRAY(image, uintProduct(rows, planes)); + REALLOCARRAY(imlen, uintProduct(rows, planes)); + } +@@ -235,8 +240,10 @@ main(int argc, const char ** argv) { + col += 2) + for (cmd = image[plane + row * planes][col], + val = image[plane + row * planes][col+1]; +- cmd >= 0 && i < newcols; cmd--, i++) ++ cmd >= 0 && i < newcols; cmd--, i++) { + buf[i] = val; ++ overflow_add(i, 1); ++ } + cols = MAX(cols, i); + free(image[plane + row * planes]); + /* +@@ -247,6 +254,7 @@ main(int argc, const char ** argv) { + image[plane + row * planes] = realloc(buf, i); + } + } ++ overflow2(cols, 8); + cols *= 8; + } + +diff --git a/converter/ppm/ppmtoeyuv.c b/converter/ppm/ppmtoeyuv.c +index f5ce115..6f072be 100644 +--- a/converter/ppm/ppmtoeyuv.c ++++ b/converter/ppm/ppmtoeyuv.c +@@ -114,6 +114,7 @@ create_multiplication_tables(const pixval maxval) { + + int index; + ++ overflow_add(maxval, 1); + MALLOCARRAY_NOFAIL(mult299 , maxval+1); + MALLOCARRAY_NOFAIL(mult587 , maxval+1); + MALLOCARRAY_NOFAIL(mult114 , maxval+1); +diff --git a/converter/ppm/ppmtolj.c b/converter/ppm/ppmtolj.c +index 7ed814e..b4e7db1 100644 +--- a/converter/ppm/ppmtolj.c ++++ b/converter/ppm/ppmtolj.c +@@ -182,6 +182,7 @@ int main(int argc, char *argv[]) { + ppm_readppminit( ifp, &cols, &rows, &maxval, &format ); + pixelrow = ppm_allocrow( cols ); + ++ overflow2(cols, 6); + obuf = (unsigned char *) pm_allocrow(cols * 3, sizeof(unsigned char)); + cbuf = (unsigned char *) pm_allocrow(cols * 6, sizeof(unsigned char)); + if (mode == C_TRANS_MODE_DELTA) +diff --git a/converter/ppm/ppmtomitsu.c b/converter/ppm/ppmtomitsu.c +index 50b790d..63d3182 100644 +--- a/converter/ppm/ppmtomitsu.c ++++ b/converter/ppm/ppmtomitsu.c +@@ -685,6 +685,8 @@ main(int argc, char * argv[]) { + medias = MSize_User; + + if (dpi300) { ++ overflow2(medias.maxcols, 2); ++ overflow2(medias.maxrows, 2); + medias.maxcols *= 2; + medias.maxrows *= 2; + } +diff --git a/converter/ppm/ppmtopcx.c b/converter/ppm/ppmtopcx.c +index 76f0629..e7b06ff 100644 +--- a/converter/ppm/ppmtopcx.c ++++ b/converter/ppm/ppmtopcx.c +@@ -422,6 +422,8 @@ ppmTo16ColorPcx(pixel ** const pixels, + else Planes = 1; + } + } ++ overflow2(BitsPerPixel, cols); ++ overflow_add(BitsPerPixel * cols, 7); + BytesPerLine = ((cols * BitsPerPixel) + 7) / 8; + MALLOCARRAY_NOFAIL(indexRow, cols); + MALLOCARRAY_NOFAIL(planesrow, BytesPerLine); +diff --git a/converter/ppm/ppmtopict.c b/converter/ppm/ppmtopict.c +index 36464b6..c91ccf2 100644 +--- a/converter/ppm/ppmtopict.c ++++ b/converter/ppm/ppmtopict.c +@@ -450,6 +450,8 @@ main(int argc, const char ** argv) { + putShort(stdout, 0); /* mode */ + + /* Finally, write out the data. */ ++ overflow_add(cols/MAX_COUNT, 1); ++ overflow_add(cols, cols/MAX_COUNT+1); + outBuf = malloc((unsigned)(cols+cols/MAX_COUNT+1)); + for (row = 0, oc = 0; row < rows; ++row) { + unsigned int rowSize; +diff --git a/converter/ppm/ppmtopj.c b/converter/ppm/ppmtopj.c +index d116773..49d08fc 100644 +--- a/converter/ppm/ppmtopj.c ++++ b/converter/ppm/ppmtopj.c +@@ -179,6 +179,7 @@ char *argv[]; + pixels = ppm_readppm( ifp, &cols, &rows, &maxval ); + + pm_close( ifp ); ++ overflow2(cols,2); + obuf = (unsigned char *) pm_allocrow(cols, sizeof(unsigned char)); + cbuf = (unsigned char *) pm_allocrow(cols * 2, sizeof(unsigned char)); + +diff --git a/converter/ppm/ppmtopjxl.c b/converter/ppm/ppmtopjxl.c +index 90bcef0..72d0027 100644 +--- a/converter/ppm/ppmtopjxl.c ++++ b/converter/ppm/ppmtopjxl.c +@@ -267,6 +267,9 @@ main(int argc, const char * argv[]) { + if (maxval > PCL_MAXVAL) + pm_error("color range too large; reduce with ppmcscale"); + ++ if (cols < 0 || rows < 0) ++ pm_error("negative size is not possible"); ++ + /* Figure out the colormap. */ + pm_message("Computing colormap..."); + chv = ppm_computecolorhist(pixels, cols, rows, MAXCOLORS, &colors); +@@ -286,6 +289,8 @@ main(int argc, const char * argv[]) { + case 0: /* direct mode (no palette) */ + bpp = bitsperpixel(maxval); /* bits per pixel */ + bpg = bpp; bpb = bpp; ++ overflow2(bpp, 3); ++ overflow_add(bpp*3, 7); + bpp = (bpp*3+7)>>3; /* bytes per pixel now */ + bpr = (bpp<<3)-bpg-bpb; + bpp *= cols; /* bytes per row now */ +@@ -295,9 +300,13 @@ main(int argc, const char * argv[]) { + case 3: case 7: pclindex++; + default: + bpp = 8/pclindex; ++ overflow_add(cols, bpp); ++ if(bpp == 0) ++ pm_error("assert: no bpp"); + bpp = (cols+bpp-1)/bpp; /* bytes per row */ + } + } ++ overflow2(bpp,2); + inrow = (char *)malloc((unsigned)bpp); + outrow = (char *)malloc((unsigned)bpp*2); + runcnt = (signed char *)malloc((unsigned)bpp); +diff --git a/converter/ppm/ppmtowinicon.c b/converter/ppm/ppmtowinicon.c +index c673798..f026c08 100644 +--- a/converter/ppm/ppmtowinicon.c ++++ b/converter/ppm/ppmtowinicon.c +@@ -12,6 +12,7 @@ + + #include + #include ++#include + + #include "pm_c_util.h" + #include "winico.h" +@@ -214,6 +215,7 @@ createAndBitmap (gray ** const ba, int const cols, int const rows, + MALLOCARRAY_NOFAIL(rowData, rows); + icBitmap->xBytes = xBytes; + icBitmap->data = rowData; ++ overflow2(xBytes, rows); + icBitmap->size = xBytes * rows; + for (y=0;yxBytes = xBytes; + icBitmap->data = rowData; ++ overflow2(xBytes, rows); + icBitmap->size = xBytes * rows; + + for (y=0;yxBytes = xBytes; + icBitmap->data = rowData; ++ overflow2(xBytes, rows); + icBitmap->size = xBytes * rows; + + for (y=0;ybitcount = bpp; + entry->ih = createInfoHeader(entry, xorBitmap, andBitmap); + entry->colors = palette->colors; ++ overflow2(4, entry->color_count); ++ overflow_add(xorBitmap->size, andBitmap->size); ++ overflow_add(xorBitmap->size + andBitmap->size, 40); ++ overflow_add(xorBitmap->size + andBitmap->size + 40, 4 * entry->color_count); + entry->size_in_bytes = + xorBitmap->size + andBitmap->size + 40 + (4 * entry->color_count); + if (verbose) +diff --git a/converter/ppm/ppmtoxpm.c b/converter/ppm/ppmtoxpm.c +index 0e31692..1b3923f 100644 +--- a/converter/ppm/ppmtoxpm.c ++++ b/converter/ppm/ppmtoxpm.c +@@ -198,6 +198,7 @@ genNumstr(unsigned int const input, int const digits) { + unsigned int i; + + /* Allocate memory for printed number. Abort if error. */ ++ overflow_add(digits, 1); + if (!(str = (char *) malloc(digits + 1))) + pm_error("out of memory"); + +@@ -315,6 +316,7 @@ genCmap(colorhist_vector const chv, + unsigned int charsPerPixel; + unsigned int xpmMaxval; + ++ if (includeTransparent) overflow_add(ncolors, 1); + MALLOCARRAY(cmap, cmapSize); + if (cmapP == NULL) + pm_error("Out of memory allocating %u bytes for a color map.", +diff --git a/converter/ppm/qrttoppm.c b/converter/ppm/qrttoppm.c +index 935463e..653084c 100644 +--- a/converter/ppm/qrttoppm.c ++++ b/converter/ppm/qrttoppm.c +@@ -46,7 +46,7 @@ main( argc, argv ) + + ppm_writeppminit( stdout, cols, rows, maxval, 0 ); + pixelrow = ppm_allocrow( cols ); +- buf = (unsigned char *) malloc( 3 * cols ); ++ buf = (unsigned char *) malloc2( 3 , cols ); + if ( buf == (unsigned char *) 0 ) + pm_error( "out of memory" ); + +diff --git a/converter/ppm/sldtoppm.c b/converter/ppm/sldtoppm.c +index 2fef023..ce73025 100644 +--- a/converter/ppm/sldtoppm.c ++++ b/converter/ppm/sldtoppm.c +@@ -506,6 +506,8 @@ slider(slvecfn slvec, + + /* Allocate image buffer and clear it to black. */ + ++ overflow_add(ixdots, 1); ++ overflow_add(iydots, 1); + pixels = ppm_allocarray(pixcols = ixdots + 1, pixrows = iydots + 1); + PPM_ASSIGN(rgbcolor, 0, 0, 0); + ppmd_filledrectangle(pixels, pixcols, pixrows, pixmaxval, 0, 0, +diff --git a/converter/ppm/ximtoppm.c b/converter/ppm/ximtoppm.c +index 9620942..e9083f3 100644 +--- a/converter/ppm/ximtoppm.c ++++ b/converter/ppm/ximtoppm.c +@@ -118,6 +118,7 @@ ReadXimHeader(FILE * const in_fp, + header->bits_channel = atoi(a_head.bits_per_channel); + header->alpha_flag = atoi(a_head.alpha_channel); + if (strlen(a_head.author)) { ++ overflow_add(strlen(a_head.author),1); + if (!(header->author = calloc((unsigned int)strlen(a_head.author)+1, + 1))) { + pm_message("ReadXimHeader: can't calloc author string" ); +@@ -127,6 +128,7 @@ ReadXimHeader(FILE * const in_fp, + strncpy(header->author, a_head.author, strlen(a_head.author)); + } + if (strlen(a_head.date)) { ++ overflow_add(strlen(a_head.date),1); + if (!(header->date =calloc((unsigned int)strlen(a_head.date)+1,1))){ + pm_message("ReadXimHeader: can't calloc date string" ); + return(0); +@@ -135,6 +137,7 @@ ReadXimHeader(FILE * const in_fp, + strncpy(header->date, a_head.date, strlen(a_head.date)); + } + if (strlen(a_head.program)) { ++ overflow_add(strlen(a_head.program),1); + if (!(header->program = calloc( + (unsigned int)strlen(a_head.program) + 1, 1))) { + pm_message("ReadXimHeader: can't calloc program string" ); +@@ -161,6 +164,7 @@ ReadXimHeader(FILE * const in_fp, + if (header->nchannels == 3 && header->bits_channel == 8) + header->ncolors = 0; + else if (header->nchannels == 1 && header->bits_channel == 8) { ++ overflow2(header->ncolors, sizeof(Color)); + header->colors = (Color *)calloc((unsigned int)header->ncolors, + sizeof(Color)); + if (header->colors == NULL) { +diff --git a/editor/pamcut.c b/editor/pamcut.c +index 1fc9d9b..ad0e030 100644 +--- a/editor/pamcut.c ++++ b/editor/pamcut.c +@@ -799,6 +799,8 @@ cutOneImage(FILE * const ifP, + + outpam = inpam; /* Initial value -- most fields should be same */ + outpam.file = ofP; ++ overflow_add(rightcol, 1); ++ overflow_add(bottomrow, 1); + outpam.width = rightcol - leftcol + 1; + outpam.height = bottomrow - toprow + 1; + +diff --git a/editor/pnmgamma.c b/editor/pnmgamma.c +index 1fdf20e..98b7e90 100644 +--- a/editor/pnmgamma.c ++++ b/editor/pnmgamma.c +@@ -596,6 +596,7 @@ createGammaTables(enum transferFunction const transferFunction, + xelval ** const btableP) { + + /* Allocate space for the tables. */ ++ overflow_add(maxval, 1); + MALLOCARRAY(*rtableP, maxval+1); + MALLOCARRAY(*gtableP, maxval+1); + MALLOCARRAY(*btableP, maxval+1); +diff --git a/editor/pnmhisteq.c b/editor/pnmhisteq.c +index a339f73..c2c85a3 100644 +--- a/editor/pnmhisteq.c ++++ b/editor/pnmhisteq.c +@@ -107,6 +107,7 @@ computeLuminosityHistogram(xel * const * const xels, + unsigned int pixelCount; + unsigned int * lumahist; + ++ overflow_add(maxval, 1); + MALLOCARRAY(lumahist, maxval + 1); + if (lumahist == NULL) + pm_error("Out of storage allocating array for %u histogram elements", +diff --git a/editor/pnmindex.csh b/editor/pnmindex.csh +index c6f1e84..c513a84 100755 +--- a/editor/pnmindex.csh ++++ b/editor/pnmindex.csh +@@ -1,5 +1,7 @@ + #!/bin/csh -f + # ++echo "Unsafe code, needs debugging, do not ship" ++exit 1 + # pnmindex - build a visual index of a bunch of anymaps + # + # Copyright (C) 1991 by Jef Poskanzer. +diff --git a/editor/pnmpad.c b/editor/pnmpad.c +index 55cdcd6..10da3af 100644 +--- a/editor/pnmpad.c ++++ b/editor/pnmpad.c +@@ -654,6 +654,8 @@ main(int argc, const char ** argv) { + + computePadSizes(cmdline, cols, rows, &lpad, &rpad, &tpad, &bpad); + ++ overflow_add(cols, lpad); ++ overflow_add(cols + lpad, rpad); + newcols = cols + lpad + rpad; + + if (cmdline.reportonly) +diff --git a/editor/pnmremap.c b/editor/pnmremap.c +index 0c0096b..8b86cb7 100644 +--- a/editor/pnmremap.c ++++ b/editor/pnmremap.c +@@ -468,6 +468,7 @@ fserr_init(struct pam * const pamP, + + unsigned int const fserrSize = pamP->width + 2; + ++ overflow_add(pamP->width, 2); + fserrP->width = pamP->width; + + MALLOCARRAY(fserrP->thiserr, pamP->depth); +@@ -506,6 +507,7 @@ floydInitRow(struct pam * const pamP, + + unsigned int col; + ++ overflow_add(pamP->width, 2); + for (col = 0; col < pamP->width + 2; ++col) { + unsigned int plane; + for (plane = 0; plane < pamP->depth; ++plane) +diff --git a/editor/pnmscalefixed.c b/editor/pnmscalefixed.c +index 884ca31..f4d7086 100644 +--- a/editor/pnmscalefixed.c ++++ b/editor/pnmscalefixed.c +@@ -214,6 +214,7 @@ compute_output_dimensions(const struct cmdline_info cmdline, + const int rows, const int cols, + int * newrowsP, int * newcolsP) { + ++ overflow2(rows, cols); + if (cmdline.pixels) { + if (rows * cols <= cmdline.pixels) { + *newrowsP = rows; +@@ -265,6 +266,7 @@ compute_output_dimensions(const struct cmdline_info cmdline, + + if (*newcolsP < 1) *newcolsP = 1; + if (*newrowsP < 1) *newrowsP = 1; ++ overflow2(*newcolsP, *newrowsP); + } + + +@@ -446,6 +448,8 @@ main(int argc, char **argv ) { + unfilled. We can address that by stretching, whereas the other + case would require throwing away some of the input. + */ ++ overflow2(newcols, SCALE); ++ overflow2(newrows, SCALE); + sxscale = SCALE * newcols / cols; + syscale = SCALE * newrows / rows; + +diff --git a/editor/ppmdither.c b/editor/ppmdither.c +index ec1b977..c46a974 100644 +--- a/editor/ppmdither.c ++++ b/editor/ppmdither.c +@@ -352,6 +352,9 @@ dithMatrix(unsigned int const dithPower) { + assert(dithPower < sizeof(unsigned int) * 8); + + { ++ overflow2(dithDim, sizeof(*dithMat)); ++ overflow3(dithDim, dithDim, sizeof(**dithMat)); ++ overflow_add(dithDim * sizeof(*dithMat), dithDim * dithDim * sizeof(**dithMat)); + unsigned int const dithMatSize = + (dithDim * sizeof(*dithMat)) + /* pointers */ + (dithDim * dithDim * sizeof(**dithMat)); /* data */ +diff --git a/editor/specialty/pamoil.c b/editor/specialty/pamoil.c +index 6cb8d3a..6f4bde9 100644 +--- a/editor/specialty/pamoil.c ++++ b/editor/specialty/pamoil.c +@@ -112,6 +112,7 @@ main(int argc, char *argv[] ) { + tuples = pnm_readpam(ifp, &inpam, PAM_STRUCT_SIZE(tuple_type)); + pm_close(ifp); + ++ overflow_add(inpam.maxval, 1); + MALLOCARRAY(hist, inpam.maxval + 1); + if (hist == NULL) + pm_error("Unable to allocate memory for histogram."); +diff --git a/lib/libpam.c b/lib/libpam.c +index a8f140b..e6986f1 100644 +--- a/lib/libpam.c ++++ b/lib/libpam.c +@@ -225,7 +225,8 @@ allocPamRow(const struct pam * const pamP) { + unsigned int const bytesPerTuple = allocationDepth(pamP) * sizeof(sample); + tuple * tuplerow; + +- tuplerow = malloc(pamP->width * (sizeof(tuple *) + bytesPerTuple)); ++ overflow_add(sizeof(tuple *), bytesPerTuple); ++ tuplerow = malloc2(pamP->width, (sizeof(tuple *) + bytesPerTuple)); + + if (tuplerow != NULL) { + /* Now we initialize the pointers to the individual tuples +diff --git a/lib/libpammap.c b/lib/libpammap.c +index 569156f..bc24d22 100644 +--- a/lib/libpammap.c ++++ b/lib/libpammap.c +@@ -108,6 +108,8 @@ allocTupleIntListItem(struct pam * const pamP) { + */ + struct tupleint_list_item * retval; + ++ overflow2(pamP->depth, sizeof(sample)); ++ overflow_add(sizeof(*retval)-sizeof(retval->tupleint.tuple), pamP->depth*sizeof(sample)); + unsigned int const size = + sizeof(*retval) - sizeof(retval->tupleint.tuple) + + pamP->depth * sizeof(sample); +diff --git a/lib/libpm.c b/lib/libpm.c +index 47a2f49..a263598 100644 +--- a/lib/libpm.c ++++ b/lib/libpm.c +@@ -888,5 +888,53 @@ pm_parse_height(const char * const arg) { + return height; + } + ++/* ++ * Maths wrapping ++ */ + ++void __overflow2(int a, int b) ++{ ++ if(a < 0 || b < 0) ++ pm_error("object too large"); ++ if(b == 0) ++ return; ++ if(a > INT_MAX / b) ++ pm_error("object too large"); ++} ++ ++void overflow3(int a, int b, int c) ++{ ++ overflow2(a,b); ++ overflow2(a*b, c); ++} ++ ++void overflow_add(int a, int b) ++{ ++ if( a > INT_MAX - b) ++ pm_error("object too large"); ++} ++ ++void *malloc2(int a, int b) ++{ ++ overflow2(a, b); ++ if(a*b == 0) ++ pm_error("Zero byte allocation"); ++ return malloc(a*b); ++} ++ ++void *malloc3(int a, int b, int c) ++{ ++ overflow3(a, b, c); ++ if(a*b*c == 0) ++ pm_error("Zero byte allocation"); ++ return malloc(a*b*c); ++} ++ ++void *realloc2(void * a, int b, int c) ++{ ++ overflow2(b, c); ++ if(b*c == 0) ++ pm_error("Zero byte allocation"); ++ return realloc(a, b*c); ++} + +diff --git a/lib/pm.h b/lib/pm.h +index 3fc92fb..17a25f1 100644 +--- a/lib/pm.h ++++ b/lib/pm.h +@@ -441,5 +441,12 @@ pm_parse_height(const char * const arg); + } + #endif + ++#define overflow2(a,b) __overflow2(a,b) ++void __overflow2(int, int); ++void overflow3(int, int, int); ++void overflow_add(int, int); ++void *malloc2(int, int); ++void *malloc3(int, int, int); ++void *realloc2(void *, int, int); + + #endif +diff --git a/other/pnmcolormap.c b/other/pnmcolormap.c +index 7da3122..dafa390 100644 +--- a/other/pnmcolormap.c ++++ b/other/pnmcolormap.c +@@ -1002,6 +1002,7 @@ colormapToSquare(struct pam * const pamP, + pamP->width = intsqrt; + else + pamP->width = intsqrt + 1; ++ overflow_add(intsqrt, 1); + } + { + unsigned int const intQuotient = colormap.size / pamP->width; +diff --git a/urt/Runput.c b/urt/Runput.c +index 3bc562a..cb6e7c5 100644 +--- a/urt/Runput.c ++++ b/urt/Runput.c +@@ -202,9 +202,11 @@ RunSetup(rle_hdr * the_hdr) + if ( the_hdr->background != 0 ) + { + register int i; +- register rle_pixel *background = +- (rle_pixel *)malloc( (unsigned)(the_hdr->ncolors + 1) ); ++ register rle_pixel *background; + register int *bg_color; ++ ++ overflow_add(the_hdr->ncolors,1); ++ background = (rle_pixel *)malloc( (unsigned)(the_hdr->ncolors + 1) ); + /* + * If even number of bg color bytes, put out one more to get to + * 16 bit boundary. +@@ -224,7 +226,7 @@ RunSetup(rle_hdr * the_hdr) + /* Big-endian machines are harder */ + register int i, nmap = (1 << the_hdr->cmaplen) * + the_hdr->ncmap; +- register char *h_cmap = (char *)malloc( nmap * 2 ); ++ register char *h_cmap = (char *)malloc2( nmap, 2 ); + if ( h_cmap == NULL ) + { + fprintf( stderr, +diff --git a/urt/rle.h b/urt/rle.h +index 0071774..6a905ba 100644 +--- a/urt/rle.h ++++ b/urt/rle.h +@@ -152,6 +152,17 @@ rle_hdr /* End of typedef. */ + */ + extern rle_hdr rle_dflt_hdr; + ++/* ++ * Provided by pm library ++ */ ++ ++extern void overflow_add(int, int); ++#define overflow2(a,b) __overflow2(a,b) ++extern void __overflow2(int, int); ++extern void overflow3(int, int, int); ++extern void *malloc2(int, int); ++extern void *malloc3(int, int, int); ++extern void *realloc2(void *, int, int); + + /* Declare RLE library routines. */ + +diff --git a/urt/rle_addhist.c b/urt/rle_addhist.c +index b165175..e09ed94 100644 +--- a/urt/rle_addhist.c ++++ b/urt/rle_addhist.c +@@ -70,13 +70,18 @@ rle_addhist(char * argv[], + return; + + length = 0; +- for (i = 0; argv[i]; ++i) ++ for (i = 0; argv[i]; ++i) { ++ overflow_add(length, strlen(argv[i])); ++ overflow_add(length+1, strlen(argv[i])); + length += strlen(argv[i]) +1; /* length of each arg plus space. */ ++ } + + time(&temp); + timedate = ctime(&temp); + length += strlen(timedate); /* length of date and time in ASCII. */ +- ++ overflow_add(strlen(padding), 4); ++ overflow_add(strlen(histoire), strlen(padding) + 4); ++ overflow_add(length, strlen(histoire) + strlen(padding) + 4); + length += strlen(padding) + 3 + strlen(histoire) + 1; + /* length of padding, "on " and length of history name plus "="*/ + if (in_hdr) /* if we are interested in the old comments... */ +@@ -84,8 +89,10 @@ rle_addhist(char * argv[], + else + old = NULL; + +- if (old && *old) ++ if (old && *old) { ++ overflow_add(length, strlen(old)); + length += strlen(old); /* add length if there. */ ++ } + + ++length; /*Cater for the null. */ + +diff --git a/urt/rle_getrow.c b/urt/rle_getrow.c +index ae220f5..39010ba 100644 +--- a/urt/rle_getrow.c ++++ b/urt/rle_getrow.c +@@ -164,6 +164,7 @@ rle_get_setup(rle_hdr * const the_hdr) { + char * cp; + + VAXSHORT(comlen, infile); /* get comment length */ ++ overflow_add(comlen, 1); + evenlen = (comlen + 1) & ~1; /* make it even */ + if (evenlen) { + MALLOCARRAY(comment_buf, evenlen); +diff --git a/urt/rle_hdr.c b/urt/rle_hdr.c +index 1edb7a3..c3dd60f 100644 +--- a/urt/rle_hdr.c ++++ b/urt/rle_hdr.c +@@ -148,6 +148,7 @@ rle_hdr_cp(rle_hdr * const fromHdrP, + if (toHdrP->cmap) { + size_t const size = + toHdrP->ncmap * (1 << toHdrP->cmaplen) * sizeof(rle_map); ++ overflow3(toHdrP->ncmap, 1<cmaplen, sizeof(rle_map)); + toHdrP->cmap = malloc(size); + if (!toHdrP->cmap) + pm_error("Failed to allocate memory for %u color maps " +@@ -163,12 +164,16 @@ rle_hdr_cp(rle_hdr * const fromHdrP, + const char ** cp; + + /* Count the comments. */ +- for (cp = toHdrP->comments, size = 0; *cp; ++cp) ++ for (cp = toHdrP->comments, size = 0; *cp; ++cp) { ++ overflow_add(size, 1); + ++size; ++ } + + /* Check if there are really any comments. */ + if (size > 0) { ++ overflow_add(size, 1); + ++size; /* Copy the NULL pointer, too. */ ++ overflow2(size, sizeof(char *)); + size *= sizeof(char *); + toHdrP->comments = malloc(size); + if (!toHdrP->comments) +diff --git a/urt/rle_open_f.c b/urt/rle_open_f.c +index 1aeb644..595b15c 100644 +--- a/urt/rle_open_f.c ++++ b/urt/rle_open_f.c +@@ -163,65 +163,7 @@ dealWithSubprocess(const char * const file_name, + FILE ** const fpP, + bool * const noSubprocessP, + const char ** const errorP) { +- +-#ifdef NO_OPEN_PIPES + *noSubprocessP = TRUE; +-#else +- const char *cp; +- +- reapChildren(catchingChildrenP, pids); +- +- /* Real file, not stdin or stdout. If name ends in ".Z", +- * pipe from/to un/compress (depending on r/w mode). +- * +- * If it starts with "|", popen that command. +- */ +- +- cp = file_name + strlen(file_name) - 2; +- /* Pipe case. */ +- if (file_name[0] == '|') { +- pid_t thepid; /* PID from my_popen */ +- +- *noSubprocessP = FALSE; +- +- *fpP = my_popen(file_name + 1, mode, &thepid); +- if (*fpP == NULL) +- *errorP = "%s: can't invoke <<%s>> for %s: "; +- else { +- /* One more child to catch, eventually. */ +- if (*catchingChildrenP < MAX_CHILDREN) +- pids[(*catchingChildrenP)++] = thepid; +- } +- } else if (cp > file_name && *cp == '.' && *(cp + 1) == 'Z' ) { +- /* Compress case. */ +- pid_t thepid; /* PID from my_popen. */ +- const char * command; +- +- *noSubprocessP = FALSE; +- +- if (*mode == 'w') +- pm_asprintf(&command, "compress > %s", file_name); +- else if (*mode == 'a') +- pm_asprintf(&command, "compress >> %s", file_name); +- else +- pm_asprintf(&command, "compress -d < %s", file_name); +- +- *fpP = my_popen(command, mode, &thepid); +- +- if (*fpP == NULL) +- *errorP = "%s: can't invoke 'compress' program, " +- "trying to open %s for %s"; +- else { +- /* One more child to catch, eventually. */ +- if (*catchingChildrenP < MAX_CHILDREN) +- pids[(*catchingChildrenP)++] = thepid; +- } +- pm_strfree(command); +- } else { +- *noSubprocessP = TRUE; +- *errorP = NULL; +- } +-#endif + } + + +diff --git a/urt/rle_putcom.c b/urt/rle_putcom.c +index ab2eb20..ce83615 100644 +--- a/urt/rle_putcom.c ++++ b/urt/rle_putcom.c +@@ -98,12 +98,14 @@ rle_putcom(const char * const value, + const char * v; + const char ** old_comments; + int i; +- for (i = 2, cp = the_hdr->comments; *cp != NULL; ++i, ++cp) ++ for (i = 2, cp = the_hdr->comments; *cp != NULL; ++i, ++cp) { ++ overflow_add(i, 1); + if (match(value, *cp) != NULL) { + v = *cp; + *cp = value; + return v; + } ++ } + /* Not found */ + /* Can't realloc because somebody else might be pointing to this + * comments block. Of course, if this were true, then the +diff --git a/urt/scanargs.c b/urt/scanargs.c +index f3af334..8dfa05b 100644 +--- a/urt/scanargs.c ++++ b/urt/scanargs.c +@@ -62,8 +62,8 @@ typedef int *ptr; + /* + * Storage allocation macros + */ +-#define NEW( type, cnt ) (type *) malloc( (cnt) * sizeof( type ) ) +-#define RENEW( type, ptr, cnt ) (type *) realloc( ptr, (cnt) * sizeof( type ) ) ++#define NEW( type, cnt ) (type *) malloc2( (cnt) , sizeof( type ) ) ++#define RENEW( type, ptr, cnt ) (type *) realloc2( ptr, (cnt), sizeof( type ) ) + + static CONST_DECL char * prformat( CONST_DECL char *, int ); + static int isnum( CONST_DECL char *, int, int ); + diff --git a/netpbm-CAN-2005-2471.patch b/netpbm-CAN-2005-2471.patch index 77a3cd7..de6bc59 100644 --- a/netpbm-CAN-2005-2471.patch +++ b/netpbm-CAN-2005-2471.patch @@ -1,8 +1,7 @@ -diff --git a/converter/other/pstopnm.c b/converter/other/pstopnm.c -index f534265..2ab48ab 100644 ---- a/converter/other/pstopnm.c -+++ b/converter/other/pstopnm.c -@@ -896,11 +896,11 @@ execGhostscript(int const inputPipeFd, +diff -urNp a/converter/other/pstopnm.c b/converter/other/pstopnm.c +--- a/converter/other/pstopnm.c 2025-02-04 10:47:27.857451432 +0100 ++++ b/converter/other/pstopnm.c 2025-02-04 10:55:56.430470597 +0100 +@@ -896,11 +896,11 @@ execGhostscript(int const ghostscriptProg, arg0, deviceopt, outfileopt, gopt, ropt, textalphabitsopt, "-q", "-dNOPAUSE", @@ -10,10 +9,9 @@ index f534265..2ab48ab 100644 + "-dPARANOIDSAFER", "-"); } -- execl(ghostscriptProg, arg0, deviceopt, outfileopt, gopt, ropt, -- textalphabitsopt, "-q", "-dNOPAUSE", "-dSAFER", "-", NULL); -+ execl(ghostscriptProg, arg0, deviceopt, outfileopt, gopt, ropt, "-q", -+ "-dNOPAUSE", "-dPARANOIDSAFER", "-", NULL); + execl(ghostscriptProg, arg0, deviceopt, outfileopt, gopt, ropt, +- textalphabitsopt, "-q", "-dNOPAUSE", "-dSAFER", "-", NULL); ++ "-q", "-dNOPAUSE", "-dPARANOIDSAFER", "-", NULL); pm_error("execl() of Ghostscript ('%s') failed, errno=%d (%s)", ghostscriptProg, errno, strerror(errno)); diff --git a/netpbm-c99.patch b/netpbm-c99.patch new file mode 100644 index 0000000..bcb8a99 --- /dev/null +++ b/netpbm-c99.patch @@ -0,0 +1,41 @@ +Remove the contents of libjasper_compat.c. The assignment + + *errorP = errorP; + +is bogus because it creates a non-null value in *errorP even on +success, and the caller expects a null pointer int his case. + +The source file is compiled, but not actually linked in, so this is +only a problem because of the type error that fails the build. + +diff --git a/converter/other/jpeg2000/libjasper_compat.c b/converter/other/jpeg2000/libjasper_compat.c +index 101820a321212dc6..e69de29bb2d1d643 100644 +--- a/converter/other/jpeg2000/libjasper_compat.c ++++ b/converter/other/jpeg2000/libjasper_compat.c +@@ -1,26 +0,0 @@ +-#include "netpbm/nstring.h" +- +-#include "jasper/jasper.h" +-#include "jasper/jas_image.h" +- +-#ifndef JAS_HAVE_PMJAS_IMAGE_DECODE +- +-void +-pmjas_image_decode(jas_stream_t * const in, +- int const fmtArg, +- const char * const optstr, +- jas_image_t ** const imagePP, +- const char ** const errorP) { +- +- jas_image_t * const jasperP = jas_image_decode(in, fmtArg, optstr); +- +- if (jasperP) { +- *imagePP = jasperP; +- *errorP = errorP; +- } else { +- pm_asprintf(errorP, "Failed. Details may have been written to " +- "Standard Error"); +- } +-} +- +-#endif diff --git a/netpbm-cmuwtopbm.patch b/netpbm-cmuwtopbm.patch deleted file mode 100644 index f5b328b..0000000 --- a/netpbm-cmuwtopbm.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff -up netpbm-10.61.01/converter/pbm/cmuwmtopbm.c.cmuwtopbmfix netpbm-10.61.01/converter/pbm/cmuwmtopbm.c ---- netpbm-10.61.01/converter/pbm/cmuwmtopbm.c.cmuwtopbmfix 2013-01-02 18:39:57.000000000 +0100 -+++ netpbm-10.61.01/converter/pbm/cmuwmtopbm.c 2013-01-03 05:41:36.024984241 +0100 -@@ -18,7 +18,7 @@ - This program does not check the pad bits at the end of each row. - */ - -- -+#include - #include "pbm.h" - - /*-------------------------- -@@ -42,7 +42,7 @@ readCmuwmHeader(FILE * const ifP - "CMU window manager header EOF / read error"; - uint32_t const cmuwmMagic = 0xf10040bb; - -- long l; -+ uint32_t l; - short s; - int rc; - diff --git a/netpbm-glibc.patch b/netpbm-glibc.patch index 4ae71e8..c500386 100644 --- a/netpbm-glibc.patch +++ b/netpbm-glibc.patch @@ -1,9 +1,10 @@ ---- netpbm-10.35/converter/other/pnmtotiffcmyk.c.glibc 2006-09-18 12:20:06.000000000 +0200 -+++ netpbm-10.35/converter/other/pnmtotiffcmyk.c 2007-08-23 09:18:30.000000000 +0200 -@@ -974,8 +974,8 @@ int main( int argc, char **argv ) { +diff -urNp a/converter/other/pnmtotiffcmyk.c b/converter/other/pnmtotiffcmyk.c +--- a/converter/other/pnmtotiffcmyk.c 2025-02-04 10:47:27.858451429 +0100 ++++ b/converter/other/pnmtotiffcmyk.c 2025-02-04 11:04:46.118394226 +0100 +@@ -989,8 +989,8 @@ int main( int argc, char **argv ) { if ( (err = parseOpts( argc, argv, rt )) ) goto exit ; - + - if ( (err = rt->in->open( rt->in, rt )) ) goto exit ; - if ( (err = rt->out->open( rt->out, rt )) ) goto exit ; + if ( (err = (rt->in->open)( rt->in, rt )) ) goto exit ; diff --git a/netpbm-manfix.patch b/netpbm-manfix.patch index c28beb4..6d759c1 100644 --- a/netpbm-manfix.patch +++ b/netpbm-manfix.patch @@ -1,30 +1,20 @@ -diff --git a/userguide/avstopam.html b/userguide/avstopam.html -index eb39766..d104518 100644 ---- a/userguide/avstopam.html -+++ b/userguide/avstopam.html -@@ -2,25 +2,29 @@ +diff -urNp a/userguide/avstopam.html b/userguide/avstopam.html +--- a/userguide/avstopam.html 2025-02-04 10:47:27.823451565 +0100 ++++ b/userguide/avstopam.html 2025-02-04 17:49:34.981978989 +0100 +@@ -2,9 +2,9 @@ Avstopam User Manual

avstopam

-Updated: 07 February 2010 -
-+ -+

Updated: 7 February 2010

+-Table Of Contents ++

Updated: 07 February 2010

+ +

Table Of Contents

-+ - Table Of Contents

NAME

--

avstopam - convert an AVS X image to a Netpbm image -+

avstopam - convert an AVS X image to a Netpbm image

-+ - --

SYNOPSIS

-+

SYNOPSIS

- -

avstopam - [avsfile] +

avstopam - convert an AVS X image to a Netpbm image +@@ -16,40 +16,40 @@ Updated: 07 February 2010

DESCRIPTION

@@ -37,8 +27,11 @@ index eb39766..d104518 100644 +image as output.

avsfile is the input file, which defaults to Standard Input. - Output is always on Standard Output. -@@ -30,26 +34,26 @@ Output is always on Standard Output. +-Output is always on Standard Output. ++Output is always on Standard Output.

+ +

OPTIONS

+

There are no command line options defined specifically for avstopam, but it recognizes the options common to all programs based on libnetpbm (See @@ -48,8 +41,8 @@ index eb39766..d104518 100644

AUTHOR

Copyright © 2010 Scott Pakin, --scott+pbm@pakin.org. -+scott+pbm@pakin.org.

+-scott+pbm@pakin.org ++scott+pbm@pakin.org

SEE ALSO

@@ -69,52 +62,229 @@ index eb39766..d104518 100644 +
  • DESCRIPTION
  • +
  • OPTIONS
  • +
  • AUTHOR
  • -+
  • SEE ALSO
  • ++
  • SEE ALSO
  • -diff --git a/userguide/escp2topbm.html b/userguide/escp2topbm.html -index 9e808b7..33b19a0 100644 ---- a/userguide/escp2topbm.html -+++ b/userguide/escp2topbm.html -@@ -8,6 +8,7 @@ Updated: 14 July 2015 - -

    NAME

    - -+

    NAME

    - escp2topbm - convert an ESC/P2 printer file to a PBM image - -

    SYNOPSIS

    -diff --git a/userguide/faxformat.html b/userguide/faxformat.html -index 44b1ba5..827ffc8 100644 ---- a/userguide/faxformat.html -+++ b/userguide/faxformat.html +diff -urNp a/userguide/faxformat.html b/userguide/faxformat.html +--- a/userguide/faxformat.html 2025-02-04 10:47:27.824451560 +0100 ++++ b/userguide/faxformat.html 2025-02-04 17:50:41.300631089 +0100 @@ -5,10 +5,11 @@ Updated: 03 December 2008
    -+

    SYNOPSIS

    ++

    SYNOPSIS

    This page, part of the Netpbm user's guide, describes FAX formats in relation to Netpbm facilities. - -+

    DESCRIPTION

    ++

    DESCRIPTION

    The ITU (formerly CCITT) publishes standards for operation of fax machines (the idea is to provide a way to be sure that a fax machine is able to receive a fax sent by another). These standards incidentally specify graphics file -diff --git a/userguide/pampaintspill.html b/userguide/pampaintspill.html -index eeb1cac..e42db76 100644 ---- a/userguide/pampaintspill.html -+++ b/userguide/pampaintspill.html -@@ -2,12 +2,12 @@ - Pampaintspill User Manual - -

    pampaintspill

    --Updated: 09 February 2020 -+

    Updated: 09 February 2020 -
    --Table Of Contents -+Table Of Contents

    +diff -urNp a/userguide/libnetpbm_ug.html b/userguide/libnetpbm_ug.html +--- a/userguide/libnetpbm_ug.html 2025-02-04 10:47:27.824451560 +0100 ++++ b/userguide/libnetpbm_ug.html 2025-02-04 17:52:02.045207328 +0100 +@@ -374,7 +374,7 @@ plain format. +

    Reference

    + +

    The Libnetpbm Netpbm Image +-Processing Manual describes the the libnetpbm functions for ++Processing Manual describes the libnetpbm functions for + processing image data. + +

    The Libnetpbm Utility Manual +diff -urNp a/userguide/pamfunc.html b/userguide/pamfunc.html +--- a/userguide/pamfunc.html 2025-02-04 10:47:27.823451565 +0100 ++++ b/userguide/pamfunc.html 2025-02-04 17:52:19.661114878 +0100 +@@ -60,7 +60,7 @@ output image. + and bit string (such as and with 01001000). For the arithmetic functions, the + function arguments and results are the fraction that a sample is of the + maxval, i.e. normal interpretation of PAM tuples. But for the bit string +-functions, the value is the the bit string whose value as a binary cipher is ++functions, the value is the bit string whose value as a binary cipher is + the sample value, and the maxval indicates the width of the bit string. + +

    Arithmetic functions

    +diff -urNp a/userguide/pammixmulti.html b/userguide/pammixmulti.html +--- a/userguide/pammixmulti.html 2025-02-04 10:47:27.820451577 +0100 ++++ b/userguide/pammixmulti.html 2025-02-04 17:56:58.538651212 +0100 +@@ -7,8 +7,8 @@ Updated: 18 December 2024 + Table Of Contents + + +-

    NAME

    +-

    pammixmulti - blend together multiple PAM images ++

    NAME

    ++

    pammixmulti - blend together multiple PAM images

    + + +

    SYNOPSIS

    +@@ -17,19 +17,19 @@ Updated: 18 December 2024 + [-maskfile=filename] + [-stdev=number] + [-randomseed integer] +- filename ... ++ filename ...

    + +

    Minimum unique abbreviation of an option is acceptable. You can use double + hyphen instead of a single hyphen to denote options. You can use white + space in place of the equals sign to separate an option name from its +-value. ++value.

    + + +

    DESCRIPTION

    +-

    This file is part of Netpbm. ++

    This file is part of Netpbm.

    + +

    pammixmulti mixes two or more images to produce a new image. The +-program provides multiple ways to interpret "mix." ++program provides multiple ways to interpret "mix."

    + + +

    OPTIONS

    +@@ -37,7 +37,7 @@ program provides multiple ways to interp +

    In addition to the options common to all programs based on libnetpbm + (most notably -quiet, see + Common Options), pammixmulti recognizes the following +-command line options: ++command line options:

    + +
    +
    -blend=average|alpha-weighted|random|mask
    +@@ -55,8 +55,8 @@ of the input images, chosen at random on + With -blend=mask, each pixel in the output is + produced by a weighted average of the corresponding pixels from all + the input images based on the grayscale level of an additional mask +-image. +-

    -alpha-weighted was new in Netpbm 11.09 (December 2024). ++image.

    ++

    -alpha-weighted was new in Netpbm 11.09 (December 2024).

    + + +
    -maskfile=filename
    +@@ -66,7 +66,7 @@ grayscale mask file to control the blend + not grayscale, the first channel is treated as gray). Where the mask file is + black, the first image is selected. Where the mask file is white, the last + image is selected. Intermediate levels of gray select intermediate +-images. ++images.

    + + +
    -stdev=number
    +@@ -83,7 +83,7 @@ that includes roughly equal amounts of t + and 2 but less of the corresponding pixel from image 3. As number + tends towards the number of input images (going beyond that has diminishing + impact), the output tends to look more +-like -blend=average. number defaults to 0.25. ++like -blend=average. number defaults to 0.25.

    + + +
    -randomseed integer +@@ -91,45 +91,45 @@ like -blend=average. numberThis is the seed for the random number generator used with + -blend=random + +-

    Use this to ensure you get the same image on separate invocations. ++

    Use this to ensure you get the same image on separate invocations.

    + +
    + +

    ARGUMENTS

    + +-

    You supply the names of the files to mix as non-option arguments. ++

    You supply the names of the files to mix as non-option arguments.

    + + +

    EXAMPLES

    + +-

    Average a bunch of PPM images to produce a new PAM image: ++

    Average a bunch of PPM images to produce a new PAM image:

    +
    
    +     pammixmulti input*.ppm >output.ppm
    + 
    + +

    Mix these same images by taking each pixel from a randomly selected input +-image: ++image:

    + +
    
    +     pammixmulti -blend=random input*.ppm >output.ppm
    + 
    + +

    Use a mask image to control the fading among input images on a +-pixel-by-pixel basis: ++pixel-by-pixel basis:

    + +
    
    +     pammixmulti -blend=mask -maskfile=mask.pgm >output.pam \
    +        one.pam two.pam three.pam four.pam
    + 
    + +-

    Do the same but with more abrupt transitions: ++

    Do the same but with more abrupt transitions:

    + +
    
    +     pammixmulti -blend=mask -maskfile=mask.pgm -stdev=0.0 >output.pam \
    +        one.pam two.pam three.pam four.pam
    + 
    + +-

    and now with more gradual transitions: ++

    and now with more gradual transitions:

    + +
    
    +     pammixmulti -blend=mask -maskfile=mask.pgm -stdev=1.0 >output.pam \
    +@@ -139,12 +139,12 @@ pixel-by-pixel basis:
    + 
    + 

    HISTORY

    + +-

    pammixmulti was new in Netpbm 10.85 (December 2018). ++

    pammixmulti was new in Netpbm 10.85 (December 2018).

    + + +

    AUTHOR

    + +-

    Copyright 2018–2024 Scott Pakin, scott+pbm@pakin.org. ++

    Copyright 2018–2024 Scott Pakin, scott+pbm@pakin.org.

    + +

    SEE ALSO

    + +@@ -152,20 +152,20 @@ pixel-by-pixel basis: + ppmmix, + pamarith, + pnm, +-pam ++pam

    + + +

    Table Of Contents

    + + + + +diff -urNp a/userguide/pampaintspill.html b/userguide/pampaintspill.html +--- a/userguide/pampaintspill.html 2025-02-04 10:47:27.823451565 +0100 ++++ b/userguide/pampaintspill.html 2025-02-04 18:01:50.746117598 +0100 +@@ -7,7 +7,7 @@ Updated: 02 November 2021 + Table Of Contents

    NAME

    -pampaintspill - smoothly spill colors into the background @@ -122,12 +292,13 @@ index eeb1cac..e42db76 100644

    SYNOPSIS

    -@@ -16,31 +16,31 @@ pampaintspill - smoothly spill colors into the background - [--bgcolor=color] - [--wrap] [--all] +@@ -19,48 +19,48 @@ pampaintspill - smoothly spill colors in [--downsample=number] --[--power=number] [filename] -+[--power=number] [filename]

    + [--near=number] + [--power=number] [filename] +-[-randomseed=integer] ++[-randomseed=integer]

    +

    Minimum unique abbreviations of option are acceptable. You may use double hyphens instead of single hyphen to denote options. You may use @@ -160,7 +331,9 @@ index eeb1cac..e42db76 100644

  • pampaintspill can produce tileable output and can control how tightly the gradient colors bind to their source -@@ -49,14 +49,14 @@ paint" onto the background. pampaintspill is similar to +- pixels. ++ pixels.
  • +

    Results are generally best when the input image contains just a few, crisp spots of color. Use your drawing program's pencil tool — as opposed to a @@ -177,40 +350,96 @@ index eeb1cac..e42db76 100644

    --bgcolor=color
    -diff --git a/userguide/pamrecolor.html b/userguide/pamrecolor.html -index 3f341d4..a5f2671 100644 ---- a/userguide/pamrecolor.html -+++ b/userguide/pamrecolor.html -@@ -2,12 +2,15 @@ +@@ -117,45 +117,45 @@ command line options: + gradients away from them. + +
    -randomseed=integer +-
    This is the seed for the random number generator that generates the +- pixels. ++
    This is the seed fodr the random number generator that generates the ++ pixels.
    + +-

    Use this to ensure you get the same image on separate invocations. ++

    Use this to ensure you get the same image on separate invocations.

    + +-

    This option was new in Netpbm 10.94 (March 2021). ++

    This option was new in Netpbm 10.94 (March 2021).

    +
    + + +

    SEE ALSO

    + + + +

    HISTORY

    + +-

    pampaintspill was new in Netpbm 10.50 (March 2010). ++

    pampaintspill was new in Netpbm 10.50 (March 2010).

    + + + + +

    Copyright © 2010–2021 Scott Pakin, +-scott+pbm@pakin.org. ++scott+pbm@pakin.org.

    + +

    Table Of Contents

    + + + + +diff -urNp a/userguide/pamrecolor.html b/userguide/pamrecolor.html +--- a/userguide/pamrecolor.html 2025-02-04 10:47:27.823451565 +0100 ++++ b/userguide/pamrecolor.html 2025-02-04 18:10:00.968545076 +0100 +@@ -2,9 +2,9 @@ Pamrecolor User Manual

    pamrecolor

    -Updated: 31 July 2010 --
    ++

    Updated: 31 July 2010 +
    -Table Of Contents ++Table Of Contents

    --

    NAME

    --pamrecolor - alter colors without affecting luminance -+

    Updated: 31 July 2010

    -+ -+

    Table Of Contents

    -+ -+ -+

    NAME

    -+ -+

    pamrecolor - alter colors without affecting luminance

    - -

    SYNOPSIS

    - -@@ -22,6 +25,7 @@ pamrecolor - alter colors without affecting luminance +

    NAME

    + pamrecolor - alter colors without affecting luminance +@@ -22,15 +22,15 @@ pamrecolor - alter colors without affect [-randomseed=integer] [infile] +- +

    -

    Minimum unique abbreviation of option is acceptable. You may use double -@@ -30,7 +34,7 @@ space in place of the equals sign to separate an option name from its value. + hyphens instead of single hyphen to denote options. You may use white +-space in place of the equals sign to separate an option name from its value. ++space in place of the equals sign to separate an option name from its value.

    DESCRIPTION

    @@ -219,16 +448,19 @@ index 3f341d4..a5f2671 100644

    pamrecolor changes an image's colors to be as close as possible to given target colors but with the constraint that the -@@ -39,7 +43,7 @@ image will look identical if both are converted to grayscale +@@ -39,17 +39,17 @@ image will look identical if both are co (e.g. with ppmtopgm). You can have pamrecolor select target colors randomly, specify a single hue for the entire image, or take the -target colors from a target image. +target colors from a target image.

    -

    pamrecolor works on pseudo-Netpbm images based on arbitrary - color spaces. You can define the color space explicitly or choose one -@@ -49,7 +53,7 @@ of many that pamrecolor knows by name. +

    In addition to real Netpbm images, pamrecolor works on pseudo-Netpbm + images based on arbitrary color spaces. You can define the color space +-explicitly or choose one of many that pamrecolor knows by name. ++explicitly or choose one of many that pamrecolor knows by name.

    + +

    The output is a PAM image on standard output. Options control the exact format of the PAM. If you want a PNM (PBM, PGM, or PPM) image, use pamtopnm on the output. There is no need to convert if you will use the image as input to a current Netpbm @@ -237,7 +469,7 @@ index 3f341d4..a5f2671 100644

    OPTIONS

    -@@ -57,7 +61,7 @@ program, but many other programs don't know what a PAM is. +@@ -57,7 +57,7 @@ program, but many other programs don't k

    In addition to the options common to all programs based on libnetpbm (most notably -quiet, see Common Options), pamrecolor recognizes the following @@ -246,7 +478,28 @@ index 3f341d4..a5f2671 100644

    -@@ -109,12 +113,12 @@ the format that uses sRGB. +@@ -67,7 +67,7 @@ to luminance of each of the red, green, + example, in the SMPTE-C color space an RGB color is converted to + grayscale by multiplying the red channel by 0.2124132, the green + channel by 0.7010437, and the blue channel by 0.0865432 and summing +-the resulting three products. ++the resulting three products. + +

    When you use this option, the input and output images are not true Netpbm + images, because the Netpbm image format specifies a particular color space. +@@ -76,9 +76,9 @@ the raster have different meaning. Many + images actually use a variation with a different color space. For example, + GIMP uses sRGB internally and if you + have GIMP generate a Netpbm image file, it really generates a variation of +-the format that uses sRGB. ++the format that uses sRGB.

    + +-

    pamrecolor knows the following color spaces (name values): ++

    pamrecolor knows the following color spaces (name values):

    + +
    +
    adobe
    +@@ -109,12 +109,12 @@ the format that uses sRGB.

    The default is "ntsc" because this is the color space that the Netpbm formats and many graphics utilities use. As a counterexample, GIMP uses sRGB as its native color @@ -257,29 +510,64 @@ index 3f341d4..a5f2671 100644 Bruce Lindbloom's -Computing RGB-to-XYZ and XYZ-to-RGB matrices page. -+Computing RGB-to-XYZ and XYZ-to-RGB matrices page.

    ++Computing RGB-to-XYZ and XYZ-to-RGB matrices page.

    --rmult=fraction
    --gmult=fraction
    -@@ -137,7 +141,7 @@ library routine (e.g., "hotpink" or "#ff69b4"). +@@ -133,15 +133,13 @@ image. pamrecolor will make each + to color subject to the constraint that the luminance must stay the + same as in the original image. Specify color as in + the argument of the pnm_parsecolor() +-library routine (e.g., "hotpink" or "#ff69b4"). ++library routine (e.g., "hotpink" or "#ff69b4"). + +

    If you specify neither --targetcolor nor + --colorfile, pamrecolor will randomly select a target color for +-each pixel of the input image. +- +-

    You may not specify both -targetcolor and -colorfile. ++each pixel of the input image.

    + +- ++

    You may not specify both -targetcolor and -colorfile.

    + +
    --colorfile=file
    +
    Take per-pixel target colors from Netpbm file file instead +@@ -150,40 +148,38 @@ of using a single target color for the e + If the image in the file wider or taller than the input image, + pamrecolor uses only the left and top part of it. + If the image is narrower or shorter, pamrecolor considers the +-image to be repeated in a tile pattern. ++image to be repeated in a tile pattern.

    If you specify neither --targetcolor nor --colorfile, pamrecolor will randomly select a target color for -each pixel of the input image. +each pixel of the input image.

    -

    You may not specify both -targetcolor and -colorfile. +-

    You may not specify both -targetcolor and -colorfile. ++

    You may not specify both -targetcolor and -colorfile.

    -@@ -154,7 +158,7 @@ image to be repeated in a tile pattern. +-
    -randomseed=integer ++
    -randomseed=integer
    -

    If you specify neither --targetcolor nor - --colorfile, pamrecolor will randomly select a target color for --each pixel of the input image. -+each pixel of the input image.

    +
    This is the seed for the random number generator that generates the +-pixels. ++pixels.
    -

    You may not specify both -targetcolor and -colorfile. +-

    Use this to ensure you get the same image on separate invocations. ++

    Use this to ensure you get the same image on separate invocations.

    + +

    By default, pamrecolor uses a seed derived from the time of day + and process ID, which gives you fairly uncorrelated results in multiple +-invocations. +- +-

    This option was new in Netpbm 10.61 (December 2012). ++invocations.

    + +-
    ++

    This option was new in Netpbm 10.61 (December 2012).

    -@@ -176,23 +180,23 @@ invocations.

    EXAMPLES

    @@ -287,8 +575,7 @@ index 3f341d4..a5f2671 100644 +

    This command tints an image yellow:

    --    pamrecolor --targetcolor=yellow colorpic.pam > yellowpic.pam
    -+    pamrecolor --targetcolor=yellow colorpic.pam > yellowpic.pam
    +     pamrecolor --targetcolor=yellow colorpic.pam > yellowpic.pam
      

    This command takes the colors from colorpicture.ppm and applies @@ -296,10 +583,8 @@ index 3f341d4..a5f2671 100644 +them to graypicture.pgm:

    --    pamrecolor --colorfile=colorpic.ppm graypic.pgm > colorizedpic.pam
    -+    pamrecolor --colorfile=colorpic.ppm graypic.pgm > colorizedpic.pam
    - 
    - + pamrecolor --colorfile=colorpic.ppm graypic.pgm > colorizedpic.pam +@@ -192,52 +188,52 @@ them to graypicture.pgm:

    The grayscale version of colorizedpic.pam will look just like graypic.pgm. Note that if you use a non-Netpbm tool to do the conversion to grayscale, you may additionally need to specify an @@ -308,7 +593,11 @@ index 3f341d4..a5f2671 100644

    NOTES

    -@@ -203,25 +207,25 @@ appropriate --colorspace value for your conversion tool. + +

    Here are a couple of fun special effects you can produce with +-pamrecolor: ++pamrecolor:

    +
    • Specify a color file that is identical to the input image but with some large, colored text added to it. The text will "magically" @@ -336,18 +625,30 @@ index 3f341d4..a5f2671 100644 -

      Scott Pakin wrote pamrecolor in July 2010. +

      Scott Pakin wrote pamrecolor in July 2010.

      -

      pamrecolor was new in Netpbm 10.52 (September 2010). +-

      pamrecolor was new in Netpbm 10.52 (September 2010). ++

      pamrecolor was new in Netpbm 10.52 (September 2010).

      + -@@ -229,7 +233,7 @@ photograph of the late 1800s).

      AUTHOR

      Copyright (C) 2010 Scott --Pakin, scott+pbm@pakin.org. -+Pakin, scott+pbm@pakin.org.

      +-Pakin, scott+pbm@pakin.org ++Pakin, scott+pbm@pakin.org

      SEE ALSO

      -@@ -246,14 +250,14 @@ Pakin, scott+pbm@pakin.org. + + + + +@@ -246,14 +242,14 @@ Pakin, Table Of Contents
        @@ -370,1632 +671,39 @@ index 3f341d4..a5f2671 100644
      -diff --git a/userguide/pamsistoaglyph.html b/userguide/pamsistoaglyph.html -index 1ca53ac..e545986 100644 ---- a/userguide/pamsistoaglyph.html -+++ b/userguide/pamsistoaglyph.html -@@ -1,15 +1,18 @@ - - Pamsistoaglyph User Manual - -+ -

      pamsistoaglyph

      --Updated: 05 April 2009 --
      --
      Table Of Contents -+ -+

      Updated: 5 April 2009

      -+ -+

      Table Of Contents

      -+ - -

      NAME

      - --pamsistoaglyph - convert a single-image stereogram to a red/cyan --anaglyphic image -+

      pamsistoaglyph - convert a single-image stereogram to a red/cyan -+anaglyphic image

      - - -

      SYNOPSIS

      -@@ -20,11 +23,11 @@ anaglyphic image - [--minsep=number] - [--gray=number] - [in_netpbmfile -- -+

      - -

      All options can be abbreviated to their shortest unique prefix. You - may use either white space or an equals sign between an option name --and its value. -+and its value.

      - - -

      DESCRIPTION

      -@@ -32,7 +35,7 @@ and its value. -

      This program is part of Netpbm. - -

      pamsistoaglyph reads a Netpbm image as input and --produces a Netpbm image as output. -+produces a Netpbm image as output.

      - -

      pamsistoaglyph takes a single-image stereogram - (SIS) such as those produced by

      - Common Options), pamsistoaglyph recognizes the following --command line options: -+command line options:

      - -

      For most images, no command-line options need to be specified. The --following options are available, however, for unusual circumstances. -+following options are available, however, for unusual circumstances.

      - -
      --
      --invert -+
      --invert
      -
      Swap the left- and right-eye - images. pamsistoaglyph assumes that its input - represents a wall-eyed stereogram and generates the anaglyphic -@@ -71,17 +74,17 @@ following options are available, however, for unusual circumstances. - the page where it should pop out of the page (and vice versa), - this typically implies that the input image represents a - cross-eyed stereogram. Use --invert to correct -- the image depth. -+ the image depth.
      - --
      --sep=number -+
      --sep=number
      -
      Specify the distance in pixels between the left- and right-eye - images. Essentially, this corresponds to the distance between - repetitions of the background pattern. The --sep - option should rarely be necessary - as pamsistoaglyph is fairly good at determining -- automatically the eye-separation distance. -+ automatically the eye-separation distance.
      - --
      --minsep=number -+
      --minsep=number
      -
      This option is similar to --sep but - constrains pamsistoaglyph only to - a minimum eye-separation distance. Any distance larger -@@ -90,9 +93,9 @@ following options are available, however, for unusual circumstances. - as pamsistoaglyph is fairly good at determining - automatically the eye-separation distance. The default value for - the minimum eye-separation distance is 10% of the image width; -- this value seems to work well in practice. -+ this value seems to work well in practice.
      - --
      --gray=number -+
      --gray=number
      -
      Limit the number of gray levels to use when searching for the - optimal eye-separation - distance. Because pamsistoaglyph looks for -@@ -103,7 +106,7 @@ following options are available, however, for unusual circumstances. - unintentional color variations (such as those caused by conversion - from a low-quality JPEG image, for example). The default of 63 - seems to work well so the --gray option should -- rarely be necessary. -+ rarely be necessary.
      -
      - - -@@ -112,22 +115,22 @@ following options are available, however, for unusual circumstances. -

      The registration algorithm used by pamsistoaglyph - was developed specifically for this program. As far as the author - knows, there are no existing algorithms for converting stereograms to --anaglyphs. The algorithm works as follows: -+anaglyphs. The algorithm works as follows:

      - -
        -
      1. Convert the image to grayscale to increase the ability to identify -- matches. -+ matches.
      2. - -
      3. Count the number of pixels that match N pixels ahead in the -- image for all N in [1, width/2]. -+ image for all N in [1, width/2].
      4. - -
      5. Maintain a running mean (μ) and standard deviation (σ) of -- the number of matched pixels. -+ the number of matched pixels.
      6. - -
      7. Store the N corresponding to each spike in the number of - matched pixels. A spike is defined as a tally that exceeds the - mean plus one, two, or three standard deviations. Only the first -- spike of a given standard-deviation multiplier is stored. -+ spike of a given standard-deviation multiplier is stored.
      8. - -
      9. If a tally greater than μ+3σ was encountered, return the - corresponding N. If not, then if a tally greater than -@@ -138,13 +141,13 @@ anaglyphs. The algorithm works as follows: - produces the minimum average distance between matched pixels - (i.e., #matches divided by #pixels). If no - such N exceeds the minimum allowable eye-separation value, -- return zero to indicate failure. -+ return zero to indicate failure.
      10. - -
      11. If the algorithm returned zero, rerun the algorithm independently - on each row of the input image and return the median of - all N that exceed the minimum allowable eye-separation - value. If no such N exists, abort with an error -- message. -+ message.
      12. -
      - -

      HISTORY

      -@@ -156,7 +159,7 @@ in Netpbm in Release 10.47 (June 2009). -

      AUTHOR

      - -

      Copyright (C) 2009 Scott --Pakin, scott+pbm@pakin.org. -+Pakin, scott+pbm@pakin.org.

      - - -

      SEE ALSO

      -@@ -174,13 +177,13 @@ Pakin, scott+pbm@pakin.org. -

      Table Of Contents

      - - - - -diff --git a/userguide/pamtoavs.html b/userguide/pamtoavs.html -index 5d0ae35..bee1a40 100644 ---- a/userguide/pamtoavs.html -+++ b/userguide/pamtoavs.html -@@ -2,13 +2,15 @@ - Pamtoavs User Manual - -

      pamtoavs

      --Updated: 07 February 2010 --
      --Table Of Contents -+ -+

      Updated: 7 February 2010

      -+ -+

      Table Of Contents

      -+ - -

      NAME

      - --

      pamtoavs - convert a Netpbm image to an AVS X image -+

      pamtoavs - convert a Netpbm image to an AVS X image

      - -

      SYNOPSIS

      - -@@ -17,7 +19,7 @@ Updated: 07 February 2010 - -

      DESCRIPTION

      - --

      This program is part of Netpbm. -+

      This program is part of Netpbm.

      - -

      pamtoavs reads a Netpbm image as input and produces a Stardent - AVS -@@ -27,14 +29,14 @@ href="http://www.gnuplot.info/">Gnuplot v4.2 and later can use. -

      netpbmfile is the input file, which defaults to Standard Input. - Output is always on Standard Output. - --

      Try the following: -+

      Try the following:

      - -
      -     gnuplot> plot 'myimage.avs' binary filetype=avs with rgbimage
      - 
      - -

      See the Gnuplot --manual for more information. -+manual for more information.

      - - -

      OPTIONS

      -@@ -42,29 +44,29 @@ manual for more information. -

      There are no command line options defined specifically - for pamtoavs, but it recognizes the options common to all - programs based on libnetpbm (See --Common Options.) -+Common Options.)

      - -

      AUTHOR

      - -

      Copyright © 2010 Scott Pakin, --scott+pbm@pakin.org. -+scott+pbm@pakin.org.

      - -

      SEE ALSO

      - -

      avstopam, - gnuplot, --pam -+pam

      - -
      - -

      Table Of Contents

      - - - - -diff --git a/userguide/pamtooctaveimg.html b/userguide/pamtooctaveimg.html -index 4e09e8e..d2cc50b 100644 ---- a/userguide/pamtooctaveimg.html -+++ b/userguide/pamtooctaveimg.html -@@ -2,13 +2,13 @@ - Pamtooctaveimg User Manual - -

      pamtooctaveimg

      --
      --

      Updated: 27 June 2007
      --Table Of Contents -+ -+

      Updated: 27 June 2007
      -+Table Of Contents

      - -

      NAME

      - --

      pamtooctaveimg - convert a Netpbm image to a GNU Octave image -+

      pamtooctaveimg - convert a Netpbm image to a GNU Octave image

      - -

      SYNOPSIS

      - -@@ -17,7 +17,7 @@ - -

      DESCRIPTION

      - --

      This program is part of Netpbm. -+

      This program is part of Netpbm.

      - -

      pamtooctaveimg reads a Netpbm image as input and produces a GNU Octave image file as output. -@@ -45,7 +45,7 @@ Image Processing chapter of the GNU Octave manual for details. -

      There are no command line options defined specifically - for pamtooctaveimg, but it recognizes the options common to all - programs based on libnetpbm (See --Common Options.) -+Common Options.)

      - -

      ARGUMENTS

      - -@@ -77,7 +77,8 @@ specify netpbmfile, the input is from Standard Input. -

      NOTES

      - -

      There is no octavetopam program. However, GNU Octave's --saveimage command can save images in PPM format. -+saveimage command can save images in PPM format.

      -+ - +diff -urNp a/userguide/pbmtog3.html b/userguide/pbmtog3.html +--- a/userguide/pbmtog3.html 2025-02-04 10:47:27.827451549 +0100 ++++ b/userguide/pbmtog3.html 2025-02-04 18:10:55.328259786 +0100 +@@ -80,7 +80,7 @@ You cannot specify both.

      HISTORY

      -@@ -86,7 +87,7 @@ specify netpbmfile, the input is from Standard Input. -

      AUTHOR

      +

      Before Netpbm 10.79 (June 2017), there was a different program by the same +-name in Netpbm, which was written by by Paul Haeberli ++name in Netpbm, which was written by Paul Haeberli + <paul@manray.sgi.com> in 1989 + and then modified extensively by others. -

      Copyright (C) 2007 Scott Pakin, --scott+pbm@pakin.org. -+scott+pbm@pakin.org.

      - -

      SEE ALSO

      - -@@ -98,15 +99,15 @@ href="http://www.gnu.org/software/octave/doc/interpreter/index.html">octaveTable Of Contents - - - -diff --git a/userguide/pnmflip.html b/userguide/pnmflip.html -index 2bd7368..8a1916e 100644 ---- a/userguide/pnmflip.html -+++ b/userguide/pnmflip.html -@@ -5,17 +5,18 @@ - -

      NAME

      - --pnmflip - replaced by pamflip -+

      pnmflip - replaced by pamflip

      - -

      DESCRIPTION

      - --

      This program is part of Netpbm. -+

      This program is part of Netpbm.

      - -

      pnmflip was replaced in Netpbm 10.13 (December 2002) by - pamflip. - -+

      DESCRIPTION

      -

      pamflip is mostly backward compatible with pnmflip, --but works on PAM images too. -+but works on PAM images too.

      - -

      One way pamflip is not backward compatible with pnmflip - is that pnmflip lets you specify any number of basic flip options, -@@ -23,12 +24,12 @@ whereas pamflip requires exactly one. (pamflip provides - the -xform option for requesting multiple transformations, though). - Because of this incompatibility, pnmflip still exists as a - separate program, and all it does is translate its options to pamflip --style and run pamflip. -+style and run pamflip.

      - -

      You should not make any new use of pnmflip and if you modify an - existing use, you should upgrade to pamflip. But note that if you - write a program that might have to be used with very old --Netpbm, pnmflip is the only way to do that. -+Netpbm, pnmflip is the only way to do that.

      - - - -diff --git a/userguide/pnmmercator.html b/userguide/pnmmercator.html -index 998f7fb..65576ac 100644 ---- a/userguide/pnmmercator.html -+++ b/userguide/pnmmercator.html -@@ -18,11 +18,12 @@ projection and vice-versa - [filename] - -

      Minimum unique abbreviation of option is acceptable. --You may use double hyphens instead of single hyphen to denote options. -+You may use double hyphens instead of single hyphen to denote options.

      - -

      DESCRIPTION

      - --

      This program is part of Netpbm. -+

      This program is part of Netpbm.

      - -

      The pnmmercator utility, converts a rectangular projection worldmap - to a Mercator projection format, as used for maps.google.com and many other -@@ -31,34 +32,34 @@ online maps. The map used as input for pnmmercator must have rows for - file will typically be twice as wide as high, but this is not a - requirement. The output file will be using the Mercator --projection and will get double the height of the input file. -+projection and will get double the height of the input file.

      - -

      Maps using the Mercator projection are stretched more the closer a row is - to the North or South Pole. The last few degrees (> 85 or < -85 degrees) - are not part of a Mercator map at all because they would be stretched too much - and the rows close to the edge will show banding, because they originate from --the same row in the original map. -+the same row in the original map.

      - -

      To overcome this, the program will by default do interpolation of pixel - colors, which will eliminate the banding effect, but will cause some blurring - of the output. With the -nomix option, this interpolation of colors isn't - applied. You can obtain the highest quality output by starting with an input - map of high resolution, so that you can follow the pnmmercator --transformation with a pamscale reduction in size. -+transformation with a pamscale reduction in size.

      - -

      This program can also convert a Mercator projection map back to a - rectangular projection based. As said, the Mercator map doesn't have - information about the latitudes close to the poles. Therefore the top rows in - the output image will be identical and copied from the row corresponding with --latitude of 85 degrees. The same at the bottom of the map. -+latitude of 85 degrees. The same at the bottom of the map.

      - -

      Pnmmercator doesn't have any provision for scaling the image. You can scale - by piping the output of the program through Netpbm programs such as --pamscale. -+pamscale.

      - -

      You can find maps to be used as input at flatplanet.sourceforge.net --or uic.edu/pape. -+or uic.edu/pape.

      - -

      The point of a Mercator projection map is that compass directions work on - it. If you draw a straight line northeast from some point on the Mercator -@@ -78,33 +79,33 @@ proportional to angular longitude. -

      PARAMETERS

      - -

      filename is the name of the input file. If you don't specify --this, pnmmercator reads the image from standard Input. -+this, pnmmercator reads the image from standard Input.

      - -

      OPTIONS

      - -

      In addition to the options common to all programs based on libnetpbm - (most notably -quiet, see - Common Options), pnmmercator recognizes the following --command line options: -+command line options:

      - -
      -
      -inverse
      -
      -

      With this option a conversion from Mercator to degrees is applied.The --output image will have half the height of the input map. -+output image will have half the height of the input map.

      -
      -
      -nomix
      -
      -

      Default behaviour is that color blending is applied in between two adjacent - rows. If you specify the -nomix parameter there is no blending. The - consequence is a banding at the top and bottom of the map. With this option, --the output map will also consist of exactly the same colors as the input. -+the output map will also consist of exactly the same colors as the input.

      -
      -
      -verbose and -vverbose
      -
      -

      This parameter outputs some additional information. If you double the 'v', - it will output debug data about the lat/long degree and Mercator --conversions. -+conversions.

      -
      -
      - -@@ -114,25 +115,26 @@ conversions. - ppmglobe - -

      HISTORY

      --

      pnmmercator was new in Netpbm 10.49 (December 2009). -+

      pnmmercator was new in Netpbm 10.49 (December 2009).

      - -

      AUTHORS

      - -

      Willem van Schaik (of - pnmtopng/pngtopnm fame) wrote this program in October 2009 and --suggested it for inclusion in Netpbm. -+suggested it for inclusion in Netpbm.

      - -
      - -

      Table Of Contents

      - - - -diff --git a/userguide/ppmtogif.html b/userguide/ppmtogif.html -index 513133a..fa72e09 100644 ---- a/userguide/ppmtogif.html -+++ b/userguide/ppmtogif.html -@@ -5,17 +5,16 @@ +diff -urNp a/userguide/ppmtogif.html b/userguide/ppmtogif.html +--- a/userguide/ppmtogif.html 2025-02-04 10:47:27.828451545 +0100 ++++ b/userguide/ppmtogif.html 2025-02-04 18:12:39.950710820 +0100 +@@ -5,17 +5,17 @@

      NAME

      -ppmtogif - replaced by pamtogif - -

      DESCRIPTION

      -- --

      This program is part of Netpbm. +

      ppmtogif - replaced by pamtogif

      -+

      This program is part of Netpbm.

      -

      ppmtogif was replaced in Netpbm 10.37 (December 2006) by --pamtogif. -+pamtogif.

      +

      This program is part of Netpbm. +

      SYNOPSIS

      +

      ppmtogif was replaced in Netpbm 10.37 (December 2006) by + pamtogif. +

      pamtogif is mostly backward compatible with ppmtogif. +

      DESCRIPTION

      One way pamtogif is not backward compatible with ppmtogif is that to specify a transparency (alpha) mask with ppmtogif, you supply the transparency as a separate pseudo-PGM image and use the -@@ -77,8 +76,8 @@ the alpha image need not have the same maxval as the input. - ppmtogif interprets the alpha file using the alpha file's - maxval. - --

      You cannot specify both -transparent and -alpha. -+

      You cannot specify both -transparent and -alpha.

      - - -- -- -+ -+ -diff -urNp a/userguide/pamstereogram.html b/userguide/pamstereogram.html ---- a/userguide/pamstereogram.html 2021-01-26 13:41:35.057401508 +0100 -+++ b/userguide/pamstereogram.html 2021-01-26 14:23:22.076294594 +0100 -@@ -9,7 +9,8 @@ - -

      NAME

      - --pamstereogram - create a single-image stereogram from a PAM depth map -+

      pamstereogram - create a single-image stereogram from a PAM -+depth map

      - -

      SYNOPSIS

      - -@@ -39,13 +40,13 @@ pamstereogram - create a single-image st - [-randomseed=integer] - [-tileable] - [infile] -- -+

      - - - -

      DESCRIPTION

      - --

      This program is part of Netpbm. -+

      This program is part of Netpbm.

      - -

      pamstereogram inputs a depth map (a map of the distances - from your eye of the points in a scene) and outputs a single-image -@@ -55,22 +56,22 @@ eyes. What's exciting about single-image - don't require special glasses to view, although it does require a bit - of practice to train your eyes to unfocus properly. The - pamstereogram program provides a wealth of control over how the --stereogram is generated, including the following: -+stereogram is generated, including the following:

      - -
        --
      • black and white, grayscale, or color output -+
      • black and white, grayscale, or color output
      • - -
      • single-image random-dot stereograms (SIRDS), single-image - stereograms (SIS) using a tiled image, or mapped-texture stereograms --(MTS) -+(MTS)
      • - --
      • images targeting a given device resolution and eye separation -+
      • images targeting a given device resolution and eye separation
      • - --
      • optional guide boxes to assist in focusing -+
      • optional guide boxes to assist in focusing
      • - --
      • the ability to trade off depth levels for easier viewing -+
      • the ability to trade off depth levels for easier viewing
      • - --
      • choice of wall-eyed or cross-eyed stereograms -+
      • choice of wall-eyed or cross-eyed stereograms
      • - -
      -

      The output is a PAM image on standard output. Options control -@@ -80,7 +81,7 @@ if you will use the image as input to a - many other programs don't know what a PAM is. - -

      To make a red/cyan type of stereogram (that you view with 3-D --glasses) instead, see ppm3d. -+glasses) instead, see ppm3d.

      - - -

      OPTIONS

      -@@ -92,32 +93,32 @@ from its value. -

      In addition to the options common to all programs based on libnetpbm - (most notably -quiet, see - Common Options), pamstereogram recognizes the following --command line options: -+command line options:

      - -
      - --
      -verbose -+
      -verbose
      -
      Display messages about image sizes and formats and properties --of the stereogram being generated. -+of the stereogram being generated.
      - --
      -blackandwhite -+
      -blackandwhite
      -
      Produce a single-image random-dot black-and-white stereogram. --This is the default. -+This is the default.
      - --
      -grayscale --
      Produce a single-image random-dot grayscale stereogram. -+
      -grayscale
      -+
      Produce a single-image random-dot grayscale stereogram.
      - --
      -color --
      Produce a single-image random-dot color stereogram. -+
      -color
      -+
      Produce a single-image random-dot color stereogram.
      - --
      -maxval=value -+
      -maxval=value
      -
      Designate the maximum value of each gray/color component, i.e. - the color resolution. Smaller values make the output image have - smaller numbers of unique grays/colors. If you don't specify - -maxval, pamstereogram uses the maxval of the input --image. This option has no effect with -blackandwhite. -+image. This option has no effect with -blackandwhite.
      - --
      -patfile=pamfile -+
      -patfile=pamfile
      -
      Specify an image to use as a repeated background pattern for - the stereogram instead of a random-dot pattern. Intricate images - generally produce a crisper 3-D effect that simpler images. The -@@ -126,9 +127,9 @@ grayscale or color) as the pattern file. - -patfile option along with -blackandwhite, - -grayscale, -color, or -maxval. The - -verbose option will give you information on the ideal --dimensions of the pattern file. -+dimensions of the pattern file.
      - --
      -xbegin=pixels -+
      -xbegin=pixels
      -
      Specify the horizontal coordinate at which to begin stereogram generation. - The background pattern will be minimally distorted at this point and more - distorted at greater distances. Consider using this in conjunction -@@ -136,38 +137,38 @@ with -xshift to align the horizon - horizontal start of stereogram generation. -xbegin is meaningful only - in conjunction with -patfile, -makemask, or -texfile, - and pamstereogram actually ignores it with respect to -texfile --(but may not in a future version of pamstereogram). -+(but may not in a future version of pamstereogram).
      - --

      The default is to begin in the center. -+

      The default is to begin in the center.

      - --

      This option was new in Netpbm 10.71 (June 2015). -+

      This option was new in Netpbm 10.71 (June 2015).

      - --
      -texfile=pamfile -+
      -texfile=pamfile
      -
      Specify an image to use as the texture for a mapped-texture - stereogram. The idea is that the depth-map image provides the depth - values of the 3-D object/scene while the texture image provides the - true-color values. Consequently, the texture image should align with - the depth-map image. (Note that it's required to have the same - dimensions.) The texture image's background color is ignored when --blending colors. -+blending colors.
      - --

      This option was new in Netpbm 10.53 (December 2010). -+

      This option was new in Netpbm 10.53 (December 2010).

      - - --
      -bgcolor=color -+
      -bgcolor=color
      -
      Use color as the texture image's background color instead - of letting pamstereogram determine it automatically. Specify - the color as described for the - argument of the pnm_parsecolor() library - routine. The -bgcolor option is meaningful only in conjunction --with -texfile. -+with -texfile.
      - --

      This option was new in Netpbm 10.53 (December 2010). -+

      This option was new in Netpbm 10.53 (December 2010).

      - - --
      -smoothing=pixels -+
      -smoothing=pixels
      -
      When used without -texfile, attempt to eliminate artifacts --introduced by edges in the depth map if pixels is greater than zero. -+introduced by edges in the depth map if pixels is greater than zero.
      - -

      When used with -texfile, horizontally blur non-background - colors into background pixels up to a distance of pixels pixels. -@@ -176,22 +177,22 @@ by the stereogram's color constraints wh - stereogram. In this case, the -smoothing option is helpful - when the texture image includes smooth color transitions (as in a - photograph) but makes crisp texture images (as in a line drawing) --appear blurry. -+appear blurry.

      - -

      This option was new in Netpbm 10.53 (December 2010). Before --Netpbm 10.61 (December 2012), it has no effect without -texfile. -+Netpbm 10.61 (December 2012), it has no effect without -texfile.

      - - --
      -xshift=pixels -+
      -xshift=pixels
      -
      Shift the pattern image (designated by -patfile) to the --right by pixels pixels (default: 0). --

      --This option is valid only along with -patfile. -+right by pixels pixels (default: 0).

      -+ -+

      This option is valid only along with -patfile.

      - --
      -yshift pixels -+
      -yshift pixels
      -
      Shift the pattern image (designated by -patfile) - downwards by pixels pixels (default: 0). This option is --valid only along with -patfile. -+valid only along with -patfile.
      - -
      -yfillshift pixels
      -
      Shift the pattern image (designated by -patfile) downwards -@@ -200,77 +201,77 @@ population of the pattern. (If used wit - shifts are summed.) A small -yfillshift helps reduce visual - artifacts in the 3-D image. Steer's website, referenced under - SEE ALSO, recommends a shift of approximately --1/16" (6–7 pixels at pamstereogram's default of 100 DPI). -+1/16" (6–7 pixels at pamstereogram's default of 100 DPI).
      - --

      This option was new in Netpbm 10.94 (March 2021). -+

      This option was new in Netpbm 10.94 (March 2021).

      - --
      -magnifypat=scale -+
      -magnifypat=scale
      -
      Magnify each pixel in the pattern file or each random dot by - integral scaling factor scale. Note that - pamstereogram applies the pattern magnification - after pattern shifting (-xshift and ---yshift). -+-yshift).
      - --
      -guidebottom -+
      -guidebottom
      -
      - Draw a pair of black squares on a white background underneath the stereogram - proper. These squares help you guide your eyes into proper focus to view the - 3-D image. The trick is to focus your eyes some distance behind the image, - causing you to see four black squares, then continue altering your focus - distance until the middle two black squares fuse into a single black --square. At that point, a crisp, 3-D image will appear. -+square. At that point, a crisp, 3-D image will appear.
      - -

      This option was new in Netpbm 10.61 (December 2012). Before that, - the presence of -guidesize, with a positive value, has the same --effect. -+effect.

      - - --
      -guidetop -+
      -guidetop
      -
      --Same as -guidebottom, except the guides go at the top of the image. -+Same as -guidebottom, except the guides go at the top of the image.
      - -

      This option was new in Netpbm 10.61 (December 2012). Before that, - the presence of -guidesize, with a negative value, has the same --effect. -+effect.

      - --
      -guidesize=pixels -+
      -guidesize=pixels
      - --
      The size (width and height) of each guide box. -+
      The size (width and height) of each guide box.
      - --

      This is valid only with -guidetop or -guidebottom. -+

      This is valid only with -guidetop or -guidebottom.

      - --

      Default is 20. -+

      Default is 20.

      - -

      Before Netpbm 10.61 (December 2012), if you don't specify this option, - pamstereogram draws no guides. If you specify it with a positive - value, pamstereogram behaves as if you specified -guidebottom - too, and if you specify it with a negative value, it behaves as if you - specified -guidetop and specified guidesize with the absolute --value of that negative value. -+value of that negative value.

      - --
      -dpi=resolution -+
      -dpi=resolution
      -
      Specify the resolution of the output device in dots per inch. - The default is 100 DPI, which represents a fairly crisp screen --resolution. -+resolution.
      - --

      Before Netpbm 10.53 (December 2010), the default was 96 DPI. -+

      Before Netpbm 10.53 (December 2010), the default was 96 DPI.

      - - --
      -crosseyed -+
      -crosseyed
      -
      Invert the gray levels in the depth map (input image) so that the 3-D - image pops out of the page where it would otherwise sink into the page and - vice versa. Some people are unable to diverge their eyes and can only cross - them. The -crosseyed option enables such people to see the 3-D image as - intended. You can also specify the -crosseyed option if you prefer - using depth maps in which darker colors are closer to the eye and lighter --colors are farther from the eye. -+colors are farther from the eye.
      - -

      Before Netpbm 10.53 (December 2010), pamstereogram used higher - (lighter) numbers for things closer to the eye without ---crosseyed and vice versa. -+-crosseyed and vice versa.

      - - --
      -makemask -+
      -makemask
      -
      Instead of a stereogram, output a PAM mask image showing - coloring constraints. New pixels will be taken from the pattern - file where the mask is black. Copies of existing pixels will be -@@ -278,30 +279,30 @@ taken from the pattern file where the ma - -makemask option can be used to help create more - sophisticated pattern files (to use with -patfile) Note that - -makemask ignores -magnifypat; it always produces --masks that assume a pattern magnification of 1. -+masks that assume a pattern magnification of 1.
      - --
      -eyesep=inches -+
      -eyesep=inches
      -
      Specify the separation in inches between your eyes. The - default, 2.5 inches (6.4 cm), should be sufficient for most people --and probably doesn't need to be changed. -+and probably doesn't need to be changed.
      - --
      -depth=fraction -+
      -depth=fraction
      -
      Specify the output image's depth of field. That is, - fraction represents the fractional distance of the near - plane from the far plane. Smaller numbers make the 3-D image easier - to perceive but flatter. Larger numbers make the 3-D image more - difficult to perceive but deeper. The default, 0.3333, generally --works fairly well. -+works fairly well.
      - --
      -planes=near_pixels,far_pixels -+
      -planes=near_pixels,far_pixels
      -
      Explicitly specify the distance between repeated pixels in the near plane - and in the far plane. This is an alternative to - -eyesep and -depth. The following equalities hold: - -
        --
      • eyesep = 2 * far -+
      • eyesep = 2 * far
      • -
      • depth = 2 * (farnear) / -- (2 * farnear) -+ (2 * farnear)
      • -
      - -

      The number of distinct 3-D depths is far -@@ -309,34 +310,35 @@ and in the far plane. This is an altern - and -depth are a more human-friendly way to specify stereoscopic - parameters (distance between eyes and tradeoff between perceptibility - and depth) while -planes is a more computer-centric way (pixel --distances in the resulting stereogram). -+distances in the resulting stereogram).

      - --

      This option was new in Netpbm 10.59 (June 2012). -+

      This option was new in Netpbm 10.59 (June 2012).

      -+
      - - --
      -randomseed=integer -+
      -randomseed=integer
      -
      Specify a seed to be used for the random number generator. - The default is to use a seed based on the time of day, to one second --granularity. -+granularity.
      - -

      It is useful to specify the seed if you want to create reproducible - results. With the same random seed, you should get identical results --every time you run pamstereogram. -+every time you run pamstereogram.

      - -

      This is irrelevant if you use a pattern file (-patfile - option), because there is no random element to pamstereogram's --behavior. -+behavior.

      - --

      This option was new in Netpbm 10.32 (February 2006). -+

      This option was new in Netpbm 10.32 (February 2006).

      - --
      -tileable -+
      -tileable
      - -
      Make the generated image horizontally tileable. This works by - blending a left-to-right rendering (the equivalent - of -xbegin=0) with a right-to-left rendering (the equivalent - of -xbegin=width−1). - --

      This option was new in Netpbm 10.91 (June 2020). -+

      This option was new in Netpbm 10.91 (June 2020).

      - -
      - -@@ -345,21 +347,21 @@ of -xbegin=width−1). - -

      The only parameter, infile, is the name of an input file - that is a depth map image. If you don't specify infile, the --input is from standard input. -+input is from standard input.

      - -

      The input is a PAM image of depth 1. Each sample represents the - distance from the eye that the 3-D image at that location should --be. Lower (darker) numbers mean further from the eye. -+be. Lower (darker) numbers mean further from the eye.

      - -

      NOTES

      - -

      Input Images

      - -

      pamstereogram pays no attention to the image's tuple type and --ignores all planes other than plane 0. -+ignores all planes other than plane 0.

      - -

      Like any Netpbm program, pamstereogram will accept PNM --input as if it were the PAM equivalent. -+input as if it were the PAM equivalent.

      - -

      Mapped-texture Stereograms

      - -@@ -367,12 +369,12 @@ input as if it were the PAM equivalent. - drawn with true colors. Unlike a SIRDS or tiled-image SIS, however, - the image portrayed by an MTS is apparent in normal 2-D viewing. It - appears repeated multiple times and overlapped with itself, but it is --not hidden. -+not hidden.

      - -

      You create an MTS with pamstereogram by passing the filename - of a PAM "texture image" with a -texfile option. A - texture image portrays the same 3-D object as the depth-map image but --indicates the colors that the program should apply to the object. -+indicates the colors that the program should apply to the object.

      - -

      pamstereogram ignores the texture image's background color when it - overlaps copies of the 3-D object. This prevents, for example, a bright-red -@@ -382,32 +384,32 @@ object remains bright red. A consequenc - best when the objects in the texture image have a crisp outline. Smooth - transitions to the background color result in unwanted color artifacts around - edges because the program ignores only exact matches with the --background color. -+background color.

      - -

      You should specify a larger-than-normal value for -eyesep - (and/or -dpi) when producing an MTS. Otherwise, the 3-D object will - repeat so many times that most colored pixels will overlap other colored --pixels, reducing the number of true-colored pixels that remain. -+pixels, reducing the number of true-colored pixels that remain.

      - -

      An MTS can employ a background pattern (-patfile). In this - case, pamstereogram replaces background pixels with pattern pixels in --the final step of generating the image. -+the final step of generating the image.

      - - -

      Miscellaneous

      - -

      A good initial test is to input an image consisting of a solid - shape of distance 0 within a large field of maximum distance (e.g., a --white square on a black background). -+white square on a black background).

      - -

      With the default values for -dpi and -eyesep, pattern --images that are 128 pixels wide can tile seamlessly. -+images that are 128 pixels wide can tile seamlessly.

      - - -

      EXAMPLES

      - -

      Generate a SIRDS out of small, brightly colored squares and --prepare it for display on an 87 DPI monitor: -+prepare it for display on an 87 DPI monitor:

      - -
      -     pamstereogram depthmap.pam \
      -@@ -439,21 +441,21 @@ speckles:
      - 
      - 

      SEE ALSO

      - - - -@@ -461,32 +463,32 @@ URL: AUTHOR --

      Copyright © 2006-2020 Scott Pakin, scott+pbm@pakin.org. -+

      Copyright © 2006-2020 Scott Pakin, scott+pbm@pakin.org.

      - -

      Table Of Contents

      - - - -diff -urNp a/userguide/pamhomography.html b/userguide/pamhomography.html ---- a/userguide/pamhomography.html 2021-01-26 15:19:07.403345047 +0100 -+++ b/userguide/pamhomography.html 2021-01-26 15:29:36.659652764 +0100 -@@ -9,7 +9,7 @@ - - - --

      pamhomography

      -+

      pamhomography

      - - Updated: 03 January 2021 -
      -@@ -29,7 +29,7 @@ Updated: 03 January 2021 - [-mapfile=map_file] - [-view=coords] - [-fill=color] -- [pam_file] -+ [pam_file

      ] - -

      You can abbreviate any option to its shortest unique prefix. You can use - two hyphens instead of one to delimit an option. You can separate an option -@@ -42,7 +42,7 @@ from its value with whitespace instead o - of Netpbm.

      - -

      pamhomography transforms a quadrilateral—not necessarily --rectangular—region of an image, producing a new image. -+rectangular—region of an image, producing a new image.

      - -

      You can do any - affine image transformation: translation, reflection, scaling, -@@ -111,9 +111,9 @@ quadrilateral.

      -

      This is the color with which the program fills all pixels that lie outside - of the target quadrilateral. Specify the color as described for the - --argument of the pnm_parsecolor() library routine. -+argument of the pnm_parsecolor() library routine.

      - --

      The default is black, and for images with a transparency plane, transparent. -+

      The default is black, and for images with a transparency plane, transparent.

      - - -
    -@@ -132,7 +132,7 @@ by map_file.

    - -

    pamhomography's only parameter, pam_file, is the name of the - file containing the input image. If you don't specify pam_file, the -- image comes from Standard Input. -+ image comes from Standard Input.

    - - -

    NOTES

    -@@ -260,23 +260,23 @@ preceding examples:

    -

    SEE ALSO

    - - - - -

    SEE ALSO

    - --

    pamhomography was new in Netpbm 10.94 (March 2021). -+

    pamhomography was new in Netpbm 10.94 (March 2021).

    - - -

    AUTHOR

    -diff -urNp a/userguide/pamhomography.1 b/userguide/pamhomography.1 ---- a/userguide/pamhomography.1 1970-01-01 01:00:00.000000000 +0100 -+++ b/userguide/pamhomography.1 2021-01-26 15:23:06.759944223 +0100 -@@ -0,0 +1,407 @@ -+\ -+.\" This man page was generated by the Netpbm tool 'makeman' from HTML source. -+.\" Do not hand-hack it! If you have bug fixes or improvements, please find -+.\" the corresponding HTML page on the Netpbm website, generate a patch -+.\" against that, and send it to the Netpbm maintainer. -+.TH "pamhomography" 1 "03 January 2021" "netpbm documentation" -+ -+ -+ -+ -+ -+ -+.UN NAME -+.SH NAME -+.PP -+pamhomography - map one arbitrary quadrilateral image region to another -+ -+ -+.UN SYNOPSIS -+.SH SYNOPSIS -+.PP -+\fBpamhomography\fP -+ [\fB-from\fP=\fIcoords\fP] -+ [\fB-to\fP=\fIcoords\fP] -+ [\fB-mapfile\fP=\fImap_file\fP] -+ [\fB-view\fP=\fIcoords\fP] -+ [\fB-fill\fP=\fIcolor\fP] -+ [\fIpam_file\fP] -+.PP -+You can abbreviate any option to its shortest unique prefix. You can use -+two hyphens instead of one to delimit an option. You can separate an option -+from its value with whitespace instead of \f(CW=\fP. -+ -+ -+.UN DESCRIPTION -+.SH DESCRIPTION -+.PP -+This program is part -+of -+.UR http://netpbm.sourceforge.net/ -+Netpbm -+.UE -+\&. -+.PP -+\fBpamhomography\fP transforms a quadrilateral-not necessarily -+rectangular-region of an image, producing a new image. -+.PP -+You can do any -+.UR https://en.wikipedia.org/wiki/Affine_transformation#Image_transformation -+affine image transformation -+.UE -+\&: translation, reflection, scaling, -+rotation, and shearing/skewing. However, \fBpamhomography\fP additionally can -+do \fIbilinear\fP transforms, which means it can warp any quadrilateral to any -+other quadrilateral, even when this mapping cannot be described using a single -+set of linear equations. This can be useful, for example, for creating -+perspective views of rectangular images or for reverse-mapping a perspective -+view back to a rectangular projection. -+ -+ -+.UN OPTIONS -+.SH OPTIONS -+.PP -+In addition to the options common to all programs based on libnetpbm (most -+notably \fB-quiet\fP, see -+.UR http://index.html#commonoptions -+Common Options -+.UE -+\&), \fBpamhomography\fP recognizes the following command line -+options: -+ -+ -+ -+
    \fB-from\fP=\fIcoords\fP -+.sp -+This defines the source quadrilateral. \fIcoords\fP is a list of four -+ integer-valued (\fIx\fP, \fIy\fP) coordinates. If you do not -+ specify \fB-from\fP, the source quadrilateral is taken to be the four -+ corners of the input image in clockwise order, starting from the upper -+ left. -+ -+ -+
    \fB-to\fP=\fIcoords\fP -+.sp -+This defines the target quadrilateral. \fIcoords\fP is a list of four -+integer-valued (\fIx\fP, \fIy\fP) coordinates. If you do not -+specify \fB-to\fP, the target quadrilateral is taken to be the four corners -+of the input image in clockwise order, starting from the upper left. -+ -+ -+
    \fB-mapfile\fP=\fImap_file\fP -+.sp -+This names a text file that describes the mapping from the source to the -+target quadrilateral. The file \fImap_file\fP must contain either eight -+integer-valued (\fIx\fP, \fIy\fP) coordinates, being the four source -+coordinates followed by the corresponding four target coordinates, or only -+four (\fIx\fP, \fIy\fP) coordinates, being only the four target -+coordinates. In the latter case, the source quadrilateral is taken to be the -+four corners of the input image in clockwise order, starting from the upper -+left. -+ -+ -+
    \fB-view\fP=\fIcoords\fP -+.sp -+This defines the target view. \fIcoords\fP is a list of two integer-valued -+(\fIx\fP, \fIy\fP) coordinates: the upper left and lower right boundaries, -+respectively, of the pixels that will be visible in the output image. If -+\fB-view\fP is not specified, the target view will fit precisely the target -+quadrilateral. -+ -+ -+
    \fB-fill\fP=\fIcolor\fP -+.sp -+This is the color with which the program fills all pixels that lie outside -+of the target quadrilateral. Specify the color as described for the -+.UR http://libnetpbm_image.html#colorname -+ argument of the pnm_parsecolor() library routine -+.UE -+\&. -+.sp -+The default is black, and for images with a transparency plane, transparent. -+ -+ -+ -+.PP -+Cooordinates should normally be specified in clockwise order. The syntax is -+fairly flexible: all characters other than the plus sign, minus sign, and -+digits are treated as separators. Although coordinates need to be integers, -+they may lie outside the image's boundary. -+.PP -+If you specify \fB-mapfile\fP along with \fB-from\fP and/or \fB-to\fP, -+\fB-from\fP and \fB-to\fP override the quadrilaterals specified -+by \fImap_file\fP. -+ -+ -+.UN PARAMETERS -+.SH PARAMETERS -+.PP -+\fBpamhomography\fP's only parameter, \fIpam_file\fP, is the name of the -+ file containing the input image. If you don't specify \fIpam_file\fP, the -+ image comes from Standard Input. -+ -+ -+.UN NOTES -+.SH NOTES -+.PP -+The output image uses the same Netpbm format as the input image. -+.PP -+Simple transformations are best handled by other Netpbm programs, such as -+those listed in the -+.UR #SEE-ALSO -+\&'SEE ALSO' -+.UE -+\& section -+below. Use \fBpamhomography\fP for more sophisticated transformations such as -+perspective adjustments, rotations around an arbitrary point in the image, -+extraction of non-rectangular quadrilaterals, shearings by coordinates rather -+than by angle, and, in general, all transformations that are most easily -+expressed as mapping four points in one image to four points in another -+image. -+ -+.UN EXAMPLES -+.SH EXAMPLES -+.PP -+The following examples use the -+.UR park_row.ppm -+park_row.ppm -+.UE -+\& test image, which is a -+.UR https://commons.wikimedia.org/wiki/File:15_Park_Row_3.JPG -+ photograph of New York City's Park Row Building -+.UE -+\&, scaled to -+441×640, converted to a PPM file, and redistributed under the terms of -+the -+.UR https://en.wikipedia.org/wiki/GNU_Free_Documentation_License -+ GFDL -+.UE -+\&. -+.PP -+The first example showcases the real power of bilinear transformations. -+Assuming \fIpark_row_rect.map\fP has the following contents: -+ -+.nf\f(CW (147, 51) (316, 105) (402, 595) (92, 560) -+ (0, 0) (440, 0) (440, 639) (0, 639)\fP
    -+.PP -+then -+ -+.nf\f(CW pamhomography -mapfile park_row_rect.map park_row.ppm > park_row_rect.ppm\fP -+.PP -+projects the building's facade from a perspective view to a rectilinear -+front-on view. Remember that \fBpamhomography\fP ignores the parentheses and -+commas used in \fIpark_row_rect.map\fP; they merely make the file more -+human-readable. We equivalently could have written -+ -+.nf\f(CW 147 51 316 105 402 595 92 560 0 0 440 0 440 639 0 639\fP -+.PP -+or any of myriad other variations. -+.PP -+\fBpamhomography\fP can warp the image to a trapezoid to make it look like -+it's leaning backwards in 3-D: -+ -+.nf\f(CW pamhomography -to '50,0 390,0 440,200 0,200' park_row.ppm > park_row_trap.ppm\fP -+.PP -+As a very simple example, -+ -+.nf\f(CW pamhomography -to '440,0 0,0 0,639 440,639' park_row.ppm > park_row_flip.ppm\fP -+.PP -+flips the image left-to-right. Note that in this case the target -+quadrilateral's coordinates are listed in counterclockwise order because -+that represents the correspondence between points (0, 0) ↔ (440, 0) and -+(0, 639) ↔ (639, 0). -+.PP -+Scaling is also straightforward. The following command scales down the -+image from 441×640 to 341×540: -+ -+.nf\f(CW pamhomography -to '0,0 340,0 340,539 0,539' park_row.ppm > park_row_small.ppm\fP -+.PP -+Let's add 100 pixels of tan border to the above. We use \fB-view\fP and -+\fB-fill\fP to accomplish that task: -+ -+.nf\f(CW pamhomography -to '0,0 340,0 340,539 0,539' -view '-100,-100 440,639' -fill tan park_row.ppm > park_row_small_border.ppm\fP -+.PP -+We can add a border without having to scale the image: -+ -+.nf\f(CW pamhomography -view '-100,-100 540,739' -fill tan park_row.ppm > park_row_border.ppm\fP -+.PP -+The \fB-view\fP option can also be used to extract a rectangle out of an -+image, discarding the rest of the image: -+ -+.nf\f(CW pamhomography -view '130,10 205,80' park_row.ppm > park_row_cut.ppm\fP -+.PP -+Specifying the same set of coordinates to \fB-from\fP and \fB-to\fP has -+the same effect but also allows you to extract non-rectangular quadrilaterals -+from an image: -+ -+.nf\f(CW pamhomography -from '185,300 310,325 320,425 180,405' -to '185,300 310,325 320,425 180,405' park_row.ppm > park_row_cut_2.ppm\fP -+.PP -+Rotation is doable but takes some effort. The challenge is that you need to -+compute the rotated coordinates yourself. The matrix expression to rotate -+points \e((x_1, y_1)\e) \e((x_2, y_2)\e), \e((x_3, y_3)\e), and \e((x_4, y_4)\e) -+clockwise by \e(\etheta\e) degrees around point \e((c_x, c_y)\e) is -+.PP -+\e[ \ebegin{bmatrix} 1 & 0 & c_x \e\e 0 & 1 & c_y \e\e 0 & 0 -+& 1 \eend{bmatrix} \ebegin{bmatrix} \ecos \etheta & -\esin \etheta & 0 -+\e\e \esin \etheta & \ecos \etheta & 0 \e\e 0 & 0 & 1 \eend{bmatrix} -+\ebegin{bmatrix} 1 & 0 & -c_x \e\e 0 & 1 & -c_y \e\e 0 & 0 -+& 1 \eend{bmatrix} \ebegin{bmatrix} x_1 & x_2 & x_3 & x_4 \e\e y_1 -+& y_2 & y_3 & y_4 \e\e 1 & 1 & 1 & 1 \eend{bmatrix} -+\equad. \e] -+.PP -+For example, to rotate \fIpark_row.ppm\fP 30° clockwise around (220, -+320) you would compute -+.PP -+\e[ \ebegin{bmatrix} 1 & 0 & 220 \e\e 0 & 1 & 320 \e\e 0 & 0 -+& 1 \eend{bmatrix} \ebegin{bmatrix} \ecos 30^{\ecirc} & -\esin 30^{\ecirc} -+& 0 \e\e \esin 30^{\ecirc} & \ecos 30^{\ecirc} & 0 \e\e 0 & 0 & 1 -+\eend{bmatrix} \ebegin{bmatrix} 1 & 0 & -220 \e\e 0 & 1 & -320 \e\e -+0 & 0 & 1 \eend{bmatrix} \ebegin{bmatrix} 0 & 440 & 440 & 0 -+\e\e 0 & 0 & 639 & 639 \e\e 1 & 1 & 1 & 1 \eend{bmatrix} = -+\ebegin{bmatrix} 189.4744 & 570.5256 & 251.0256 & -130.0256 \e\e -+-67.1281 & 152.8719 & 706.2621 & 486.2621 \e\e 1.0000 & 1.0000 -+& 1.0000 & 1.0000 \eend{bmatrix} \equad, \e] -+.PP -+round these coordinates to integers, transpose the matrix, and produce the -+following map file, \fIpark_row_rot30.map\fP: -+ -+.nf\f(CW 189 -67 -+ 571 153 -+ 251 706 -+ -130 486\fP -+.PP -+(These are the 'to' coordinates; we use the default, full-image -+\&'from' coordinates.) The mapping then works as in all of the -+preceding examples: -+ -+.nf\f(CW pamhomography -mapfile park_row_rot30.map park_row.ppm > park_row_rot30.ppm\fP -+ -+ -+.UN SEE-ALSO -+.SH SEE ALSO -+ -+ -+.IP \(bu -+ -+.BR "pamcut" (1)\c -+\& -+.IP \(bu -+ -+.BR "pamenlarge" (1)\c -+\& -+.IP \(bu -+ -+.BR "pamflip" (1)\c -+\& -+.IP \(bu -+ -+.BR "pamperspective" (1)\c -+\& -+.IP \(bu -+ -+.BR "pamscale" (1)\c -+\& -+.IP \(bu -+ -+.BR "pamstretch" (1)\c -+\& -+.IP \(bu -+ -+.BR "pam" (1)\c -+\& -+.IP \(bu -+ -+.BR "pnmmargin" (1)\c -+\& -+.IP \(bu -+ -+.BR "pnmpad" (1)\c -+\& -+.IP \(bu -+ -+.BR "pnmrotate" (1)\c -+\& -+.IP \(bu -+ -+.BR "pnmshear" (1)\c -+\& -+ -+ -+ -+.UN SEE-ALSO -+.SH SEE ALSO -+.PP -+\fBpamhomography\fP was new in Netpbm 10.94 (March 2021). -+ -+ -+.UN AUTHOR -+.SH AUTHOR -+.PP -+Copyright \(co 2020 Scott -+Pakin, \fIscott+pbm@pakin.org\fP -+ -+ -+.UN index -+.SH Table of Contents -+ -+ -+.IP \(bu -+ -+.UR #SYNOPSIS -+SYNOPSIS -+.UE -+\& -+.IP \(bu -+ -+.UR #DESCRIPTION -+DESCRIPTION -+.UE -+\& -+.IP \(bu -+ -+.UR #OPTIONS -+OPTIONS -+.UE -+\& -+.IP \(bu -+ -+.UR #PARAMETERS -+PARAMETERS -+.UE -+\& -+.IP \(bu -+ -+.UR #NOTES -+NOTES -+.UE -+\& -+.IP \(bu -+ -+.UR #EXAMPLES -+EXAMPLES -+.UE -+\& -+.IP \(bu -+ -+.UR #SEE-ALSO -+SEE ALSO -+.UE -+\& -+.IP \(bu -+ -+.UR #HISTORY -+HISTORY -+.UE -+\& -+.IP \(bu -+ -+.UR #AUTHOR -+AUTHOR -+.UE -+\& -+.SH DOCUMENT SOURCE -+This manual page was generated by the Netpbm tool 'makeman' from HTML -+source. The master documentation is at -+.IP -+.B http://netpbm.sourceforge.net/doc/pamhomography.html -+.PP -\ Chybí znak konce řádku na konci souboru diff --git a/netpbm-manual-pages.patch b/netpbm-manual-pages.patch deleted file mode 100644 index df35cbb..0000000 --- a/netpbm-manual-pages.patch +++ /dev/null @@ -1,1348 +0,0 @@ -diff --git a/userguide/libnetpbm_ug.html b/userguide/libnetpbm_ug.html -index 92df98a..60ccc88 100644 ---- a/userguide/libnetpbm_ug.html -+++ b/userguide/libnetpbm_ug.html -@@ -374,7 +374,7 @@ plain format. -

    Reference

    - -

    The Libnetpbm Netpbm Image --Processing Manual describes the the libnetpbm functions for -+Processing Manual describes the libnetpbm functions for - processing image data. - -

    The Libnetpbm Utility Manual -diff --git a/userguide/pamfunc.html b/userguide/pamfunc.html -index 60d53d6..80f90f2 100644 ---- a/userguide/pamfunc.html -+++ b/userguide/pamfunc.html -@@ -60,7 +60,7 @@ output image. - and bit string (such as and with 01001000). For the arithmetic functions, the - function arguments and results are the fraction that a sample is of the - maxval, i.e. normal interpretation of PAM tuples. But for the bit string --functions, the value is the the bit string whose value as a binary cipher is -+functions, the value is the bit string whose value as a binary cipher is - the sample value, and the maxval indicates the width of the bit string. - -

    Arithmetic functions

    -diff --git a/userguide/pbmtog3.html b/userguide/pbmtog3.html -index 88de765..4590a17 100644 ---- a/userguide/pbmtog3.html -+++ b/userguide/pbmtog3.html -@@ -36,7 +36,7 @@ use those encodings. -

    In addition to the options common to all programs based on libnetpbm - (most notably -quiet, see - Common Options), pbmtog3 recognizes the following --command line options: -+command line options:

    - -
    -
    -reversebits -@@ -80,7 +80,7 @@ You cannot specify both. -

    HISTORY

    - -

    Before Netpbm 10.79 (June 2017), there was a different program by the same --name in Netpbm, which was written by by Paul Haeberli -+name in Netpbm, which was written by Paul Haeberli - <paul@manray.sgi.com> in 1989 - and then modified extensively by others. - -diff --git a/userguide/ppmtompeg.html b/userguide/ppmtompeg.html -deleted file mode 100644 -index af5a8d7..0000000 ---- a/userguide/ppmtompeg.html -+++ /dev/null -@@ -1,1294 +0,0 @@ -- --Ppmtompeg User Manual -- --

    ppmtompeg

    --Updated: 23 July 2006 --
    --Table Of Contents -- --

    NAME

    --ppmtompeg - encode an MPEG-1 bitstream -- --

    SYNOPSIS

    -- --ppmtompeg --[options] --parameter-file -- --

    DESCRIPTION

    -- --

    This program is part of Netpbm. -- --

    ppmtompeg produces an MPEG-1 video stream. MPEG-1 is the --first great video compression method, and is what is used in Video CDs --(VCD). ppmtompeg originated in the year 1995. DVD uses a more --advanced method, MPEG-2. There is an even newer method called MPEG-4 --which is also called Divx. I don't know where one finds that used. -- --

    There's technically a difference between a compression method for --video and an actual file (stream) format for a movie, and I don't know --if it can be validly said that the format of the stream --ppmtompeg produces is MPEG-1. -- --

    Mencoder from the Mplayer --package is probably superior for most video format generation --needs, if for no other reason than that it is more popular. -- --

    The programming library PM2V --generates MPEG-2 streams. -- --

    Use Mplayer (not part of Netpbm) --to do the reverse conversion: to create a series of PNM files from an MPEG --stream. -- --

    param_file is a parameter file which includes a list of --input files and other parameters. The file is described in detail --below. -- --

    To understand this program, you need to understand something about --the complex MPEG-1 format. One source of information about this --standard format is the section Introduction to MPEG in the Compression FAQ. -- --

    OPTIONS

    -- --

    The -gop, -combine_gops, -frames, and ---combine_frames options are all mutually exclusive. -- --

    --
    -stat stat_file -- --
    This option causes ppmtompeg to append the statistics that --it write to Standard Output to the file stat_file as well. The --statistics use the following abbreviations: bits per block (bpb), bits --per frame (bpf), seconds per frame (spf), and bits per second (bps). -- --

    These statistics include how many I, P, and B frames there were, --and information about compression and quality. -- -- --

    -quiet num_seconds -- --
    causes ppmtompeg not to report remaining time more often --than every num_seconds seconds (unless the time estimate rises, --which will happen near the beginning of the run). A negative value --tells ppmtompeg not to report at all. 0 is the default --(reports once after each frame). Note that the time remaining is an --estimate and does not take into account time to read in frames. -- --
    -realquiet
    causes ppmtompeg to run silently, --with the only screen output being errors. Particularly useful when --reading input from stdin. The equivalent of the -quiet --common option of most other Netpbm programs. -- --
    ---no_frame_summary -- --
    This option prevents ppmtompeg from printing a summary --line for each frame -- --
    -float_dct -- --
    forces ppmtompeg to use a more accurate, yet more --computationally expensive version of the DCT. -- --
    -gop gop_num --
    --causes ppmtompeg to encode only the numbered GOP (first GOP is 0). The --parameter file is the same as for normal usage. The output file will be --the normal output file with the suffix .gop.gop_num. --ppmtompeg does not output any sequence information. -- --
    -combine_gops -- --
    causes ppmtompeg simply to combine some GOP files into a --single MPEG output stream. ppmtompeg inserts a sequence header --and trailer. In this case, the parameter file needs only to contain --the SIZE value, an output file, and perhaps a list of input GOP --files (see below). -- --If you don't supply a list of input GOP files is used, then --ppmtompeg assumes you're using the same parameter file you used --when you created the input (with the -gop option) and --calculates the corresponding gop filenames itself. If this is not the --case, you can specify input GOP files in the same manner as normal --input files -- except instead of using INPUT_DIR, INPUT, and --END_INPUT, use GOP_INPUT_DIR, GOP_INPUT, and GOP_END_INPUT. If no --input GOP files are specified, then the default is to use the output --file name with suffix .gop.gop_num, with gop_num --starting from 0, as the input files. -- --

    Thus, unless you're mixing and matching GOP files from different --sources, you can simply use the same parameter file for creating the --GOP files (-gop) and for later turning them into an MPEG stream --(-combine_gops). -- -- --

    -frames first_frame last_frame -- --
    This option causes ppmtompeg to encode only the frames numbered --first_frame to last_frame, inclusive. The parameter --file is the same as for normal usage. The output will be placed in --separate files, one per frame, with the file names being the normal --output file name with the suffix .frame.frame_num. No --GOP header information is output. (Thus, the parameter file need not --include the GOP_SIZE value) -- --

    Use ppmtompeg -combine_frames to combine these frames later into --an MPEG stream. -- -- --

    -combine_frames -- --
    This option causes ppmtompeg simply to combine some --individual MPEG frames (such as you might have created with an earlier --run of ppmtompeg -frames) into a single MPEG stream. Sequence --and GOP headers are inserted appropriately. In this case, the --parameter file needs to contain only the SIZE value, the GOP_SIZE --value, an output file, and perhaps a list of frame files (see below). -- --

    The parameter file may specify input frame files in the same manner --as normal input files -- except instead of using INPUT_DIR, INPUT, and --END_INPUT, use FRAME_INPUT_DIR, FRAME_INPUT, and FRAME_END_INPUT. If --no input frame files are specified, then the default is to use the --output file name with suffix .frame.frame_num, with --frame_num starting from 0, as the input files. -- -- -- --

    -nice -- --
    This option causes ppmtompeg to run any remote processes --"nicely," i.e. at low priority. (This is relevant only if you are --running ppmtompeg in parallel mode. Otherwise, there are no --remote processes). See 'man nice.' -- --
    -max_machines num_machines -- --
    This option causes ppmtompeg to use no more than --num_machines machines as slaves for use in parallel encoding. -- --
    -snr -- --
    This option causes ppmtompeg to include the signal-to-noise --ratio in the reported statistics. Prints SNR (Y U V) and peak SNR (Y --U V) for each frame. In summary, prints averages of luminance only --(Y). SNR is defined as 10*log(variance of original/variance of --error). Peak SNR is defined as 20*log(255/RMSE). Note that --ppmtompeg runs a little slower when you use this option. -- --
    -mse -- --
    This option causes ppmtompeg to report the mean squared --error per block. It also automatically reports the quality of the --images, so there is no need to specify -snr then. -- --
    -bit_rate_info rate_file -- --
    This option makes ppmtompeg write bit rate information --into the file rate_file. Bit rate information is bits per frame, and --also bits per I-frame-to-I-frame. -- --
    -mv_histogram -- --
    This option causes ppmtompeg to print a histogram of the --motion vectors as part of statistics. There are three histograms -- --one for P frame, one for forward B frame, and one for backward B frame --motion vectors. -- --

    The output is in the form of a matrix, each entry corresponding to one --motion vector in the search window. The center of the matrix --represents (0,0) motion vectors. -- --

    -debug_sockets -- --
    This option causes ppmtompeg to print to Standard Output --messages that narrate the communication between the machines when you run --ppmtompeg in parallel mode. -- --
    -debug_machines -- --
    This option causes ppmtompeg to print to Standard Output --messages that narrate the progress of the conversion on the various --machines when you run ppmtompeg in parallel --mode. -- --
    -- --

    PARAMETER FILE

    -- --

    The parameter file must contain the following --lines (except when using the -combine_gops or -combine_frames --options): -- --

    -- --
    PATTERN pattern -- --
    This statement specifies the pattern (sequence) of I frames, P frames, --and B frames. pattern is just a sequence of the letters I, P, and --B with nothing between. Example: -- --
    --    PATTERN IBBPBBPBBPBBPBB
    --
    -- --

    See I Frames, P Frames, B Frames. -- --

    OUTPUT output file --
    This names the file where the output MPEG stream goes. -- --
    INPUT_DIR directory -- --
    This statement tells where the input images (frames) come from. --If each frame is in a separate file, directory is the directory --where they all are. You may use . to refer to the current --directory. A null directory refers to the root directory of the --system file tree. -- --

    To have ppmtompeg read all the frames serially from Standard --Input, specify --

    --    INPUT_DIR stdin
    --
    -- --
    INPUT --
    --This line must be followed by a list of the input files (in display order) --and then the line END_INPUT. -- --

    There are three types of lines between INPUT and END_INPUT. First, --a line may simply be the name of an input file. Second, the line --may be of the form single_star_expr --[x-y]. --single_star_expr can have a single * in it. It is --replaced by all the numbers between x and y inclusive. So, for --example, the line tennis*.ppm [12-15] refers to the files --tennis12.ppm, tennis13.ppm, tennis14.ppm, tennis15.ppm. -- --

    Uniform zero-padding occurs, as well. For example, the line --football.*.ppm [001-130] refers to the files football.001.ppm, --football.002.ppm, ..., football.009.ppm, football.010.ppm, ..., --football.130.ppm. -- --

    The third type of line is: single_star_expr --[x-y+s], where the --line is treated exactly as above, except that we skip by s. Thus, the --line football.*.ppm [001-130+4] refers to the files --football.001.ppm, football.005.ppm, football.009.ppm, --football.013.ppm, etc. -- --

    Furthermore, a line may specify a shell command to execute to --generate lines to be interpreted as described above, as if those lines --were in the parameter file instead. Use back ticks, like in the --Bourne Shell, like this: -- --

    --    `cat myfilelist`
    --
    -- --

    --If input is from Standard Input (per the INPUT_DIR statement), --ppmtompeg ignores the INPUT/END_INPUT block, but --it still must be present. -- --

    BASE_FILE_FORMAT {PPM | PNM | YUV | -- JPEG | JMOVIE} -- --
    ppmtompeg must convert all input files to one of the --following formats as a first step of processing: PNM, YUV, JPEG(v4), --or JMOVIE. (The conversion may be trivial if your input files are --already in one of these formats). This line specifies which of the --four formats. PPM is actually a subset of PNM. The separate --specification is allowed for backward compatibility. Use PNM instead --of PPM in new applications. -- --
    INPUT_CONVERT conversion_command -- --
    You must specify how to convert a file to the base file format. --If no conversion is necessary, then you would just say: -- --
    --     INPUT_CONVERT *
    --     
    -- --

    Otherwise, conversion_command is a shell command that causes --an image in the format your specified with BASE_FILE_FORMAT to --be written to Standard Output. ppmtompeg executes the command --once for each line between INPUT and END_INPUT (which is --normally, but not necessarily, a file name). In the conversion --command, ppmtompeg replaces each '*' with the contents of that --line. -- -- If you had a bunch of gif files, you might say: --

    --     INPUT_CONVERT giftopnm *
    --     
    -- -- If you have a bunch of separate a.Y, a.U, and a.V files (where -- the U and V have already been subsampled), then you might say: -- --
    --     INPUT_CONVERT cat *.Y *.U *.V
    --     
    -- --

    Input conversion is not allowed with input from stdin, so use -- --

    --     INPUT_CONVERT *
    --     
    -- --as described above. -- --
    SIZE widthxheight -- --
    -- --

    width and height are the width and height of each --frame in pixels. -- --

    When ppmtompeg can get this information from the input image --files, it ignores the SIZE parameter and you may omit it. -- --

    When the image files are in YUV format, the files don't contain --dimension information, so SIZE is required. -- --

    When ppmtompeg is running in parallel mode, not all of the --processes in the network have access to the image files, so --SIZE is required and must give the same dimensions as the --input image files. -- --

    YUV_SIZE widthxheight -- --
    This is an obsolete synonym of SIZE. -- --
    YUV_FORMAT {ABEKAS | PHILLIPS | UCB | -- EYUV | pattern} -- --
    This is meaningful only when BASE_FILE_FORMAT specifies --YUV format, and then it is required. It specifies the sub-format of --the YUV class. -- -- --
    GOP_SIZE n -- --
    n is the number of frames in a Group of Pictures. Except that --because a GOP must start with an I frame, ppmtompeg makes a GOP as --much longer than n as it has to to make the next GOP start with an --I frame. -- --

    Normally, it makes sense to make your GOP size a multiple of your --pattern length (the latter is determined by the PATTERN parameter file --statement). -- --

    See Group Of Pictures. -- --

    SLICES_PER_FRAME n --
    n is roughly the number of slices per frame. Note, at --least one MPEG player may complain if slices do not start at the left --side of an image. To ensure this does not happen, make sure the --number of rows is divisible by SLICES_PER_FRAME. -- --
    PIXEL {FULL | HALF} -- --
    use half-pixel motion vectors, or just full-pixel ones It is --usually important that you use half-pixel motion vectors, because it --results in both better quality and better compression. -- -- --
    RANGE n --
    Use a search range of n pixels in each of the four directions --from a subject pixel. (So the search window is a square n*2 pixels --on a side). -- --
    PSEARCH_ALG {EXHAUSTIVE | TWOLEVEL | -- SUBSAMPLE | LOGARITHMIC} -- --
    This statement tells ppmtompeg what kind of search -- technique (algorithm) to use for P frames. You select the desired -- combination of speed and compression. EXHAUSTIVE gives the -- best compression, but LOGARITHMIC is the fastest. -- TWOLEVEL is an exhaustive full-pixel search, followed by a -- local half- pixel search around the best full-pixel vector (the -- PIXEL option is ignored for this search technique). -- --
    BSEARCH_ALG {SIMPLE | CROSS2 | EXHAUSTIVE} -- --
    This statement tells ppmtompeg what kind of search -- technique (algorithm) to use for B frames. SIMPLE means -- find best forward and backward vectors, then interpolate. -- CROSS2 means find those two vectors, then see what backward -- vector best matches the best forward vector, and vice versa. -- EXHAUSTIVE does an n-squared search and is -- extremely slow in relation to the others (CROSS2 -- is about half as fast as SIMPLE). -- --
    IQSCALE n --
    Use n as the qscale for I frames. -- See Qscale. -- --
    PQSCALE n --
    Use n as the qscale for P frames. -- See Qscale. -- --
    BQSCALE n --
    Use n as the qscale for B frames. -- See Qscale. -- --
    REFERENCE_FRAME {ORIGINAL | DECODED}
    This --statement determines whether ppmtompeg uses the original images --or the decoded images when computing motion vectors. Using decoded --images is more accurate and should increase the playback quality of --the output, but it makes the encoding take longer and seems to give --worse compression. It also causes some complications with parallel --encoding. (see the section on parallel encoding). One thing you can --do as a trade-off is select ORIGINAL here, and lower the --qscale (see QSCALE if the quality is not good enough. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    Original or Decoded? (Normalized)
    ReferenceCompressionSpeedQuality IQuality PQuality B
    Decoded100010001000969919
    Original88513731000912884
    -- -- -- --
    -- --

    The following lines are optional: -- --

    -- --
    FORCE_ENCODE_LAST_FRAME -- --
    This statement is obsolete. It does nothing. -- --

    Before Netpbm 10.26 (January 2005), ppmtompeg would drop --trailing B frames from your movie, since a movie can't end with a B --frame. (See I Frames, P Frames, B Frames. --You would have to specify FORCE_ENCODE_LAST_FRAME to stop --that from happening and get the same function that ppmtompeg --has today. -- -- --

    NIQTABLE -- --
    This statement specifies a custom non-intra quantization table. --If you don't specify this statement, ppmtompeg uses a default --non-intra quantization table. -- --

    --The 8 lines immediately following NIQTABLE specify the quantization --table. Each line defines a table row and consists of 8 integers, --whitespace-delimited, which define the table columns. -- --

    IQTABLE -- --
    This is analogous to NIQTABLE, but for the intra quantization table. -- --
    ASPECT_RATIO ratio -- --
    This statement specifies the aspect ratio for ppmtompeg to --specify in the MPEG output. I'm not sure what this is used for. -- --

    ratio must be 1.0, 0.6735, 0.7031, 0.7615, 0.8055, 0.8437, --0.8935, 0.9157, 0.9815, 1.0255, 1.0695, 1.0950, 1.1575, or 1.2015. -- --

    FRAME_RATE rate --
    This specifies the frame rate for ppmtompeg to specify in the --MPEG output. Some players use this value to determine the playback rate. -- --

    rate must be 23.976, 24, 25, 29.97, 30, 50, 59.94, or 60. -- --

    BIT_RATE rate --
    This specifies the bit rate for Constant Bit Rate (CBR) encoding. -- --

    rate must be an integer. -- --

    BUFFER_SIZE size -- --
    This specifies the value --ppmtompeg is to specify in the MPEG output for the Video --Buffering Verifier (VBV) buffer size needed to decode the sequence. -- --

    A Video Verifying Buffer is a buffer in which a decoder keeps the --decoded bits in order to match the uneven speed of the decoding with --the required constant playback speed. -- --

    As ppmtompeg encodes the image, it simulates the decoding --process in terms of how many bits would be in the VBV as each frame gets --decoded, assuming a VBV of the size you indicate. -- --

    If you specify the WARN_VBV_UNDERFLOW statement, --ppmtompeg issues a warning each time the simulation underflows --the buffer, which suggests that an underflow would occur on playback, --which suggests the buffer is too small. -- --

    If you specify the WARN_VBV_OVERFLOW statement, --ppmtompeg issues a warning each time the simulation overflows --the buffer, which suggests that an overflow would occur on playback, --which suggests the buffer is too small. -- --

    WARN_VBV_UNDERFLOW --
    WARN_VBV_OVERFLOW -- --
    See BUFFER_SIZE. -- --

    These options were new in Netpbm 10.26 (January 2005). Before that, --ppmtompeg issued the warnings always. -- --

    -- -- --The following statements apply only to parallel operation: -- --
    -- --
    PARALLEL -- --
    This statement, paired with END PARALLEL, is what causes --ppmtompeg to operate in parallel mode. See Parallel Operation. -- --
    END PARALLEL -- --
    This goes with PARALLEL. -- --
    PARALLEL_TEST_FRAMES n -- --
    The master starts off by measuring each slave's speed. It does --this by giving each slave n frames to encode and noting how --long the slave takes to finish. These are not just test frames, --though -- they're real frames and the results become part of the --output. --ppmtompeg is old and measures time in undivided seconds, so --to get useful timings, specify enough frames that it will take at --least 5 seconds to process them. The default is 10. -- --

    If you specify FORCE_I_ALIGN, ppmtompeg will increase --the test frames value enough to maintain the alignment. -- --

    If there aren't enough frames for every slave to have the indicated --number of test frames, ppmtompeg will give some slaves fewer. -- -- --

    PARALLEL_TIME_CHUNKS t -- --
    When you specify this statement, the master attempts to feed work --to the slaves in chunks that take t seconds to process. It uses --the speed measurement it made when it started up (see PARALLEL_TEST_FRAMES) --to decide how many frames to put in the chunk. This statement obviously --doesn't affect the first batch of work sent to each slave, which is the --one used to measure the slave's speed. -- --

    Smaller values of t increase communication, but improve load --balancing. The default is 30 seconds. -- --

    You may specify only one of PARALLEL_TIME_CHUNKS, PARALLEL_CHUNK_TAPER, --and PARALLEL_PERFECT. PARALLEL_CHUNK_TAPER is usually best. -- --

    PARALLEL_CHUNK_TAPER -- --
    When you specify this statement, the master distributes work like --with PARALLEL_TIME_CHUNKS, except that the master chooses the number --of seconds for the chunks. It starts with a large number and, as it --gets closer to finishing the job, reduces it. That way, it reduces --scheduling overhead when precise scheduling isn't helpful, but still --prevents a slave from finishing early after all the work has already --been handed out to the other slaves, and then sitting idle while --there's still work to do. -- --

    You may specify only one of PARALLEL_TIME_CHUNKS, PARALLEL_CHUNK_TAPER, --and PARALLEL_PERFECT. PARALLEL_CHUNK_TAPER is usually best. -- -- --

    PARALLEL_PERFECT -- --
    If this statement is present, ppmtompeg schedules on the --assumption that each machine is about the same speed. The master will --simply divide up the frames evenly between the slaves -- each --slave gets the same number of frames. If some slaves are faster than --others, they will finish first and remain idle while the slower slaves --continue. -- --

    This has the advantage of minimal scheduling overhead. Where slaves --have different speeds, though, it makes inefficient use of the fast --ones. Where slaves are the same speed, it also has the disadvantage --that they all finish at the same time and feed their output to the --single Combine Server in a burst, which makes less efficient use of --the Combine Server and thus can increase the total elapsed time. -- --

    You may specify only one of PARALLEL_TIME_CHUNKS, PARALLEL_CHUNK_TAPER, --and PARALLEL_PERFECT. PARALLEL_CHUNK_TAPER is usually best. -- --

    RSH remote_shell_command -- --
    ppmtompeg executes the shell command --remote_shell_command to start a process on another machine. --The default command is rsh, and whatever command you specify --must have compatible semantics. ssh is usually compatible. --The command ppmtompeg uses is one like this: --ssh remote.host.com -l username shellcommand. -- --

    Be sure to set up .rhosts files or SSH key authorizations --where needed. Otherwise, you'll have to type in passwords. -- --

    On some HP machines, rsh is the restricted shell, and you want --to specify remsh. -- --

    FORCE_I_ALIGN -- --
    This statement forces each slave to encode a chunk of frames which --is a multiple of the pattern length (see PATTERN). Since the --first frame in any pattern is an I frame, this forces each chunk --encoded by a slave to begin with an I frame. -- --

    This document used to say there was an argument to --FORCE_I_ALIGN which was the number of frames ppmtompeg --would use (and was required to be a multiple of the pattern length). --But ppmtompeg has apparently always ignored that argument, and --it does now. -- --

    KEEP_TEMP_FILES -- --
    This statement causes ppmtompeg not to delete the temporary --files it uses to transmit encoded frames to the combine server. This --means you will be left with a file for each frame, the same as you --would get with the -frames option. -- --

    This is mostly useful for debugging. -- --

    This works only if you're using a shared filesystem to communicate --between the servers. -- --

    This option was new in Netpbm 10.26 (January 2005). -- --

    -- -- --

    Parameter File Notes

    -- --

    If you use the -combine_gops option, then you need to specify --only the SIZE and OUTPUT values in the parameter file. In --addition, the parameter file may specify input GOP files in the same --manner as normal input files -- except instead of using INPUT_DIR, --INPUT, and END_INPUT, use GOP_INPUT_DIR, GOP_INPUT, and GOP_END_INPUT. --If you specify no input GOP files, then ppmtompeg uses by default the --output file name with suffix .gop.gop_num, with gop_num --starting from 0, as the input files. -- --

    If you use the -combine_frames option, then you need to --specify only the SIZE, GOP_SIZE, and OUTPUT values in the --parameter file. In addition, the parameter file may specify input --frame files in the same manner as normal input files -- except instead --of using INPUT_DIR, INPUT, and END_INPUT, use FRAME_INPUT_DIR, --FRAME_INPUT, and FRAME_END_INPUT. If no input frame files are --specified, then the default is to use the output file name with suffix --.frame.frame_num, with frame_num starting from 0, --as the input files. -- --

    Any number of spaces and tabs may come between each option and value. Lines --beginning with # are ignored. Any other lines are ignored except for --those between INPUT and END_INPUT. This allows you to use the same --parameter file for normal usage and for -combine_gops and ---combine_frames. -- --

    The file format is case-sensitive so all keywords should be in --upper case. -- --

    The statements may appear in any order, except that the order within --a block statement (such as INPUT ... END INPUT) is significant. -- --

    ppmtompeg is prepared to handle up to 16 B frames between --reference frames when encoding with input from stdin. (To build a --modified ppmtompeg with a higher limit, change the constant --B_FRAME_RUN in frame.c and recompile). -- --

    GENERAL USAGE INFORMATION

    -- --

    Qscale

    -- --

    The quantization scale values (qscale) give a trade-off between --quality and compression. Using different Qscale values has very little --effect on speed. The qscale values can be set separately for I, P, and --B frames. -- --

    You select the qscale values with the IQSCALE, --PQSCALE, and BSCALE parameter file statements. -- --

    A qscale value is an integer from 1 to 31. Larger numbers give --better compression, but worse quality. In the following, the quality --numbers are peak signal-to-noise ratio, defined as: --signal-to-noise formula --where MSE is the mean squared error. -- -- --

    Flower garden tests: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    Qscale vs Quality
    QscaleI FramesP FramesB Frames
    143.246.346.5
    632.634.634.3
    1128.629.530.0
    1626.326.828.6
    2124.725.027.9
    2623.523.927.5
    3122.623.027.3
    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    Qscale vs Compression
    QscaleI FramesP FramesB Frames
    1222
    671015
    11111843
    16152997
    211941173
    262456256
    312873330
    -- -- --

    Search Techniques

    -- --

    There are several different motion vector search techniques --available. There are different techniques available for P frame --search and B frame search. Using different search techniques present --little difference in quality, but a large difference in compression --and speed. -- --

    There are 4 types of P frame search: Exhaustive, TwoLevel, --SubSample, and Logarithmic. -- --

    There are 3 types of B frame search: Exhaustive, Cross2, and --Simple. -- --The recommended search techniques are TwoLevel and Logarithmic for --P frame search, and Cross2 and Simple for B frame search. Here are --some numbers comparing the different search methods: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    P frame Motion Vector Search (Normalized)
    TechniqueCompression1Speed 2Quality 3
    Exhaustive100010001000
    SubSample100824561000
    TwoLevel100932371000
    Logarithmic10858229998
    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    B frame Motion Vector Search (Normalized)
    TechniqueCompression1Speed2Quality3
    Exhaustive100010001000
    Cross29751000996
    Simple9381765991
    -- -- 1Smaller numbers are better --compression. -- -- 2Larger numbers mean faster --execution. -- -- 3Larger numbers mean better quality. -- --

    For some reason, Simple seems to give better compression, but it --depends on the image sequence. -- --

    Select the search techniques with the PSEARCH_ALG and --BSEARCH_ALG parameter file statements. -- -- --

    Group Of Pictures (GOP)

    -- --

    A Group of Pictures (GOP) is a roughly independently decodable --sequence of frames. An MPEG video stream is made of one or more --GOP's. You may specify how many frames should be in each GOP with the --GOP_SIZE parameter file statement. A GOP always starts with an --I frame. -- --

    Instead of encoding an entire sequence, you can encode a single --GOP. To do this, use the -gop command option. You can later --join the resulting GOP files at any time by running ppmtompeg --with the -combine_gops command option. -- -- --

    Slices

    -- --

    A slice is an independently decodable unit in a frame. It can be --as small as one macroblock, or it can be as big as the entire frame. --Barring transmission error, adding slices does not change quality or --speed; the only effect is slightly worse compression. More slices are --used for noisy transmission so that errors are more recoverable. Since --usually errors are not such a problem, we usually just use one slice --per frame. -- --

    Control the slice size with the SLICES_PER_FRAME parameter --file statement. -- --

    Some MPEG playback systems require that each slice consist of whole --rows of macroblocks. If you are encoding for this kind of player, if --the height of the image is H pixels, then you should set the --SLICES_PER_FRAME to some number which divides H/16. For example, if --the image is 240 pixels (15 macroblocks) high, then you should use --only 15, 5, 3, or 1 slices per frame. -- --

    Note: these MPEG playback systems are really wrong, since the MPEG --standard says this doesn't have to be so. -- -- -- --

    Search Window

    -- --

    The search window is the window in which ppmtompeg searches --for motion vectors. The window is a square. You can specify the size --of the square, and whether to allow half-pixel motion vectors or not, --with the RANGE and PIXEL parameter file statements. -- --

    I Frames, P Frames, B Frames

    -- --

    In MPEG-1, a movie is represented as a sequence of MPEG frames, --each of which is an I Frame, a P Frame, or a B Frame. Each represents --an actual frame of the movie (don't get confused by the dual use of --the word "frame." A movie frame is a graphical image. An MPEG frame --is a set of data that describes a movie frame). -- --

    An I frame ("intra" frame) describes a movie frame in isolation -- --without respect to any other frame in the movie. A P frame --("predictive" frame) describes a movie frame by describing how it --differs from the movie frame described by the latest preceding I or --P frame. A B frame ("bidirectional" frame) describes a movie frame by --describing how it differs from the movie frames described by the --nearest I or P frame before and after it. -- --

    Note that the first frame of a movie must be described by an I --frame (because there is no previous movie frame) and the last movie --frame must be described by an I or P frame (because there is no --subsequent movie frame). -- --

    Beyond that, you can choose which frames are represented by which --types. You specify a pattern, such as IBPBP and ppmtompeg --simply repeats it over and over throughout the movie. The pattern --affects speed, quality, and stream size. Here is a chart which shows --some of the trade-offs: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    Comparison of I/P/B Frames (Normalized)
    Frame TypeSizeSpeedQuality
    I frames100010001000
    P frames409609969
    B frames72260919
    -- --(this is with constant qscale) -- --

    A standard sequence is IBBPBBPBBPBBPBB. -- --

    Select the sequence with the PATTERN parameter file statement. -- --

    Since the last MPEG frame cannot be a B frame (see above), if the --pattern you specify indicates a B frame for the last movie frame of --the movie, ppmtompeg makes it an I frame instead. -- --

    Before Netpbm 10.26 (January 2005), ppmtompeg instead drops --the trailing B frames by default, and you need the --FORCE_ENCODE_LAST_FRAME parameter file statement to make it do --this. -- --

    The MPEG frames don't appear in the MPEG-1 stream in the same order that --the corresponding movie frames appear in the movie -- the B frames come after --the I and P frames on which they are based. For example, if the movie is --4 frames that you will represent with the pattern IBBP, the MPEG-1 stream --will start with an I frame describing movie frame 0. The next frame in --the MPEG-1 stream is a P frame describing movie frame 3. The last two --frames in the MPEG-1 stream are B frames describing movie frames 1 and 2, --respectively. -- -- --

    Specifying Input and Output Files

    -- --

    Specify the input frame images with the INPUT_DIR, --INPUT, END_INPUT, BASE_FILE_FORMAT, --SIZE, YUV_FORMAT and INPUT_CONVERT parameter --file statements. -- --

    Specify the output file with the OUTPUT parameter file statement. -- -- --

    Statistics

    -- --

    ppmtompeg can generate a variety of statistics about the --encoding. See the -stat, -snr, -mv_histogram, ---quiet, -no_frame_summary, and -bit_rate_info --options. -- -- --

    PARALLEL OPERATION

    -- --

    You can run ppmtompeg on multiple machines at once, encoding --the same MPEG stream. When you do, the machines are used as shown in --the following diagram. We call this "parallel mode." -- --

    ppmtompeg-par.gif -- --

    To do parallel processing, put the statement -- --

    --    PARALLEL
    --
    -- --in the parameter file, followed by a listing of the machines, one --machine per line, then -- --
    --    END_PARALLEL
    --
    -- --Each of the machine lines must be in one of two forms. If the machine --has filesystem access to the input files, then the line is: -- --

    --machine user executable -- --

    The executable is normally ppmtompeg (you may need to give --the complete path if you've built for different architectures). If --the machine does not have filesystem access to the input files, the line --is: -- --

    REMOTE machine user executable --parameter file -- --

    The -max_machines command option limits the number of --machines ppmtompeg will use. If you specify more machines in --the parameter file than -max_machines allows, ppmtompeg --uses only the machines listed first. This is handy if you want to --experiment with different amounts of parallelism. -- --

    In general, you should use full path file names when describing --executables and parameter files. This includes the parameter --file argument on the original invocation of ppmtompeg. -- --

    All file names must be the same on all systems (so if e.g. you're --using an NFS filesystem, you must make sure it is mounted at the same --mountpoint on all systems). -- --

    Because not all of the processes involved in parallel operation --have easy access to the input files, you must specify the SIZE --parameter file statement when you do parallel operation. -- --

    The machine on which you originally invoke ppmtompeg is the --master machine. It hosts a "combine server,", a --"decode server," and a number of "i/o servers," --all as separate processes. The other machines in the network (listed --in the parameter file) are slave machines. Each hosts a single --process that continuously requests work from the master and does it. --The slave process does the computation to encode MPEG frames. It --processes frames in batches identified by the master. -- --

    The master uses a remote shell command to start a process on a --slave machine. By default, it uses an rsh shell command to do --this. But use the RSH parameter file statement to control --this. The shell command the master executes remotely is --ppmtompeg, but with options to indicate that it is to perform --slave functions. -- --

    The various machines talk to each other over TCP connections. Each --machine finds and binds to a free TCP port number and tells its --partners the port number. These port numbers are at least 2048. -- --

    Use the PARALLEL_TEST_FRAMES, PARALLEL_TIME_CHUNKS, and --PARALLEL_PERFECT parameter file statements to control the way the --master divides up work among the slaves. -- --

    Use the -nice command option to cause all slave processes to run --"nicely," i.e. as low priority processes. That way, this substantial and --long-running CPU load will have minimal impact on other, possibly --interactive, users of the systems. -- --

    SPEED

    -- --

    Here is a look at ppmtompeg speed, in single-node (not parallel) --operation: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
    Compression Speed
    Machine TypeMacroblocks per second1
    HP 9000/755280
    DEC 3000/400247
    HP 9000/750191
    Sparc 10104
    DEC 500068
    --1A macroblock is a 16x16 pixel square -- --

    The measurements in the table are with inputs and outputs via a --conventional locally attached filesystem. If you are using a network --filesystem over a single 10 MB/s Ethernet, that constrains your speed more --than your CPU speed. In that case, don't expect to get better than 4 --or 5 frames per second no matter how fast your CPUs are. -- --

    Network speed is even more of a bottleneck when the slaves do not --have filesystem access to the input files -- i.e. you declare them --REMOTE. -- --

    Where I/O is the bottleneck, size of the input frames can make a big --difference. So YUV input is better than PPM, and JPEG is better than --both. -- --

    When you're first trying to get parallel mode working, be sure to --use the -debug_machines option so you can see what's going on. --Also, -debug_sockets can help you diagnose communication --problems. -- -- --

    AUTHORS

    -- -- -- --
    --

    Table Of Contents

    -- -- -- diff --git a/netpbm-pamtojpeg2k.patch b/netpbm-pamtojpeg2k.patch index 7eeed54..8fbd899 100644 --- a/netpbm-pamtojpeg2k.patch +++ b/netpbm-pamtojpeg2k.patch @@ -1,234 +1,7 @@ -diff --git a/converter/other/jpeg2000/pamtojpeg2k.c b/converter/other/jpeg2000/pamtojpeg2k.c -index 4d73316..a53573f 100644 ---- a/converter/other/jpeg2000/pamtojpeg2k.c -+++ b/converter/other/jpeg2000/pamtojpeg2k.c -@@ -98,7 +98,7 @@ parseCommandLine(int argc, char ** argv, - char * modeOpt; - - unsigned int option_def_index; -- -+ - MALLOCARRAY_NOFAIL(option_def, 100); - - option_def_index = 0; /* incremented by OPTENTRY */ -@@ -134,25 +134,25 @@ parseCommandLine(int argc, char ** argv, - &numrlvlsSpec, 0); - OPTENT3(0, "numgbits", OPT_UINT, &cmdlineP->numgbits, - &numgbitsSpec, 0); -- OPTENT3(0, "nomct", OPT_FLAG, NULL, -+ OPTENT3(0, "nomct", OPT_FLAG, NULL, - &cmdlineP->nomct, 0); -- OPTENT3(0, "sop", OPT_FLAG, NULL, -+ OPTENT3(0, "sop", OPT_FLAG, NULL, - &cmdlineP->sop, 0); -- OPTENT3(0, "eph", OPT_FLAG, NULL, -+ OPTENT3(0, "eph", OPT_FLAG, NULL, - &cmdlineP->eph, 0); -- OPTENT3(0, "lazy", OPT_FLAG, NULL, -+ OPTENT3(0, "lazy", OPT_FLAG, NULL, - &cmdlineP->lazy, 0); -- OPTENT3(0, "termall", OPT_FLAG, NULL, -+ OPTENT3(0, "termall", OPT_FLAG, NULL, - &cmdlineP->termall, 0); -- OPTENT3(0, "segsym", OPT_FLAG, NULL, -+ OPTENT3(0, "segsym", OPT_FLAG, NULL, - &cmdlineP->segsym, 0); -- OPTENT3(0, "vcausal", OPT_FLAG, NULL, -+ OPTENT3(0, "vcausal", OPT_FLAG, NULL, - &cmdlineP->vcausal, 0); -- OPTENT3(0, "pterm", OPT_FLAG, NULL, -+ OPTENT3(0, "pterm", OPT_FLAG, NULL, - &cmdlineP->pterm, 0); -- OPTENT3(0, "resetprob", OPT_FLAG, NULL, -+ OPTENT3(0, "resetprob", OPT_FLAG, NULL, - &cmdlineP->resetprob, 0); -- OPTENT3(0, "verbose", OPT_FLAG, NULL, -+ OPTENT3(0, "verbose", OPT_FLAG, NULL, - &cmdlineP->verbose, 0); - OPTENT3(0, "debuglevel", OPT_UINT, &cmdlineP->debuglevel, - &debuglevelSpec, 0); -@@ -223,7 +223,7 @@ parseCommandLine(int argc, char ** argv, - cmdlineP->inputFilename = strdup("-"); /* he wants stdin */ - else if (argc - 1 == 1) - cmdlineP->inputFilename = strdup(argv[1]); -- else -+ else - pm_error("Too many arguments. The only argument accepted\n" - "is the input file specification"); - -@@ -232,7 +232,7 @@ parseCommandLine(int argc, char ** argv, - - - static void --createJasperRaster(struct pam * const inpamP, -+createJasperRaster(struct pam * const inpamP, - jas_image_t * const jasperP) { - /*---------------------------------------------------------------------------- - Create the raster in the *jasperP object, reading the raster from the -@@ -254,7 +254,7 @@ createJasperRaster(struct pam * const inpamP, - if (matrix[plane] == NULL) - pm_error("Unable to create matrix for plane %u. " - "jas_matrix_create() failed.", plane); -- } -+ } - tuplerow = pnm_allocpamrow(inpamP); - - jasperMaxval = pm_bitstomaxval(pm_maxvaltobits(inpamP->maxval)); -@@ -271,7 +271,7 @@ createJasperRaster(struct pam * const inpamP, - unsigned int jasperSample; - - if (oddMaxval) -- jasperSample = tuplerow[col][plane] * -+ jasperSample = tuplerow[col][plane] * - jasperMaxval / inpamP->maxval; - else - jasperSample = tuplerow[col][plane]; -@@ -279,16 +279,16 @@ createJasperRaster(struct pam * const inpamP, - jas_matrix_set(matrix[plane], 0, col, jasperSample); - } - } -- { -+ { - unsigned int plane; - - for (plane = 0; plane < inpamP->depth; ++plane) { - int rc; -- rc = jas_image_writecmpt(jasperP, plane, 0, row, -+ rc = jas_image_writecmpt(jasperP, plane, 0, row, - inpamP->width, 1, - matrix[plane]); - if (rc != 0) -- pm_error("jas_image_writecmpt() of plane %u failed.", -+ pm_error("jas_image_writecmpt() of plane %u failed.", - plane); - } - } -@@ -297,14 +297,14 @@ createJasperRaster(struct pam * const inpamP, - pnm_freepamrow(tuplerow); - for (plane = 0; plane < inpamP->depth; ++plane) - jas_matrix_destroy(matrix[plane]); -- -+ - free(matrix); - } - - - - static void --createJasperImage(struct pam * const inpamP, -+createJasperImage(struct pam * const inpamP, - jas_image_t ** const jasperPP) { - - jas_image_cmptparm_t * cmptparms; -@@ -322,7 +322,7 @@ createJasperImage(struct pam * const inpamP, - cmptparms[plane].prec = pm_maxvaltobits(inpamP->maxval); - cmptparms[plane].sgnd = 0; - } -- *jasperPP = -+ *jasperPP = - jas_image_create(inpamP->depth, cmptparms, JAS_CLRSPC_UNKNOWN); - if (*jasperPP == NULL) - pm_error("Unable to create jasper image structure. " -@@ -371,7 +371,7 @@ convertToJasperImage(struct pam * const inpamP, - - - static void --writeJpc(jas_image_t * const jasperP, -+writeJpc(jas_image_t * const jasperP, - struct cmdlineInfo const cmdline, - FILE * const ofP) { - -@@ -383,8 +383,8 @@ writeJpc(jas_image_t * const jasperP, - - /* Note: ilyrrates is a hack because we're too lazy to properly parse - command line options to get the information and then compose -- a proper input to Jasper. So the user can screw things up by -- specifying garbage for the -ilyrrates option -+ a proper input to Jasper. So the user can screw things up by -+ specifying garbage for the -ilyrrates option - */ - if (strlen(cmdline.ilyrrates) > 0) - pm_asprintf(&ilyrratesOpt, "ilyrrates=%s", cmdline.ilyrrates); -@@ -410,7 +410,7 @@ writeJpc(jas_image_t * const jasperP, - */ - rateOpt[0] = '\0'; - } -- pm_asprintf(&options, -+ pm_asprintf(&options, - "imgareatlx=%u " - "imgareatly=%u " - "tilegrdtlx=%u " -@@ -428,7 +428,7 @@ writeJpc(jas_image_t * const jasperP, - "numrlvls=%u " - "numgbits=%u " - "%s %s %s %s %s %s %s %s %s", -- -+ - cmdline.imgareatlx, - cmdline.imgareatly, - cmdline.tilegrdtlx, -@@ -471,8 +471,8 @@ writeJpc(jas_image_t * const jasperP, - pm_message("Using Jasper to encode to 'jpc' format with options " - "'%s'", options); - -- rc = jas_image_encode(jasperP, outStreamP, -- jas_image_strtofmt((char*)"jpc"), -+ rc = jas_image_encode(jasperP, outStreamP, -+ jas_image_strtofmt((char*)"jpc"), - (char *)options); - if (rc != 0) - pm_error("jas_image_encode() failed to encode the JPEG 2000 " -@@ -484,11 +484,11 @@ writeJpc(jas_image_t * const jasperP, - int rc; - - rc = jas_stream_close(outStreamP); -- -+ - if (rc != 0) - pm_error("Failed to close output stream, " - "jas_stream_close() rc = %d", rc); -- } -+ } - - jas_image_clearfmts(); - -@@ -506,33 +506,31 @@ main(int argc, char **argv) - jas_image_t * jasperP; - - pnm_init(&argc, argv); -- -+ - parseCommandLine(argc, argv, &cmdline); -- -- { -+ -+ { - int rc; -- -+ - rc = jas_init(); - if ( rc != 0 ) - pm_error("Failed to initialize Jasper library. " - "jas_init() returns rc %d", rc ); - } -- -+ - jas_setdbglevel(cmdline.debuglevel); -- -+ - ifP = pm_openr(cmdline.inputFilename); -- -+ - pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); -- -+ - convertToJasperImage(&inpam, &jasperP); -- -+ - writeJpc(jasperP, cmdline, stdout); -- -+ - jas_image_destroy(jasperP); +diff -up netpbm-10.47.12/converter/other/jpeg2000/pamtojpeg2k.c.pamtojpeg2kfix netpbm-10.47.12/converter/other/jpeg2000/pamtojpeg2k.c +--- netpbm-10.47.12/converter/other/jpeg2000/pamtojpeg2k.c.pamtojpeg2kfix 2010-04-27 15:47:10.000000000 +0200 ++++ netpbm-10.47.12/converter/other/jpeg2000/pamtojpeg2k.c 2010-05-03 15:37:49.934269588 +0200 +@@ -532,7 +532,5 @@ main(int argc, char **argv) pm_close(ifP); diff --git a/netpbm-ppmfadeusage.patch b/netpbm-ppmfadeusage.patch index d48f5f5..2943ddb 100644 --- a/netpbm-ppmfadeusage.patch +++ b/netpbm-ppmfadeusage.patch @@ -1,57 +1,62 @@ -diff -urNp old/editor/ppmfade new/editor/ppmfade ---- old/editor/ppmfade 2017-11-01 11:47:49.869611402 +0100 -+++ new/editor/ppmfade 2017-11-01 11:53:25.524973342 +0100 -@@ -84,7 +84,7 @@ for ($n = 0; $n < @ARGV; $n++) { - if (-e $first_file) { +diff -urNp a/editor/ppmfade b/editor/ppmfade +--- a/editor/ppmfade 2025-02-04 10:47:27.812451607 +0100 ++++ b/editor/ppmfade 2025-02-04 10:52:14.233336029 +0100 +@@ -99,6 +99,9 @@ sub commandLineArgs() { + $mode = 'BLOCK'; + } elsif ($arg eq "-mix") { + $mode = 'MIX'; ++ } elsif ($arg eq "-help" || $arg eq "--help" || $arg eq "-h") { ++ print STDERR ("ppmfade: Use 'man ppmfade' for help.\n"); ++ exit 1; } else { - print "I can't find first file '$first_file'\n"; -- exit 20; + if (substr($arg, 0, 1) eq '-') { + print STDERR ("Unknown option '$arg'. " . +@@ -109,13 +112,13 @@ sub commandLineArgs() { + print STDERR ("There are no non-option arguments possible. " . + "You specified '$arg'\n"); + } +- exit 100; + exit 1; } - } elsif ($ARGV[$n] eq "-l") { - $n++; -@@ -92,7 +92,7 @@ for ($n = 0; $n < @ARGV; $n++) { - if (-e $last_file) { + } + + if (!defined($firstFileNm) && !defined($lastFileNm)) { + print STDERR ("You must specify -f or -l (or both)\n"); +- exit 90; ++ exit 1 + } + + if (!defined($mode)) { +@@ -142,7 +145,7 @@ sub imageDimensions($$) { } else { - print "I can't find last file '$last_file'\n"; -- exit 20; -+ exit 1; + print STDERR + ("Unrecognized results from pnmfile on $firstFileNm.\n"); +- exit(50); ++ exit(1); } - } elsif ($ARGV[$n] eq "-base") { - $n++; -@@ -113,9 +113,12 @@ for ($n = 0; $n < @ARGV; $n++) { - $mode = $BLOCK; - } elsif ("$ARGV[$n]" eq "-mix") { - $mode = $MIX; -+ } elsif ($ARGV[$n] eq "-help" || $ARGV[$n] eq "--help" || $ARGV[$n] eq "-h") { -+ print "ppmfade: Use 'man ppmfade' for help.\n"; -+ exit 1; } else { - print "Unknown argument: $ARGV[$n]\n"; -- exit 100; -+ exit 1; - } - } - # -@@ -134,18 +137,18 @@ if ($first_file ne "undefined") { - $width = $1; $height = $2; - } else { - print("Unrecognized results from pnmfile on $first_file.\n"); -- exit(50); -+ exit 1; + # $lastFileNm is defined +@@ -151,7 +154,7 @@ sub imageDimensions($$) { + } else { + print STDERR + ("Unrecognized results from pnmfile on $firstFileNm.\n"); +- exit(50); ++ exit(1); + } } - } elsif ($last_file ne "undefined") { - if ((`pnmfile $last_file` =~ m{\b(\d+)\sby\s(\d+)} )) { - $width = $1; $height = $2; - } else { - print("Unrecognized results from pnmfile on $first_file.\n"); -- exit(50); -+ exit 1; - } - } else { - print("ppmfade: You must specify -f or -l (or both)\n"); -- exit(90); + return $width, $height; +@@ -436,12 +439,12 @@ my ($mode, $firstFileNm, $lastFileNm, $b + + if (defined($firstFileNm) && !-e($firstFileNm)) { + print STDERR ("First file '$firstFileNm' does not exist\n"); +- exit 20; + exit 1; } - print("Frames are " . $width . "W x " . $height . "H\n"); + if (defined($lastFileNm) && !-e($lastFileNm)) { + print STDERR ("Last file '$lastFileNm' does not exist\n"); +- exit 20; ++ exit 1; + } + + my ($width, $height) = imageDimensions($firstFileNm, $lastFileNm); diff --git a/netpbm-python3.patch b/netpbm-python3.patch index f611b81..2557933 100644 --- a/netpbm-python3.patch +++ b/netpbm-python3.patch @@ -1,9 +1,28 @@ -diff -urNp old/buildtools/makeman new/buildtools/makeman ---- old/buildtools/makeman 2018-01-03 12:15:55.000000000 +0100 -+++ new/buildtools/makeman 2018-02-26 14:18:39.993760106 +0100 +diff --git a/buildtools/makeman b/buildtools/makeman +index 196dbd0..d73ab76 100755 +--- a/buildtools/makeman ++++ b/buildtools/makeman @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # makeman -- compile netpbm's stereotyped HTML to troff markup # +diff --git a/buildtools/manpage.mk b/buildtools/manpage.mk +index ef1a103..c1badb8 100644 +--- a/buildtools/manpage.mk ++++ b/buildtools/manpage.mk +@@ -126,11 +126,11 @@ reportman: + # to standard error. + %.1 %.3 %.5: $(USERGUIDE)/%.html + @echo Converting $< to $@ +- @python $(MAKEMAN) -d $(USERGUIDE) $(= nl); + assert(nh >= nl); assert(nh <= UINT_MAX-1); + overflow_add(nh - nl, 1); -+ ++ MALLOCARRAY(v, (unsigned) (nh - nl + 1)); if (v == NULL) -@@ -85,6 +87,7 @@ matrix (unsigned int const nrl, - assert(nrh >= nrl); +@@ -133,6 +135,8 @@ matrix (unsigned int const nrl, + + assert(nrh >= nrl); assert(nrh <= UINT_MAX-1); - /* allocate pointers to rows */ + overflow_add(nrh - nrl, 1); - MALLOCARRAY(m, (unsigned) (nrh - nrl + 1)); - if (m == NULL) - pm_error("Unable to allocate memory for a matrix."); -@@ -93,6 +96,7 @@ matrix (unsigned int const nrl, ++ + /* allocate pointers to rows */ + MALLOCARRAY(matrix, (unsigned) (nrh - nrl + 1)); + if (matrix == NULL) +@@ -142,6 +146,8 @@ matrix (unsigned int const nrl, - assert (nch >= ncl); + assert (nch >= ncl); assert(nch <= UINT_MAX-1); + overflow_add(nch - ncl, 1); ++ /* allocate rows and set pointers to them */ for (i = nrl; i <= nrh; ++i) { - MALLOCARRAY(m[i], (unsigned) (nch - ncl + 1)); -diff --git a/converter/other/gemtopnm.c b/converter/other/gemtopnm.c -index 6bbfcc0..f7d1dc6 100644 ---- a/converter/other/gemtopnm.c -+++ b/converter/other/gemtopnm.c -@@ -36,7 +36,7 @@ - * read 4-plane color IMG files. Therefore changed from PBM to PPM. - * Bryan changed it further to use the PNM facilities so it outputs - * both PBM and PPM in the Netpbm tradition. Name changed from -- * gemtopbm to gemtopnm. -+ * gemtopbm to gemtopnm. - */ + MALLOCARRAY(matrix[i], (unsigned) (nch - ncl + 1)); +diff -urNp a/converter/other/gemtopnm.c b/converter/other/gemtopnm.c +--- a/converter/other/gemtopnm.c 2025-02-03 09:24:28.345500482 +0100 ++++ b/converter/other/gemtopnm.c 2025-02-03 09:28:49.455092222 +0100 +@@ -153,6 +153,8 @@ main(int argc, const char ** argv) { - #include -@@ -50,106 +50,107 @@ - char pattern[8]; + pnm_writepnminit(stdout, cols, rows, MAXVAL, type, 0); - static void getinit ARGS ((FILE *file, int *colsP, int *rowsP, int *padrightP, -- int *patlenP, int *planesP)); -+ int *patlenP, int *planesP)); - - int - main(argc, argv) -- int argc; -- char *argv[]; -+ int argc; -+ char *argv[]; - { -- int debug = 0; -- FILE *f; -+ int debug = 0; -+ FILE *f; - int row; -- int rows, cols, padright, patlen, planes; -+ int rows, cols, padright, patlen, planes; - /* attributes of input image */ - int type; /* The format type (PBM/PPM) of the output image */ -- bit *bitrow[4]; -+ bit *bitrow[4]; - /* One row of input, one or four planes. (If one, only [0] is defined)*/ - xel * xelrow; /* One row of output */ -- const char * const usage = "[-debug] [gem IMG file]"; -- int argn; -+ const char * const usage = "[-debug] [gem IMG file]"; -+ int argn; - - /* Process multiple planes by maintaining a separate row of bits for each -- * plane. In a single-plane image, all we have to do is write out the -+ * plane. In a single-plane image, all we have to do is write out the - * first plane; in a multiple-plane image, we combine them just before writing - * out the row. - */ -- pnm_init( &argc, argv ); -- -+ pnm_init( &argc, argv ); -+ - argn = 1; - -- while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0') -- { -- if (pm_keymatch(argv[1], "-debug", 2)) -- debug = 1; -- else -- pm_usage (usage); -- ++argn; -- } -+ while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0') -+ { -+ if (pm_keymatch(argv[1], "-debug", 2)) -+ debug = 1; -+ else -+ pm_usage (usage); -+ ++argn; -+ } - -- if (argc == argn) -- f = stdin; -- else { -- f = pm_openr (argv[argn]); -- ++argn; -- } -+ if (argc == argn) -+ f = stdin; -+ else { -+ f = pm_openr (argv[argn]); -+ ++argn; -+ } - -- if (argn != argc) -- pm_usage (usage); -+ if (argn != argc) -+ pm_usage (usage); - -- getinit (f, &cols, &rows, &padright, &patlen, &planes); -+ getinit (f, &cols, &rows, &padright, &patlen, &planes); - -- if (planes == 1) -+ if (planes == 1) - type = PBM_TYPE; -- else -+ else - type = PPM_TYPE; - -- pnm_writepnminit( stdout, cols, rows, MAXVAL, type, 0 ); -+ pnm_writepnminit( stdout, cols, rows, MAXVAL, type, 0 ); - -- { + overflow_add(cols, padright); -+ { ++ + { /* allocate input row data structure */ - int plane; -- for (plane = 0; plane < planes; plane++) -+ for (plane = 0; plane < planes; plane++) - bitrow[plane] = malloc (cols + padright); - } - xelrow = pnm_allocrow(cols+padright); /* Output row */ - -- for (row = 0; row < rows; ) { -+ for (row = 0; row < rows; ) { - int linerep; - int plane; - -- linerep = 1; -- for (plane = 0; plane < planes; plane++) { -+ linerep = 1; -+ for (plane = 0; plane < planes; plane++) { - int col; -- col = 0; -- while (col < cols) { -+ col = 0; -+ while (col < cols) { - int c; -- switch (c = getc(f)) { -- case 0x80: /* Bit String */ -+ switch (c = getc(f)) { -+ case 0x80: /* Bit String */ - { - int j; -- c = getc(f); /* Byte count */ -- if (debug) -+ c = getc(f); /* Byte count */ -+ if (debug) - pm_message("bit string of %d bytes", c); -- -- if (col + c * 8 > cols + padright) -- pm_error ("bad byte count"); -- for (j = 0; j < c; ++j) { -+ -+ if (col + c * 8 > cols + padright) -+ pm_error ("bad byte count"); -+ for (j = 0; j < c; ++j) { - int cc, k; -- cc = getc(f); -- for (k = 0x80; k; k >>= 1) { -- bitrow[plane][col] = (k & cc) ? 0 : 1; -- ++col; -- } -- } -+ cc = getc(f); -+ for (k = 0x80; k; k >>= 1) { -+ bitrow[plane][col] = (k & cc) ? 0 : 1; -+ ++col; -+ } -+ } - } - break; -- case 0: /* Pattern run */ -+ case 0: /* Pattern run */ - { - int j, l; -- c = getc(f); /* Repeat count */ -- if (debug) -- pm_message("pattern run of %d repetitions", c); -+ c = getc(f); /* Repeat count */ -+ if (debug) -+ pm_message("pattern run of %d repetitions", c); - /* line repeat */ - if (c == 0) { - c = getc(f); -@@ -158,25 +159,25 @@ main(argc, argv) - linerep = getc(f); - break; - } -- fread (pattern, 1, patlen, f); -- if (col + c * patlen * 8 > cols + padright) -- pm_error ("bad pattern repeat count"); -- for (j = 0; j < c; ++j) -- for (l = 0; l < patlen; ++l) { -+ fread (pattern, 1, patlen, f); -+ if (col + c * patlen * 8 > cols + padright) -+ pm_error ("bad pattern repeat count"); -+ for (j = 0; j < c; ++j) -+ for (l = 0; l < patlen; ++l) { - int k; -- for (k = 0x80; k; k >>= 1) { -- bitrow[plane][col] = (k & pattern[l]) ? 0 : 1; -- ++col; -- } -+ for (k = 0x80; k; k >>= 1) { -+ bitrow[plane][col] = (k & pattern[l]) ? 0 : 1; -+ ++col; -+ } - } - } - break; - -- default: /* Solid run */ -+ default: /* Solid run */ - { - int l, j; -- if (debug) -- pm_message("solid run of %d bytes %s", c & 0x7f, -+ if (debug) -+ pm_message("solid run of %d bytes %s", c & 0x7f, - c & 0x80 ? "on" : "off" ); - /* each byte had eight bits DSB */ - l = (c & 0x80) ? 0: 1; -@@ -185,23 +186,23 @@ main(argc, argv) - pm_error ("bad solid run repeat count"); - for (j = 0; j < c; ++j) { - bitrow[plane][col] = l; -- ++col; -+ ++col; - } - } -- break; -+ break; - -- case EOF: /* End of file */ -- pm_error( "end of file reached" ); -+ case EOF: /* End of file */ -+ pm_error( "end of file reached" ); - -- } -- } -+ } -+ } - if ( debug ) - pm_message( "EOL plane %d row %d", plane, row ); - if (col != cols + padright) - pm_error( "EOL beyond edge" ); -- } -+ } - -- if (planes == 4) { -+ if (planes == 4) { - /* Construct a pixel from the 4 planes of bits for this row */ - int col; - for (col = 0; col < cols; col++) { -@@ -212,21 +213,21 @@ main(argc, argv) - const int b_bit = !bitrow[2][col]; - i = bitrow[3][col]; - -- /* Deal with weird GEM palette - white/black/gray are -- encoded oddly -+ /* Deal with weird GEM palette - white/black/gray are -+ encoded oddly - */ -- if (r_bit == g_bit && g_bit == b_bit) { -+ if (r_bit == g_bit && g_bit == b_bit) { - /* It's black, white, or gray */ -- if (r_bit && i) r = LIGHT; -- else if (r_bit) r = BLACK; -- else if (i) r = MAXVAL; -- else r = DARK; -- g = b = r; -- } else { -+ if (r_bit && i) r = LIGHT; -+ else if (r_bit) r = BLACK; -+ else if (i) r = MAXVAL; -+ else r = DARK; -+ g = b = r; -+ } else { - /* It's one of the twelve colored colors */ - if (!i) { - /* Low intensity */ -- r = r_bit * LIGHT; -+ r = r_bit * LIGHT; - g = g_bit * LIGHT; - b = b_bit * LIGHT; - } else { -@@ -237,21 +238,21 @@ main(argc, argv) - } - } - PPM_ASSIGN(xelrow[col], r, g, b); -- } -- } else { -+ } -+ } else { - int col; -- for (col = 0; col < cols; col++) -+ for (col = 0; col < cols; col++) - PNM_ASSIGN1(xelrow[col], bitrow[0][col]); - } -- while (linerep--) { -- pnm_writepnmrow( stdout, xelrow, cols, MAXVAL, type, 0 ); -- ++row; -- } -- } -+ while (linerep--) { -+ pnm_writepnmrow( stdout, xelrow, cols, MAXVAL, type, 0 ); -+ ++row; -+ } -+ } - pnm_freerow(xelrow); -- pm_close( f ); -- pm_close( stdout ); -- exit(0); -+ pm_close( f ); -+ pm_close( stdout ); -+ exit(0); - } - - -@@ -303,5 +304,3 @@ getinit (file, colsP, rowsP, padrightP, patlenP, planesP) - } - } - -- -- -diff --git a/converter/other/jpegtopnm.c b/converter/other/jpegtopnm.c -index 98552c0..311298c 100644 ---- a/converter/other/jpegtopnm.c -+++ b/converter/other/jpegtopnm.c -@@ -862,6 +862,8 @@ convertImage(FILE * const ofP, + unsigned int plane; +diff -urNp a/converter/other/jpegtopnm.c b/converter/other/jpegtopnm.c +--- a/converter/other/jpegtopnm.c 2025-02-03 09:24:28.346500477 +0100 ++++ b/converter/other/jpegtopnm.c 2025-02-03 09:29:57.845723398 +0100 +@@ -894,6 +894,8 @@ convertImage(FILE * /* Calculate output image dimensions so we can allocate space */ jpeg_calc_output_dimensions(cinfoP); @@ -359,23 +52,21 @@ index 98552c0..311298c 100644 /* Start decompressor */ jpeg_start_decompress(cinfoP); -diff --git a/converter/other/pbmtopgm.c b/converter/other/pbmtopgm.c -index 817fb5b..8baaa57 100644 ---- a/converter/other/pbmtopgm.c -+++ b/converter/other/pbmtopgm.c -@@ -60,6 +60,7 @@ main(int argc, char *argv[]) { - +diff -urNp a/converter/other/pbmtopgm.c b/converter/other/pbmtopgm.c +--- a/converter/other/pbmtopgm.c 2025-02-03 09:24:28.346500477 +0100 ++++ b/converter/other/pbmtopgm.c 2025-02-03 09:32:07.478024266 +0100 +@@ -88,6 +88,7 @@ main(int argc, const char ** argv) { + up = cmdline.convRows / 2; down = cmdline.convRows - up; outrow = pgm_allocrow(cols) ; -+ overflow2(width, height); - maxval = MIN(PGM_OVERALLMAXVAL, width*height); ++ overflow2(cmdline.convCols, cmdline.convRows); + maxval = MIN(PGM_OVERALLMAXVAL, cmdline.convCols * cmdline.convRows); pgm_writepgminit(stdout, cols, rows, maxval, 0) ; -diff --git a/converter/other/pnmtoddif.c b/converter/other/pnmtoddif.c -index b7b942b..52be0e4 100644 ---- a/converter/other/pnmtoddif.c -+++ b/converter/other/pnmtoddif.c -@@ -629,6 +629,7 @@ main(int argc, char *argv[]) { +diff -urNp a/converter/other/pnmtoddif.c b/converter/other/pnmtoddif.c +--- a/converter/other/pnmtoddif.c 2025-02-03 09:24:28.346500477 +0100 ++++ b/converter/other/pnmtoddif.c 2025-02-03 09:33:21.228626549 +0100 +@@ -627,6 +627,7 @@ main(int argc, char *argv[]) { switch (PNM_FORMAT_TYPE(format)) { case PBM_TYPE: ip.bits_per_pixel = 1; @@ -383,7 +74,7 @@ index b7b942b..52be0e4 100644 ip.bytes_per_line = (cols + 7) / 8; ip.spectral = 2; ip.components = 1; -@@ -644,6 +645,7 @@ main(int argc, char *argv[]) { +@@ -642,6 +643,7 @@ main(int argc, char *argv[]) { ip.polarity = 2; break; case PPM_TYPE: @@ -391,1311 +82,112 @@ index b7b942b..52be0e4 100644 ip.bytes_per_line = 3 * cols; ip.bits_per_pixel = 24; ip.spectral = 5; -diff --git a/converter/other/pnmtojpeg.c b/converter/other/pnmtojpeg.c -index e345831..757d08d 100644 ---- a/converter/other/pnmtojpeg.c -+++ b/converter/other/pnmtojpeg.c -@@ -9,7 +9,7 @@ - This program is by Bryan Henderson on 2000.03.06, but is derived - with permission from the program cjpeg, which is in the Independent - Jpeg Group's JPEG library package. Under the terms of that permission, -- redistribution of this software is restricted as described in the -+ redistribution of this software is restricted as described in the - file README.JPEG. +diff -urNp a/converter/other/pnmtops.c b/converter/other/pnmtops.c +--- a/converter/other/pnmtops.c 2025-02-03 09:24:28.345500482 +0100 ++++ b/converter/other/pnmtops.c 2025-02-03 09:42:01.586878661 +0100 +@@ -298,17 +298,21 @@ parseCommandLine(int argc, const char ** + validateCompDimension(width, psScaleFactor, "-width value"); + validateCompDimension(height, psScaleFactor, "-height value"); - Copyright (C) 1991-1998, Thomas G. Lane. -@@ -84,12 +84,12 @@ struct cmdlineInfo { - struct density density; - }; - --static void --interpret_maxmemory (const char * const maxmemory, -- long int * const max_memory_to_use_p) { -+static void -+interpret_maxmemory (const char * const maxmemory, -+ long int * const max_memory_to_use_p) { - long int lval; - char ch; -- -+ - if (maxmemory == NULL) { - *max_memory_to_use_p = -1; /* unspecified */ - } else if (sscanf(maxmemory, "%ld%c", &lval, &ch) < 1) { -@@ -119,9 +119,9 @@ interpret_restart(const char * const restart, - long lval; - char ch; - unsigned int matches; -- -+ - matches= sscanf(restart, "%ld%c", &lval, &ch); -- if (matches == 0) -+ if (matches == 0) - pm_error("Invalid value for the --restart option : '%s'.", - restart); - else { -@@ -160,7 +160,7 @@ interpret_density(const char * const densityString, - int horiz, vert; - - unitName = malloc(strlen(densityString)+1); -- -+ - matched = sscanf(densityString, "%dx%d%s", &horiz, &vert, unitName); - - if (matched < 2) -@@ -178,7 +178,7 @@ interpret_density(const char * const densityString, - densityP->horiz = horiz; - densityP->vert = vert; - -- if (matched < 3) -+ if (matched < 3) - densityP->unit = DEN_UNSPECIFIED; - else { - if (streq(unitName, "dpi") || streq(unitName, "DPI")) -@@ -235,7 +235,7 @@ parseCommandLine(const int argc, char ** argv, - - option_def_index = 0; /* incremented by OPTENTRY */ - OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); -- OPTENT3(0, "quality", OPT_UINT, &cmdlineP->quality, -+ OPTENT3(0, "quality", OPT_UINT, &cmdlineP->quality, - &qualitySpec, 0); - OPTENT3(0, "baseline", OPT_FLAG, NULL, &cmdlineP->force_baseline, 0); - OPTENT3(0, "progressive", OPT_FLAG, NULL, &cmdlineP->progressive, 0); -@@ -250,14 +250,14 @@ parseCommandLine(const int argc, char ** argv, - OPTENT3(0, "qtables", OPT_STRING, &cmdlineP->qtablefile, NULL, 0); - OPTENT3(0, "sample", OPT_STRING, &cmdlineP->sample, NULL, 0); - OPTENT3(0, "scans", OPT_STRING, &cmdlineP->scans, NULL, 0); -- OPTENT3(0, "smooth", OPT_UINT, &cmdlineP->smoothing_factor, -+ OPTENT3(0, "smooth", OPT_UINT, &cmdlineP->smoothing_factor, - &smoothSpec, 0); - OPTENT3(0, "optimize", OPT_FLAG, NULL, &cmdlineP->optimize, 0); - OPTENT3(0, "optimise", OPT_FLAG, NULL, &cmdlineP->optimize, 0); - OPTENT3(0, "restart", OPT_STRING, &restart, NULL, 0); - OPTENT3(0, "comment", OPT_STRING, &cmdlineP->comment, NULL, 0); - OPTENT3(0, "exif", OPT_STRING, &cmdlineP->exif_filespec, NULL, 0); -- OPTENT3(0, "density", OPT_STRING, &density, -+ OPTENT3(0, "density", OPT_STRING, &density, - &cmdlineP->density_spec, 0); - - /* Set the defaults */ -@@ -295,7 +295,7 @@ parseCommandLine(const int argc, char ** argv, - cmdlineP->input_filespec = strdup("-"); /* he wants stdin */ - else if (argc_parse - 1 == 1) - cmdlineP->input_filespec = strdup(argv_parse[1]); -- else -+ else - pm_error("Too many arguments. The only argument accepted " - "is the input file specification."); - if (dctval == NULL) -@@ -314,15 +314,15 @@ parseCommandLine(const int argc, char ** argv, - interpret_maxmemory(maxmemory, &cmdlineP->max_memory_to_use); - interpret_restart(restart, &cmdlineP->restart_value, - &cmdlineP->restart_unit); -- if (cmdlineP->density_spec) -+ if (cmdlineP->density_spec) - interpret_density(density, &cmdlineP->density); -- -+ - if (cmdlineP->smoothing_factor > 100) - pm_error("Smoothing factor %d is greater than 100 (%%).", - cmdlineP->smoothing_factor); - - if (streq(cmdlineP->input_filespec, "=") && -- cmdlineP->exif_filespec && -+ cmdlineP->exif_filespec && - streq(cmdlineP->exif_filespec, "-")) - - pm_error("Cannot have both input image and exif header be from " -@@ -336,7 +336,7 @@ parseCommandLine(const int argc, char ** argv, - - static void - report_compressor(const struct jpeg_compress_struct cinfo) { -- -+ - if (cinfo.scan_info == NULL) - pm_message("No scan script is being used"); - else { -@@ -346,7 +346,7 @@ report_compressor(const struct jpeg_compress_struct cinfo) { - for (i = 0; i < cinfo.num_scans; i++) { - int j; - pm_message(" Scan %2d: Ss=%2d Se=%2d Ah=%2d Al=%2d " -- "%d components", -+ "%d components", - i, - cinfo.scan_info[i].Ss, - cinfo.scan_info[i].Se, -@@ -364,11 +364,11 @@ report_compressor(const struct jpeg_compress_struct cinfo) { - - - static void --setup_jpeg_source_parameters(struct jpeg_compress_struct * const cinfoP, -- int const width, int const height, -+setup_jpeg_source_parameters(struct jpeg_compress_struct * const cinfoP, -+ int const width, int const height, - int const format) { - /*---------------------------------------------------------------------------- -- Set up in the compressor descriptor *cinfoP the description of the -+ Set up in the compressor descriptor *cinfoP the description of the - source image as required by the compressor. - -----------------------------------------------------------------------------*/ - -@@ -379,7 +379,7 @@ setup_jpeg_source_parameters(struct jpeg_compress_struct * const cinfoP, - cinfoP->input_components = 1; - break; - case PPM_TYPE: -- cinfoP->in_color_space = JCS_RGB; -+ cinfoP->in_color_space = JCS_RGB; - cinfoP->input_components = 3; - break; - default: -@@ -391,7 +391,7 @@ setup_jpeg_source_parameters(struct jpeg_compress_struct * const cinfoP, - - - static void --setup_jpeg_density(struct jpeg_compress_struct * const cinfoP, -+setup_jpeg_density(struct jpeg_compress_struct * const cinfoP, - struct density const density) { - /*---------------------------------------------------------------------------- - Set up in the compressor descriptor *cinfoP the density information -@@ -402,7 +402,7 @@ setup_jpeg_density(struct jpeg_compress_struct * const cinfoP, - case DEN_DOTS_PER_INCH: cinfoP->density_unit = 1; break; - case DEN_DOTS_PER_CM: cinfoP->density_unit = 2; break; - } -- -+ - cinfoP->X_density = density.horiz; - cinfoP->Y_density = density.vert; - } -@@ -411,7 +411,7 @@ setup_jpeg_density(struct jpeg_compress_struct * const cinfoP, - - /*---------------------------------------------------------------------------- - The functions below here are essentially the file rdswitch.c from -- the JPEG library. They perform the functions specified by the following -+ the JPEG library. They perform the functions specifed by the following - pnmtojpeg options: - - -qtables file Read quantization tables from text file -@@ -426,7 +426,7 @@ text_getc (FILE * file) - /* A comment/newline sequence is returned as a newline */ - { - register int ch; -- -+ - ch = getc(file); - if (ch == '#') { - do { -@@ -454,12 +454,12 @@ readTextInteger(FILE * const fileP, - -----------------------------------------------------------------------------*/ - int ch; - boolean retval; -- -+ - /* Skip any leading whitespace, detect EOF */ - do { - ch = text_getc(fileP); - } while (isspace(ch)); -- -+ - if (!isdigit(ch)) - retval = FALSE; - else { -@@ -554,7 +554,7 @@ read_scan_script(j_compress_ptr const cinfo, - ncomps = 1; - while (termchar == ' ') { - if (ncomps >= MAX_COMPS_IN_SCAN) { -- pm_message("Too many components in one scan in file %s", -+ pm_message("Too many components in one scan in file %s", - filename); - fclose(fp); - return FALSE; -@@ -603,10 +603,14 @@ read_scan_script(j_compress_ptr const cinfo, - /* Stash completed scan list in cinfo structure. NOTE: in - this program, JPOOL_IMAGE is the right lifetime for this - data, but if you want to compress multiple images you'd -- want JPOOL_PERMANENT. -+ want JPOOL_PERMANENT. - */ - const unsigned int scan_info_size = nscans * sizeof(jpeg_scan_info); -- jpeg_scan_info * const scan_info = -+ const jpeg_scan_info * scan_info; -+ -+ overflow2(nscans, sizeof(jpeg_scan_info)); -+ -+ scan_info = - (jpeg_scan_info *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - scan_info_size); -@@ -656,7 +660,7 @@ read_quant_tables (j_compress_ptr cinfo, char * filename, - if (tblno >= NUM_QUANT_TBLS) { - pm_message("Too many tables in file %s", filename); - error = TRUE; -- } else { -+ } else { - unsigned int table[DCTSIZE2]; - unsigned int i; - -@@ -686,7 +690,7 @@ read_quant_tables (j_compress_ptr cinfo, char * filename, - fclose(fp); - retval = !error; - } -- -+ - return retval; - } - -@@ -717,7 +721,7 @@ set_quant_slots (j_compress_ptr cinfo, char *arg) - return FALSE; - } - cinfo->comp_info[ci].quant_tbl_no = val; -- while (*arg && *arg++ != ',') -+ while (*arg && *arg++ != ',') - /* advance to next segment of arg string */ - ; - } else { -@@ -747,7 +751,7 @@ set_sample_factors (j_compress_ptr cinfo, char *arg) - if ((ch1 != 'x' && ch1 != 'X') || ch2 != ',') /* syntax check */ - return FALSE; - if (val1 <= 0 || val1 > 4) { -- pm_message("Invalid sampling factor: %d. " -+ pm_message("Invalid sampling factor: %d. " - "JPEG sampling factors must be 1..4", val1); - return FALSE; - } -@@ -758,11 +762,11 @@ set_sample_factors (j_compress_ptr cinfo, char *arg) - } - cinfo->comp_info[ci].h_samp_factor = val1; - cinfo->comp_info[ci].v_samp_factor = val2; -- while (*arg && *arg++ != ',') -+ while (*arg && *arg++ != ',') - /* advance to next segment of arg string */ - ; - } else { -- /* reached end of parameter, set remaining components -+ /* reached end of parameter, set remaining components - to 1x1 sampling */ - cinfo->comp_info[ci].h_samp_factor = 1; - cinfo->comp_info[ci].v_samp_factor = 1; -@@ -776,13 +780,13 @@ set_sample_factors (j_compress_ptr cinfo, char *arg) - static void - setup_jpeg(struct jpeg_compress_struct * const cinfoP, - struct jpeg_error_mgr * const jerrP, -- struct cmdlineInfo const cmdline, -+ struct cmdlineInfo const cmdline, - int const width, - int const height, - pixval const maxval, - int const input_fmt, - FILE * const output_file) { -- -+ - int quality; - int q_scale_factor; - -@@ -794,14 +798,14 @@ setup_jpeg(struct jpeg_compress_struct * const cinfoP, - - jpeg_set_defaults(cinfoP); - -- cinfoP->data_precision = BITS_IN_JSAMPLE; -+ cinfoP->data_precision = BITS_IN_JSAMPLE; - /* we always rescale data to this */ - cinfoP->image_width = (unsigned int) width; - cinfoP->image_height = (unsigned int) height; - - cinfoP->arith_code = cmdline.arith_code; - cinfoP->dct_method = cmdline.dct_method; -- if (cmdline.trace_level == 0 && cmdline.verbose) -+ if (cmdline.trace_level == 0 && cmdline.verbose) - cinfoP->err->trace_level = 1; - else cinfoP->err->trace_level = cmdline.trace_level; - if (cmdline.grayscale) -@@ -822,26 +826,26 @@ setup_jpeg(struct jpeg_compress_struct * const cinfoP, - quality = cmdline.quality; - q_scale_factor = jpeg_quality_scaling(cmdline.quality); - } -- if (cmdline.smoothing_factor != -1) -+ if (cmdline.smoothing_factor != -1) - cinfoP->smoothing_factor = cmdline.smoothing_factor; - - /* Set quantization tables for selected quality. */ - /* Some or all may be overridden if user specified --qtables. */ - jpeg_set_quality(cinfoP, quality, cmdline.force_baseline); -- -+ - if (cmdline.qtablefile != NULL) { - if (! read_quant_tables(cinfoP, cmdline.qtablefile, -- q_scale_factor, cmdline.force_baseline)) -+ q_scale_factor, cmdline.force_baseline)) - pm_error("Can't use quantization table file '%s'.", - cmdline.qtablefile); - } -- -+ - if (cmdline.qslots != NULL) { - if (! set_quant_slots(cinfoP, cmdline.qslots)) -- pm_error("Bad quantization-table-selectors parameter string '%s'.", -+ pm_error("Bad quantization-table-selectors parameter string '%s'.", - cmdline.qslots); - } -- -+ - if (cmdline.sample != NULL) { - if (! set_sample_factors(cinfoP, cmdline.sample)) - pm_error("Bad sample-factors parameters string '%s'.", -@@ -878,7 +882,7 @@ write_exif_header(struct jpeg_compress_struct * const cinfoP, - /*---------------------------------------------------------------------------- - Generate an APP1 marker in the JFIF output that is an Exif header. - -- The contents of the Exif header are in the file with filespec -+ The contents of the Exif header are in the file with filespec - 'exif_filespec' (file spec and contents are not validated). - - exif_filespec = "-" means Standard Input. -@@ -888,7 +892,7 @@ write_exif_header(struct jpeg_compress_struct * const cinfoP, - -----------------------------------------------------------------------------*/ - FILE * exif_file; - unsigned short length; -- -+ - exif_file = pm_openr(exif_filespec); - - pm_readbigshort(exif_file, (short*)&length); -@@ -900,7 +904,7 @@ write_exif_header(struct jpeg_compress_struct * const cinfoP, - else { - unsigned char * exif_data; - size_t rc; -- size_t const data_length = length - 2; -+ size_t const data_length = length - 2; - /* Subtract 2 byte length field*/ - - assert(data_length > 0); -@@ -917,16 +921,16 @@ write_exif_header(struct jpeg_compress_struct * const cinfoP, - "%u bytes of data, read only %u", - (unsigned)data_length, (unsigned)rc); - -- jpeg_write_marker(cinfoP, JPEG_APP0+1, -+ jpeg_write_marker(cinfoP, JPEG_APP0+1, - (const JOCTET *) exif_data, data_length); - - free(exif_data); - } -- -+ - pm_close(exif_file); - } - -- -+ - - static void - compute_rescaling_array(JSAMPLE ** const rescale_p, const pixval maxval, -@@ -938,9 +942,11 @@ compute_rescaling_array(JSAMPLE ** const rescale_p, const pixval maxval, - const long half_maxval = maxval / 2; - long val; - -+ overflow_add(maxval, 1); -+ overflow2(maxval+1, sizeof(JSAMPLE)); - *rescale_p = (JSAMPLE *) - (cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_IMAGE, -- (size_t) (((long) maxval + 1L) * -+ (size_t) (((long) maxval + 1L) * - sizeof(JSAMPLE))); - for (val = 0; val <= maxval; val++) { - /* The multiplication here must be done in 32 bits to avoid overflow */ -@@ -951,9 +957,9 @@ compute_rescaling_array(JSAMPLE ** const rescale_p, const pixval maxval, - - - static void --translate_row(const pixel pnm_buffer[], -- JSAMPLE jpeg_buffer[], -- int const width, -+translate_row(const pixel pnm_buffer[], -+ JSAMPLE jpeg_buffer[], -+ int const width, - int const input_components, - const JSAMPLE translate[]) { - /*---------------------------------------------------------------------------- -@@ -971,16 +977,16 @@ translate_row(const pixel pnm_buffer[], - - switch (input_components) { - case 1: -- for (column = 0; column < width; column++) -+ for (column = 0; column < width; column++) - jpeg_buffer[column] = translate[(int)PNM_GET1(pnm_buffer[column])]; - break; - case 3: - for (column = 0; column < width; column++) { -- jpeg_buffer[column*3+0] = -+ jpeg_buffer[column*3+0] = - translate[(int)PPM_GETR(pnm_buffer[column])]; -- jpeg_buffer[column*3+1] = -+ jpeg_buffer[column*3+1] = - translate[(int)PPM_GETG(pnm_buffer[column])]; -- jpeg_buffer[column*3+2] = -+ jpeg_buffer[column*3+2] = - translate[(int)PPM_GETB(pnm_buffer[column])]; - } - break; -@@ -1000,44 +1006,45 @@ convert_scanlines(struct jpeg_compress_struct * const cinfo_p, - int const input_fmt, - JSAMPLE xlate_table[]){ - /*---------------------------------------------------------------------------- -- Read scan lines from the input file, which is already opened in the -- netpbm library sense and ready for reading, and write them to the -+ Read scan lines from the input file, which is already opened in the -+ netpbm library sense and ready for reading, and write them to the - output JPEG object. Translate the pnm sample values to JPEG sample - values through the thable xlate_table[]. - -----------------------------------------------------------------------------*/ -- xel * pnm_buffer; -+ xel * pnm_buffer; - /* contains the row of the input image currently being processed, - in pnm_readpnmrow format - */ - JSAMPARRAY buffer; -- /* Row 0 of this array contains the row of the output image currently -+ /* Row 0 of this array contains the row of the output image currently - being processed, in JPEG compressor input format. The array only - has that one row. - */ - - /* Allocate the libpnm output and compressor input buffers */ -+ overflow2(cinfo_p->image_width, cinfo_p->input_components); - buffer = (*cinfo_p->mem->alloc_sarray) - ((j_common_ptr) cinfo_p, JPOOL_IMAGE, -- (unsigned int) cinfo_p->image_width * cinfo_p->input_components, -+ (unsigned int) cinfo_p->image_width * cinfo_p->input_components, - (unsigned int) 1); -- -+ - pnm_buffer = pnm_allocrow(cinfo_p->image_width); - - while (cinfo_p->next_scanline < cinfo_p->image_height) { -- if (cinfo_p->err->trace_level > 1) -+ if (cinfo_p->err->trace_level > 1) - pm_message("Converting Row %d...", cinfo_p->next_scanline); -- pnm_readpnmrow(input_file, pnm_buffer, cinfo_p->image_width, -+ pnm_readpnmrow(input_file, pnm_buffer, cinfo_p->image_width, - maxval, input_fmt); -- translate_row(pnm_buffer, buffer[0], -+ translate_row(pnm_buffer, buffer[0], - cinfo_p->image_width, cinfo_p->input_components, - xlate_table); - jpeg_write_scanlines(cinfo_p, buffer, 1); -- if (cinfo_p->err->trace_level > 1) -+ if (cinfo_p->err->trace_level > 1) - pm_message("Done."); - } - - pnm_freerow(pnm_buffer); -- /* Don't worry about the compressor input buffer; it gets freed -+ /* Don't worry about the compressor input buffer; it gets freed - automatically - */ - } -@@ -1053,11 +1060,11 @@ main(int argc, - struct jpeg_error_mgr jerr; - FILE * input_file; - FILE * output_file; -- int height; -+ int height; - /* height of the input image in rows, as specified by its header */ -- int width; -+ int width; - /* width of the input image in columns, as specified by its header */ -- pixval maxval; -+ pixval maxval; - /* maximum value of an input pixel component, as specified by header */ - int input_fmt; - /* The input format, as determined by its header. */ -@@ -1081,7 +1088,7 @@ main(int argc, - if (cmdline.verbose) { - pm_message("Input file has format %c%c.\n" - "It has %d rows of %d columns of pixels " -- "with max sample value of %d.", -+ "with max sample value of %d.", - (char) (input_fmt/256), (char) (input_fmt % 256), - height, width, maxval); - } -@@ -1091,13 +1098,13 @@ main(int argc, - - compute_rescaling_array(&rescale, maxval, cinfo); - -- if (cmdline.comment) -- jpeg_write_marker(&cinfo, JPEG_COM, (const JOCTET *) cmdline.comment, -+ if (cmdline.comment) -+ jpeg_write_marker(&cinfo, JPEG_COM, (const JOCTET *) cmdline.comment, - strlen(cmdline.comment)); - - if (cmdline.exif_filespec) - write_exif_header(&cinfo, cmdline.exif_filespec); -- -+ - /* Translate and copy over the actual scanlines */ - convert_scanlines(&cinfo, input_file, maxval, input_fmt, rescale); - -@@ -1110,10 +1117,7 @@ main(int argc, - pm_close(input_file); - - /* Program may have exited with non-zero completion code via -- various function calls above. -+ various function calls above. - */ - return jerr.num_warnings > 0 ? EXIT_WARNING : EXIT_SUCCESS; - } -- -- -- -diff --git a/converter/other/pnmtops.c b/converter/other/pnmtops.c -index 45d856d..09c28d5 100644 ---- a/converter/other/pnmtops.c -+++ b/converter/other/pnmtops.c -@@ -125,8 +125,8 @@ static bool verbose; - - - static void --parseDpi(const char * const dpiOpt, -- unsigned int * const dpiXP, -+parseDpi(const char * const dpiOpt, -+ unsigned int * const dpiXP, - unsigned int * const dpiYP) { - - char *dpistr2; -@@ -253,9 +253,9 @@ parseCommandLine(int argc, const char ** argv, - OPTENT3(0, "showpage", OPT_FLAG, NULL, &showpage, 0); - OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); - OPTENT3(0, "debug", OPT_FLAG, NULL, &cmdlineP->debug, 0); -- OPTENT3(0, "level", OPT_UINT, &cmdlineP->level, -+ OPTENT3(0, "level", OPT_UINT, &cmdlineP->level, - &cmdlineP->levelSpec, 0); -- -+ - opt.opt_table = option_def; - opt.short_allowed = FALSE; - opt.allowNegNum = FALSE; -@@ -293,18 +293,22 @@ parseCommandLine(int argc, const char ** argv, - - validateCompDimension(width, 72, "-width value"); - validateCompDimension(height, 72, "-height value"); -- -+ -+ overflow2(width, 72); - cmdlineP->width = width * 72; -+ overflow2(height, 72); - cmdlineP->height = height * 72; ++ overflow2(width, psScaleFactor); + cmdlineP->width = width * psScaleFactor; ++ overflow2(height, psScaleFactor); + cmdlineP->height = height * psScaleFactor; if (imagewidthSpec) { - validateCompDimension(imagewidth, 72, "-imagewidth value"); -+ overflow2(imagewidth, 72); - cmdlineP->imagewidth = imagewidth * 72; + validateCompDimension(imagewidth, psScaleFactor, "-imagewidth value"); ++ overflow2(imagewidth, psScaleFactor); + cmdlineP->imagewidth = imagewidth * psScaleFactor; } else cmdlineP->imagewidth = 0; if (imageheightSpec) { -- validateCompDimension(imagewidth, 72, "-imageheight value"); -+ validateCompDimension(imageheight, 72, "-imageheight value"); -+ overflow2(imageheight, 72); - cmdlineP->imageheight = imageheight * 72; +- validateCompDimension(imagewidth, psScaleFactor, "-imageheight value"); ++ validateCompDimension(imageheight, psScaleFactor, "-imageheight value"); ++ overflow2(imageheight, psScaleFactor); + cmdlineP->imageheight = imageheight * psScaleFactor; } else -@@ -318,7 +322,7 @@ parseCommandLine(int argc, const char ** argv, - if (cmdlineP->bitspersampleSpec) - validateBps_1_2_4_8_12(cmdlineP->bitspersample); - -- if (argc-1 == 0) -+ if (argc-1 == 0) - cmdlineP->inputFileName = "-"; - else if (argc-1 != 1) - pm_error("Program takes zero or one argument (filename). You " -@@ -326,7 +330,7 @@ parseCommandLine(int argc, const char ** argv, - else - cmdlineP->inputFileName = argv[1]; - -- free(option_def); -+ free(option_def); - } - - -@@ -432,7 +436,7 @@ addToPidList(pid_t * const pidList, - /*=========================================================================== - The output encoder - ===========================================================================*/ -- -+ - enum OutputType {AsciiHex, Ascii85}; - - typedef struct { -@@ -453,7 +457,7 @@ bytesPerRow (unsigned int const cols, - -----------------------------------------------------------------------------*/ - unsigned int retval; - -- assert(bitsPerSample==1 || bitsPerSample==2 || bitsPerSample==4 || -+ assert(bitsPerSample==1 || bitsPerSample==2 || bitsPerSample==4 || - bitsPerSample==8 || bitsPerSample==12); - - switch (bitsPerSample) { -@@ -519,7 +523,7 @@ typedef void FilterFn(FILE * const ifP, - /* This is a function that can be run in a separate process to do - arbitrary modifications of the raster data stream. - */ -- -+ - - - #ifndef NOFLATE -@@ -545,7 +549,7 @@ initZlib(z_stream * const strmP) { - - static FilterFn flateFilter; - --static void -+static void - flateFilter(FILE * const ifP, - FILE * const ofP, - OutputEncoder * const oeP) { -@@ -600,12 +604,12 @@ flateFilter(FILE * const ifP, - } while (flush != Z_FINISH); - - free(in); -- free(out); -+ free(out); - deflateEnd(&strm); - fclose(ifP); - fclose(ofP); - #else -- assert(false); /* filter is never used */ -+ assert(false); /* filter is never used */ - #endif - } - -@@ -687,7 +691,7 @@ asciiHexFilter(FILE * const ifP, - unsigned int i; - - for (i = 0; i < readCt; ++i) { -- int const item = inbuff[i]; -+ int const item = inbuff[i]; - outbuff[i*2] = hexits[item >> 4]; - outbuff[i*2+1] = hexits[item & 15]; - } -@@ -736,7 +740,7 @@ ascii85Filter(FILE * const ifP, - ++outcount; - count = 0; - } else if (count == 4) { -- outbuff[4] = value % 85 + 33; value/=85; -+ outbuff[4] = value % 85 + 33; value/=85; - outbuff[3] = value % 85 + 33; value/=85; - outbuff[2] = value % 85 + 33; value/=85; - outbuff[1] = value % 85 + 33; -@@ -745,7 +749,7 @@ ascii85Filter(FILE * const ifP, - writeFileChar(outbuff, count + 1, "ASCII 85 filter", ofP); - - count = value = 0; -- outcount += 5; -+ outcount += 5; - } - - if (outcount > 75) { -@@ -794,9 +798,9 @@ closeAllBut(int const saveFd0, - 'saveFd1', and 'saveFd2'. - - This is helpful because even if this process doesn't touch other file -- descriptors, its very existence will keep the files open. -+ desriptors, its very existence will keep the files open. - -----------------------------------------------------------------------------*/ -- -+ - /* Unix provides no good way to do this; we just assume file descriptors - above 9 are not used in this program; Caller must ensure that is true. - */ -@@ -829,15 +833,15 @@ spawnFilter(FILE * const ofP, - pid_t rc; - - makePipe(pipeFd); -- -+ - rc = fork(); - - if (rc == (pid_t)-1) -- pm_error("fork() of filter process failed. errno=%d (%s)", -+ pm_error("fork() of filter process failed. errno=%d (%s)", - errno, strerror(errno)); - else if (rc == 0) { - /* This is the child process */ -- -+ - FILE * ifP; - - ifP = fdopen(pipeFd[0], "r"); -@@ -892,11 +896,11 @@ addFilter(const char * const description, - pid_t pid; - - spawnFilter(oldFeedFileP, filter, oeP, &newFeedFileP, &pid); -- -+ - if (verbose) - pm_message("%s filter spawned: pid %u", - description, (unsigned)pid); -- -+ - if (debug) { - int const outFd = fileno(oldFeedFileP); - int const supplyFd = fileno(newFeedFileP); -@@ -971,7 +975,7 @@ waitForChildren(const pid_t * const pidList) { - signal is the default), the process' children do not become - zombies. Consequently, waitpid() always fails with ECHILD - but - nonetheless waits for the child to exit. -- -+ - We expect the process not to have the action for SIGCHLD set that - way. - */ -@@ -1004,9 +1008,9 @@ waitForChildren(const pid_t * const pidList) { - - - static void --validateComputableBoundingBox(float const scols, -+validateComputableBoundingBox(float const scols, - float const srows, -- float const llx, -+ float const llx, - float const lly) { - - float const bbWidth = llx + scols + 0.5; -@@ -1036,22 +1040,22 @@ warnUserRescaling(float const scale) { - - - static void --computeImagePosition(int const dpiX, -- int const dpiY, -- int const icols, -+computeImagePosition(int const dpiX, -+ int const dpiY, -+ int const icols, - int const irows, - bool const mustturn, - bool const canturn, - bool const center, -- int const pagewid, -- int const pagehgt, -+ int const pagewid, -+ int const pagehgt, - float const requestedScale, - float const imagewidth, - float const imageheight, - bool const equalpixels, - float * const scolsP, - float * const srowsP, -- float * const llxP, -+ float * const llxP, - float * const llyP, - bool * const turnedP ) { - /*---------------------------------------------------------------------------- -@@ -1091,7 +1095,7 @@ computeImagePosition(int const dpiX, - rotated if applicable - */ - bool shouldturn; /* The image fits the page better if we turn it */ -- -+ - if (icols > irows && pagehgt > pagewid) - shouldturn = TRUE; - else if (irows > icols && pagewid > pagehgt) -@@ -1120,27 +1124,27 @@ computeImagePosition(int const dpiX, - scale = (float) imagewidth/cols; - else - scale = MIN((float)imagewidth/cols, (float)imageheight/rows); -- -+ - *scolsP = cols*scale; - *srowsP = rows*scale; - } else { - /* He didn't give us a bounding box for the image so figure - out output image size from other inputs. - */ -- const int devpixX = dpiX / 72.0 + 0.5; -- const int devpixY = dpiY / 72.0 + 0.5; -+ const int devpixX = dpiX / 72.0 + 0.5; -+ const int devpixY = dpiY / 72.0 + 0.5; - /* How many device pixels make up 1/72 inch, rounded to - nearest integer */ - const float pixfacX = 72.0 / dpiX * devpixX; /* 1, approx. */ - const float pixfacY = 72.0 / dpiY * devpixY; /* 1, approx. */ - float scale; - -- scale = MIN(requestedScale, -+ scale = MIN(requestedScale, - MIN((float)pagewid/cols, (float)pagehgt/rows)); - - *scolsP = scale * cols * pixfacX; - *srowsP = scale * rows * pixfacY; -- -+ - if (scale != requestedScale) - warnUserRescaling(scale); - -@@ -1236,7 +1240,7 @@ defineReadstring(bool const rle) { - static void - setupReadstringNative(bool const rle, - bool const color, -- unsigned int const icols, -+ unsigned int const icols, - unsigned int const bitsPerSample) { - /*---------------------------------------------------------------------------- - Write to Standard Output statements to define /readstring and also -@@ -1247,7 +1251,7 @@ setupReadstringNative(bool const rle, - /* Size of row buffer, padded up to byte boundary. */ - - defineReadstring(rle); -- -+ - if (color) { - printf("/rpicstr %d string def\n", bytesPerRow); - printf("/gpicstr %d string def\n", bytesPerRow); -@@ -1266,18 +1270,18 @@ putFilters(unsigned int const postscriptLevel, - bool const color) { - - assert(postscriptLevel > 1); -- -+ - /* We say to decode flate, then rle, so Caller must ensure it encodes - rel, then flate. - */ - - if (ascii85) - printf("/ASCII85Decode filter "); -- else -+ else - printf("/ASCIIHexDecode filter "); - if (flate) - printf("/FlateDecode filter "); -- if (rle) -+ if (rle) - printf("/RunLengthDecode filter "); - } - -@@ -1311,7 +1315,7 @@ putSetup(unsigned int const dictSize, - if (dictSize > 0) - /* inputf {r,g,b,}pictsr readstring readrlestring rlestring */ - printf("%u dict begin\n", dictSize); -- -+ - if (!psFilter) - setupReadstringNative(rle, color, icols, bitsPerSample); - -@@ -1353,7 +1357,7 @@ putInitPsFilter(unsigned int const postscriptLevel, - putFilters(postscriptLevel, rle, flate, ascii85, color); - - putImage(filterTrue, color); -- -+ - printf(" } exec"); - } - -@@ -1365,7 +1369,7 @@ putInitReadstringNative(bool const color) { - bool const filterFalse = FALSE; - - putReadstringNative(color); -- -+ - putImage(filterFalse, color); - } - -@@ -1373,18 +1377,18 @@ putInitReadstringNative(bool const color) { - - static void - putInit(unsigned int const postscriptLevel, -- char const name[], -- int const icols, -- int const irows, -- float const scols, -+ char const name[], -+ int const icols, -+ int const irows, -+ float const scols, - float const srows, -- float const llx, -+ float const llx, - float const lly, - int const bitsPerSample, -- int const pagewid, -+ int const pagewid, - int const pagehgt, -- bool const color, -- bool const turned, -+ bool const color, -+ bool const turned, - bool const rle, - bool const flate, - bool const ascii85, -@@ -1438,7 +1442,7 @@ putInit(unsigned int const postscriptLevel, - - - static void --putEnd(bool const showpage, -+putEnd(bool const showpage, - bool const psFilter, - bool const ascii85, - unsigned int const dictSize, -@@ -1486,7 +1490,7 @@ validateBpsRequest(unsigned int const bitsPerSampleReq, - "-psfilter, the maximum is 8", bitsPerSampleReq); - } - -- -+ - - static unsigned int - bpsFromInput(unsigned int const bitsRequiredByMaxval, -@@ -1553,7 +1557,7 @@ warnUserAboutReducedDepth(unsigned int const bitsGot, - - static void - computeDepth(xelval const inputMaxval, -- unsigned int const postscriptLevel, -+ unsigned int const postscriptLevel, - bool const psFilter, - unsigned int const bitsPerSampleReq, - unsigned int * const bitsPerSampleP) { -@@ -1584,7 +1588,7 @@ computeDepth(xelval const inputMaxval, - "%u bits per sample, so maxval = %u", - inputMaxval, *bitsPerSampleP, psMaxval); - } --} -+} - - - -@@ -1643,7 +1647,7 @@ ba_add(BitAccumulator * const baP, - /*---------------------------------------------------------------------------- - Combine bit sequences that do not fit into a byte. - -- Used when bitsPerSample =1, 2, 4. -+ Used when bitsPerSample =1, 2, 4. - Logic also works for bitsPerSample = 8, 16. - - The accumulator, baP->value is unsigned int (usually 32 bits), but -@@ -1725,7 +1729,7 @@ flushOutput(BitAccumulator * const baP, - - convertRowNative and convertRowPsFilter are the general converters. - They are quite similar, the differences being: -- (1) Native output separates the color planes: -+ (1) Native output separates the color planes: - (RRR...RRR GGG...GGG BBB...BBB), - whereas psFilter does not: - (RGB RGB RGB RGB ......... RGB). -@@ -1765,10 +1769,10 @@ convertRowPbm(struct pam * const pamP, - - - static void --convertRowNative(struct pam * const pamP, -- tuple * tuplerow, -+convertRowNative(struct pam * const pamP, -+ tuple * tuplerow, - unsigned int const bitsPerSample, -- FILE * const fP) { -+ FILE * const fP) { - - unsigned int const psMaxval = pm_bitstomaxval(bitsPerSample); - -@@ -1795,7 +1799,7 @@ static void - convertRowPsFilter(struct pam * const pamP, - tuple * tuplerow, - unsigned int const bitsPerSample, -- FILE * const fP) { -+ FILE * const fP) { - - unsigned int const psMaxval = pm_bitstomaxval(bitsPerSample); - -@@ -1828,7 +1832,7 @@ selectPostscriptLevel(bool const levelIsGiven, - bool const psFilter, - unsigned int * const postscriptLevelP) { - -- unsigned int const maxPermittedLevel = -+ unsigned int const maxPermittedLevel = - levelIsGiven ? levelGiven : UINT_MAX; - unsigned int minPossibleLevel; - -@@ -1877,7 +1881,7 @@ convertRaster(struct pam * const inpamP, - Read the raster described by *inpamP, and write a bit stream of samples - to *fP. This stream has to be compressed and converted to text before it - can be part of a Postscript program. -- -+ - 'psFilter' means to do the conversion using built in Postscript filters, as - opposed to our own filters via /readstring. - -@@ -1897,7 +1901,7 @@ convertRaster(struct pam * const inpamP, - } else { - tuple *tuplerow; - unsigned int row; -- -+ - tuplerow = pnm_allocpamrow(inpamP); - - for (row = 0; row < inpamP->height; ++row) { -@@ -1920,31 +1924,31 @@ convertRaster(struct pam * const inpamP, - pipe but this program's output, then we don't want it closed when the - filter terminates because we'll need it to be open for the next image - the program converts (with a whole new chain of filters). -- -- To prevent the program output file from getting closed, we pass a -+ -+ To prevent the progam output file from getting closed, we pass a - duplicate of it to spawnFilters() and keep the original open. - */ - - - - static void --convertPage(FILE * const ifP, -- int const turnflag, -- int const turnokflag, -+convertPage(FILE * const ifP, -+ int const turnflag, -+ int const turnokflag, - bool const psFilter, -- bool const rle, -+ bool const rle, - bool const flate, - bool const ascii85, - bool const setpage, - bool const showpage, -- bool const center, -+ bool const center, - float const scale, -- int const dpiX, -- int const dpiY, -- int const pagewid, -+ int const dpiX, -+ int const dpiY, -+ int const pagewid, - int const pagehgt, -- int const imagewidth, -- int const imageheight, -+ int const imagewidth, -+ int const imageheight, - bool const equalpixels, - unsigned int const bitsPerSampleReq, - char const name[], -@@ -1952,7 +1956,7 @@ convertPage(FILE * const ifP, - bool const vmreclaim, - bool const levelIsGiven, - unsigned int const levelGiven) { -- -+ - struct pam inpam; - float scols, srows; - float llx, lly; -@@ -1960,7 +1964,7 @@ convertPage(FILE * const ifP, - bool color; - unsigned int postscriptLevel; - unsigned int bitsPerSample; -- unsigned int dictSize; -+ unsigned int dictSize; - /* Size of Postscript dictionary we should define */ - OutputEncoder oe; - pid_t filterPidList[MAX_FILTER_CT + 1]; -@@ -1974,19 +1978,19 @@ convertPage(FILE * const ifP, - pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); - - validateCompDimension(inpam.width, 16, "Input image width"); -- -+ - if (!STRSEQ(inpam.tuple_type, PAM_PBM_TUPLETYPE) && - !STRSEQ(inpam.tuple_type, PAM_PGM_TUPLETYPE) && - !STRSEQ(inpam.tuple_type, PAM_PPM_TUPLETYPE)) - pm_error("Unrecognized tuple type %s. This program accepts only " -- "PBM, PGM, PPM, and equivalent PAM input images", -+ "PBM, PGM, PPM, and equivalent PAM input images", - inpam.tuple_type); - - color = STRSEQ(inpam.tuple_type, PAM_PPM_TUPLETYPE); -- -- selectPostscriptLevel(levelIsGiven, levelGiven, color, -+ -+ selectPostscriptLevel(levelIsGiven, levelGiven, color, - dict, flate, ascii85, psFilter, &postscriptLevel); -- -+ - if (color) - pm_message("generating color Postscript program."); - -@@ -1996,16 +2000,16 @@ convertPage(FILE * const ifP, - /* In positioning/scaling the image, we treat the input image as if - it has a density of 72 pixels per inch. - */ -- computeImagePosition(dpiX, dpiY, inpam.width, inpam.height, -+ computeImagePosition(dpiX, dpiY, inpam.width, inpam.height, - turnflag, turnokflag, center, - pagewid, pagehgt, scale, imagewidth, imageheight, - equalpixels, - &scols, &srows, &llx, &lly, &turned); - - determineDictionaryRequirement(dict, psFilter, &dictSize); -- -- putInit(postscriptLevel, name, inpam.width, inpam.height, -- scols, srows, llx, lly, bitsPerSample, -+ -+ putInit(postscriptLevel, name, inpam.width, inpam.height, -+ scols, srows, llx, lly, bitsPerSample, - pagewid, pagehgt, color, - turned, rle, flate, ascii85, setpage, psFilter, dictSize); - -@@ -2017,7 +2021,7 @@ convertPage(FILE * const ifP, - /* spawnFilters() closes this. See FILE MANAGEMENT above */ - - spawnFilters(filterChainOfP, &oe, &feedFileP, filterPidList); -- -+ - convertRaster(&inpam, bitsPerSample, psFilter, feedFileP); - - fflush(feedFileP); -@@ -2081,17 +2085,17 @@ main(int argc, const char * argv[]) { - - eof = FALSE; /* There is always at least one image */ - for (imageSeq = 0; !eof; ++imageSeq) { -- convertPage(ifP, cmdline.mustturn, cmdline.canturn, -+ convertPage(ifP, cmdline.mustturn, cmdline.canturn, - cmdline.psfilter, -- cmdline.rle, cmdline.flate, cmdline.ascii85, -+ cmdline.rle, cmdline.flate, cmdline.ascii85, - cmdline.setpage, cmdline.showpage, - cmdline.center, cmdline.scale, - cmdline.dpiX, cmdline.dpiY, -- cmdline.width, cmdline.height, -- cmdline.imagewidth, cmdline.imageheight, -+ cmdline.width, cmdline.height, -+ cmdline.imagewidth, cmdline.imageheight, - cmdline.equalpixels, - cmdline.bitspersampleSpec ? cmdline.bitspersample : 0, -- name, -+ name, - cmdline.dict, cmdline.vmreclaim, - cmdline.levelSpec, cmdline.level); - pnm_nextimage(ifP, &eof); -@@ -2121,7 +2125,7 @@ main(int argc, const char * argv[]) { - ** wrzl@gup.uni-linz.ac.at. - ** - ** July 2011 afu --** row converters rewritten, fast PBM-only row converter added, -+** row convertors rewritten, fast PBM-only row convertor added, - ** rle compression slightly modified, flate compression added - ** ascii85 output end added. - ** -diff --git a/converter/other/rletopnm.c b/converter/other/rletopnm.c -index 97f271d..72b63d3 100644 ---- a/converter/other/rletopnm.c -+++ b/converter/other/rletopnm.c -@@ -19,6 +19,8 @@ - * If you modify this software, you should include a notice giving the - * name of the person performing the modification, the date of modification, - * and the reason for such modification. -+ * -+ * 2002-12-19: Fix maths wrapping bugs. Alan Cox - */ - /* - * rletopnm - A conversion program to convert from Utah's "rle" image format -diff --git a/converter/other/sirtopnm.c b/converter/other/sirtopnm.c -index fafcc91..9fe49d0 100644 ---- a/converter/other/sirtopnm.c -+++ b/converter/other/sirtopnm.c -@@ -69,6 +69,7 @@ char* argv[]; - } - break; - case PPM_TYPE: -+ overflow3(cols, rows, 3); - picsize = cols * rows * 3; - planesize = cols * rows; - if ( !( sirarray = (unsigned char*) malloc( picsize ) ) ) -diff --git a/converter/other/tifftopnm.c b/converter/other/tifftopnm.c -index 0c301a4..88c99e7 100644 ---- a/converter/other/tifftopnm.c -+++ b/converter/other/tifftopnm.c -@@ -1372,7 +1372,9 @@ convertRasterByRows(pnmOut * const pnmOutP, - if (scanbuf == NULL) - pm_error("can't allocate memory for scanline buffer"); - +diff -urNp a/converter/other/sirtopnm.c b/converter/other/sirtopnm.c +--- a/converter/other/sirtopnm.c 2025-02-03 09:24:28.347500471 +0100 ++++ b/converter/other/sirtopnm.c 2025-02-03 09:44:25.547151413 +0100 +@@ -84,6 +84,7 @@ convertPpm(FILE * const ifP, + unsigned int const cols, + xel * const xelrow) { + ++ overflow3(cols, rows, 3); + unsigned int const picsize = cols * rows * 3; + unsigned int const planesize = cols * rows; + +diff -urNp a/converter/other/tifftopnm.c b/converter/other/tifftopnm.c +--- a/converter/other/tifftopnm.c 2025-02-03 09:24:28.345500482 +0100 ++++ b/converter/other/tifftopnm.c 2025-02-03 09:46:55.210395347 +0100 +@@ -1358,7 +1358,8 @@ convertRasterByRows(pnmOut * const + if (UINT_MAX/cols < spp) + pm_error("Image is too wide/deep (%u x %u) for computations", + cols, spp); - MALLOCARRAY(samplebuf, cols * spp); + /* samplebuf is unsigned int * !!! */ -+ samplebuf = (unsigned int *) malloc3(cols , sizeof(unsigned int) , spp); -+ ++ samplebuf = (unsigned int *) malloc3(cols, sizeof(unsigned int), spp); if (samplebuf == NULL) pm_error("can't allocate memory for row buffer"); -diff --git a/converter/other/xwdtopnm.c b/converter/other/xwdtopnm.c -index a99768b..6e23aa6 100644 ---- a/converter/other/xwdtopnm.c -+++ b/converter/other/xwdtopnm.c -@@ -210,6 +210,10 @@ processX10Header(X10WDFileHeader * const h10P, - *colorsP = pnm_allocrow(2); - PNM_ASSIGN1((*colorsP)[0], 0); - PNM_ASSIGN1((*colorsP)[1], *maxvalP); +diff -urNp a/converter/other/xwdtopnm.c b/converter/other/xwdtopnm.c +--- a/converter/other/xwdtopnm.c 2025-02-03 09:24:28.345500482 +0100 ++++ b/converter/other/xwdtopnm.c 2025-02-03 09:55:18.695851996 +0100 +@@ -243,6 +243,10 @@ processX10Header(X10WDFileHeader * cons + *colorsP = pnm_allocrow(*maxvalP + 1); + for (i = 0; i <= *maxvalP; ++i) + PNM_ASSIGN1((*colorsP)[i], i); + overflow_add(h10P->pixmap_width, 15); + if(h10P->pixmap_width < 0) + pm_error("assert: negative width"); + overflow2((((h10P->pixmap_width + 15) / 16) * 16 - h10P->pixmap_width), 8); *padrightP = (((h10P->pixmap_width + 15) / 16) * 16 - h10P->pixmap_width) * 8; - *bits_per_itemP = 16; -@@ -635,6 +639,7 @@ processX11Header(X11WDFileHeader * const h11P, - - *colsP = h11FixedP->pixmap_width; - *rowsP = h11FixedP->pixmap_height; + *bitsPerItemP = 16; +@@ -671,6 +675,7 @@ processX11Header(const X11WDFileHeader * + "%u bits per pixel, which is too many for this program " + "to compute", + h11FixedP->pixmap_width, h11FixedP->bits_per_pixel); + overflow2(h11FixedP->bytes_per_line, 8); *padrightP = h11FixedP->bytes_per_line * 8 - h11FixedP->pixmap_width * h11FixedP->bits_per_pixel; -diff --git a/converter/pbm/mdatopbm.c b/converter/pbm/mdatopbm.c -index 461b3f8..c8bab6c 100644 ---- a/converter/pbm/mdatopbm.c -+++ b/converter/pbm/mdatopbm.c -@@ -245,10 +245,13 @@ main(int argc, char **argv) { - pm_readlittleshort(infile, &yy); nInCols = yy; +diff -urNp a/converter/pbm/mdatopbm.c b/converter/pbm/mdatopbm.c +--- a/converter/pbm/mdatopbm.c 2025-02-03 09:24:28.358500411 +0100 ++++ b/converter/pbm/mdatopbm.c 2025-02-03 09:57:03.495422912 +0100 +@@ -283,11 +283,13 @@ main(int argc, const char **argv) { + pm_readlittleshort(ifP, &yy); nInCols = yy; } - + + overflow2(nOutCols, 8); nOutCols = 8 * nInCols; nOutRows = nInRows; -- if (bScale) +- if (bScale) + if (bScale) { + overflow2(nOutRows, 2); nOutRows *= 2; +- + } - data = pbm_allocarray(nOutCols, nOutRows); - -diff --git a/converter/pbm/mgrtopbm.c b/converter/pbm/mgrtopbm.c -index 9f7004a..60e8477 100644 ---- a/converter/pbm/mgrtopbm.c -+++ b/converter/pbm/mgrtopbm.c -@@ -65,6 +65,8 @@ readMgrHeader(FILE * const ifP, - if (head.h_high < ' ' || head.l_high < ' ') - pm_error("Invalid width field in MGR header"); - + + MALLOCARRAY_NOFAIL(mdrow, nInCols); +diff -urNp a/converter/pbm/mgrtopbm.c b/converter/pbm/mgrtopbm.c +--- a/converter/pbm/mgrtopbm.c 2025-02-03 09:24:28.358500411 +0100 ++++ b/converter/pbm/mgrtopbm.c 2025-02-03 09:58:19.232265999 +0100 +@@ -105,6 +105,8 @@ readMgrHeader(FILE * const ifP, + interpHdrWidth (head, colsP); + interpHdrHeight(head, rowsP); + + overflow_add(*colsP, pad); + - *colsP = (((int)head.h_wide - ' ') << 6) + ((int)head.l_wide - ' '); - *rowsP = (((int)head.h_high - ' ') << 6) + ((int) head.l_high - ' '); - *padrightP = ( ( *colsP + pad - 1 ) / pad ) * pad - *colsP; -diff --git a/converter/pbm/pbmto4425.c b/converter/pbm/pbmto4425.c -index 1d97ac6..c4c8cbb 100644 ---- a/converter/pbm/pbmto4425.c -+++ b/converter/pbm/pbmto4425.c -@@ -2,6 +2,7 @@ + *padrightP = ((*colsP + pad - 1) / pad) * pad - *colsP; + } - #include "nstring.h" - #include "pbm.h" -+#include - - static char bit_table[2][3] = { - {1, 4, 0x10}, -@@ -160,7 +161,7 @@ main(int argc, char * argv[]) { - xres = vmap_width * 2; - yres = vmap_height * 3; - -- vmap = malloc(vmap_width * vmap_height * sizeof(char)); -+ vmap = malloc3(vmap_width, vmap_height, sizeof(char)); - if(vmap == NULL) - { - pm_error( "Cannot allocate memory" ); -diff --git a/converter/pbm/pbmtogem.c b/converter/pbm/pbmtogem.c -index 4fd30e9..c82757d 100644 ---- a/converter/pbm/pbmtogem.c -+++ b/converter/pbm/pbmtogem.c +diff -urNp a/converter/pbm/pbmtogem.c b/converter/pbm/pbmtogem.c +--- a/converter/pbm/pbmtogem.c 2025-02-03 09:24:28.358500411 +0100 ++++ b/converter/pbm/pbmtogem.c 2025-02-03 10:25:34.259707343 +0100 @@ -79,6 +79,7 @@ putinit (int const rows, int const cols) bitsperitem = 0; bitshift = 7; @@ -1704,10 +196,9 @@ index 4fd30e9..c82757d 100644 outmax = (cols + 7) / 8; outrow = (unsigned char *) pm_allocrow (outmax, sizeof (unsigned char)); lastrow = (unsigned char *) pm_allocrow (outmax, sizeof (unsigned char)); -diff --git a/converter/pbm/pbmtogo.c b/converter/pbm/pbmtogo.c -index 4f84f39..943dc84 100644 ---- a/converter/pbm/pbmtogo.c -+++ b/converter/pbm/pbmtogo.c +diff -urNp a/converter/pbm/pbmtogo.c b/converter/pbm/pbmtogo.c +--- a/converter/pbm/pbmtogo.c 2025-02-03 09:24:28.359500407 +0100 ++++ b/converter/pbm/pbmtogo.c 2025-02-03 10:26:22.723447123 +0100 @@ -158,6 +158,7 @@ main(int argc, bitrow = pbm_allocrow(cols); @@ -1716,15 +207,14 @@ index 4f84f39..943dc84 100644 rucols = ( cols + 7 ) / 8; bytesperrow = rucols; /* GraphOn uses bytes */ rucols = rucols * 8; -diff --git a/converter/pbm/pbmtolj.c b/converter/pbm/pbmtolj.c -index 3cd7670..0b51932 100644 ---- a/converter/pbm/pbmtolj.c -+++ b/converter/pbm/pbmtolj.c -@@ -120,7 +120,11 @@ parseCommandLine(int argc, char ** argv, +diff -urNp a/converter/pbm/pbmtolj.c b/converter/pbm/pbmtolj.c +--- a/converter/pbm/pbmtolj.c 2025-02-03 09:24:28.357500417 +0100 ++++ b/converter/pbm/pbmtolj.c 2025-02-03 10:29:37.442401385 +0100 +@@ -120,7 +120,11 @@ parseCommandLine(int argc, const char ** static void allocateBuffers(unsigned int const cols) { -+ overflow_add(cols, 8); ++ overflow_add(cols, 7); rowBufferSize = (cols + 7) / 8; + overflow_add(rowBufferSize, 128); + overflow_add(rowBufferSize, rowBufferSize+128); @@ -1732,427 +222,162 @@ index 3cd7670..0b51932 100644 packBufferSize = rowBufferSize + (rowBufferSize + 127) / 128 + 1; deltaBufferSize = rowBufferSize + rowBufferSize / 8 + 10; -diff --git a/converter/pbm/pbmtomda.c b/converter/pbm/pbmtomda.c -index 3ad5149..9efe5cf 100644 ---- a/converter/pbm/pbmtomda.c -+++ b/converter/pbm/pbmtomda.c -@@ -179,6 +179,7 @@ int main(int argc, char **argv) - - nOutRowsUnrounded = bScale ? nInRows/2 : nInRows; +diff -urNp a/converter/pbm/pbmtomda.c b/converter/pbm/pbmtomda.c +--- a/converter/pbm/pbmtomda.c 2025-02-03 09:24:28.357500417 +0100 ++++ b/converter/pbm/pbmtomda.c 2025-02-03 10:31:40.714199457 +0100 +@@ -204,6 +204,7 @@ main(int argc, const char ** argv) { + + nOutRowsUnrounded = cmdline.dscale ? nInRows/2 : nInRows; + overflow_add(nOutRowsUnrounded, 3); nOutRows = ((nOutRowsUnrounded + 3) / 4) * 4; - /* MDA wants rows a multiple of 4 */ + /* MDA wants rows a multiple of 4 */ nOutCols = nInCols / 8; -diff --git a/converter/pbm/pbmtoppa/pbm.c b/converter/pbm/pbmtoppa/pbm.c -index ae36e0d..1c8d236 100644 ---- a/converter/pbm/pbmtoppa/pbm.c -+++ b/converter/pbm/pbmtoppa/pbm.c -@@ -11,185 +11,128 @@ - #include - #include - #include --#include +diff -urNp a/converter/pbm/pbmtoppa/pbm.c b/converter/pbm/pbmtoppa/pbm.c +--- a/converter/pbm/pbmtoppa/pbm.c 2025-02-03 09:24:28.356500423 +0100 ++++ b/converter/pbm/pbmtoppa/pbm.c 2025-02-03 10:48:49.928347495 +0100 +@@ -157,6 +157,7 @@ pbm_readline(pbm_stat * const pbmSt + break; + case P4: { + int tmp, tmp2; ++ overflow_add(pbmStatP->width, 7); + tmp = (pbmStatP->width+7)/8; + tmp2 = fread(data,1,tmp,pbmStatP->fptr); + if (tmp2 == tmp) { +@@ -189,6 +190,7 @@ pbm_unreadline(pbm_stat * const pbmStatP --#include "pm.h" --#include "nstring.h" - #include "ppapbm.h" - --int --make_pbm_stat(pbm_stat * const pbmStatP, -- FILE * const ifP) { -- -- char line[1024]; -- char * rc; -- int retval; -- -- pbmStatP->fptr = ifP; -- pbmStatP->version = none; -- pbmStatP->current_line = 0; -- pbmStatP->unread = 0; -- -- rc = fgets(line, 1024, ifP); -- if (rc == NULL) -- retval = 0; -- else { -- line[strlen(line)-1] = 0; -- -- if (streq(line,"P1")) -- pbmStatP->version=P1; -- if (streq(line,"P4")) -- pbmStatP->version=P4; -- -- if (pbmStatP->version == none) { -- pm_message("unknown PBM magic '%s'", line); -- retval = 0; -- } else { -- do { -- char * rc; -- rc = fgets(line, 1024, ifP); -- if (rc == NULL) -- return 0; -- } while (line[0] == '#'); -- { -- int rc; -- rc = sscanf(line, "%d %d", -- &pbmStatP->width, &pbmStatP->height); -- if (rc != 2) -- retval = 0; -- else { -- if (pbmStatP->width < 0) { -- pm_message("Image has negative width"); -- retval = 0; -- } else if (pbmStatP->width > INT_MAX/2) { -- pm_message("Uncomputeably large width: %d", -- pbmStatP->width); -- retval = 0; -- } else if (pbmStatP->height < 0) { -- pm_message("Image has negative height"); -- retval = 0; -- } else if (pbmStatP->height > INT_MAX/2) { -- pm_message("Uncomputeably large height: %d", -- pbmStatP->height); -- retval = 0; -- } else -- retval = 1; -- } -- } -- } -- } -- return retval; --} -+int make_pbm_stat(pbm_stat* pbm,FILE* fptr) -+{ -+ char line[1024]; - -+ pbm->fptr=fptr; -+ pbm->version=none; -+ pbm->current_line=0; -+ pbm->unread = 0; - -+ if (fgets (line, 1024, fptr) == NULL) -+ return 0; -+ line[strlen(line)-1] = 0; - --static int --getbytes(FILE * const ifP, -- unsigned int const width, -- unsigned char * const data) { -- -- unsigned char mask; -- unsigned char acc; -- unsigned char * place; -- unsigned int num; -- int retval; -- -- if (width == 0) -- retval = 0; -- else { -- for (mask = 0x80, acc = 0, num = 0, place = data; num < width; ) { -- switch (getc(ifP)) { -- case EOF: -- return 0; -- case '1': -- acc |= mask; -- /* fall through */ -- case '0': -- mask >>= 1; -- ++num; -- if (mask == 0x00) { /* if (num % 8 == 0) */ -- *place++ = acc; -- acc = 0; -- mask = 0x80; -- } -- } -- } -- if (width % 8 != 0) -- *place = acc; -- -- retval = 1; -- } -- return retval; --} -+ if(!strcmp(line,"P1")) pbm->version=P1; -+ if(!strcmp(line,"P4")) pbm->version=P4; -+ if(pbm->version == none) -+ { -+ fprintf(stderr,"pbm_readheader(): unknown PBM magic '%s'\n",line); -+ return 0; -+ } - -+ do -+ if (fgets (line, 1024, fptr) == NULL) -+ return 0; -+ while (line[0] == '#'); - -+ if (2 != sscanf (line, "%d %d", &pbm->width, &pbm->height)) -+ return 0; - --int --pbm_readline(pbm_stat * const pbmStatP, -- unsigned char * const data) { --/*---------------------------------------------------------------------------- -- Read a single line into data which must be at least (pbmStatP->width+7)/8 -- bytes of storage. -------------------------------------------------------------------------------*/ -- int retval; -- -- if (pbmStatP->current_line >= pbmStatP->height) -- retval = 0; -- else { -- if (pbmStatP->unread) { -- memcpy(data, pbmStatP->revdata, (pbmStatP->width+7)/8); -- ++pbmStatP->current_line; -- pbmStatP->unread = 0; -- free(pbmStatP->revdata); -- pbmStatP->revdata = NULL; -- retval = 1; -- } else { -- switch (pbmStatP->version) { -- case P1: -- if (getbytes(pbmStatP->fptr, pbmStatP->width, data)) { -- pbmStatP->current_line++; -- retval = 1; -- } else -- retval = 0; -- break; -- case P4: { -- int tmp, tmp2; -- tmp = (pbmStatP->width+7)/8; -- tmp2 = fread(data,1,tmp,pbmStatP->fptr); -- if (tmp2 == tmp) { -- ++pbmStatP->current_line; -- retval = 1; -- } else { -- pm_message("error reading line data (%d)", tmp2); -- retval = 0; -- } -- } break; -- -- default: -- pm_message("unknown PBM version"); -- retval = 0; -- } -- } -- } -- return retval; -+ return 1; - } - -+static int getbytes(FILE *fptr,int width,unsigned char* data) -+{ -+ unsigned char mask,acc,*place; -+ int num; -+ -+ if(!width) return 0; -+ for(mask=0x80, acc=0, num=0, place=data; num>=1; -+ num++; -+ if(!mask) /* if(num%8 == 0) */ -+ { -+ *place++ = acc; -+ acc=0; -+ mask=0x80; -+ } -+ } -+ } -+ if(width%8) -+ *place=acc; -+ return 1; -+} - -+/* Reads a single line into data which must be at least (pbm->width+7)/8 -+ bytes of storage */ -+int pbm_readline(pbm_stat* pbm,unsigned char* data) -+{ -+ int tmp,tmp2; -+ -+ if(pbm->current_line >= pbm->height) return 0; -+ -+ if (pbm->unread) -+ { -+ memcpy (data, pbm->revdata, (pbm->width+7)/8); -+ pbm->current_line++; -+ pbm->unread = 0; -+ free (pbm->revdata); -+ pbm->revdata = NULL; -+ return 1; -+ } - --void --pbm_unreadline(pbm_stat * const pbmStatP, -- void * const data) { --/*---------------------------------------------------------------------------- -- Push a line back into the buffer; we read too much! -------------------------------------------------------------------------------*/ -- /* can store only one line in the unread buffer */ -- -- if (!pbmStatP->unread) { -- pbmStatP->unread = 1; -- pbmStatP->revdata = malloc ((pbmStatP->width+7)/8); -- memcpy(pbmStatP->revdata, data, (pbmStatP->width+7)/8); -- --pbmStatP->current_line; -+ switch(pbm->version) -+ { -+ case P1: -+ if(getbytes(pbm->fptr,pbm->width,data)) -+ { -+ pbm->current_line++; -+ return 1; - } --} -+ return 0; -+ -+ case P4: -+ overflow_add(pbm->width, 7); -+ tmp=(pbm->width+7)/8; -+ tmp2=fread(data,1,tmp,pbm->fptr); -+ if(tmp2 == tmp) -+ { -+ pbm->current_line++; -+ return 1; -+ } -+ fprintf(stderr,"pbm_readline(): error reading line data (%d)\n",tmp2); -+ return 0; - -+ default: -+ fprintf(stderr,"pbm_readline(): unknown PBM version\n"); -+ return 0; -+ } -+} - -+/* push a line back into the buffer; we read too much! */ -+void pbm_unreadline (pbm_stat *pbm, void *data) -+{ -+ /* can only store one line in the unread buffer */ -+ if (pbm->unread) -+ return; -+ -+ pbm->unread = 1; -+ overflow_add(pbm->width, 7); -+ pbm->revdata = malloc ((pbm->width+7)/8); -+ memcpy (pbm->revdata, data, (pbm->width+7)/8); -+ pbm->current_line--; -+} -diff --git a/converter/pbm/pbmtoppa/pbmtoppa.c b/converter/pbm/pbmtoppa/pbmtoppa.c -index ff4a599..aa510ec 100644 ---- a/converter/pbm/pbmtoppa/pbmtoppa.c -+++ b/converter/pbm/pbmtoppa/pbmtoppa.c -@@ -453,6 +453,7 @@ main(int argc, char *argv[]) { + if (!pbmStatP->unread) { + pbmStatP->unread = 1; ++ overflow_add(pbmStatP->width, 7); + pbmStatP->revdata = malloc ((pbmStatP->width+7)/8); + memcpy(pbmStatP->revdata, data, (pbmStatP->width+7)/8); + --pbmStatP->current_line; +diff -urNp a/converter/pbm/pbmtoppa/pbmtoppa.c b/converter/pbm/pbmtoppa/pbmtoppa.c +--- a/converter/pbm/pbmtoppa/pbmtoppa.c 2025-02-03 09:24:28.356500423 +0100 ++++ b/converter/pbm/pbmtoppa/pbmtoppa.c 2025-02-03 10:49:30.440158354 +0100 +@@ -456,6 +456,7 @@ main(int argc, char *argv[]) { pm_error("main(): unrecognized parameter '%s'", argv[argn]); } + overflow_add(Width, 7); - Pwidth=(Width+7)/8; - printer.fptr=out; + Pwidth = (Width+7)/8; + printer.fptr = ofP; -diff --git a/converter/pbm/pbmtoxbm.c b/converter/pbm/pbmtoxbm.c -index ecb72b3..fc0eb9c 100644 ---- a/converter/pbm/pbmtoxbm.c -+++ b/converter/pbm/pbmtoxbm.c -@@ -352,6 +352,8 @@ convertRaster(FILE * const ifP, - - unsigned char * bitrow; - unsigned int row; -+ -+ overflow_add(cols, padright); +diff -urNp a/converter/pbm/pbmtoxbm.c b/converter/pbm/pbmtoxbm.c +--- a/converter/pbm/pbmtoxbm.c 2025-02-03 09:24:28.357500417 +0100 ++++ b/converter/pbm/pbmtoxbm.c 2025-02-03 10:50:31.351873866 +0100 +@@ -370,6 +370,7 @@ convertRaster(FILE * const ifP, putinit(xbmVersion); -diff --git a/converter/pbm/pktopbm.c b/converter/pbm/pktopbm.c -index 712f339..b6fcb02 100644 ---- a/converter/pbm/pktopbm.c -+++ b/converter/pbm/pktopbm.c -@@ -280,6 +280,7 @@ main(int argc, char *argv[]) { - if (flagbyte == 7) { /* long form preamble */ - integer packetlength = get32() ; /* character packet length */ - car = get32() ; /* character number */ -+ overflow_add(packetlength, pktopbm_pkloc); - endofpacket = packetlength + pktopbm_pkloc; - /* calculate end of packet */ - if ((car >= MAXPKCHAR) || !filename[car]) { -diff --git a/converter/pbm/thinkjettopbm.l b/converter/pbm/thinkjettopbm.l -index 5de4f2b..7f31de5 100644 ---- a/converter/pbm/thinkjettopbm.l -+++ b/converter/pbm/thinkjettopbm.l -@@ -114,7 +114,9 @@ DIG [0-9] - \033\*b{DIG}+W { - int l; ++ overflow_add(cols, padright); + bitrow = pbm_allocrow_packed(cols + padright); + + for (row = 0; row < rows; ++row) { +diff -urNp a/converter/pbm/pktopbm.c b/converter/pbm/pktopbm.c +--- a/converter/pbm/pktopbm.c 2025-02-03 09:24:28.357500417 +0100 ++++ b/converter/pbm/pktopbm.c 2025-02-03 17:09:21.430572232 +0100 +@@ -454,6 +454,7 @@ readCharacterHeader(int * const + if (packetLength > UINT_MAX - pkLoc) + pm_error("Invalid character header - excessive packet length"); + ++ overflow_add(packetLength, pkLoc); + *endOfPacketP = packetLength + pkLoc; + + *cheightP = cheight; +diff -urNp a/converter/pbm/thinkjettopbm.l b/converter/pbm/thinkjettopbm.l +--- a/converter/pbm/thinkjettopbm.l 2025-02-03 09:24:28.359500407 +0100 ++++ b/converter/pbm/thinkjettopbm.l 2025-02-03 17:11:07.302725005 +0100 +@@ -117,6 +117,7 @@ DIG [0-9] if (rowCount >= rowCapacity) { -- rowCapacity += 100; -+ overflow_add(rowCapacity, 100); -+ rowCapacity += 100; -+ overflow2(rowCapacity, sizeof *rows); - rows = realloc (rows, rowCapacity * sizeof *rows); + if (rowCapacity > INT_MAX-100) + pm_error("Too many rows to count"); ++ overflow_add(rowCapacity, 100); + rowCapacity += 100; + REALLOCARRAY(rows, rowCapacity); if (rows == NULL) - pm_error ("Out of memory."); -@@ -226,6 +228,8 @@ yywrap (void) +@@ -232,6 +233,7 @@ yywrap (void) /* * Quite simple since ThinkJet bit arrangement matches PBM */ -+ + overflow2(maxRowLength, 8); pbm_writepbminit(stdout, maxRowLength*8, rowCount, 0); packed_bitrow = malloc(maxRowLength); -diff --git a/converter/pbm/ybmtopbm.c b/converter/pbm/ybmtopbm.c -index 2a42908..cf1ff03 100644 ---- a/converter/pbm/ybmtopbm.c -+++ b/converter/pbm/ybmtopbm.c -@@ -43,6 +43,7 @@ getinit(FILE * const ifP, - pm_error("EOF / read error"); +diff -urNp a/converter/pbm/ybmtopbm.c b/converter/pbm/ybmtopbm.c +--- a/converter/pbm/ybmtopbm.c 2025-02-03 09:24:28.359500407 +0100 ++++ b/converter/pbm/ybmtopbm.c 2025-02-03 17:17:57.638369880 +0100 +@@ -88,8 +88,12 @@ main(int argc, const char * argv[]) { - *depthP = 1; -+ overflow_add(*colsP, 15); - } + pbm_writepbminit(stdout, cols, rows, 0); - -diff --git a/converter/pgm/lispmtopgm.c b/converter/pgm/lispmtopgm.c -index 40dd3fb..b5469f7 100644 ---- a/converter/pgm/lispmtopgm.c -+++ b/converter/pgm/lispmtopgm.c -@@ -58,6 +58,7 @@ main( argc, argv ) - pm_error( "depth (%d bits) is too large", depth); - - pgm_writepgminit( stdout, cols, rows, (gray) maxval, 0 ); -+ overflow_add(cols, 7); - grayrow = pgm_allocrow( ( cols + 7 ) / 8 * 8 ); - - for ( row = 0; row < rows; ++row ) -@@ -102,6 +103,8 @@ getinit( file, colsP, rowsP, depthP, padrightP ) - - if ( *depthP == 0 ) - *depthP = 1; /* very old file */ ++ overflow_add(cols, 8); + -+ overflow_add((int)colsP, 31); - - *padrightP = ( ( *colsP + 31 ) / 32 ) * 32 - *colsP; - -diff --git a/converter/pgm/psidtopgm.c b/converter/pgm/psidtopgm.c -index 07417d1..25bb311 100644 ---- a/converter/pgm/psidtopgm.c -+++ b/converter/pgm/psidtopgm.c -@@ -78,6 +78,7 @@ main(int argc, - pm_error("bits/sample (%d) is too large.", bitspersample); + bitrow = pbm_allocrow_packed(cols + 8); - pgm_writepgminit(stdout, cols, rows, maxval, 0); -+ overflow_add(cols, 7); - grayrow = pgm_allocrow((cols + 7) / 8 * 8); ++ overflow_add(cols, 15); ++ for (row = 0; row < rows; ++row) { - unsigned int col; -diff --git a/converter/ppm/Makefile b/converter/ppm/Makefile -index 003ef8d..b97349d 100644 ---- a/converter/ppm/Makefile -+++ b/converter/ppm/Makefile + uint16_t * const itemrow = (uint16_t *) bitrow; + unsigned int const itemCt = (cols + 15) / 16; +diff -urNp a/converter/ppm/ilbmtoppm.c b/converter/ppm/ilbmtoppm.c +--- a/converter/ppm/ilbmtoppm.c 2025-02-03 09:24:28.330500563 +0100 ++++ b/converter/ppm/ilbmtoppm.c 2025-02-03 18:06:05.606638402 +0100 +@@ -1385,6 +1385,9 @@ dcol_to_ppm(FILE * const ifP, + if (redmaxval != maxval || greenmaxval != maxval || bluemaxval != maxval) + pm_message("scaling colors to %u bits", pm_maxvaltobits(maxval)); + ++ overflow_add(redmaxval, 1); ++ overflow_add(greenmaxval, 1); ++ overflow_add(bluemaxval, 1); + MALLOCARRAY_NOFAIL(redtable, redmaxval + 1); + MALLOCARRAY_NOFAIL(greentable, greenmaxval + 1); + MALLOCARRAY_NOFAIL(bluetable, bluemaxval + 1); +@@ -1875,12 +1878,14 @@ PCHG_ConvertSmall(PCHGHeader * const + else { + unsigned int const changeCt16 = *dataCursor++; + unsigned int const changeCt32 = *dataCursor++; ++ overflow_add(changeCt16, changeCt32); + unsigned int const changeCt = changeCt16 + changeCt32; + + unsigned int i; + + remDataSize -= 2; + ++ overflow_add(changeCt, 1); + MALLOCARRAY_NOFAIL(cmapP->mp_change[row], changeCt + 1); + for (i = 0; i < changeCt; ++i) { + if (totalChangeCt >= pchgP->TotalChanges) goto fail; +@@ -2122,6 +2127,7 @@ read_pchg(FILE * const ifP, + "is less than minreg (%u)", + PCHG.MaxReg, PCHG.MinReg); + else { ++ overflow_add(PCHG.MaxReg-PCHG.MinReg, 2); + unsigned int const nch = PCHG.MaxReg - PCHG.MinReg + 1; + + unsigned int i; +diff -urNp a/converter/ppm/imgtoppm.c b/converter/ppm/imgtoppm.c +--- a/converter/ppm/imgtoppm.c 2025-02-03 09:24:28.330500563 +0100 ++++ b/converter/ppm/imgtoppm.c 2025-02-03 18:10:34.478961449 +0100 +@@ -85,6 +85,7 @@ main(int argc, const char ** argv) { + len = atoi((char*) buf); + if (fread(buf, len, 1, ifP) != 1) + pm_error("bad colormap buf"); ++ overflow2(cmaplen, 3); + if (len != cmaplen * 3) { + pm_message( + "cmaplen (%u) and colormap buf length (%u) do not match", +@@ -105,6 +106,7 @@ main(int argc, const char ** argv) { + pm_error("bad pixel data header"); + buf[8] = '\0'; + len = atoi((char*) buf); ++ overflow2(cols, rows); + if (len != cols * rows) + pm_message( + "pixel data length (%u) does not match image size (%u)", +diff -urNp a/converter/ppm/Makefile b/converter/ppm/Makefile +--- a/converter/ppm/Makefile 2025-02-03 09:24:28.331500558 +0100 ++++ b/converter/ppm/Makefile 2025-02-03 17:39:13.338685028 +0100 @@ -11,7 +11,7 @@ SUBDIRS = hpcdtoppm ppmtompeg PORTBINARIES = 411toppm eyuvtoppm gouldtoppm ilbmtoppm imgtoppm \ @@ -2162,586 +387,84 @@ index 003ef8d..b97349d 100644 ppmtoacad ppmtoapplevol ppmtoarbtxt ppmtoascii \ ppmtobmp ppmtoeyuv ppmtogif ppmtoicr ppmtoilbm \ ppmtoleaf ppmtolj ppmtomitsu ppmtoneo \ -diff --git a/converter/ppm/ilbmtoppm.c b/converter/ppm/ilbmtoppm.c -index b9b8986..f4fe331 100644 ---- a/converter/ppm/ilbmtoppm.c -+++ b/converter/ppm/ilbmtoppm.c -@@ -608,6 +608,7 @@ decode_row(FILE * const ifP, - rawtype *chp; +diff -urNp a/converter/ppm/pcxtoppm.c b/converter/ppm/pcxtoppm.c +--- a/converter/ppm/pcxtoppm.c 2025-02-03 09:24:28.329500569 +0100 ++++ b/converter/ppm/pcxtoppm.c 2025-02-03 18:12:34.245400166 +0100 +@@ -378,6 +378,7 @@ pcxPlanesToPixels(unsigned char * const + to conceive how this subroutine should work with other numbers of bits per + sample, but it doesn't. + -----------------------------------------------------------------------------*/ ++ overflow2(bytesPerLine, 8); + unsigned int const pixelCt = bytesPerLine * 8; - cols = bmhdP->w; -+ overflow_add(cols, 15); - bytes = RowBytes(cols); - for( plane = 0; plane < nPlanes; plane++ ) { - int mask; -@@ -695,6 +696,23 @@ decode_mask(FILE * const ifP, - Multipalette handling - ****************************************************************************/ - -+static void * -+xmalloc2(x, y) -+ int x; -+ int y; -+{ -+ void *mem; -+ -+ overflow2(x,y); -+ if( x * y == 0 ) -+ return NULL; -+ -+ mem = malloc2(x,y); -+ if( mem == NULL ) -+ pm_error("out of memory allocating %d bytes", x * y); -+ return mem; -+} -+ - - static void - multi_adjust(ColorMap * const cmapP, -@@ -1363,6 +1381,9 @@ dcol_to_ppm(FILE * const ifP, - if( redmaxval != maxval || greenmaxval != maxval || bluemaxval != maxval ) - pm_message("scaling colors to %d bits", pm_maxvaltobits(maxval)); - -+ overflow_add(redmaxval, 1); -+ overflow_add(greenmaxval, 1); -+ overflow_add(bluemaxval, 1); - MALLOCARRAY_NOFAIL(redtable, redmaxval +1); - MALLOCARRAY_NOFAIL(greentable, greenmaxval +1); - MALLOCARRAY_NOFAIL(bluetable, bluemaxval +1); -@@ -1802,7 +1823,9 @@ PCHG_ConvertSmall(PCHGHeader * const pchgP, - ChangeCount32 = *data++; - remDataSize -= 2; - -+ overflow_add(ChangeCount16, ChangeCount32); - changes = ChangeCount16 + ChangeCount32; -+ overflow_add(changes, 1); - for (i = 0; i < changes; ++i) { - if (totalchanges >= pchgP->TotalChanges) goto fail; - if (remDataSize < 2) goto fail; -@@ -2067,6 +2090,9 @@ read_pchg(FILE * const ifP, - cmap->mp_change[i] = NULL; - if( PCHG.StartLine < 0 ) { - int nch; -+ if(PCHG.MaxReg < PCHG.MinReg) -+ pm_error("assert: MinReg > MaxReg"); -+ overflow_add(PCHG.MaxReg-PCHG.MinReg, 2); - nch = PCHG.MaxReg - PCHG.MinReg +1; - MALLOCARRAY_NOFAIL(cmap->mp_init, nch + 1); - for( i = 0; i < nch; i++ ) -@@ -2143,6 +2169,7 @@ process_body( FILE * const ifP, - if (typeid == ID_ILBM) { - int isdeep; - -+ overflow_add(bmhdP->w, 15); - MALLOCARRAY_NOFAIL(ilbmrow, RowBytes(bmhdP->w)); - *viewportmodesP |= fakeviewport; /* -isham/-isehb */ - -diff --git a/converter/ppm/ilbmtoppm.c.rej b/converter/ppm/ilbmtoppm.c.rej -new file mode 100644 -index 0000000..972cad0 ---- /dev/null -+++ b/converter/ppm/ilbmtoppm.c.rej -@@ -0,0 +1,46 @@ -+--- converter/ppm/ilbmtoppm.c -++++ converter/ppm/ilbmtoppm.c -+@@ -694,6 +695,23 @@ decode_mask(FILE * const ifP, -+ Multipalette handling -+ ****************************************************************************/ -+ -++static void * -++xmalloc2(x, y) -++ int x; -++ int y; -++{ -++ void *mem; -++ -++ overflow2(x,y); -++ if( x * y == 0 ) -++ return NULL; -++ -++ mem = malloc2(x,y); -++ if( mem == NULL ) -++ pm_error("out of memory allocating %d bytes", x * y); -++ return mem; -++} -++ -+ -+ static void -+ multi_adjust(cmap, row, palchange) -+@@ -1356,6 +1374,9 @@ dcol_to_ppm(FILE * const ifP, -+ if( redmaxval != maxval || greenmaxval != maxval || bluemaxval != maxval ) -+ pm_message("scaling colors to %d bits", pm_maxvaltobits(maxval)); -+ -++ overflow_add(redmaxval, 1); -++ overflow_add(greenmaxval, 1); -++ overflow_add(bluemaxval, 1); -+ MALLOCARRAY_NOFAIL(redtable, redmaxval +1); -+ MALLOCARRAY_NOFAIL(greentable, greenmaxval +1); -+ MALLOCARRAY_NOFAIL(bluetable, bluemaxval +1); -+@@ -1785,7 +1806,9 @@ PCHG_ConvertSmall(PCHG, cmap, mask, datasize) -+ ChangeCount32 = *data++; -+ datasize -= 2; -+ -++ overflow_add(ChangeCount16, ChangeCount32); -+ changes = ChangeCount16 + ChangeCount32; -++ overflow_add(changes, 1); -+ for( i = 0; i < changes; i++ ) { -+ if( totalchanges >= PCHG->TotalChanges ) goto fail; -+ if( datasize < 2 ) goto fail; -diff --git a/converter/ppm/imgtoppm.c b/converter/ppm/imgtoppm.c -index 7078b88..eb8509e 100644 ---- a/converter/ppm/imgtoppm.c -+++ b/converter/ppm/imgtoppm.c -@@ -84,6 +84,7 @@ main(int argc, char ** argv) { - len = atoi((char*) buf ); - if ( fread( buf, len, 1, ifp ) != 1 ) - pm_error( "bad colormap buf" ); -+ overflow2(cmaplen, 3); - if ( cmaplen * 3 != len ) - { - pm_message( -@@ -105,6 +106,7 @@ main(int argc, char ** argv) { - pm_error( "bad pixel data header" ); - buf[8] = '\0'; - len = atoi((char*) buf ); -+ overflow2(cols, rows); - if ( len != cols * rows ) - pm_message( - "pixel data length (%d) does not match image size (%d)", -diff --git a/converter/ppm/pcxtoppm.c b/converter/ppm/pcxtoppm.c -index e252ba2..270ae3b 100644 ---- a/converter/ppm/pcxtoppm.c -+++ b/converter/ppm/pcxtoppm.c -@@ -409,6 +409,7 @@ pcx_planes_to_pixels(pixels, bitplanes, bytesperline, planes, bitsperpixel) - /* - * clear the pixel buffer - */ -+ overflow2(bytesperline, 8); - npixels = (bytesperline * 8) / bitsperpixel; - p = pixels; - while (--npixels >= 0) -@@ -470,6 +471,7 @@ pcx_16col_to_ppm(FILE * const ifP, + unsigned int bitPlanesIdx; +diff -urNp a/converter/ppm/pjtoppm.c b/converter/ppm/pjtoppm.c +--- a/converter/ppm/pjtoppm.c 2025-02-03 09:24:28.329500569 +0100 ++++ b/converter/ppm/pjtoppm.c 2025-02-03 18:21:28.636228030 +0100 +@@ -77,6 +77,7 @@ modifyImageMode1(unsigned int const + val = image[plane + row * planes][col+1]; + cmd >= 0 && i < newcols; --cmd, ++i) + buf[i] = val; ++ overflow_add(i, 1); + } + cols = MAX(cols, i); + free(image[row * planes + plane]); +@@ -90,6 +91,7 @@ modifyImageMode1(unsigned int const + } + } } - - /* BytesPerLine should be >= BitsPerPixel * cols / 8 */ -+ overflow2(BytesPerLine, 8); - rawcols = BytesPerLine * 8 / BitsPerPixel; - if (headerCols > rawcols) { - pm_message("warning - BytesPerLine = %d, " -diff --git a/converter/ppm/picttoppm.c b/converter/ppm/picttoppm.c -index 4bc5337..a5a0ad5 100644 ---- a/converter/ppm/picttoppm.c -+++ b/converter/ppm/picttoppm.c -@@ -1,3 +1,4 @@ -+#error "Unfixable. Don't ship me" - /* - * picttoppm.c -- convert a MacIntosh PICT file to PPM format. - * -diff --git a/converter/ppm/pjtoppm.c b/converter/ppm/pjtoppm.c -index e556803..c458c06 100644 ---- a/converter/ppm/pjtoppm.c -+++ b/converter/ppm/pjtoppm.c -@@ -10,98 +10,66 @@ - ** implied warranty. - */ - --#include -- - #include "ppm.h" --#include "pm_c_util.h" - #include "mallocvar.h" - - static char usage[] = "[paintjetfile]"; - -- -- --static unsigned int --uintProduct(unsigned int const multiplicand, -- unsigned int const multiplier) { -- -- if (UINT_MAX / multiplier < multiplicand) -- pm_error("Airthmetic overflow"); -- -- return multiplicand * multiplier; --} -- -- -- -+static int egetc ARGS((FILE *fp)); - static int --egetc(FILE * const ifP) { -+egetc(fp) -+ FILE *fp; -+{ - int c; -- -- c = fgetc(ifP); -- -- if (c == -1) -+ if ((c = fgetc(fp)) == -1) - pm_error("unexpected end of file"); -- -- return c; -+ return(c); ++ overflow2(cols, 8); + *colsP = cols * 8; assert(cols < UINT_MAX/8); } -- -- - int --main(int argc, const char ** argv) { -- -+main(argc, argv) -+ int argc; -+ char *argv[]; -+{ - int cmd, val; - char buffer[BUFSIZ]; -- int planes = 3; -- unsigned int rows; -- unsigned int rowsX; -- unsigned int cols; -- bool colsIsSet; -+ int planes = 3, rows = -1, cols = -1; -+ int r = 0, c = 0, p = 0, i; - unsigned char **image = NULL; - int *imlen; -- FILE * ifP; -+ FILE *fp = stdin; - int mode; -- bool modeIsSet; - int argn; - unsigned char bf[3]; -- pixel * pixrow; -- int c; -- int row; -- int plane; -+ pixel *pixrow; - -- pm_proginit(&argc, argv); - -+ ppm_init(&argc, argv); - argn = 1; - if (argn != argc) -- ifP = pm_openr(argv[argn++]); -+ fp = pm_openr(argv[argn++]); - else -- ifP = stdin; -+ fp = stdin; - - if (argn != argc) - pm_usage(usage); - -- row = 0; /* initial value */ -- plane = 0; /* initial value */ -- modeIsSet = false; /* initial value */ -- colsIsSet = false; /* initial value */ -- rowsX = 0; /* initial value */ -- -- while ((c = fgetc(ifP)) != -1) { -+ while ((c = fgetc(fp)) != -1) { - if (c != '\033') - continue; -- switch (c = egetc(ifP)) { -+ switch (c = egetc(fp)) { - case 'E': /* reset */ - break; -- case '*': { -- unsigned int i; -- cmd = egetc(ifP); -+ case '*': -+ cmd = egetc(fp); - for (i = 0; i < BUFSIZ; i++) { -- if (!isdigit(c = egetc(ifP)) && c != '+' && c != '-') -+ if (!isdigit(c = egetc(fp)) && c != '+' && c != '-') - break; - buffer[i] = c; - } - if (i != 0) { - buffer[i] = '\0'; -- if (sscanf(buffer, "%d", &val) != 1) -+ if (sscanf(buffer, "%d", &val) != 1) - pm_error("bad value `%s' at *%c%c", buffer, cmd, c); - } - else -@@ -125,18 +93,18 @@ main(int argc, const char ** argv) { - case 'r': - switch (c) { - case 'S': /* width */ -- if (val < 0) -+ if (val < 0) { - pm_error("invalid width value"); -- else { -+ } else { - cols = val; -- colsIsSet = true; - } - break; - case 'T': /* height */ -- if (val < 0) -+ if (val < 0) { - pm_error ("invalid height value"); -- else -- rowsX = val; -+ } else { -+ rows = val; -+ } - break; - case 'U': /* planes */ - planes = val; -@@ -163,40 +131,43 @@ main(int argc, const char ** argv) { - if (val != 0 && val != 1) - pm_error("unimplemented transmission mode %d", val); - mode = val; -- modeIsSet = true; - break; +@@ -265,8 +267,10 @@ main(int argc, const char ** argv) { case 'V': /* send plane */ case 'W': /* send last plane */ -- if (row >= rowsX || image == NULL) { + if (row >= rowsX || image == NULL) { - if (row >= rowsX) -- rowsX += 100; -+ if (rows == -1 || r >= rows || image == NULL) { -+ if (rows == -1 || r >= rows) { ++ if (row >= rowsX) { + overflow_add(rows, 100); -+ rows += 100; + rowsX += 100; + } -+ - if (image == NULL) { -- MALLOCARRAY(image, uintProduct(rowsX, planes)); -- MALLOCARRAY(imlen, uintProduct(rowsX, planes)); -- } else { -- REALLOCARRAY(image, uintProduct(rowsX, planes)); -- REALLOCARRAY(imlen, uintProduct(rowsX, planes)); -+ image = (unsigned char **) -+ malloc3(rows , planes , sizeof(unsigned char *)); -+ imlen = (int *) malloc3(rows , planes, sizeof(int)); - } -+ else { -+ overflow2(rows,planes); -+ image = (unsigned char **) -+ realloc2(image, rows * planes, -+ sizeof(unsigned char *)); -+ imlen = (int *) realloc2(imlen, rows * planes, sizeof(int)); } + REALLOCARRAY(image, uintProduct(rowsX, planes)); + REALLOCARRAY(imlen, uintProduct(rowsX, planes)); } - if (image == NULL || imlen == NULL) - pm_error("out of memory"); -- if (plane >= planes) -+ if (p == planes) - pm_error("too many planes"); -- if (!colsIsSet) -- pm_error("missing width value"); -- -- cols = MAX(cols, val); -- imlen[row * planes + plane] = val; -- MALLOCARRAY(image[row * planes + plane], val); -- if (image[row * planes + plane] == NULL) -+ cols = cols > val ? cols : val; -+ imlen[r * planes + p] = val; -+ MALLOCARRAY(image[r * planes + p], val); -+ if (image[r * planes + p] == NULL) - pm_error("out of memory"); -- if (fread(image[row * planes + plane], 1, val, ifP) != val) -+ if (fread(image[r * planes + p], 1, val, fp) != val) - pm_error("short data"); - if (c == 'V') -- ++plane; -+ p++; - else { -- plane = 0; -- ++row; -+ p = 0; -+ r++; - } - break; - default: -@@ -205,7 +176,7 @@ main(int argc, const char ** argv) { - } - break; - case 'p': /* Position */ -- if (plane != 0) -+ if (p != 0) - pm_error("changed position in the middle of " - "transferring planes"); - switch (c) { -@@ -214,15 +185,15 @@ main(int argc, const char ** argv) { - break; - case 'Y': - if (buffer[0] == '+') -- val = row + val; -+ val = r + val; - if (buffer[0] == '-') -- val = row - val; -- for (; val > row; ++row) -- for (plane = 0; plane < 3; ++plane) { -- imlen[row * planes + plane] = 0; -- image[row * planes + plane] = NULL; -+ val = r - val; -+ for (; val > r; r++) -+ for (p = 0; p < 3; p++) { -+ imlen[r * planes + p] = 0; -+ image[r * planes + p] = NULL; - } -- row = val; -+ r = val; - break; - default: - pm_message("uninmplemented *%c%d%c", cmd, val, c); -@@ -231,86 +202,65 @@ main(int argc, const char ** argv) { - default: - pm_message("uninmplemented *%c%d%c", cmd, val, c); - break; -- } -- } /* case */ -- } /* switch */ -+ } -+ } - } -- pm_close(ifP); -- -- if (!modeIsSet) -- pm_error("Input does not contain a 'bM' transmission mode order"); -- -- rows = row; -+ pm_close(fp); -+ rows = r; - if (mode == 1) { -- unsigned int const newcols = 10240; -- /* It could not be larger than that! */ -- -- unsigned char * buf; -- unsigned int row; -- -- for (row = 0, cols = 0; row < rows; ++row) { -- unsigned int plane; -- if (image[row * planes] == NULL) -+ unsigned char *buf; -+ int newcols = 0; -+ newcols = 10240; /* It could not be larger that that! */ -+ cols = 0; -+ for (r = 0; r < rows; r++) { -+ if (image[r * planes] == NULL) - continue; -- for (plane = 0; plane < planes; ++plane) { -- unsigned int i; -- unsigned int col; -+ for (p = 0; p < planes; p++) { - MALLOCARRAY(buf, newcols); -- if (buf == NULL) -+ if (buf == NULL) - pm_error("out of memory"); -- for (i = 0, col = 0; -- col < imlen[plane + row * planes]; -- col += 2) -- for (cmd = image[plane + row * planes][col], -- val = image[plane + row * planes][col+1]; -- cmd >= 0 && i < newcols; cmd--, i++) -+ for (i = 0, c = 0; c < imlen[p + r * planes]; c += 2) -+ for (cmd = image[p + r * planes][c], -+ val = image[p + r * planes][c+1]; -+ cmd >= 0 && i < newcols; cmd--, i++) { - buf[i] = val; -- cols = MAX(cols, i); -- free(image[plane + row * planes]); -- /* -- * This is less than what we have so it realloc should -+ overflow_add(i, 1); -+ } -+ cols = cols > i ? cols : i; -+ free(image[p + r * planes]); -+ /* -+ * This is less than what we have so it realloc should - * not return null. Even if it does, tough! We will - * lose a line, and probably die on the next line anyway - */ -- image[plane + row * planes] = realloc(buf, i); -+ image[p + r * planes] = (unsigned char *) realloc(buf, i); - } - } -+ overflow2(cols, 8); - cols *= 8; - } -- -+ -+ - ppm_writeppminit(stdout, cols, rows, (pixval) 255, 0); - pixrow = ppm_allocrow(cols); -- -- for (row = 0; row < rows; ++row) { -- if (image[row * planes] == NULL) { -- unsigned int col; -- for (col = 0; col < cols; ++col) -- PPM_ASSIGN(pixrow[col], 0, 0, 0); -+ for (r = 0; r < rows; r++) { -+ if (image[r * planes] == NULL) { -+ for (c = 0; c < cols; c++) -+ PPM_ASSIGN(pixrow[c], 0, 0, 0); - continue; - } -- { -- unsigned int col; -- unsigned int cmd; -- for (cmd = 0, col = 0; col < cols; col += 8, ++cmd) { -- unsigned int i; -- for (i = 0; i < 8 && col + i < cols; ++i) { -- unsigned int plane; -- for (plane = 0; plane < planes; ++plane) -- if (mode == 0 && cmd >= imlen[row * planes + plane]) -- bf[plane] = 0; -- else -- bf[plane] = (image[row * planes + plane][cmd] & -- (1 << (7 - i))) ? 255 : 0; -- PPM_ASSIGN(pixrow[col + i], bf[0], bf[1], bf[2]); -- } -+ for (cmd = 0, c = 0; c < cols; c += 8, cmd++) -+ for (i = 0; i < 8 && c + i < cols; i++) { -+ for (p = 0; p < planes; p++) -+ if (mode == 0 && cmd >= imlen[r * planes + p]) -+ bf[p] = 0; -+ else -+ bf[p] = (image[r * planes + p][cmd] & -+ (1 << (7 - i))) ? 255 : 0; -+ PPM_ASSIGN(pixrow[c + i], bf[0], bf[1], bf[2]); - } -- } -- ppm_writeppmrow(stdout, pixrow, cols, 255, 0); -+ ppm_writeppmrow(stdout, pixrow, cols, (pixval) 255, 0); - } - pm_close(stdout); -- -- return 0; -+ exit(0); - } -- -- -- -diff --git a/converter/ppm/ppmtoeyuv.c b/converter/ppm/ppmtoeyuv.c -index f5ce115..6f072be 100644 ---- a/converter/ppm/ppmtoeyuv.c -+++ b/converter/ppm/ppmtoeyuv.c -@@ -114,6 +114,7 @@ create_multiplication_tables(const pixval maxval) { +@@ -277,6 +281,8 @@ main(int argc, const char ** argv) { + if (!colsIsSet) + pm_error("missing width value"); - int index; ++ overflow2(rows,planes); ++ overflow_add(rows * planes, plane); + cols = MAX(cols, val); + imlen[row * planes + plane] = val; + MALLOCARRAY(image[row * planes + plane], val); +diff -urNp a/converter/ppm/ppmtoeyuv.c b/converter/ppm/ppmtoeyuv.c +--- a/converter/ppm/ppmtoeyuv.c 2025-02-03 09:24:28.330500563 +0100 ++++ b/converter/ppm/ppmtoeyuv.c 2025-02-03 18:22:08.012087384 +0100 +@@ -117,6 +117,7 @@ chrominanceBlue(pixel const p) { + static void + createMultiplicationTables(pixval const maxval) { + overflow_add(maxval, 1); MALLOCARRAY_NOFAIL(mult299 , maxval+1); MALLOCARRAY_NOFAIL(mult587 , maxval+1); MALLOCARRAY_NOFAIL(mult114 , maxval+1); -diff --git a/converter/ppm/ppmtolj.c b/converter/ppm/ppmtolj.c -index 7ed814e..b4e7db1 100644 ---- a/converter/ppm/ppmtolj.c -+++ b/converter/ppm/ppmtolj.c -@@ -182,6 +182,7 @@ int main(int argc, char *argv[]) { - ppm_readppminit( ifp, &cols, &rows, &maxval, &format ); - pixelrow = ppm_allocrow( cols ); +diff -urNp a/converter/ppm/ppmtolj.c b/converter/ppm/ppmtolj.c +--- a/converter/ppm/ppmtolj.c 2025-02-03 09:24:28.330500563 +0100 ++++ b/converter/ppm/ppmtolj.c 2025-02-03 18:24:55.523489226 +0100 +@@ -212,6 +212,8 @@ printRaster(FILE * const ifP, + pm_error("Image is uncomputably wide (%u columns)", cols); + } + overflow2(cols, 6); ++ obuf = (unsigned char *) pm_allocrow(cols * 3, sizeof(unsigned char)); cbuf = (unsigned char *) pm_allocrow(cols * 6, sizeof(unsigned char)); - if (mode == C_TRANS_MODE_DELTA) -diff --git a/converter/ppm/ppmtomitsu.c b/converter/ppm/ppmtomitsu.c -index 50b790d..63d3182 100644 ---- a/converter/ppm/ppmtomitsu.c -+++ b/converter/ppm/ppmtomitsu.c -@@ -685,6 +685,8 @@ main(int argc, char * argv[]) { + +diff -urNp a/converter/ppm/ppmtomitsu.c b/converter/ppm/ppmtomitsu.c +--- a/converter/ppm/ppmtomitsu.c 2025-02-03 09:24:28.331500558 +0100 ++++ b/converter/ppm/ppmtomitsu.c 2025-02-03 18:27:10.691006400 +0100 +@@ -68,6 +68,8 @@ mediaSize(const char * const media, medias = MSize_User; if (dpi300) { @@ -2750,1390 +473,145 @@ index 50b790d..63d3182 100644 medias.maxcols *= 2; medias.maxrows *= 2; } -diff --git a/converter/ppm/ppmtopcx.c b/converter/ppm/ppmtopcx.c -index 5b7e100..e7b06ff 100644 ---- a/converter/ppm/ppmtopcx.c -+++ b/converter/ppm/ppmtopcx.c -@@ -31,13 +31,13 @@ - #define PCX_MAXVAL (pixval)255 +diff -urNp a/converter/ppm/ppmtopcx.c b/converter/ppm/ppmtopcx.c +--- a/converter/ppm/ppmtopcx.c 2025-02-03 09:24:28.330500563 +0100 ++++ b/converter/ppm/ppmtopcx.c 2025-02-03 18:31:08.699156362 +0100 +@@ -314,6 +314,8 @@ writeHeader(FILE * const of + putbyte(0, ofP); /* reserved byte */ + putbyte(planes, ofP); /* number of color planes */ ++ overflow2(bitsPerPixel, cols); ++ overflow_add(bitsPerPixel * cols, 7); + bytesPerLine = ((cols * bitsPerPixel) + 7) / 8; + putword(bytesPerLine, ofP); /* number of bytes per scanline */ --struct CmdlineInfo { -+struct cmdlineInfo { - /* All the information the user supplied in the command line, - in a form easy for the program to use. - */ -- const char * inputFilespec; /* '-' if stdin */ -+ const char *inputFilespec; /* '-' if stdin */ - unsigned int truecolor; /* -24bit option */ -- unsigned int use8Bit; /* -8bit option */ -+ unsigned int use_8_bit; /* -8bit option */ - unsigned int planes; /* zero means minimum */ - unsigned int packed; - unsigned int verbose; -@@ -49,16 +49,16 @@ struct CmdlineInfo { - - - --struct PcxCmapEntry { -+struct pcxCmapEntry { - unsigned char r; - unsigned char g; - unsigned char b; - }; - --static struct PcxCmapEntry -+static struct pcxCmapEntry - pcxCmapEntryFromPixel(pixel const colorPixel) { - -- struct PcxCmapEntry retval; -+ struct pcxCmapEntry retval; - - retval.r = PPM_GETR(colorPixel); - retval.g = PPM_GETG(colorPixel); -@@ -70,8 +70,8 @@ pcxCmapEntryFromPixel(pixel const colorPixel) { - - - static void --parseCommandLine(int argc, const char ** argv, -- struct CmdlineInfo * const cmdlineP) { -+parseCommandLine(int argc, 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. -@@ -82,7 +82,7 @@ parseCommandLine(int argc, const char ** argv, - 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; -+ optEntry *option_def; - /* Instructions to pm_optParseOptions3 on how to parse our options. - */ - optStruct3 opt; -@@ -97,7 +97,7 @@ parseCommandLine(int argc, const char ** argv, - OPTENT3(0, "24bit", OPT_FLAG, NULL, - &cmdlineP->truecolor, 0); - OPTENT3(0, "8bit", OPT_FLAG, NULL, -- &cmdlineP->use8Bit, 0); -+ &cmdlineP->use_8_bit, 0); - OPTENT3(0, "planes", OPT_UINT, &cmdlineP->planes, - &planesSpec, 0); - OPTENT3(0, "packed", OPT_FLAG, NULL, -@@ -115,7 +115,7 @@ parseCommandLine(int argc, const char ** argv, - opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ - opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ - -- pm_optParseOptions3( &argc, (char **)argv, opt, sizeof(opt), 0 ); -+ pm_optParseOptions3( &argc, argv, opt, sizeof(opt), 0 ); - /* Uses and sets argc, argv, and some of *cmdline_p and others. */ - - if (!xposSpec) -@@ -141,7 +141,7 @@ parseCommandLine(int argc, const char ** argv, - pm_error("-planes is meaningless with -packed."); - if (cmdlineP->truecolor) - pm_error("-planes is meaningless with -24bit"); -- if (cmdlineP->use8Bit) -+ if (cmdlineP->use_8_bit) - pm_error("-planes is meaningless with -8bit"); +diff -urNp a/converter/ppm/ppmtopict.c b/converter/ppm/ppmtopict.c +--- a/converter/ppm/ppmtopict.c 2025-02-03 09:24:28.330500563 +0100 ++++ b/converter/ppm/ppmtopict.c 2025-02-03 18:41:02.377096627 +0100 +@@ -394,6 +394,9 @@ writeRaster(FILE * const ofP, + pm_error("Image is too wide (%u columns) for computation", cols); } -@@ -151,7 +151,7 @@ parseCommandLine(int argc, const char ** argv, - if (!paletteSpec) - cmdlineP->palette = NULL; - -- if (cmdlineP->use8Bit && cmdlineP->truecolor) -+ if (cmdlineP->use_8_bit && cmdlineP->truecolor) - pm_error("You cannot specify both -8bit and -truecolor"); - - if (argc-1 < 1) -@@ -172,8 +172,8 @@ parseCommandLine(int argc, const char ** argv, - * Write out a two-byte little-endian word to the PCX file - */ - static void --putword(unsigned int const w, -- FILE * const fp) { -+Putword(int const w, -+ FILE * const fp) { - - int rc; - -@@ -189,13 +189,12 @@ putword(unsigned int const w, - * Write out a byte to the PCX file - */ - static void --putbyte(unsigned int const b, -- FILE * const ofP) { -+Putbyte(int const b, -+ FILE * const fp) { - - int rc; - -- rc = fputc(b & 0xff, ofP); -- -+ rc = fputc(b & 0xff, fp); - if (rc == EOF) - pm_error("Error writing byte to output file."); - } -@@ -204,9 +203,9 @@ putbyte(unsigned int const b, - - static void - extractPlane(unsigned char * const rawrow, -- unsigned int const cols, -+ int const cols, - unsigned char * const buf, -- unsigned int const plane) { -+ int const plane) { - /*---------------------------------------------------------------------------- - From the image row 'rawrow', which is an array of 'cols' palette indices - (as unsigned 8 bit integers), extract plane number 'plane' and return -@@ -224,7 +223,9 @@ extractPlane(unsigned char * const rawrow, - - cp = buf; /* initial value */ - -- for (col = 0, cbit = 7, byteUnderConstruction = 0x00; col < cols; ++col) { -+ cbit = 7; -+ byteUnderConstruction = 0x00; -+ for (col = 0; col < cols; ++col) { - if (rawrow[col] & planeMask) - byteUnderConstruction |= (1 << cbit); - -@@ -246,17 +247,14 @@ extractPlane(unsigned char * const rawrow, - - - static void --packBits(unsigned char * const rawrow, -- unsigned int const width, -+PackBits(unsigned char * const rawrow, -+ int const width, - unsigned char * const buf, -- unsigned int const bits) { -+ int const bits) { - -- unsigned int x; -- int i; -- int shift; -+ int x, i, shift; - -- shift = -1; -- i = -1; -+ shift = i = -1; - - for (x = 0; x < width; ++x) { - if (shift < 0) { -@@ -272,73 +270,71 @@ packBits(unsigned char * const rawrow, - - - static void --writeHeader(FILE * const ofP, -- unsigned int const cols, -- unsigned int const rows, -- unsigned int const bitsPerPixel, -- unsigned int const planes, -- struct PcxCmapEntry const cmap16[], -- unsigned int const xPos, -- unsigned int const yPos) { -- -- unsigned int bytesPerLine; -- -- putbyte(PCX_MAGIC, ofP); /* .PCX magic number */ -- putbyte(0x05, ofP); /* PC Paintbrush version */ -- putbyte(0x01, ofP); /* .PCX run length encoding */ -- putbyte(bitsPerPixel, ofP); /* bits per pixel */ -- -- putword(xPos, ofP); /* x1 - image left */ -- putword(yPos, ofP); /* y1 - image top */ -- putword(xPos+cols-1, ofP); /* x2 - image right */ -- putword(yPos+rows-1, ofP); /* y2 - image bottom */ -- -- putword(cols, ofP); /* horizontal resolution */ -- putword(rows, ofP); /* vertical resolution */ -+write_header(FILE * const fp, -+ int const cols, -+ int const rows, -+ int const BitsPerPixel, -+ int const Planes, -+ struct pcxCmapEntry const cmap16[], -+ unsigned int const xPos, -+ unsigned int const yPos) { -+ -+ int i, BytesPerLine; -+ -+ Putbyte(PCX_MAGIC, fp); /* .PCX magic number */ -+ Putbyte(0x05, fp); /* PC Paintbrush version */ -+ Putbyte(0x01, fp); /* .PCX run length encoding */ -+ Putbyte(BitsPerPixel, fp); /* bits per pixel */ -+ -+ Putword(xPos, fp); /* x1 - image left */ -+ Putword(yPos, fp); /* y1 - image top */ -+ Putword(xPos+cols-1, fp); /* x2 - image right */ -+ Putword(yPos+rows-1, fp); /* y2 - image bottom */ -+ -+ Putword(cols, fp); /* horizontal resolution */ -+ Putword(rows, fp); /* vertical resolution */ - - /* Write out the Color Map for images with 16 colors or less */ -- if (cmap16) { -- unsigned int i; -+ if (cmap16) - for (i = 0; i < 16; ++i) { -- putbyte(cmap16[i].r, ofP); -- putbyte(cmap16[i].g, ofP); -- putbyte(cmap16[i].b, ofP); -+ Putbyte(cmap16[i].r, fp); -+ Putbyte(cmap16[i].g, fp); -+ Putbyte(cmap16[i].b, fp); - } -- } else { -+ else { - unsigned int i; - for (i = 0; i < 16; ++i) { -- putbyte(0, ofP); -- putbyte(0, ofP); -- putbyte(0, ofP); -+ Putbyte(0, fp); -+ Putbyte(0, fp); -+ Putbyte(0, fp); - } - } -- putbyte(0, ofP); /* reserved byte */ -- putbyte(planes, ofP); /* number of color planes */ -+ Putbyte(0, fp); /* reserved byte */ -+ Putbyte(Planes, fp); /* number of color planes */ - -- bytesPerLine = ((cols * bitsPerPixel) + 7) / 8; -- putword(bytesPerLine, ofP); /* number of bytes per scanline */ -+ BytesPerLine = ((cols * BitsPerPixel) + 7) / 8; -+ Putword(BytesPerLine, fp); /* number of bytes per scanline */ - -- putword(1, ofP); /* palette info */ -+ Putword(1, fp); /* palette info */ - - { - unsigned int i; - for (i = 0; i < 58; ++i) /* fill to end of header */ -- putbyte(0, ofP); -+ Putbyte(0, fp); - } - } - - - - static void --pcxEncode(FILE * const ofP, -+PCXEncode(FILE * const fp, - const unsigned char * const buf, -- unsigned int const size) { -+ int const Size) { - -- const unsigned char * const end = buf + size; -+ const unsigned char * const end = buf + Size; - - const unsigned char * currentP; -- unsigned int previous; -- unsigned int count; -+ int previous, count; - - currentP = buf; - previous = *currentP++; -@@ -351,19 +347,19 @@ pcxEncode(FILE * const ofP, - else { - if (count > 1 || (previous & 0xc0) == 0xc0) { - count |= 0xc0; -- putbyte ( count , ofP ); -+ Putbyte ( count , fp ); - } -- putbyte(previous, ofP); -+ Putbyte(previous, fp); - previous = c; -- count = 1; -+ count = 1; - } - } - - if (count > 1 || (previous & 0xc0) == 0xc0) { - count |= 0xc0; -- putbyte(count, ofP); -+ Putbyte ( count , fp ); - } -- putbyte(previous, ofP); -+ Putbyte(previous, fp); - } - - -@@ -390,46 +386,63 @@ indexOfColor(colorhash_table const cht, - - - static void --writeRaster16Color(FILE * const ofP, -- pixel ** const pixels, -- unsigned int const cols, -- unsigned int const rows, -- unsigned int const planes, -- colorhash_table const cht, -- bool const packbits, -- unsigned int const bitsPerPixel) { -- -- unsigned int const bytesPerLine = ((cols * bitsPerPixel) + 7) / 8; -- -- unsigned char * indexRow; /* malloc'ed */ -- /* indexRow[x] is the palette index of the pixel at column x of -- the row currently being processed -- */ -- unsigned char * planesrow; /* malloc'ed */ -- /* This is the input for a single row to the compressor */ -+ppmTo16ColorPcx(pixel ** const pixels, -+ int const cols, -+ int const rows, -+ struct pcxCmapEntry const pcxcmap[], -+ int const colors, -+ colorhash_table const cht, -+ bool const packbits, -+ unsigned int const planesRequested, -+ unsigned int const xPos, -+ unsigned int const yPos) { - -- unsigned int row; -+ int Planes, BytesPerLine, BitsPerPixel; -+ unsigned char *indexRow; /* malloc'ed */ -+ /* indexRow[x] is the palette index of the pixel at column x of -+ the row currently being processed -+ */ -+ unsigned char *planesrow; /* malloc'ed */ -+ /* This is the input for a single row to the compressor */ -+ int row; - -+ if (packbits) { -+ Planes = 1; -+ if (colors > 4) BitsPerPixel = 4; -+ else if (colors > 2) BitsPerPixel = 2; -+ else BitsPerPixel = 1; -+ } else { -+ BitsPerPixel = 1; -+ if (planesRequested) -+ Planes = planesRequested; -+ else { -+ if (colors > 8) Planes = 4; -+ else if (colors > 4) Planes = 3; -+ else if (colors > 2) Planes = 2; -+ else Planes = 1; -+ } -+ } -+ overflow2(BitsPerPixel, cols); -+ overflow_add(BitsPerPixel * cols, 7); -+ BytesPerLine = ((cols * BitsPerPixel) + 7) / 8; - MALLOCARRAY_NOFAIL(indexRow, cols); -- MALLOCARRAY(planesrow, bytesPerLine); -- -- if (!planesrow) -- pm_error("Failed to allocate buffer for a line of %u bytes", -- bytesPerLine); -+ MALLOCARRAY_NOFAIL(planesrow, BytesPerLine); - -+ write_header(stdout, cols, rows, BitsPerPixel, Planes, pcxcmap, -+ xPos, yPos); - for (row = 0; row < rows; ++row) { -- unsigned int col; -+ int col; - for (col = 0; col < cols; ++col) - indexRow[col] = indexOfColor(cht, pixels[row][col]); - - if (packbits) { -- packBits(indexRow, cols, planesrow, bitsPerPixel); -- pcxEncode(ofP, planesrow, bytesPerLine); -+ PackBits(indexRow, cols, planesrow, BitsPerPixel); -+ PCXEncode(stdout, planesrow, BytesPerLine); - } else { - unsigned int plane; -- for (plane = 0; plane < planes; ++plane) { -+ for (plane = 0; plane < Planes; ++plane) { - extractPlane(indexRow, cols, planesrow, plane); -- pcxEncode(stdout, planesrow, bytesPerLine); -+ PCXEncode(stdout, planesrow, BytesPerLine); - } - } - } -@@ -439,143 +452,84 @@ writeRaster16Color(FILE * const ofP, - - - --static void --ppmTo16ColorPcx(pixel ** const pixels, -- unsigned int const cols, -- unsigned int const rows, -- struct PcxCmapEntry const pcxcmap[], -- unsigned int const colorCt, -- colorhash_table const cht, -- bool const packbits, -- unsigned int const planesRequested, -- unsigned int const xPos, -- unsigned int const yPos) { -- -- unsigned int planes; -- unsigned int bitsPerPixel; -- -- if (packbits) { -- planes = 1; -- if (colorCt > 4) bitsPerPixel = 4; -- else if (colorCt > 2) bitsPerPixel = 2; -- else bitsPerPixel = 1; -- } else { -- bitsPerPixel = 1; -- if (planesRequested) -- planes = planesRequested; -- else { -- if (colorCt > 8) planes = 4; -- else if (colorCt > 4) planes = 3; -- else if (colorCt > 2) planes = 2; -- else planes = 1; -- } -- } -- -- writeHeader(stdout, cols, rows, bitsPerPixel, planes, pcxcmap, -- xPos, yPos); -- -- writeRaster16Color(stdout, pixels, cols, rows, planes, cht, packbits, -- bitsPerPixel); --} -- -- -- - static void - ppmTo256ColorPcx(pixel ** const pixels, -- unsigned int const cols, -- unsigned int const rows, -- struct PcxCmapEntry const pcxcmap[], -- unsigned int const colorCt, -+ int const cols, -+ int const rows, -+ struct pcxCmapEntry const pcxcmap[], -+ int const colors, - colorhash_table const cht, - unsigned int const xPos, - unsigned int const yPos) { - -- unsigned char * rawrow; -- unsigned int row; -- -- MALLOCARRAY(rawrow, cols); -+ int row; -+ unsigned int i; -+ unsigned char *rawrow; - -- if (!rawrow) -- pm_error("Failed to allocate a buffer for %u columns", cols); -+ rawrow = (unsigned char *)pm_allocrow(cols, sizeof(unsigned char)); - - /* 8 bits per pixel, 1 plane */ -- writeHeader(stdout, cols, rows, 8, 1, NULL, xPos, yPos); -+ write_header(stdout, cols, rows, 8, 1, NULL, xPos, yPos); - for (row = 0; row < rows; ++row) { -- unsigned int col; -+ int col; - for (col = 0; col < cols; ++col) - rawrow[col] = indexOfColor(cht, pixels[row][col]); -- pcxEncode(stdout, rawrow, cols); -- -+ PCXEncode(stdout, rawrow, cols); - } -- putbyte(PCX_256_COLORS, stdout); -- -- { -- unsigned int i; -- -- for (i = 0; i < MAXCOLORS; ++i) { -- putbyte(pcxcmap[i].r, stdout); -- putbyte(pcxcmap[i].g, stdout); -- putbyte(pcxcmap[i].b, stdout); -- } -+ Putbyte(PCX_256_COLORS, stdout); -+ for (i = 0; i < MAXCOLORS; ++i) { -+ Putbyte(pcxcmap[i].r, stdout); -+ Putbyte(pcxcmap[i].g, stdout); -+ Putbyte(pcxcmap[i].b, stdout); - } -- free(rawrow); -+ pm_freerow((void*)rawrow); - } - - - - static void - ppmToTruecolorPcx(pixel ** const pixels, -- unsigned int const cols, -- unsigned int const rows, -+ int const cols, -+ int const rows, - pixval const maxval, - unsigned int const xPos, - unsigned int const yPos) { - -- unsigned char * redrow; -- unsigned char * grnrow; -- unsigned char * blurow; -- unsigned int row; -+ unsigned char *redrow, *greenrow, *bluerow; -+ int col, row; - -- MALLOCARRAY(redrow, cols); -- MALLOCARRAY(grnrow, cols); -- MALLOCARRAY(blurow, cols); -- -- if (!redrow || !grnrow || !blurow) -- pm_error("Unable to allocate buffer for a row of %u pixels", cols); -+ redrow = (unsigned char *)pm_allocrow(cols, sizeof(unsigned char)); -+ greenrow = (unsigned char *)pm_allocrow(cols, sizeof(unsigned char)); -+ bluerow = (unsigned char *)pm_allocrow(cols, sizeof(unsigned char)); - - /* 8 bits per pixel, 3 planes */ -- writeHeader(stdout, cols, rows, 8, 3, NULL, xPos, yPos); -- -- for (row = 0; row < rows; ++row) { -- pixel * const pixrow = pixels[row]; -- -- unsigned int col; -- -- for (col = 0; col < cols; ++col) { -- pixel const pix = pixrow[col]; -- -- if (maxval != PCX_MAXVAL) { -- redrow[col] = (long)PPM_GETR(pix) * PCX_MAXVAL / maxval; -- grnrow[col] = (long)PPM_GETG(pix) * PCX_MAXVAL / maxval; -- blurow[col] = (long)PPM_GETB(pix) * PCX_MAXVAL / maxval; -- } else { -- redrow[col] = PPM_GETR(pix); -- grnrow[col] = PPM_GETG(pix); -- blurow[col] = PPM_GETB(pix); -+ write_header(stdout, cols, rows, 8, 3, NULL, xPos, yPos); -+ for( row = 0; row < rows; row++ ) { -+ register pixel *pP = pixels[row]; -+ for( col = 0; col < cols; col++, pP++ ) { -+ if( maxval != PCX_MAXVAL ) { -+ redrow[col] = (long)PPM_GETR(*pP) * PCX_MAXVAL / maxval; -+ greenrow[col] = (long)PPM_GETG(*pP) * PCX_MAXVAL / maxval; -+ bluerow[col] = (long)PPM_GETB(*pP) * PCX_MAXVAL / maxval; -+ } -+ else { -+ redrow[col] = PPM_GETR(*pP); -+ greenrow[col] = PPM_GETG(*pP); -+ bluerow[col] = PPM_GETB(*pP); - } - } -- pcxEncode(stdout, redrow, cols); -- pcxEncode(stdout, grnrow, cols); -- pcxEncode(stdout, blurow, cols); -+ PCXEncode(stdout, redrow, cols); -+ PCXEncode(stdout, greenrow, cols); -+ PCXEncode(stdout, bluerow, cols); - } -- free(blurow); -- free(grnrow); -- free(redrow); -+ pm_freerow((void*)bluerow); -+ pm_freerow((void*)greenrow); -+ pm_freerow((void*)redrow); - } - - - --static const struct PcxCmapEntry -+static const struct pcxCmapEntry - stdPalette[] = { - { 0, 0, 0 }, - { 0, 0, 170 }, -@@ -653,19 +607,20 @@ putPcxColorInHash(colorhash_table const cht, - - - static void --generateStandardPalette(struct PcxCmapEntry ** const pcxcmapP, -+generateStandardPalette(struct pcxCmapEntry ** const pcxcmapP, - pixval const maxval, - colorhash_table * const chtP, -- unsigned int * const colorsP) { -+ int * const colorsP) { - - unsigned int const stdPaletteSize = 16; -- -- unsigned int colorIndex; -- struct PcxCmapEntry * pcxcmap; -- colorhash_table cht; -+ unsigned int colorIndex; -+ struct pcxCmapEntry * pcxcmap; -+ colorhash_table cht; - - MALLOCARRAY_NOFAIL(pcxcmap, MAXCOLORS); - -+ *pcxcmapP = pcxcmap; -+ - cht = ppm_alloccolorhash(); - - for (colorIndex = 0; colorIndex < stdPaletteSize; ++colorIndex) { -@@ -692,7 +647,6 @@ generateStandardPalette(struct PcxCmapEntry ** const pcxcmapP, - pcxcmap[colorIndex].b = 0; - } - -- *pcxcmapP = pcxcmap; - *chtP = cht; - *colorsP = stdPaletteSize; - } -@@ -721,10 +675,11 @@ readPpmPalette(const char * const paletteFileName, - *paletteSizeP, MAXCOLORS); - - { -- unsigned int j; -- unsigned int row; -- for (row = 0, j = 0; row < rows; ++row) { -- unsigned int col; -+ int j; -+ int row; -+ j = 0; /* initial value */ -+ for (row = 0; row < rows; ++row) { -+ int col; - for (col = 0; col < cols; ++col) - (*ppmPaletteP)[j++] = pixels[row][col]; - } -@@ -735,16 +690,16 @@ readPpmPalette(const char * const paletteFileName, - - - static void --readPaletteFromFile(struct PcxCmapEntry ** const pcxcmapP, -+readPaletteFromFile(struct pcxCmapEntry ** const pcxcmapP, - const char * const paletteFileName, - pixval const maxval, - colorhash_table * const chtP, -- unsigned int * const colorsP) { -+ int * const colorsP) { - - unsigned int colorIndex; - pixel ppmPalette[MAXCOLORS]; - unsigned int paletteSize; -- struct PcxCmapEntry * pcxcmap; -+ struct pcxCmapEntry * pcxcmap; - colorhash_table cht; - - readPpmPalette(paletteFileName, &ppmPalette, &paletteSize); -@@ -777,7 +732,7 @@ readPaletteFromFile(struct PcxCmapEntry ** const pcxcmapP, - - static void - moveBlackToIndex0(colorhist_vector const chv, -- unsigned int const colorCt) { -+ int const colors) { - /*---------------------------------------------------------------------------- - If black is in the palette, make it at Index 0. - -----------------------------------------------------------------------------*/ -@@ -789,7 +744,7 @@ moveBlackToIndex0(colorhist_vector const chv, - - blackPresent = FALSE; /* initial assumption */ - -- for (i = 0; i < colorCt; ++i) -+ for (i = 0; i < colors; ++i) - if (PPM_EQUAL(chv[i].color, blackPixel)) - blackPresent = TRUE; - -@@ -798,11 +753,10 @@ moveBlackToIndex0(colorhist_vector const chv, - beginning of the table and if the color is already elsewhere in - the table, removes it. - */ -- int colorCt2; -- -- colorCt2 = colorCt; -- ppm_addtocolorhist(chv, &colorCt2, MAXCOLORS, &blackPixel, 0, 0); -- assert(colorCt2 == colorCt); -+ int colors2; -+ colors2 = colors; -+ ppm_addtocolorhist(chv, &colors2, MAXCOLORS, &blackPixel, 0, 0); -+ assert(colors2 == colors); - } - } - -@@ -810,12 +764,12 @@ moveBlackToIndex0(colorhist_vector const chv, - - static void - makePcxColormapFromImage(pixel ** const pixels, -- unsigned int const cols, -- unsigned int const rows, -+ int const cols, -+ int const rows, - pixval const maxval, -- struct PcxCmapEntry ** const pcxcmapP, -+ struct pcxCmapEntry ** const pcxcmapP, - colorhash_table * const chtP, -- unsigned int * const colorCtP, -+ int * const colorsP, - bool * const tooManyColorsP) { - /*---------------------------------------------------------------------------- - Make a colormap (palette) for the PCX header that can be used -@@ -831,29 +785,29 @@ makePcxColormapFromImage(pixel ** const pixels, - Iff there are too many colors to do that (i.e. more than 256), - return *tooManyColorsP == TRUE. - -----------------------------------------------------------------------------*/ -- int colorCt; -+ int colors; - colorhist_vector chv; - - pm_message("computing colormap..."); - -- chv = ppm_computecolorhist(pixels, cols, rows, MAXCOLORS, &colorCt); -+ chv = ppm_computecolorhist(pixels, cols, rows, MAXCOLORS, &colors); - if (chv == NULL) - *tooManyColorsP = TRUE; - else { -- unsigned int i; -- struct PcxCmapEntry * pcxcmap; -+ int i; -+ struct pcxCmapEntry * pcxcmap; - - *tooManyColorsP = FALSE; - -- pm_message("%d colors found", colorCt); -+ pm_message("%d colors found", colors); - -- moveBlackToIndex0(chv, colorCt); -+ moveBlackToIndex0(chv, colors); - - MALLOCARRAY_NOFAIL(pcxcmap, MAXCOLORS); - - *pcxcmapP = pcxcmap; - -- for (i = 0; i < colorCt; ++i) { -+ for (i = 0; i < colors; ++i) { - pixel p; - - PPM_DEPTH(p, chv[i].color, maxval, PCX_MAXVAL); -@@ -870,9 +824,9 @@ makePcxColormapFromImage(pixel ** const pixels, - pcxcmap[i].b = 0; - } - -- *chtP = ppm_colorhisttocolorhash(chv, colorCt); -+ *chtP = ppm_colorhisttocolorhash(chv, colors); - -- *colorCtP = colorCt; -+ *colorsP = colors; - - ppm_freecolorhist(chv); - } -@@ -882,43 +836,43 @@ makePcxColormapFromImage(pixel ** const pixels, - - static void - ppmToPalettePcx(pixel ** const pixels, -- unsigned int const cols, -- unsigned int const rows, -+ int const cols, -+ int const rows, - pixval const maxval, - unsigned int const xPos, - unsigned int const yPos, -- struct PcxCmapEntry const pcxcmap[], -+ struct pcxCmapEntry const pcxcmap[], - colorhash_table const cht, -- unsigned int const colorCt, -+ int const colors, - bool const packbits, - unsigned int const planes, -- bool const use8Bit) { -+ bool const use_8_bit) { - - /* convert image */ -- if (colorCt <= 16 && !use8Bit ) -- ppmTo16ColorPcx(pixels, cols, rows, pcxcmap, colorCt, cht, -+ if( colors <= 16 && !use_8_bit ) -+ ppmTo16ColorPcx(pixels, cols, rows, pcxcmap, colors, cht, - packbits, planes, xPos, yPos); - else -- ppmTo256ColorPcx(pixels, cols, rows, pcxcmap, colorCt, cht, -+ ppmTo256ColorPcx(pixels, cols, rows, pcxcmap, colors, cht, - xPos, yPos); - } - - - - int --main(int argc, const char *argv[]) { -+main(int argc, char *argv[]) { - -- struct CmdlineInfo cmdline; -- FILE * ifP; -+ struct cmdlineInfo cmdline; -+ FILE* ifP; - int rows, cols; - pixval maxval; - pixel **pixels; -- struct PcxCmapEntry * pcxcmap; -+ struct pcxCmapEntry * pcxcmap; - colorhash_table cht; - bool truecolor; -- unsigned int colorCt; -+ int colors; - -- pm_proginit(&argc, argv); -+ ppm_init(&argc, argv); - - parseCommandLine(argc, argv, &cmdline); - -@@ -931,15 +885,15 @@ main(int argc, const char *argv[]) { - else { - if (cmdline.stdpalette) { - truecolor = FALSE; -- generateStandardPalette(&pcxcmap, maxval, &cht, &colorCt); -+ generateStandardPalette(&pcxcmap, maxval, &cht, &colors); - } else if (cmdline.palette) { - truecolor = FALSE; - readPaletteFromFile(&pcxcmap, cmdline.palette, maxval, -- &cht, &colorCt); -+ &cht, &colors); - } else { - bool tooManyColors; - makePcxColormapFromImage(pixels, cols, rows, maxval, -- &pcxcmap, &cht, &colorCt, -+ &pcxcmap, &cht, &colors, - &tooManyColors); - - if (tooManyColors) { -@@ -958,8 +912,8 @@ main(int argc, const char *argv[]) { - else { - ppmToPalettePcx(pixels, cols, rows, maxval, - cmdline.xpos, cmdline.ypos, -- pcxcmap, cht, colorCt, cmdline.packed, -- cmdline.planes, cmdline.use8Bit); -+ pcxcmap, cht, colors, cmdline.packed, -+ cmdline.planes, cmdline.use_8_bit); - - ppm_freecolorhash(cht); - free(pcxcmap); -diff --git a/converter/ppm/ppmtopict.c b/converter/ppm/ppmtopict.c -index 36464b6..c91ccf2 100644 ---- a/converter/ppm/ppmtopict.c -+++ b/converter/ppm/ppmtopict.c -@@ -450,6 +450,8 @@ main(int argc, const char ** argv) { - putShort(stdout, 0); /* mode */ - - /* Finally, write out the data. */ + overflow_add(cols/MAX_COUNT, 1); + overflow_add(cols, cols/MAX_COUNT+1); - outBuf = malloc((unsigned)(cols+cols/MAX_COUNT+1)); - for (row = 0, oc = 0; row < rows; ++row) { - unsigned int rowSize; -diff --git a/converter/ppm/ppmtopj.c b/converter/ppm/ppmtopj.c -index d116773..fc84cac 100644 ---- a/converter/ppm/ppmtopj.c -+++ b/converter/ppm/ppmtopj.c -@@ -179,6 +179,7 @@ char *argv[]; - pixels = ppm_readppm( ifp, &cols, &rows, &maxval ); - - pm_close( ifp ); -+ overflow2(cols,2); - obuf = (unsigned char *) pm_allocrow(cols, sizeof(unsigned char)); - cbuf = (unsigned char *) pm_allocrow(cols * 2, sizeof(unsigned char)); - -diff --git a/converter/ppm/ppmtopjxl.c b/converter/ppm/ppmtopjxl.c -index 90bcef0..72d0027 100644 ---- a/converter/ppm/ppmtopjxl.c -+++ b/converter/ppm/ppmtopjxl.c -@@ -267,6 +267,9 @@ main(int argc, const char * argv[]) { ++ + MALLOCARRAY(outBuf, cols + cols/MAX_COUNT + 1); + if (!outBuf) + pm_error("Unable to allocate %u-byte row buffer", +diff -urNp a/converter/ppm/ppmtopjxl.c b/converter/ppm/ppmtopjxl.c +--- a/converter/ppm/ppmtopjxl.c 2025-02-03 09:24:28.331500558 +0100 ++++ b/converter/ppm/ppmtopjxl.c 2025-02-03 18:48:46.550503012 +0100 +@@ -535,6 +535,8 @@ main(int argc, const char * argv[]) { + pm_error("image too large; reduce with ppmscale"); if (maxval > PCL_MAXVAL) pm_error("color range too large; reduce with ppmcscale"); - + if (cols < 0 || rows < 0) + pm_error("negative size is not possible"); -+ - /* Figure out the colormap. */ - pm_message("Computing colormap..."); - chv = ppm_computecolorhist(pixels, cols, rows, MAXCOLORS, &colors); -@@ -286,6 +289,8 @@ main(int argc, const char * argv[]) { - case 0: /* direct mode (no palette) */ - bpp = bitsperpixel(maxval); /* bits per pixel */ - bpg = bpp; bpb = bpp; -+ overflow2(bpp, 3); -+ overflow_add(bpp*3, 7); - bpp = (bpp*3+7)>>3; /* bytes per pixel now */ - bpr = (bpp<<3)-bpg-bpb; - bpp *= cols; /* bytes per row now */ -@@ -295,9 +300,13 @@ main(int argc, const char * argv[]) { - case 3: case 7: pclindex++; - default: - bpp = 8/pclindex; -+ overflow_add(cols, bpp); -+ if(bpp == 0) -+ pm_error("assert: no bpp"); - bpp = (cols+bpp-1)/bpp; /* bytes per row */ - } - } -+ overflow2(bpp,2); - inrow = (char *)malloc((unsigned)bpp); - outrow = (char *)malloc((unsigned)bpp*2); - runcnt = (signed char *)malloc((unsigned)bpp); -diff --git a/converter/ppm/ppmtowinicon.c b/converter/ppm/ppmtowinicon.c -index c673798..af2b445 100644 ---- a/converter/ppm/ppmtowinicon.c -+++ b/converter/ppm/ppmtowinicon.c -@@ -12,6 +12,7 @@ + computeColormap(pixels, cols, rows, MAXCOLORS, &chv, &cht, &colorCt); + +diff -urNp a/converter/ppm/ppmtowinicon.c b/converter/ppm/ppmtowinicon.c +--- a/converter/ppm/ppmtowinicon.c 2025-02-03 09:24:28.330500563 +0100 ++++ b/converter/ppm/ppmtowinicon.c 2025-02-03 18:56:25.509890831 +0100 +@@ -14,6 +14,7 @@ + #include #include #include +#include #include "pm_c_util.h" #include "winico.h" -@@ -214,6 +215,7 @@ createAndBitmap (gray ** const ba, int const cols, int const rows, - MALLOCARRAY_NOFAIL(rowData, rows); - icBitmap->xBytes = xBytes; - icBitmap->data = rowData; -+ overflow2(xBytes, rows); - icBitmap->size = xBytes * rows; - for (y=0;yxBytes = xBytes; - icBitmap->data = rowData; -+ overflow2(xBytes, rows); - icBitmap->size = xBytes * rows; - - for (y=0;yxBytes = xBytes; - icBitmap->data = rowData; -+ overflow2(xBytes, rows); - icBitmap->size = xBytes * rows; - - for (y=0;ybitcount = bpp; - entry->ih = createInfoHeader(entry, xorBitmap, andBitmap); - entry->colors = palette->colors; -- entry->size_in_bytes = -+ overflow2(4, entry->color_count); -+ overflow_add(xorBitmap->size, andBitmap->size); -+ overflow_add(xorBitmap->size + andBitmap->size, 40); -+ overflow_add(xorBitmap->size + andBitmap->size + 40, 4 * entry->color_count); -+ entry->size_in_bytes = - xorBitmap->size + andBitmap->size + 40 + (4 * entry->color_count); - if (verbose) - pm_message("entry->size_in_bytes = %d + %d + %d = %d", -diff --git a/converter/ppm/ppmtoxpm.c b/converter/ppm/ppmtoxpm.c -index 0e31692..1b3923f 100644 ---- a/converter/ppm/ppmtoxpm.c -+++ b/converter/ppm/ppmtoxpm.c -@@ -198,6 +198,7 @@ genNumstr(unsigned int const input, int const digits) { +@@ -207,6 +208,7 @@ newAndBitmap(gray ** const ba, + MALLOCARRAY_NOFAIL(rowData, rows); + icBitmapP->xBytes = xByteCt; + icBitmapP->data = rowData; ++ overflow2(xByteCt, rows); + icBitmapP->size = xByteCt * rows; + for (row = 0; row < rows; ++row) { + u1 * thisRow; /* malloc'ed */ +@@ -706,6 +708,11 @@ addEntryToIcon(MS_Ico * const MSIcon + /* all the icons I looked at ignored this value */ + entryP->ih = newInfoHeader(*entryP); + entryP->colors = paletteP->colors; ++ overflow2(4, entryCols); ++ overflow_add(xorBitmapP->size, andBitmapP->size); ++ overflow_add(xorBitmapP->size + andBitmapP->size, 40); ++ overflow_add(xorBitmapP->size + andBitmapP->size + 40, 4 * entryCols); ++ + entryP->size_in_bytes = + xorBitmapP->size + andBitmapP->size + 40 + (4 * entryCols); + if (verbose) +diff -urNp a/converter/ppm/ppmtoxpm.c b/converter/ppm/ppmtoxpm.c +--- a/converter/ppm/ppmtoxpm.c 2025-02-03 09:24:28.329500569 +0100 ++++ b/converter/ppm/ppmtoxpm.c 2025-02-03 18:59:21.646266347 +0100 +@@ -193,6 +193,7 @@ numstr(unsigned int const input, unsigned int i; /* Allocate memory for printed number. Abort if error. */ -+ overflow_add(digits, 1); - if (!(str = (char *) malloc(digits + 1))) - pm_error("out of memory"); ++ overflow_add(digitCt, 1); + MALLOCARRAY_NOFAIL(str, digitCt + 1); -@@ -315,6 +316,7 @@ genCmap(colorhist_vector const chv, - unsigned int charsPerPixel; - unsigned int xpmMaxval; - + i = input; /* initial value */ +@@ -296,6 +297,7 @@ genCmap(colorhist_vector const chv, + Return as *charsPerPixel the number of characters, or digits, that + will be needed in the XPM raster to form an index into this color map. + -----------------------------------------------------------------------------*/ + if (includeTransparent) overflow_add(ncolors, 1); - MALLOCARRAY(cmap, cmapSize); - if (cmapP == NULL) - pm_error("Out of memory allocating %u bytes for a color map.", -diff --git a/converter/ppm/qrttoppm.c b/converter/ppm/qrttoppm.c -index 935463e..653084c 100644 ---- a/converter/ppm/qrttoppm.c -+++ b/converter/ppm/qrttoppm.c -@@ -46,7 +46,7 @@ main( argc, argv ) + unsigned int const cmapSize = ncolors + (includeTransparent ? 1 : 0); - ppm_writeppminit( stdout, cols, rows, maxval, 0 ); - pixelrow = ppm_allocrow( cols ); -- buf = (unsigned char *) malloc( 3 * cols ); -+ buf = (unsigned char *) malloc2( 3 , cols ); - if ( buf == (unsigned char *) 0 ) - pm_error( "out of memory" ); + CixelMap * cmap; /* malloc'ed */ +diff -urNp a/converter/ppm/qrttoppm.c b/converter/ppm/qrttoppm.c +--- a/converter/ppm/qrttoppm.c 2025-02-03 09:24:28.331500558 +0100 ++++ b/converter/ppm/qrttoppm.c 2025-02-03 19:00:16.846070585 +0100 +@@ -51,6 +51,7 @@ main(int argc, const char ** argv) { -diff --git a/converter/ppm/sldtoppm.c b/converter/ppm/sldtoppm.c -index 2fef023..1f30cbd 100644 ---- a/converter/ppm/sldtoppm.c -+++ b/converter/ppm/sldtoppm.c -@@ -154,127 +154,85 @@ vscale(int * const px, + pixelrow = ppm_allocrow(cols); ++ overflow2(cols, 3); + MALLOCARRAY(buf, 3 * cols); - --static void --upcase(const char * const sname, -- char * const uname) { -- -- unsigned int i; -- const char * ip; -- -- for (i = 0, ip = sname; i < 31; ++i) { -- char const ch = *ip++; -- -- if (ch != EOS) -- uname[i] = islower(ch) ? toupper(ch) : ch; -- } -- uname[i] = EOS; --} -- -- -- --static void --skipBytes(FILE * const fileP, -- unsigned int const count) { -- -- unsigned int i; -- -- for (i = 0; i < count; ++i) -- getc(fileP); --} -- -- -- --static void --scanDirectory(FILE * const slFileP, -- long const dirPos, -- bool const dirOnly, -- const char * const uname, -- bool * const foundP) { --/*---------------------------------------------------------------------------- -- Scan the directory at the current position in *slFileP, either listing -- the directory ('dirOnly' true) or searching for a slide named -- 'uname' ('dirOnly' false). -- -- 'dirPos' is the offset in the file of the directory, i.e. the current -- position of *slFileP. -- -- In the latter case, return as *foundP whether the slide name is there. -------------------------------------------------------------------------------*/ -- bool found; -- bool eof; -- long pos; -- unsigned char libent[36]; -- -- for (found = false, eof = false, pos = dirPos; !found && !eof; ) { -- size_t readCt; -- readCt = fread(libent, 36, 1, slFileP); -- if (readCt != 1) -- eof = true; -- else { -- /* The directory entry is 32 bytes of NUL-terminated slide name -- followed by 4 bytes of offset of the next directory entry. -- */ -- const char * const slideName = (const char *)(&libent[0]); -- if (pm_strnlen(slideName, 32) == 32) -- pm_error("Invalid input: slide name field is not " -- "nul-terminated"); -- else { -- if (strlen(slideName) == 0) -- eof = true; -- else { -- pos += 36; -- if (dirOnly) { -- pm_message(" %s", slideName); -- } else if (streq(slideName, uname)) { -- long const dpos = -- (((((libent[35] << 8) | libent[34]) << 8) | -- libent[33]) << 8) | libent[32]; -- -- if ((slFileP == stdin) || -- (fseek(slFileP, dpos, 0) == -1)) { -- -- skipBytes(slFileP, dpos - pos); -- } -- found = true; -- } -- } -- } -- } -- } -- *foundP = found; --} -- - /* SLIDEFIND -- Find a slide in a library or, if DIRONLY is - nonzero, print a directory listing of the library. - If UCASEN is nonzero, the requested slide name is - converted to upper case. */ - - static void --slidefind(const char * const slideName, -- bool const dirOnly, -+slidefind(const char * const sname, -+ bool const dironly, - bool const ucasen) { - -- char uname[32]; /* upper case translation of 'slideName' */ -- char header[32]; /* (supposed) header read from file */ -+ char uname[32]; -+ unsigned char libent[36]; -+ long pos; - bool found; -+ bool eof; - -- if (dirOnly) -+ if (dironly) - pm_message("Slides in library:"); - else { -- upcase(slideName, uname); -+ unsigned int i; -+ const char * ip; -+ -+ ip = sname; /* initial value */ -+ -+ for (i = 0; i < 31; ++i) { -+ char const ch = *ip++; -+ if (ch == EOS) -+ break; -+ -+ { -+ char const upperCh = -+ ucasen && islower(ch) ? toupper(ch) : ch; -+ -+ uname[i] = upperCh; -+ } -+ } -+ uname[i] = EOS; - } - - /* Read slide library header and verify. */ -- -- if ((fread(header, 32, 1, slfile) != 1) || -- (!STRSEQ(header, "AutoCAD Slide Library 1.0\r\n\32"))) { -+ -+ if ((fread(libent, 32, 1, slfile) != 1) || -+ (!streq((char *)libent, "AutoCAD Slide Library 1.0\015\012\32"))) { - pm_error("not an AutoCAD slide library file."); - } -+ pos = 32; -+ -+ /* Search for a slide with the requested name or list the directory */ -+ -+ for (found = false, eof = false; !found && !eof; ) { -+ size_t readCt; -+ readCt = fread(libent, 36, 1, slfile); -+ if (readCt != 1) -+ eof = true; -+ else if (strlen((char *)libent) == 0) -+ eof = true; -+ } -+ if (!eof) { -+ pos += 36; -+ if (dironly) { -+ pm_message(" %s", libent); -+ } else if (streq((char *)libent, uname)) { -+ long dpos; -+ -+ dpos = (((((libent[35] << 8) | libent[34]) << 8) | -+ libent[33]) << 8) | libent[32]; -+ -+ if ((slfile == stdin) || (fseek(slfile, dpos, 0) == -1)) { -+ dpos -= pos; -+ -+ while (dpos-- > 0) -+ getc(slfile); -+ } -+ found = true; -+ } -+ } - -- scanDirectory(slfile, 32, dirOnly, ucasen ? uname : slideName, &found); -- -- if (!found && !dirOnly) -- pm_error("slide '%s' not in library.", slideName); -+ if (!found && !dironly) -+ pm_error("slide '%s' not in library.", sname); - } - - -@@ -392,7 +350,7 @@ slider(slvecfn slvec, - - /* Verify that slide format is compatible with this program. */ - -- if (!STRSEQ(slfrof.slh, slhi.slh)) -+ if (streq(slfrof.slh, slhi.slh)) - pm_error("this is not an AutoCAD slide file."); - - /* Verify that the number format and file level in the header are -@@ -506,6 +464,8 @@ slider(slvecfn slvec, + if (!buf) +diff -urNp a/converter/ppm/sldtoppm.c b/converter/ppm/sldtoppm.c +--- a/converter/ppm/sldtoppm.c 2025-02-03 09:24:28.330500563 +0100 ++++ b/converter/ppm/sldtoppm.c 2025-02-03 19:02:13.580656717 +0100 +@@ -542,6 +542,8 @@ slider(slvecfn slvec, /* Allocate image buffer and clear it to black. */ + overflow_add(ixdots, 1); + overflow_add(iydots, 1); - pixels = ppm_allocarray(pixcols = ixdots + 1, pixrows = iydots + 1); - PPM_ASSIGN(rgbcolor, 0, 0, 0); - ppmd_filledrectangle(pixels, pixcols, pixrows, pixmaxval, 0, 0, -diff --git a/converter/ppm/ximtoppm.c b/converter/ppm/ximtoppm.c -index d839e77..e9083f3 100644 ---- a/converter/ppm/ximtoppm.c -+++ b/converter/ppm/ximtoppm.c -@@ -22,9 +22,7 @@ - #include "shhopt.h" - #include "nstring.h" + pixcols = ixdots + 1; + pixrows = iydots + 1; + pixels = ppm_allocarray(pixcols, pixrows); +diff -urNp a/converter/ppm/ximtoppm.c b/converter/ppm/ximtoppm.c +--- a/converter/ppm/ximtoppm.c 2025-02-03 09:24:28.330500563 +0100 ++++ b/converter/ppm/ximtoppm.c 2025-02-03 19:06:57.979648387 +0100 +@@ -204,8 +204,7 @@ readImageChannel(FILE * const if + } + /* return to the beginning of the next image's buffer */ + if (fseek(ifP, marker, 0) == -1) { +- pm_message("ReadImageChannel: can't fseek to location " +- "in image buffer"); ++ pm_message("ReadImageChannel: can't fseek to location in image buffer"); + return 0; + } + free(line); +diff -urNp a/editor/pamcut.c b/editor/pamcut.c +--- a/editor/pamcut.c 2025-02-03 09:24:28.296500747 +0100 ++++ b/editor/pamcut.c 2025-02-04 09:20:22.743237833 +0100 +@@ -833,6 +833,8 @@ cutOneImage(FILE * const ifP + } else { + outpam = inpam; /* Initial value -- most fields should be same */ + outpam.file = ofP; ++ overflow_add(rightcol, 1); ++ overflow_add(bottomrow, 1); + outpam.width = rightcol - leftcol + 1; + outpam.height = bottomrow - toprow + 1; -- -- --struct CmdlineInfo { -+struct cmdlineInfo { - /* All the information the user supplied in the command line, - in a form easy for the program to use. - */ -@@ -36,8 +34,8 @@ struct CmdlineInfo { - - - static void --parseCommandLine(int argc, const char ** argv, -- struct CmdlineInfo *cmdlineP) { -+parseCommandLine(int argc, char ** argv, -+ struct cmdlineInfo *cmdlineP) { - /*---------------------------------------------------------------------------- - Note that many of the strings that this function returns in the - *cmdlineP structure are actually in the supplied argv array. And -@@ -59,7 +57,7 @@ parseCommandLine(int argc, const char ** argv, - opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ - opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ - -- pm_optParseOptions3(&argc, (char**)argv, opt, sizeof(opt), 0); -+ pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0); - /* Uses and sets argc, argv, and all of *cmdlineP. */ - - if (!alphaoutSpec) -@@ -102,11 +100,6 @@ ReadXimHeader(FILE * const in_fp, - pm_message("ReadXimHeader: unable to read file header" ); - return(0); - } -- /* Force broken ASCIIZ strings to at least be valid ASCIIZ */ -- a_head.author [sizeof(a_head.author) - 1] = '\0'; -- a_head.date [sizeof(a_head.date) - 1] = '\0'; -- a_head.program[sizeof(a_head.program) - 1] = '\0'; -- - if (atoi(a_head.header_size) != sizeof(ImageHeader)) { - pm_message("ReadXimHeader: header size mismatch" ); - return(0); -@@ -120,15 +113,39 @@ ReadXimHeader(FILE * const in_fp, - header->ncolors = atoi(a_head.num_colors); - header->nchannels = atoi(a_head.num_channels); - header->bytes_per_line = atoi(a_head.bytes_per_line); --#if 0 -- header->npics = atoi(a_head.num_pictures); --#endif -+/* header->npics = atoi(a_head.num_pictures); -+*/ - header->bits_channel = atoi(a_head.bits_per_channel); - header->alpha_flag = atoi(a_head.alpha_channel); -- header->author = pm_strdup(a_head.author); -- header->date = pm_strdup(a_head.date); -- header->program = pm_strdup(a_head.program); -- -+ if (strlen(a_head.author)) { -+ overflow_add(strlen(a_head.author),1); -+ if (!(header->author = calloc((unsigned int)strlen(a_head.author)+1, -+ 1))) { -+ pm_message("ReadXimHeader: can't calloc author string" ); -+ return(0); -+ } -+ header->width = atoi(a_head.image_width); -+ strncpy(header->author, a_head.author, strlen(a_head.author)); -+ } -+ if (strlen(a_head.date)) { -+ overflow_add(strlen(a_head.date),1); -+ if (!(header->date =calloc((unsigned int)strlen(a_head.date)+1,1))){ -+ pm_message("ReadXimHeader: can't calloc date string" ); -+ return(0); -+ } -+ header->width = atoi(a_head.image_width); -+ strncpy(header->date, a_head.date, strlen(a_head.date)); -+ } -+ if (strlen(a_head.program)) { -+ overflow_add(strlen(a_head.program),1); -+ if (!(header->program = calloc( -+ (unsigned int)strlen(a_head.program) + 1, 1))) { -+ pm_message("ReadXimHeader: can't calloc program string" ); -+ return(0); -+ } -+ header->width = atoi(a_head.image_width); -+ strncpy(header->program, a_head.program,strlen(a_head.program)); -+ } - /* Do double checking for backwards compatibility */ - if (header->npics == 0) - header->npics = 1; -@@ -147,6 +164,7 @@ ReadXimHeader(FILE * const in_fp, - if (header->nchannels == 3 && header->bits_channel == 8) - header->ncolors = 0; - else if (header->nchannels == 1 && header->bits_channel == 8) { -+ overflow2(header->ncolors, sizeof(Color)); - header->colors = (Color *)calloc((unsigned int)header->ncolors, - sizeof(Color)); - if (header->colors == NULL) { -@@ -197,8 +215,7 @@ ReadImageChannel(FILE * const infp, - } - /* return to the beginning of the next image's buffer */ - if (fseek(infp, marker, 0) == -1) { -- pm_message("ReadImageChannel: can't fseek to location " -- "in image buffer"); -+ pm_message("ReadImageChannel: can't fseek to location in image buffer" ); - return(0); - } - free((char *)line); -@@ -307,26 +324,28 @@ ReadXimImage(FILE * const in_fp, - ***********************************************************************/ - - static int --ReadXim(FILE * const in_fp, -- XimImage * const xim) { -- -+ReadXim(in_fp, xim) -+ FILE *in_fp; -+ XimImage *xim; -+{ - if (!ReadXimHeader(in_fp, xim)) { - pm_message("can't read xim header" ); -- return 0; -- } else if (!ReadXimImage(in_fp, xim)) { -+ return(0); -+ } -+ if (!ReadXimImage(in_fp, xim)) { - pm_message("can't read xim data" ); -- return 0; -- } else -- return 1; -+ return(0); -+ } -+ return(1); - } - - - - int --main(int argc, -- const char **argv) { -+main(int argc, -+ char *argv[]) { - -- struct CmdlineInfo cmdline; -+ struct cmdlineInfo cmdline; - FILE *ifP, *imageout_file, *alpha_file; - XimImage xim; - pixel *pixelrow, colormap[256]; -@@ -338,7 +357,7 @@ main(int argc, - pixval maxval; - bool success; - -- pm_proginit(&argc, argv); -+ ppm_init(&argc, argv); - - parseCommandLine(argc, argv, &cmdline); - -diff --git a/editor/pamcut.c b/editor/pamcut.c -index 1fc9d9b..ad0e030 100644 ---- a/editor/pamcut.c -+++ b/editor/pamcut.c -@@ -799,6 +799,8 @@ cutOneImage(FILE * const ifP, - - outpam = inpam; /* Initial value -- most fields should be same */ - outpam.file = ofP; -+ overflow_add(rightcol, 1); -+ overflow_add(bottomrow, 1); - outpam.width = rightcol - leftcol + 1; - outpam.height = bottomrow - toprow + 1; - -diff --git a/editor/pnmgamma.c b/editor/pnmgamma.c -index 1fdf20e..98b7e90 100644 ---- a/editor/pnmgamma.c -+++ b/editor/pnmgamma.c -@@ -596,6 +596,7 @@ createGammaTables(enum transferFunction const transferFunction, +diff -urNp a/editor/pnmgamma.c b/editor/pnmgamma.c +--- a/editor/pnmgamma.c 2025-02-03 09:24:28.296500747 +0100 ++++ b/editor/pnmgamma.c 2025-02-04 09:21:03.587045507 +0100 +@@ -596,6 +596,7 @@ createGammaTables(enum transferFunction xelval ** const btableP) { /* Allocate space for the tables. */ @@ -4141,11 +619,10 @@ index 1fdf20e..98b7e90 100644 MALLOCARRAY(*rtableP, maxval+1); MALLOCARRAY(*gtableP, maxval+1); MALLOCARRAY(*btableP, maxval+1); -diff --git a/editor/pnmhisteq.c b/editor/pnmhisteq.c -index a339f73..c2c85a3 100644 ---- a/editor/pnmhisteq.c -+++ b/editor/pnmhisteq.c -@@ -107,6 +107,7 @@ computeLuminosityHistogram(xel * const * const xels, +diff -urNp a/editor/pnmhisteq.c b/editor/pnmhisteq.c +--- a/editor/pnmhisteq.c 2025-02-03 09:24:28.296500747 +0100 ++++ b/editor/pnmhisteq.c 2025-02-04 09:21:41.957864812 +0100 +@@ -106,6 +106,7 @@ computeLuminosityHistogram(xel * const * unsigned int pixelCount; unsigned int * lumahist; @@ -4153,23 +630,10 @@ index a339f73..c2c85a3 100644 MALLOCARRAY(lumahist, maxval + 1); if (lumahist == NULL) pm_error("Out of storage allocating array for %u histogram elements", -diff --git a/editor/pnmindex.csh b/editor/pnmindex.csh -index c6f1e84..c513a84 100755 ---- a/editor/pnmindex.csh -+++ b/editor/pnmindex.csh -@@ -1,5 +1,7 @@ - #!/bin/csh -f - # -+echo "Unsafe code, needs debugging, do not ship" -+exit 1 - # pnmindex - build a visual index of a bunch of anymaps - # - # Copyright (C) 1991 by Jef Poskanzer. -diff --git a/editor/pnmpad.c b/editor/pnmpad.c -index 55cdcd6..10da3af 100644 ---- a/editor/pnmpad.c -+++ b/editor/pnmpad.c -@@ -654,6 +654,8 @@ main(int argc, const char ** argv) { +diff -urNp a/editor/pnmpad.c b/editor/pnmpad.c +--- a/editor/pnmpad.c 2025-02-03 09:24:28.299500730 +0100 ++++ b/editor/pnmpad.c 2025-02-04 09:22:39.237595043 +0100 +@@ -1127,6 +1127,8 @@ main(int argc, const char ** argv) { computePadSizes(cmdline, cols, rows, &lpad, &rpad, &tpad, &bpad); @@ -4178,19 +642,18 @@ index 55cdcd6..10da3af 100644 newcols = cols + lpad + rpad; if (cmdline.reportonly) -diff --git a/editor/pnmremap.c b/editor/pnmremap.c -index 0c0096b..8b86cb7 100644 ---- a/editor/pnmremap.c -+++ b/editor/pnmremap.c +diff -urNp a/editor/pnmremap.c b/editor/pnmremap.c +--- a/editor/pnmremap.c 2025-02-03 09:24:28.296500747 +0100 ++++ b/editor/pnmremap.c 2025-02-04 09:42:44.340919042 +0100 @@ -468,6 +468,7 @@ fserr_init(struct pam * const pamP, - - unsigned int const fserrSize = pamP->width + 2; + -----------------------------------------------------------------------------*/ + unsigned int plane; + overflow_add(pamP->width, 2); - fserrP->width = pamP->width; + unsigned int const fserrSz = pamP->width + 2; - MALLOCARRAY(fserrP->thiserr, pamP->depth); -@@ -506,6 +507,7 @@ floydInitRow(struct pam * const pamP, + fserrP->width = pamP->width; +@@ -508,6 +509,7 @@ floydInitRow(struct pam * const pamP, unsigned int col; @@ -4198,467 +661,82 @@ index 0c0096b..8b86cb7 100644 for (col = 0; col < pamP->width + 2; ++col) { unsigned int plane; for (plane = 0; plane < pamP->depth; ++plane) -diff --git a/editor/pnmremap.c.rej b/editor/pnmremap.c.rej -new file mode 100644 -index 0000000..c627c20 ---- /dev/null -+++ b/editor/pnmremap.c.rej -@@ -0,0 +1,10 @@ -+--- editor/pnmremap.c -++++ editor/pnmremap.c -+@@ -506,6 +507,7 @@ floydInitRow(struct pam * const pamP, struct Fserr * const fserrP) { -+ -+ int col; -+ -++ overflow_add(pamP->width, 2); -+ for (col = 0; col < pamP->width + 2; ++col) { -+ unsigned int plane; -+ for (plane = 0; plane < pamP->depth; ++plane) -diff --git a/editor/pnmscalefixed.c b/editor/pnmscalefixed.c -index 884ca31..747cd8f 100644 ---- a/editor/pnmscalefixed.c -+++ b/editor/pnmscalefixed.c -@@ -214,6 +214,7 @@ compute_output_dimensions(const struct cmdline_info cmdline, +diff -urNp a/editor/pnmscalefixed.c b/editor/pnmscalefixed.c +--- a/editor/pnmscalefixed.c 2025-02-03 09:24:28.299500730 +0100 ++++ b/editor/pnmscalefixed.c 2025-02-04 09:49:53.152275133 +0100 +@@ -215,6 +215,7 @@ compute_output_dimensions(const struct c const int rows, const int cols, int * newrowsP, int * newcolsP) { + overflow2(rows, cols); if (cmdline.pixels) { - if (rows * cols <= cmdline.pixels) { + if (rows <= cmdline.pixels / cols) { *newrowsP = rows; -@@ -265,6 +266,8 @@ compute_output_dimensions(const struct cmdline_info cmdline, - - if (*newcolsP < 1) *newcolsP = 1; - if (*newrowsP < 1) *newrowsP = 1; -+ -+ overflow2(*newcolsP, *newrowsP); - } - - -@@ -446,6 +449,9 @@ main(int argc, char **argv ) { - unfilled. We can address that by stretching, whereas the other - case would require throwing away some of the input. - */ +@@ -222,6 +223,8 @@ compute_output_dimensions(const struct c + } else { + const double scale = + sqrt( (float) cmdline.pixels / ((float) cols * (float) rows)); ++ overflow2(rows, scale); ++ overflow2(scale, cols); + *newrowsP = rows * scale; + *newcolsP = cols * scale; + } +@@ -455,6 +458,9 @@ main(int argc, char **argv ) { + pm_error("New image width (%d) is uncomputably large", newcols); + if (newrows > INT_MAX / SCALE) + pm_error("New image height (%d) is uncomputably large", newrows); + + overflow2(newcols, SCALE); + overflow2(newrows, SCALE); sxscale = SCALE * newcols / cols; syscale = SCALE * newrows / rows; -diff --git a/editor/ppmdither.c b/editor/ppmdither.c -index ec1b977..e701e09 100644 ---- a/editor/ppmdither.c -+++ b/editor/ppmdither.c -@@ -356,6 +356,11 @@ dithMatrix(unsigned int const dithPower) { - (dithDim * sizeof(*dithMat)) + /* pointers */ - (dithDim * dithDim * sizeof(**dithMat)); /* data */ - -+ -+ overflow2(dithDim, sizeof(*dithMat)); -+ overflow3(dithDim, dithDim, sizeof(**dithMat)); -+ overflow_add(dithDim * sizeof(*dithMat), dithDim * dithDim * sizeof(**dithMat)); -+ - dithMat = malloc(dithMatSize); - - if (dithMat == NULL) -diff --git a/editor/specialty/pamoil.c b/editor/specialty/pamoil.c -index 6cb8d3a..6f4bde9 100644 ---- a/editor/specialty/pamoil.c -+++ b/editor/specialty/pamoil.c -@@ -112,6 +112,7 @@ main(int argc, char *argv[] ) { - tuples = pnm_readpam(ifp, &inpam, PAM_STRUCT_SIZE(tuple_type)); - pm_close(ifp); +diff -urNp a/editor/specialty/pamoil.c b/editor/specialty/pamoil.c +--- a/editor/specialty/pamoil.c 2025-02-03 09:24:28.301500720 +0100 ++++ b/editor/specialty/pamoil.c 2025-02-04 09:56:21.543650456 +0100 +@@ -185,6 +185,7 @@ main(int argc, const char ** argv) { + + tuples = pnm_readpam(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); + overflow_add(inpam.maxval, 1); MALLOCARRAY(hist, inpam.maxval + 1); if (hist == NULL) pm_error("Unable to allocate memory for histogram."); -diff --git a/lib/libpam.c b/lib/libpam.c -index d19534e..ca6250a 100644 ---- a/lib/libpam.c -+++ b/lib/libpam.c -@@ -225,7 +225,8 @@ allocPamRow(const struct pam * const pamP) { +diff -urNp a/lib/libpam.c b/lib/libpam.c +--- a/lib/libpam.c 2025-02-03 09:24:28.326500585 +0100 ++++ b/lib/libpam.c 2025-02-04 10:04:33.126859799 +0100 +@@ -258,6 +258,7 @@ allocPamRow(const struct pam * const pam unsigned int const bytesPerTuple = allocationDepth(pamP) * sizeof(sample); tuple * tuplerow; -- tuplerow = malloc(pamP->width * (sizeof(tuple *) + bytesPerTuple)); + overflow_add(sizeof(tuple *), bytesPerTuple); -+ tuplerow = malloc2(pamP->width, (sizeof(tuple *) + bytesPerTuple)); + tuplerow = malloc(pamP->width * (sizeof(tuple *) + bytesPerTuple)); if (tuplerow != NULL) { - /* Now we initialize the pointers to the individual tuples -diff --git a/lib/libpammap.c b/lib/libpammap.c -index 569156f..ba27a4c 100644 ---- a/lib/libpammap.c -+++ b/lib/libpammap.c -@@ -64,7 +64,7 @@ pnm_createtuplehash(void) { - pm_error("Out of memory allocating tuple hash of size %u", - HASH_SIZE); - -- for (i = 0; i < HASH_SIZE; ++i) -+ for (i = 0; i < HASH_SIZE; ++i) - retval[i] = NULL; - - return retval; -@@ -82,13 +82,13 @@ pnm_destroytuplehash(tuplehash const tuplehash) { - for (i = 0; i < HASH_SIZE; ++i) { - struct tupleint_list_item * p; - struct tupleint_list_item * next; -- -+ - /* Walk this chain, freeing each element */ - for (p = tuplehash[i]; p; p = next) { - next = p->next; - - free(p); -- } -+ } - } - - /* Free the table of chains */ -@@ -98,18 +98,20 @@ pnm_destroytuplehash(tuplehash const tuplehash) { - - - --static struct tupleint_list_item * -+static struct tupleint_list_item * - allocTupleIntListItem(struct pam * const pamP) { - - -- /* This is complicated by the fact that the last element of a -+ /* This is complicated by the fact that the last element of a - tupleint_list_item is of variable length, because the last element -- of _it_ is of variable length -+ of _it_ is of variable length - */ - struct tupleint_list_item * retval; +diff -urNp a/lib/libpammap.c b/lib/libpammap.c +--- a/lib/libpammap.c 2025-02-03 09:24:28.325500590 +0100 ++++ b/lib/libpammap.c 2025-02-04 10:05:45.382614292 +0100 +@@ -111,6 +111,9 @@ allocTupleIntListItem(struct pam * const + if (pamP->depth > (UINT_MAX - sizeof(*retval)) / sizeof(sample)) + pm_error("Depth %u is too large for computation", pamP->depth); + overflow2(pamP->depth, sizeof(sample)); + overflow_add(sizeof(*retval)-sizeof(retval->tupleint.tuple), pamP->depth*sizeof(sample)); ++ unsigned int const size = -- sizeof(*retval) - sizeof(retval->tupleint.tuple) -+ sizeof(*retval) - sizeof(retval->tupleint.tuple) + sizeof(*retval) - sizeof(retval->tupleint.tuple) + pamP->depth * sizeof(sample); - - retval = (struct tupleint_list_item *) malloc(size); -@@ -121,7 +123,7 @@ allocTupleIntListItem(struct pam * const pamP) { - - void - pnm_addtotuplehash(struct pam * const pamP, -- tuplehash const tuplehash, -+ tuplehash const tuplehash, - tuple const tupletoadd, - int const value, - int * const fitsP) { -@@ -138,7 +140,7 @@ pnm_addtotuplehash(struct pam * const pamP, - *fitsP = FALSE; - else { - unsigned int const hashvalue = pnm_hashtuple(pamP, tupletoadd); -- -+ - *fitsP = TRUE; - - pnm_assigntuple(pamP, listItemP->tupleint.tuple, tupletoadd); -@@ -151,10 +153,10 @@ pnm_addtotuplehash(struct pam * const pamP, - - - void --pnm_lookuptuple(struct pam * const pamP, -- const tuplehash tuplehash, -- const tuple searchval, -- int * const foundP, -+pnm_lookuptuple(struct pam * const pamP, -+ const tuplehash tuplehash, -+ const tuple searchval, -+ int * const foundP, - int * const retvalP) { - /*---------------------------------------------------------------------------- - Return as *revtvalP the index of the tuple value 'searchval' in the -@@ -183,18 +185,18 @@ pnm_lookuptuple(struct pam * const pamP, - - - static void --addColorOccurrenceToHash(tuple const color, -+addColorOccurrenceToHash(tuple const color, - tuplehash const tuplefreqhash, - struct pam * const pamP, - unsigned int const maxsize, - unsigned int * const sizeP, - bool * const fullP) { -- -+ - unsigned int const hashvalue = pnm_hashtuple(pamP, color); -- -+ - struct tupleint_list_item *p; - -- for (p = tuplefreqhash[hashvalue]; -+ for (p = tuplefreqhash[hashvalue]; - p && !pnm_tupleequal(pamP, p->tupleint.tuple, color); - p = p->next); - -@@ -205,7 +207,7 @@ addColorOccurrenceToHash(tuple const color, - } else { - /* It's not in the hash yet, so add it (if allowed) */ - ++(*sizeP); -- if (maxsize > 0 && *sizeP > maxsize) -+ if (maxsize > 0 && *sizeP > maxsize) - *fullP = TRUE; - else { - *fullP = FALSE; -@@ -228,7 +230,7 @@ pnm_addtuplefreqoccurrence(struct pam * const pamP, - tuplehash const tuplefreqhash, - int * const firstOccurrenceP) { - /*---------------------------------------------------------------------------- -- Tally one more occurrence of the tuple value 'value' to the tuple frequency -+ Tally one more occurence of the tuple value 'value' to the tuple frequencey - hash 'tuplefreqhash', adding the tuple to the hash if it isn't there - already. - -@@ -238,10 +240,10 @@ pnm_addtuplefreqoccurrence(struct pam * const pamP, - program. - -----------------------------------------------------------------------------*/ - unsigned int const hashvalue = pnm_hashtuple(pamP, value); -- -+ - struct tupleint_list_item * p; - -- for (p = tuplefreqhash[hashvalue]; -+ for (p = tuplefreqhash[hashvalue]; - p && !pnm_tupleequal(pamP, p->tupleint.tuple, value); - p = p->next); - -@@ -270,8 +272,8 @@ pnm_addtuplefreqoccurrence(struct pam * const pamP, - - static void - computehashrecoverable(struct pam * const pamP, -- tuple ** const tupleArray, -- unsigned int const maxsize, -+ tuple ** const tupleArray, -+ unsigned int const maxsize, - unsigned int const newDepth, - sample const newMaxval, - unsigned int * const sizeP, -@@ -295,20 +297,20 @@ computehashrecoverable(struct pam * const pamP, - - *tuplefreqhashP = pnm_createtuplehash(); - *sizeP = 0; /* initial value */ -- -+ - *rowbufferP = pnm_allocpamrow(pamP); -- -+ - *colorP = pnm_allocpamtuple(pamP); -- -+ - full = FALSE; /* initial value */ -- -+ - /* Go through the entire raster, building a hash table of -- tuple values. -+ tuple values. - */ - for (row = 0; row < pamP->height && !full; ++row) { - unsigned int col; - const tuple * tuplerow; /* The row of tuples we are processing */ -- -+ - if (tupleArray) - tuplerow = tupleArray[row]; - else { -@@ -335,8 +337,8 @@ computehashrecoverable(struct pam * const pamP, - - static tuplehash - computetuplefreqhash(struct pam * const pamP, -- tuple ** const tupleArray, -- unsigned int const maxsize, -+ tuple ** const tupleArray, -+ unsigned int const maxsize, - unsigned int const newDepth, - sample const newMaxval, - unsigned int * const sizeP) { -@@ -350,18 +352,18 @@ computetuplefreqhash(struct pam * const pamP, - - 2) an open PAM file, positioned to the raster. In this case, - 'tupleArray' is NULL. *pamP contains the file descriptor. -- -- We return with the file still open and its position undefined. -+ -+ We return with the file still open and its position undefined. - - In either case, *pamP contains parameters of the tuple array. - - Return the number of unique tuple values found as *sizeP. - -- However, if the number of unique tuple values is greater than 'maxsize', -+ However, if the number of unique tuple values is greater than 'maxsize', - return a null return value and *sizeP undefined. - - The tuple values that index the hash have depth 'newDepth'. We look at -- only the first 'newDepth' planes of the input. Caller must ensure that -+ only the first 'newDepth' planes of the input. Caler must ensure that - the input has at least that many planes. - - The tuple values that index the hash are scaled to a new maxval of -@@ -374,18 +376,18 @@ computetuplefreqhash(struct pam * const pamP, - /* Buffer for a row read from the input file; undefined (but still - allocated) if input is not from a file. - */ -- tuple color; -+ tuple color; - /* The color currently being added, scaled to the new maxval */ - jmp_buf jmpbuf; - jmp_buf * origJmpbufP; -- -+ - /* Initialize to "none" for purposes of error recovery */ - tuplefreqhash = NULL; - rowbuffer = NULL; - color = NULL; - - if (setjmp(jmpbuf) != 0) { -- if (color) -+ if (color) - pnm_freepamtuple(color); - if (rowbuffer) - pnm_freepamrow(rowbuffer); -@@ -413,24 +415,24 @@ pnm_computetuplefreqhash(struct pam * const pamP, - Compute the tuple frequency hash for the tuple array tupleArray[][]. - -----------------------------------------------------------------------------*/ - return computetuplefreqhash(pamP, tupleArray, maxsize, -- pamP->depth, pamP->maxval, -+ pamP->depth, pamP->maxval, - sizeP); - } - - - - static void --alloctupletable(const struct pam * const pamP, -+alloctupletable(const struct pam * const pamP, - unsigned int const size, - tupletable * const tupletableP, - const char ** const errorP) { -- -+ - if (UINT_MAX / sizeof(struct tupleint) < size) - pm_asprintf(errorP, "size %u is too big for arithmetic", size); - else { - unsigned int const mainTableSize = size * sizeof(struct tupleint *); -- unsigned int const tupleIntSize = -- sizeof(struct tupleint) - sizeof(sample) -+ unsigned int const tupleIntSize = -+ sizeof(struct tupleint) - sizeof(sample) - + pamP->depth * sizeof(sample); - - /* To save the enormous amount of time it could take to allocate -@@ -442,7 +444,7 @@ alloctupletable(const struct pam * const pamP, - else { - unsigned int const allocSize = mainTableSize + size * tupleIntSize; - void * pool; -- -+ - pool = malloc(allocSize); - - if (!pool) -@@ -469,7 +471,7 @@ alloctupletable(const struct pam * const pamP, - - - tupletable --pnm_alloctupletable(const struct pam * const pamP, -+pnm_alloctupletable(const struct pam * const pamP, - unsigned int const size) { - - tupletable retval; -@@ -491,8 +493,8 @@ void - pnm_freetupletable(const struct pam * const pamP, - tupletable const tupletable) { - -- /* Note that the address 'tupletable' is, to the operating system, -- the address of a larger block of memory that contains not only -+ /* Note that the address 'tupletable' is, to the operating system, -+ the address of a larger block of memory that contains not only - tupletable, but all the samples to which it points (e.g. - tupletable[0].tuple[0]) - */ -@@ -574,7 +576,7 @@ pnm_tuplehashtotable(const struct pam * const pamP, - - - tuplehash --pnm_computetupletablehash(struct pam * const pamP, -+pnm_computetupletablehash(struct pam * const pamP, - tupletable const tupletable, - unsigned int const tupletableSize) { - /*---------------------------------------------------------------------------- -@@ -591,12 +593,12 @@ pnm_computetupletablehash(struct pam * const pamP, - tuplehash tupletablehash; - unsigned int i; - int fits; -- -+ - tupletablehash = pnm_createtuplehash(); - - fits = TRUE; /* initial assumption */ - for (i = 0; i < tupletableSize && fits; ++i) { -- pnm_addtotuplehash(pamP, tupletablehash, -+ pnm_addtotuplehash(pamP, tupletablehash, - tupletable[i]->tuple, i, &fits); - } - if (!fits) { -@@ -658,7 +660,7 @@ pnm_computetuplefreqtable3(struct pam * const pamP, - "argument (%u) greater than input depth (%u)", - newDepth, pamP->depth); - -- tuplefreqhash = computetuplefreqhash(pamP, tupleArray, maxsize, -+ tuplefreqhash = computetuplefreqhash(pamP, tupleArray, maxsize, - newDepth, newMaxval, &uniqueCount); - if (tuplefreqhash == NULL) - tuplefreqtable = NULL; -@@ -704,8 +706,8 @@ pnm_computetuplefreqtable(struct pam * const pamP, - - - char* --pam_colorname(struct pam * const pamP, -- tuple const color, -+pam_colorname(struct pam * const pamP, -+ tuple const color, - enum colornameFormat const format) { - - unsigned int r, g, b; -@@ -726,9 +728,9 @@ pam_colorname(struct pam * const pamP, - while (!done) { - struct colorfile_entry const ce = pm_colorget(f); - if (ce.colorname) { -- unsigned int const this_diff = -- abs((int)r - (int)ce.r) + -- abs((int)g - (int)ce.g) + -+ unsigned int const this_diff = -+ abs((int)r - (int)ce.r) + -+ abs((int)g - (int)ce.g) + - abs((int)b - (int)ce.b); - - if (this_diff < best_diff) { -@@ -739,7 +741,7 @@ pam_colorname(struct pam * const pamP, - done = TRUE; - } - fclose(f); -- if (best_diff != 32767 && -+ if (best_diff != 32767 && - (best_diff == 0 || format == PAM_COLORNAME_ENGLISH)) - return colorname; - } -diff --git a/lib/libpm.c b/lib/libpm.c -index bc92238..aa67dcd 100644 ---- a/lib/libpm.c -+++ b/lib/libpm.c -@@ -888,5 +888,53 @@ pm_parse_height(const char * const arg) { - return height; +diff -urNp a/lib/libpm.c b/lib/libpm.c +--- a/lib/libpm.c 2025-02-03 09:24:28.324500595 +0100 ++++ b/lib/libpm.c 2025-02-04 10:27:02.795619696 +0100 +@@ -926,4 +926,52 @@ pm_parse_maxval(const char * const arg) + return maxval; } +/* -+ * Maths wrapping ++ * Maths wrapping + */ - ++ +void __overflow2(int a, int b) +{ + if(a < 0 || b < 0) @@ -4696,22 +774,20 @@ index bc92238..aa67dcd 100644 + pm_error("Zero byte allocation"); + return malloc(a*b*c); +} -+ +void *realloc2(void * a, int b, int c) +{ -+ overflow2(b, c); -+ if(b*c == 0) ++ overflow2(b, c); ++ if(b*c == 0) + pm_error("Zero byte allocation"); + return realloc(a, b*c); +} -diff --git a/lib/pm.h b/lib/pm.h -index 3fc92fb..1e30ce9 100644 ---- a/lib/pm.h -+++ b/lib/pm.h -@@ -441,5 +441,12 @@ pm_parse_height(const char * const arg); - } - #endif +diff -urNp a/lib/pm.h b/lib/pm.h +--- a/lib/pm.h 2025-02-03 09:24:28.327500579 +0100 ++++ b/lib/pm.h 2025-02-04 10:28:10.427411309 +0100 +@@ -439,6 +439,13 @@ pm_parse_height(const char * const arg); + unsigned int + pm_parse_maxval(const char * const arg); +void *malloc2(int, int); +void *malloc3(int, int, int); @@ -4720,1655 +796,58 @@ index 3fc92fb..1e30ce9 100644 +void overflow3(int, int, int); +void overflow_add(int, int); + - + #ifdef __cplusplus + } #endif -diff --git a/lib/pm.h.orig b/lib/pm.h.orig -new file mode 100644 -index 0000000..471f445 ---- /dev/null -+++ b/lib/pm.h.orig -@@ -0,0 +1,446 @@ -+/* pm.h - interface to format-independent part of libpbm. -+** -+** Copyright (C) 1988, 1989, 1991 by Jef Poskanzer. -+** -+** Permission to use, copy, modify, and distribute this software and its -+** documentation for any purpose and without fee is hereby granted, provided -+** that the above copyright notice appear in all copies and that both that -+** copyright notice and this permission notice appear in supporting -+** documentation. This software is provided "as is" without express or -+** implied warranty. -+*/ -+ -+#ifndef PM_H_INCLUDED -+#define PM_H_INCLUDED -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+#if 0 -+} /* to fake out automatic code indenters */ -+#endif -+ -+ -+/* Definitions to make Netpbm programs work with either ANSI C or C -+ Classic. -+ -+ This is obsolete, as all compilers recognize the ANSI syntax now. -+ -+ We are slowly removing all the ARGS invocations from the programs -+ (and replacing them with explicit ANSI syntax), but we have a lot -+ of programs where we have removed ARGS from the definition but not -+ the prototype, and we have discovered that the Sun compiler -+ considers the resulting mismatch between definition and prototype -+ to be an error. So we make ARGS create the ANSI syntax -+ unconditionally to avoid having to fix all those mismatches. */ -+ -+#if 0 -+#if __STDC__ -+#define ARGS(alist) alist -+#else /*__STDC__*/ -+#define ARGS(alist) () -+#define const -+#endif /*__STDC__*/ -+#endif -+#define ARGS(alist) alist -+ -+ -+/* PM_GNU_PRINTF_ATTR lets the GNU compiler check pm_message() and pm_error() -+ calls to be sure the arguments match the format string, thus preventing -+ runtime segmentation faults and incorrect messages. -+*/ -+#ifdef __GNUC__ -+#define PM_GNU_PRINTF_ATTR(a,b) __attribute__ ((format (printf, a, b))) -+#else -+#define PM_GNU_PRINTF_ATTR(a,b) -+#endif -+ -+ -+/* PURE_FN_ATTR is the attribute you add to a function declaration -+ that indicates it's a true function -- has no side effects and return -+ value is not influenced by anything except its arguments. -+*/ -+#ifdef __GNUC__ -+#define PURE_FN_ATTR __attribute__ ((const)) -+#else -+#define PURE_FN_ATTR -+#endif -+ -+ -+/* S_IRUSR is POSIX, defined in Some old BSD systems and Windows -+ systems have S_IREAD instead. Most Unix today (2011) has both. In 2011, -+ Android has S_IRUSR and not S_IREAD. -+ -+ Some Windows has _S_IREAD. -+ -+ We're ignoring S_IREAD now to see if anyone misses it. If there are still -+ users that need it, we can handle it here. -+*/ -+#if MSVCRT -+ #define PM_S_IWUSR _S_IWRITE -+ #define PM_S_IRUSR _S_IREAD -+#else -+ #define PM_S_IWUSR S_IWUSR -+ #define PM_S_IRUSR S_IRUSR -+#endif -+ -+ -+ -+typedef struct { -+ /* Coordinates of a pixel within an image. Row 0 is the top row. -+ Column 0 is the left column. -+ */ -+ unsigned int row; -+ unsigned int col; -+} pm_pixelcoord; -+ -+extern int pm_plain_output; -+ /* Output functions are to produce plain (as opposed to raw) format -+ regardless of their 'plainformat' arguments. -+ */ -+extern const char * pm_progname; -+ -+void -+pm_init(const char * const progname, unsigned int const flags); -+ -+void -+pm_proginit(int * const argcP, const char * argv[]); -+ -+void -+pm_setMessage(int const newState, int * const oldStateP); -+ -+int -+pm_getMessage(void); -+ -+FILE * -+pm_tmpfile(void); -+ -+int -+pm_tmpfile_fd(void); -+ -+void -+pm_make_tmpfile(FILE ** const filePP, -+ const char ** const filenameP); -+ -+void -+pm_make_tmpfile_fd(int * const fdP, -+ const char ** const filenameP); -+ -+void -+pm_nextimage(FILE * const file, int * const eofP); -+ -+/* Variable-sized arrays definitions. */ -+ -+char** -+pm_allocarray (int const cols, int const rows, int const size ); -+ -+void * -+pm_allocrow(unsigned int const cols, -+ unsigned int const size); -+ -+void -+pm_freearray (char** const its, int const rows); -+ -+void -+pm_freerow(void * const row); -+ -+ -+/* Obsolete -- use shhopt instead */ -+int -+pm_keymatch(const char * const str, -+ const char * const keyword, -+ int const minchars); -+ -+ -+int PURE_FN_ATTR -+pm_maxvaltobits(int const maxval); -+ -+int PURE_FN_ATTR -+pm_bitstomaxval(int const bits); -+ -+unsigned int PURE_FN_ATTR -+pm_lcm (unsigned int const x, -+ unsigned int const y, -+ unsigned int const z, -+ unsigned int const limit); -+ -+void -+pm_setjmpbuf(jmp_buf * const jmpbufP); -+ -+void -+pm_setjmpbufsave(jmp_buf * const jmpbufP, -+ jmp_buf ** const oldJmpbufPP); -+ -+void -+pm_longjmp(void); -+ -+void -+pm_fork(int * const iAmParentP, -+ pid_t * const childPidP, -+ const char ** const errorP); -+ -+void -+pm_waitpid(pid_t const pid, -+ int * const statusP, -+ int const options, -+ pid_t * const exitedPidP, -+ const char ** const errorP); -+ -+ -+void -+pm_waitpidSimple(pid_t const pid); -+ -+typedef void pm_usermessagefn(const char * msg); -+ -+void -+pm_setusermessagefn(pm_usermessagefn * fn); -+ -+typedef void pm_usererrormsgfn(const char * msg); -+ -+void -+pm_setusererrormsgfn(pm_usererrormsgfn * fn); -+ -+void PM_GNU_PRINTF_ATTR(1,2) -+pm_message (const char format[], ...); -+ -+void PM_GNU_PRINTF_ATTR(1,2) -+pm_errormsg(const char format[], ...); -+ -+void PM_GNU_PRINTF_ATTR(1,2) -+pm_error (const char reason[], ...); -+ -+int -+pm_have_float_format(void); -+ -+/* Obsolete - use shhopt and user's manual instead */ -+void -+pm_usage (const char usage[]); -+ -+FILE* -+pm_openr (const char* const name); -+ -+FILE* -+pm_openw (const char* const name); -+ -+FILE * -+pm_openr_seekable(const char name[]); -+ -+void -+pm_close (FILE* const f); -+ -+void -+pm_closer (FILE* const f); -+ -+void -+pm_closew (FILE* const f); -+ -+ -+ -+void -+pm_readchar(FILE * const ifP, -+ char * const cP); -+ -+static __inline__ void -+pm_readcharu(FILE * const ifP, -+ unsigned char * const cP) { -+ pm_readchar(ifP, (char *) cP); -+} -+ -+void -+pm_writechar(FILE * const ofP, -+ char const c); -+ -+static __inline__ void -+pm_writecharu(FILE * const ofP, -+ unsigned char const c) { -+ pm_writechar(ofP, (char) c); -+} -+ -+int -+pm_readbigshort(FILE * const ifP, -+ short * const sP); -+ -+static __inline__ int -+pm_readbigshortu(FILE* const ifP, -+ unsigned short * const sP) { -+ return pm_readbigshort(ifP, (short *) sP); -+} -+ -+int -+pm_writebigshort(FILE * const ofP, -+ short const s); -+ -+static __inline__ int -+pm_writebigshortu(FILE * const ofP, -+ unsigned short const s) { -+ return pm_writebigshort(ofP, (short) s); -+} -+ -+int -+pm_readbiglong(FILE * const ifP, -+ long * const lP); -+ -+static __inline__ int -+pm_readbiglongu(FILE * const ifP, -+ unsigned long * const lP) { -+ return pm_readbiglong(ifP, (long *) lP); -+} -+ -+int -+pm_readbiglong2(FILE * const ifP, -+ int32_t * const lP); -+ -+static __inline__ int -+pm_readbiglongu2(FILE * const ifP, -+ uint32_t * const lP) { -+ return pm_readbiglong2(ifP, (int32_t *) lP); -+} -+ -+int -+pm_writebiglong(FILE * const ofP, -+ long const l); -+ -+static __inline__ int -+pm_writebiglongu(FILE * const ofP, -+ unsigned long const l) { -+ return pm_writebiglong(ofP, (long) l); -+} -+ -+int -+pm_readlittleshort(FILE * const ifP, -+ short * const sP); -+ -+static __inline__ int -+pm_readlittleshortu(FILE * const ifP, -+ unsigned short * const sP) { -+ return pm_readlittleshort(ifP, (short *) sP); -+} -+ -+int -+pm_writelittleshort(FILE * const ofP, -+ short const s); -+ -+static __inline__ int -+pm_writelittleshortu(FILE * const ofP, -+ unsigned short const s) { -+ return pm_writelittleshort(ofP, (short) s); -+} -+ -+int -+pm_readlittlelong(FILE * const ifP, -+ long * const lP); -+ -+static __inline__ int -+pm_readlittlelongu(FILE * const ifP, -+ unsigned long * const lP) { -+ return pm_readlittlelong(ifP, (long *) lP); -+} -+ -+int -+pm_readlittlelong2(FILE * const ifP, -+ int32_t * const lP); -+ -+static __inline__ int -+pm_readlittlelong2u(FILE * const ifP, -+ uint32_t * const lP) { -+ return pm_readlittlelong2(ifP, (int32_t *) lP); -+} -+ -+int -+pm_writelittlelong(FILE * const ofP, -+ long const l); -+ -+static __inline__ int -+pm_writelittlelongu(FILE * const ofP, -+ unsigned long const l) { -+ return pm_writelittlelong(ofP, (long) l); -+} -+ -+int -+pm_readmagicnumber(FILE * const ifP); -+ -+char* -+pm_read_unknown_size(FILE * const ifP, -+ long * const buf); -+ -+void -+pm_getline(FILE * const ifP, -+ char ** const bufferP, -+ size_t * const bufferSzP, -+ int * const eofP, -+ size_t * const lineLenP); -+ -+short -+pm_bs_short(short const s); -+ -+long -+pm_bs_long(long const l); -+ -+unsigned int -+pm_tell(FILE * const fileP); -+ -+void -+pm_tell2(FILE * const fileP, -+ void * const fileposP, -+ unsigned int const fileposSize); -+ -+void -+pm_seek2(FILE * const fileP, -+ const pm_filepos * const fileposP, -+ unsigned int const fileposSize); -+ -+void -+pm_seek(FILE * const fileP, unsigned long filepos); -+ -+enum pm_check_code { -+ PM_CHECK_OK, -+ PM_CHECK_UNKNOWN_TYPE, -+ PM_CHECK_TOO_LONG, -+ PM_CHECK_UNCHECKABLE, -+ PM_CHECK_TOO_SHORT -+}; -+ -+enum pm_check_type { -+ PM_CHECK_BASIC -+}; -+ -+void -+pm_check(FILE * const file, -+ enum pm_check_type const check_type, -+ pm_filepos const need_raster_size, -+ enum pm_check_code * const retval_p); -+ -+void -+pm_drain(FILE * const fileP, -+ unsigned int const limit, -+ unsigned int * const bytesReadP); -+ -+char * -+pm_arg0toprogname(const char arg0[]); -+ -+unsigned int -+pm_randseed(void); -+ -+unsigned int -+pm_parse_width(const char * const arg); -+ -+unsigned int -+pm_parse_height(const char * const arg); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+ -+#endif -diff --git a/other/pnmcolormap.c b/other/pnmcolormap.c -index 7da3122..dafa390 100644 ---- a/other/pnmcolormap.c -+++ b/other/pnmcolormap.c -@@ -1002,6 +1002,7 @@ colormapToSquare(struct pam * const pamP, +diff -urNp a/other/pnmcolormap.c b/other/pnmcolormap.c +--- a/other/pnmcolormap.c 2025-02-03 09:24:28.303500709 +0100 ++++ b/other/pnmcolormap.c 2025-02-04 10:29:08.620231936 +0100 +@@ -1130,8 +1130,10 @@ colormapToSquare(struct pam * const pamP + unsigned int const intsqrt = (int)sqrt((float)colormap.size); + if (SQR(intsqrt) == colormap.size) pamP->width = intsqrt; - else - pamP->width = intsqrt + 1; +- else ++ else { + overflow_add(intsqrt, 1); + pamP->width = intsqrt + 1; ++ } } { unsigned int const intQuotient = colormap.size / pamP->width; -diff --git a/other/pnmcolormap.c.orig b/other/pnmcolormap.c.orig -new file mode 100644 -index 0000000..7da3122 ---- /dev/null -+++ b/other/pnmcolormap.c.orig -@@ -0,0 +1,1143 @@ -+/****************************************************************************** -+ pnmcolormap.c -+******************************************************************************* -+ -+ Create a colormap file (a PPM image containing one pixel of each of a set -+ of colors). Base the set of colors on an input image. -+ -+ For PGM input, do the equivalent for grayscale and produce a PGM graymap. -+ -+ By Bryan Henderson, San Jose, CA 2001.12.17 -+ -+ Derived from ppmquant, originally by Jef Poskanzer. -+ -+ Copyright (C) 1989, 1991 by Jef Poskanzer. -+ Copyright (C) 2001 by Bryan Henderson. -+ -+ Permission to use, copy, modify, and distribute this software and its -+ documentation for any purpose and without fee is hereby granted, provided -+ that the above copyright notice appear in all copies and that both that -+ copyright notice and this permission notice appear in supporting -+ documentation. This software is provided "as is" without express or -+ implied warranty. -+ -+******************************************************************************/ -+ -+#include -+#include -+ -+#include "pm_config.h" -+#include "pm_c_util.h" -+#include "mallocvar.h" -+#include "nstring.h" -+#include "shhopt.h" -+#include "pam.h" -+#include "pammap.h" -+ -+enum MethodForLargest {LARGE_NORM, LARGE_LUM}; -+ -+enum MethodForRep {REP_CENTER_BOX, REP_AVERAGE_COLORS, REP_AVERAGE_PIXELS}; -+ -+enum MethodForSplit {SPLIT_MAX_PIXELS, SPLIT_MAX_COLORS, SPLIT_MAX_SPREAD}; -+ -+struct Box { -+ unsigned int index; -+ unsigned int colorCt; -+ unsigned int sum; -+ unsigned int maxdim; -+ /* which dimension has the largest spread. RGB plane number. */ -+ sample spread; -+ /* spread in dimension 'maxdim' */ -+}; -+ -+struct BoxVector { -+ struct Box * box; /* malloc'ed array */ -+ unsigned int boxCt; -+ unsigned int capacity; -+}; -+ -+struct CmdlineInfo { -+ /* All the information the user supplied in the command line, -+ in a form easy for the program to use. -+ */ -+ const char * inputFileNm; /* Name of input file */ -+ unsigned int allcolors; /* boolean: select all colors from the input */ -+ unsigned int newcolors; -+ /* Number of colors argument; meaningless if allcolors true */ -+ enum MethodForLargest methodForLargest; -+ /* -spreadintensity/-spreadluminosity options */ -+ enum MethodForRep methodForRep; -+ /* -center/-meancolor/-meanpixel options */ -+ enum MethodForSplit methodForSplit; -+ /* -splitpixelct/-splitcolorct/-splitspread options */ -+ unsigned int sort; -+ unsigned int square; -+ unsigned int verbose; -+}; -+ -+ -+ -+static void -+parseCommandLine (int argc, const char ** argv, -+ struct CmdlineInfo *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 option_def_index; -+ -+ unsigned int spreadbrightness, spreadluminosity; -+ unsigned int center, meancolor, meanpixel; -+ unsigned int splitpixelct, splitcolorct, splitspread; -+ -+ MALLOCARRAY_NOFAIL(option_def, 100); -+ -+ option_def_index = 0; /* incremented by OPTENT3 */ -+ OPTENT3(0, "spreadbrightness", OPT_FLAG, -+ NULL, &spreadbrightness, 0); -+ OPTENT3(0, "spreadluminosity", OPT_FLAG, -+ NULL, &spreadluminosity, 0); -+ OPTENT3(0, "center", OPT_FLAG, -+ NULL, ¢er, 0); -+ OPTENT3(0, "meancolor", OPT_FLAG, -+ NULL, &meancolor, 0); -+ OPTENT3(0, "meanpixel", OPT_FLAG, -+ NULL, &meanpixel, 0); -+ OPTENT3(0, "splitpixelct", OPT_FLAG, -+ NULL, &splitpixelct, 0); -+ OPTENT3(0, "splitcolorct", OPT_FLAG, -+ NULL, &splitcolorct, 0); -+ OPTENT3(0, "splitspread", OPT_FLAG, -+ NULL, &splitspread, 0); -+ OPTENT3(0, "sort", OPT_FLAG, NULL, -+ &cmdlineP->sort, 0 ); -+ OPTENT3(0, "square", OPT_FLAG, NULL, -+ &cmdlineP->square, 0 ); -+ OPTENT3(0, "verbose", OPT_FLAG, NULL, -+ &cmdlineP->verbose, 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 *cmdline_p and others. */ -+ -+ -+ if (spreadbrightness && spreadluminosity) -+ pm_error("You cannot specify both -spreadbrightness and " -+ "spreadluminosity."); -+ if (spreadluminosity) -+ cmdlineP->methodForLargest = LARGE_LUM; -+ else -+ cmdlineP->methodForLargest = LARGE_NORM; -+ -+ if (center + meancolor + meanpixel > 1) -+ pm_error("You can specify only one of -center, -meancolor, and " -+ "-meanpixel."); -+ if (meancolor) -+ cmdlineP->methodForRep = REP_AVERAGE_COLORS; -+ else if (meanpixel) -+ cmdlineP->methodForRep = REP_AVERAGE_PIXELS; -+ else -+ cmdlineP->methodForRep = REP_CENTER_BOX; -+ -+ if (splitpixelct) -+ cmdlineP->methodForSplit = SPLIT_MAX_PIXELS; -+ else if (splitcolorct) -+ cmdlineP->methodForSplit = SPLIT_MAX_COLORS; -+ else if (splitspread) -+ cmdlineP->methodForSplit = SPLIT_MAX_SPREAD; -+ else -+ cmdlineP->methodForSplit = SPLIT_MAX_PIXELS; -+ -+ if (argc-1 > 2) -+ pm_error("Program takes at most two arguments: number of colors " -+ "and input file specification. " -+ "You specified %d arguments.", argc-1); -+ else { -+ if (argc-1 < 2) -+ cmdlineP->inputFileNm = "-"; -+ else -+ cmdlineP->inputFileNm = argv[2]; -+ -+ if (argc-1 < 1) -+ pm_error("You must specify the number of colors in the " -+ "output as an argument."); -+ else { -+ if (strcmp(argv[1], "all") == 0) -+ cmdlineP->allcolors = TRUE; -+ else { -+ char * tail; -+ long int const newcolors = strtol(argv[1], &tail, 10); -+ if (*tail != '\0') -+ pm_error("The number of colors argument '%s' is not " -+ "a number or 'all'", argv[1]); -+ else if (newcolors < 1) -+ pm_error("The number of colors must be positive"); -+ else if (newcolors == 1) -+ pm_error("The number of colors must be greater than 1."); -+ else { -+ cmdlineP->newcolors = newcolors; -+ cmdlineP->allcolors = FALSE; -+ } -+ } -+ } +diff -urNp a/urt/rle_addhist.c b/urt/rle_addhist.c +--- a/urt/rle_addhist.c 2025-02-03 09:24:28.360500401 +0100 ++++ b/urt/rle_addhist.c 2025-02-04 10:37:56.010607217 +0100 +@@ -52,6 +52,8 @@ newCommentLen(const char * const histoi + for (i = 0; argv[i]; ++i) { + size_t const thisArgLen = strlen(argv[i]); + if (thisArgLen < UINT_MAX - length - 100) { ++ overflow_add(length, thisArgLen); ++ overflow_add(length+thisArgLen, 1); + length += thisArgLen; + length += 1; /* For the space */ + } +@@ -61,10 +63,16 @@ newCommentLen(const char * const histoi + length += strlen(timedate); + + /* Add length of padding, "on ", and length of history name plus "="*/ ++ overflow_add(strlen(padding), 4); ++ overflow_add(strlen(histoire), strlen(padding) + 4); ++ overflow_add(length, strlen(histoire) + strlen(padding) + 4); + length += strlen(padding) + 3 + strlen(histoire) + 1; + +- if (old && *old) ++ overflow_add(length, 1); ++ if (old && *old) { ++ overflow_add(length, strlen(old)); + length += strlen(old); /* add length if there. */ + } -+} -+ -+ -+ -+#ifndef LITERAL_FN_DEF_MATCH -+static qsort_comparison_fn compareplane; -+#endif -+ -+static unsigned int compareplanePlane; -+ /* This is a parameter to compareplane(). We use this global variable -+ so that compareplane() can be called by qsort(), to compare two -+ tuples. qsort() doesn't pass any arguments except the two tuples. -+ */ -+static int -+compareplane(const void * const arg1, -+ const void * const arg2) { -+ -+ const struct tupleint * const * const comparandPP = arg1; -+ const struct tupleint * const * const comparatorPP = arg2; -+ -+ sample const comparandSample = (*comparandPP) ->tuple[compareplanePlane]; -+ sample const comparatorSample = (*comparatorPP)->tuple[compareplanePlane]; -+ -+ return -+ comparandSample < comparatorSample ? -1 : -+ comparandSample > comparatorSample ? 1 : -+ 0; -+} -+ -+ -+ -+#ifndef LITERAL_FN_DEF_MATCH -+static qsort_comparison_fn sumcompare; -+#endif -+ -+static int -+sumcompare(const void * const arg1, -+ const void * const arg2) { -+ -+ struct Box * const comparandP = (struct Box *)arg1; -+ struct Box * const comparatorP = (struct Box *)arg2; -+ -+ return -+ comparatorP->sum < comparandP->sum ? -1 : -+ comparatorP->sum > comparandP->sum ? 1 : -+ 0; -+} -+ -+ -+ -+#ifndef LITERAL_FN_DEF_MATCH -+static qsort_comparison_fn colcompare; -+#endif -+ -+static int -+colcompare(const void * const arg1, -+ const void * const arg2) { -+ -+ struct Box * const comparandP = (struct Box *)arg1; -+ struct Box * const comparatorP = (struct Box *)arg2; -+ -+ return -+ comparatorP->colorCt < comparandP->colorCt ? -1 : -+ comparatorP->colorCt > comparandP->colorCt ? 1 : -+ 0; -+} -+ -+ -+ -+#ifndef LITERAL_FN_DEF_MATCH -+static qsort_comparison_fn spreadcompare; -+#endif -+ -+static int -+spreadcompare(const void * const arg1, -+ const void * const arg2) { -+ -+ struct Box * const comparandP = (struct Box *)arg1; -+ struct Box * const comparatorP = (struct Box *)arg2; -+ -+ return -+ comparatorP->spread < comparandP->spread ? -1 : -+ comparatorP->spread > comparandP->spread ? 1 : -+ 0; -+} -+ -+ -+ -+static void -+sortBoxes(struct BoxVector * const boxVectorP, -+ enum MethodForSplit const methodForSplit) { -+ -+ qsort_comparison_fn * comparisonFn; -+ -+ switch (methodForSplit){ -+ case SPLIT_MAX_PIXELS: comparisonFn = &sumcompare; break; -+ case SPLIT_MAX_COLORS: comparisonFn = &colcompare; break; -+ case SPLIT_MAX_SPREAD: comparisonFn = &spreadcompare; break; -+ } -+ -+ qsort((char*) &boxVectorP->box[0], boxVectorP->boxCt, sizeof(struct Box), -+ comparisonFn); -+} -+ -+ -+ -+/* -+** Here is the fun part, the median-cut colormap generator. This is based -+** on Paul Heckbert's paper "Color Image Quantization for Frame Buffer -+** Display", SIGGRAPH '82 Proceedings, page 297. -+*/ -+ -+static void -+findBoxBoundaries(tupletable2 const colorfreqtable, -+ unsigned int const depth, -+ unsigned int const boxStart, -+ unsigned int const boxSize, -+ sample minval[], -+ sample maxval[]) { -+/*---------------------------------------------------------------------------- -+ Go through the box finding the minimum and maximum of each component - the -+ boundaries of the box. -+-----------------------------------------------------------------------------*/ -+ unsigned int plane; -+ unsigned int i; -+ -+ for (plane = 0; plane < depth; ++plane) { -+ minval[plane] = colorfreqtable.table[boxStart]->tuple[plane]; -+ maxval[plane] = minval[plane]; -+ } -+ -+ for (i = 1; i < boxSize; ++i) { -+ unsigned int plane; -+ for (plane = 0; plane < depth; ++plane) { -+ sample const v = colorfreqtable.table[boxStart + i]->tuple[plane]; -+ if (v < minval[plane]) minval[plane] = v; -+ if (v > maxval[plane]) maxval[plane] = v; -+ } -+ } -+} -+ -+ -+ -+static void -+findPlaneWithLargestSpreadByNorm(sample const minval[], -+ sample const maxval[], -+ unsigned int const depth, -+ unsigned int * const planeP, -+ sample * const spreadP) { -+ -+ unsigned int planeWithLargest; -+ sample largestSpreadSoFar; -+ unsigned int plane; -+ -+ for (plane = 0, largestSpreadSoFar = 0; plane < depth; ++plane) { -+ -+ sample const spread = maxval[plane]-minval[plane]; -+ if (spread > largestSpreadSoFar) { -+ largestSpreadSoFar = spread; -+ planeWithLargest = plane; -+ } -+ } -+ *planeP = planeWithLargest; -+ *spreadP = largestSpreadSoFar; -+} -+ -+ -+ -+static void -+findPlaneWithLargestSpreadByLuminosity(sample const minval[], -+ sample const maxval[], -+ unsigned int const depth, -+ unsigned int * const planeP, -+ sample * const spreadP) { -+/*---------------------------------------------------------------------------- -+ This subroutine presumes that the tuple type is either -+ BLACKANDWHITE, GRAYSCALE, or RGB (which implies pamP->depth is 1 or 3). -+ To save time, we don't actually check it. -+-----------------------------------------------------------------------------*/ -+ if (depth == 1){ -+ *planeP = 0; -+ *spreadP = 0; -+ } else { -+ /* An RGB tuple */ -+ unsigned int planeWithLargest; -+ sample largestSpreadSoFar; -+ unsigned int plane; -+ -+ assert(depth >= 3); -+ -+ for (plane = 0, largestSpreadSoFar = 0; plane < 3; ++plane) { -+ double const spread = -+ pnm_lumin_factor[plane] * (maxval[plane]-minval[plane]); -+ if (spread > largestSpreadSoFar) { -+ largestSpreadSoFar = spread; -+ planeWithLargest = plane; -+ } -+ } -+ *planeP = planeWithLargest; -+ *spreadP = largestSpreadSoFar; -+ } -+} -+ -+ -+ -+static void -+computeBoxSpread(const struct Box * const boxP, -+ tupletable2 const colorfreqtable, -+ unsigned int const depth, -+ enum MethodForLargest const methodForLargest, -+ unsigned int * const planeWithLargestP, -+ sample * const spreadP -+ ) { -+/*---------------------------------------------------------------------------- -+ Find the spread in the dimension in which it is greatest. -+ -+ Return as *planeWithLargestP the number of that plane and as *spreadP the -+ spread in that plane. -+-----------------------------------------------------------------------------*/ -+ sample * minval; /* malloc'ed array */ -+ sample * maxval; /* malloc'ed array */ -+ -+ MALLOCARRAY_NOFAIL(minval, depth); -+ MALLOCARRAY_NOFAIL(maxval, depth); -+ -+ findBoxBoundaries(colorfreqtable, depth, boxP->index, boxP->colorCt, -+ minval, maxval); -+ -+ switch (methodForLargest) { -+ case LARGE_NORM: -+ findPlaneWithLargestSpreadByNorm(minval, maxval, depth, -+ planeWithLargestP, spreadP); -+ break; -+ case LARGE_LUM: -+ findPlaneWithLargestSpreadByLuminosity(minval, maxval, depth, -+ planeWithLargestP, spreadP); -+ break; -+ } -+ free(minval); free(maxval); -+} -+ -+ -+ -+static unsigned int -+freqTotal(tupletable2 const freqtable) { -+ -+ unsigned int i; -+ unsigned int sum; -+ -+ for (i = 0, sum = 0; i < freqtable.size; ++i) -+ sum += freqtable.table[i]->value; -+ -+ return sum; -+} -+ -+ -+ -+static struct BoxVector -+newBoxVector(tupletable2 const colorfreqtable, -+ unsigned int const capacity, -+ unsigned int const depth, -+ enum MethodForLargest const methodForLargest) { -+ -+ unsigned int const colorCt = colorfreqtable.size; -+ unsigned int const sum = freqTotal(colorfreqtable); -+ -+ struct BoxVector boxVector; -+ -+ MALLOCARRAY(boxVector.box, capacity); -+ -+ if (!boxVector.box) -+ pm_error("out of memory allocating box vector table"); -+ -+ /* Set up the initial box. */ -+ boxVector.box[0].index = 0; -+ boxVector.box[0].colorCt = colorCt; -+ boxVector.box[0].sum = sum; -+ -+ computeBoxSpread(&boxVector.box[0], colorfreqtable, depth, -+ methodForLargest, -+ &boxVector.box[0].maxdim, -+ &boxVector.box[0].spread); -+ -+ boxVector.boxCt = 1; -+ boxVector.capacity = capacity; -+ -+ return boxVector; -+} -+ -+ -+ -+static void -+destroyBoxVector(struct BoxVector const boxVector) { -+ -+ free(boxVector.box); -+} -+ -+ -+ -+static void -+centerBox(int const boxStart, -+ int const boxSize, -+ tupletable2 const colorfreqtable, -+ unsigned int const depth, -+ tuple const newTuple) { -+ -+ unsigned int plane; -+ -+ for (plane = 0; plane < depth; ++plane) { -+ int minval, maxval; -+ unsigned int i; -+ -+ minval = maxval = colorfreqtable.table[boxStart]->tuple[plane]; -+ -+ for (i = 1; i < boxSize; ++i) { -+ int const v = colorfreqtable.table[boxStart + i]->tuple[plane]; -+ minval = MIN( minval, v); -+ maxval = MAX( maxval, v); -+ } -+ newTuple[plane] = (minval + maxval) / 2; -+ } -+} -+ -+ -+ -+static tupletable2 -+newColorMap(unsigned int const colorCt, -+ unsigned int const depth) { -+ -+ tupletable2 colormap; -+ unsigned int i; -+ struct pam pam; -+ -+ pam.depth = depth; -+ -+ colormap.table = pnm_alloctupletable(&pam, colorCt); -+ -+ for (i = 0; i < colorCt; ++i) { -+ unsigned int plane; -+ for (plane = 0; plane < depth; ++plane) -+ colormap.table[i]->tuple[plane] = 0; -+ } -+ colormap.size = colorCt; -+ -+ return colormap; -+} -+ -+ -+ -+static void -+averageColors(int const boxStart, -+ int const boxSize, -+ tupletable2 const colorfreqtable, -+ unsigned int const depth, -+ tuple const newTuple) { -+ -+ unsigned int plane; -+ -+ for (plane = 0; plane < depth; ++plane) { -+ sample sum; -+ int i; -+ -+ sum = 0; -+ -+ for (i = 0; i < boxSize; ++i) -+ sum += colorfreqtable.table[boxStart+i]->tuple[plane]; -+ -+ newTuple[plane] = ROUNDDIV(sum, boxSize); -+ } -+} -+ -+ -+ -+static void -+averagePixels(int const boxStart, -+ int const boxSize, -+ tupletable2 const colorfreqtable, -+ unsigned int const depth, -+ tuple const newTuple) { -+ -+ unsigned int n; -+ /* Number of tuples represented by the box */ -+ unsigned int plane; -+ unsigned int i; -+ -+ /* Count the tuples in question */ -+ n = 0; /* initial value */ -+ for (i = 0; i < boxSize; ++i) -+ n += colorfreqtable.table[boxStart + i]->value; -+ -+ -+ for (plane = 0; plane < depth; ++plane) { -+ sample sum; -+ int i; -+ -+ sum = 0; -+ -+ for (i = 0; i < boxSize; ++i) -+ sum += colorfreqtable.table[boxStart+i]->tuple[plane] -+ * colorfreqtable.table[boxStart+i]->value; -+ -+ newTuple[plane] = ROUNDDIV(sum, n); -+ } -+} -+ -+ -+ -+static tupletable2 -+colormapFromBv(unsigned int const colorCt, -+ struct BoxVector const boxVector, -+ tupletable2 const colorfreqtable, -+ unsigned int const depth, -+ enum MethodForRep const methodForRep) { -+ /* -+ ** Ok, we've got enough boxes. Now choose a representative color for -+ ** each box. There are a number of possible ways to make this choice. -+ ** One would be to choose the center of the box; this ignores any structure -+ ** within the boxes. Another method would be to average all the colors in -+ ** the box - this is the method specified in Heckbert's paper. A third -+ ** method is to average all the pixels in the box. -+ */ -+ tupletable2 colormap; -+ unsigned int boxIdx; -+ -+ colormap = newColorMap(colorCt, depth); -+ -+ for (boxIdx = 0; boxIdx < boxVector.boxCt; ++boxIdx) { -+ switch (methodForRep) { -+ case REP_CENTER_BOX: -+ centerBox(boxVector.box[boxIdx].index, -+ boxVector.box[boxIdx].colorCt, -+ colorfreqtable, depth, -+ colormap.table[boxIdx]->tuple); -+ break; -+ case REP_AVERAGE_COLORS: -+ averageColors(boxVector.box[boxIdx].index, -+ boxVector.box[boxIdx].colorCt, -+ colorfreqtable, depth, -+ colormap.table[boxIdx]->tuple); -+ break; -+ case REP_AVERAGE_PIXELS: -+ averagePixels(boxVector.box[boxIdx].index, -+ boxVector.box[boxIdx].colorCt, -+ colorfreqtable, depth, -+ colormap.table[boxIdx]->tuple); -+ break; -+ default: -+ pm_error("Internal error: invalid value of methodForRep: %d", -+ methodForRep); -+ } -+ } -+ return colormap; -+} -+ -+ -+ -+static void -+splitBox(struct BoxVector * const boxVectorP, -+ unsigned int const boxIdx, -+ tupletable2 const colorfreqtable, -+ unsigned int const depth, -+ enum MethodForLargest const methodForLargest, -+ enum MethodForSplit const methodForSplit) { -+/*---------------------------------------------------------------------------- -+ Split Box 'boxIdx' in the box vector 'boxVector' (so that bv contains one -+ more box than it did as input). Split it so that each new box represents -+ about half of the pixels in the distribution given by 'colorfreqtable' for -+ the colors in the original box, but with distinct colors in each of the two -+ new boxes. -+ -+ Assume the box contains at least two colors. -+-----------------------------------------------------------------------------*/ -+ unsigned int const boxStart = boxVectorP->box[boxIdx].index; -+ unsigned int const boxSize = boxVectorP->box[boxIdx].colorCt; -+ unsigned int const sum = boxVectorP->box[boxIdx].sum; -+ -+ unsigned int medianIndex; -+ int lowersum; -+ /* Number of pixels whose value is "less than" the median */ -+ -+ -+ /* Perhaps this sort should go after creating a box, not before splitting. -+ Because you need the sort to use the REP_CENTER_BOX method of choosing -+ a color to represent the final boxes -+ */ -+ -+ /* Set the gross global variable 'compareplanePlane' as a -+ parameter to compareplane(), which is called by qsort(). -+ */ -+ compareplanePlane = boxVectorP->box[boxIdx].maxdim; -+ qsort((char*) &colorfreqtable.table[boxStart], boxSize, -+ sizeof(colorfreqtable.table[boxStart]), -+ compareplane); -+ -+ { -+ /* Find the median based on the counts, so that about half the pixels -+ (not colors, pixels) are in each subdivision. -+ */ -+ unsigned int i; -+ -+ lowersum = colorfreqtable.table[boxStart]->value; /* initial value */ -+ for (i = 1; i < boxSize - 1 && lowersum < sum/2; ++i) { -+ lowersum += colorfreqtable.table[boxStart + i]->value; -+ } -+ medianIndex = i; -+ } -+ /* Split the box, and sort to bring the biggest boxes to the top. */ -+ { -+ struct Box * const oldBoxP = &boxVectorP->box[boxIdx]; -+ -+ oldBoxP->colorCt = medianIndex; -+ oldBoxP->sum = lowersum; -+ computeBoxSpread(oldBoxP, colorfreqtable, depth, methodForLargest, -+ &oldBoxP->maxdim, &oldBoxP->spread); -+ } -+ { -+ struct Box * const newBoxP = &boxVectorP->box[boxVectorP->boxCt]; -+ -+ newBoxP->index = boxStart + medianIndex; -+ newBoxP->colorCt = boxSize - medianIndex; -+ newBoxP->sum = sum - lowersum; -+ computeBoxSpread(newBoxP, colorfreqtable, depth, methodForLargest, -+ &newBoxP->maxdim, &newBoxP->spread); -+ ++boxVectorP->boxCt; -+ } -+ -+ sortBoxes(boxVectorP, methodForSplit); -+} -+ -+ -+ -+static void -+mediancut(tupletable2 const colorfreqtable, -+ unsigned int const depth, -+ int const newcolorCt, -+ enum MethodForLargest const methodForLargest, -+ enum MethodForRep const methodForRep, -+ enum MethodForSplit const methodForSplit, -+ tupletable2 * const colormapP) { -+/*---------------------------------------------------------------------------- -+ Compute a set of only 'newcolorCt' colors that best represent an -+ image whose pixels are summarized by the histogram -+ 'colorfreqtable'. Each tuple in that table has depth 'depth'. -+ colorfreqtable.table[i] tells the number of pixels in the subject image -+ have a particular color. -+ -+ As a side effect, sort 'colorfreqtable'. -+-----------------------------------------------------------------------------*/ -+ struct BoxVector boxVector; -+ bool multicolorBoxesExist; -+ /* There is at least one box that contains at least 2 colors; ergo, -+ there is more splitting we can do. -+ */ -+ -+ boxVector = newBoxVector(colorfreqtable, newcolorCt, depth, -+ methodForLargest); -+ -+ multicolorBoxesExist = (colorfreqtable.size > 1); -+ -+ /* Split boxes until we have enough. */ -+ while (boxVector.boxCt < newcolorCt && multicolorBoxesExist) { -+ unsigned int boxIdx; -+ -+ for (boxIdx = 0; -+ boxIdx < boxVector.boxCt && boxVector.box[boxIdx].colorCt < 2; -+ ++boxIdx); -+ /* Find the first splittable box. */ -+ -+ if (boxIdx >= boxVector.boxCt) -+ multicolorBoxesExist = FALSE; -+ else -+ splitBox(&boxVector, boxIdx, colorfreqtable, depth, -+ methodForLargest, methodForSplit); -+ } -+ *colormapP = colormapFromBv(newcolorCt, boxVector, colorfreqtable, -+ depth, methodForRep); -+ -+ destroyBoxVector(boxVector); -+} -+ -+ -+ -+ -+static void -+validateCompatibleImage(struct pam * const inpamP, -+ struct pam * const firstPamP, -+ unsigned int const imageSeq) { -+ -+ if (inpamP->depth != firstPamP->depth) -+ pm_error("Image %u depth (%u) is not the same as Image 0 (%u)", -+ imageSeq, inpamP->depth, firstPamP->depth); -+ if (inpamP->maxval != firstPamP->maxval) -+ pm_error("Image %u maxval (%u) is not the same as Image 0 (%u)", -+ imageSeq, -+ (unsigned)inpamP->maxval, (unsigned)firstPamP->maxval); -+ if (inpamP->format != firstPamP->format) -+ pm_error("Image %u format (%d) is not the same as Image 0 (%d)", -+ imageSeq, inpamP->format, firstPamP->format); -+ if (!streq(inpamP->tuple_type, firstPamP->tuple_type)) -+ pm_error("Image %u tuple type (%s) is not the same as Image 0 (%s)", -+ imageSeq, inpamP->tuple_type, firstPamP->tuple_type); -+} -+ -+ -+ -+static void -+addImageColorsToHash(struct pam * const pamP, -+ tuplehash const tuplehash, -+ unsigned int * const colorCountP) { -+ -+ tuple * tuplerow; -+ unsigned int row; -+ -+ tuplerow = pnm_allocpamrow(pamP); -+ -+ for (row = 0; row < pamP->height; ++row) { -+ unsigned int col; -+ -+ pnm_readpamrow(pamP, tuplerow); -+ -+ for (col = 0; col < pamP->width; ++col) { -+ int firstOccurrence; -+ -+ pnm_addtuplefreqoccurrence(pamP, tuplerow[col], tuplehash, -+ &firstOccurrence); -+ -+ if (firstOccurrence) -+ ++(*colorCountP); -+ } -+ } -+ pnm_freepamrow(tuplerow); -+} -+ -+ -+ -+static void -+computeHistogram(FILE * const ifP, -+ int * const formatP, -+ struct pam * const freqPamP, -+ tupletable2 * const colorfreqtableP) { -+/*---------------------------------------------------------------------------- -+ Make a histogram of the colors in the image stream in the file '*ifP'. -+ -+ Return as *freqPamP a description of the tuple values in the histogram. -+ Only the fields of *freqPamP that describe individual tuples are -+ meaningful (depth, maxval, tuple type); -+ -+ As a fringe benefit, also return the format of the input file as -+ *formatP. -+----------------------------------------------------------------------------*/ -+ unsigned int imageSeq; -+ struct pam firstPam; -+ tuplehash tuplehash; -+ unsigned int colorCount; -+ int eof; -+ -+ pm_message("making histogram..."); -+ -+ tuplehash = pnm_createtuplehash(); -+ colorCount = 0; -+ -+ eof = FALSE; -+ -+ for (imageSeq = 0; !eof; ++imageSeq) { -+ struct pam inpam; -+ -+ pm_message("Scanning image %u", imageSeq); -+ -+ pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); -+ -+ if (imageSeq == 0) -+ firstPam = inpam; -+ else -+ validateCompatibleImage(&inpam, &firstPam, imageSeq); -+ -+ addImageColorsToHash(&inpam, tuplehash, &colorCount); -+ -+ pm_message("%u colors so far", colorCount); -+ -+ pnm_nextimage(ifP, &eof); -+ } -+ colorfreqtableP->table = -+ pnm_tuplehashtotable(&firstPam, tuplehash, colorCount); -+ colorfreqtableP->size = colorCount; -+ -+ pnm_destroytuplehash(tuplehash); -+ -+ pm_message("%u colors found", colorfreqtableP->size); -+ -+ freqPamP->size = sizeof(*freqPamP); -+ freqPamP->len = PAM_STRUCT_SIZE(tuple_type); -+ freqPamP->maxval = firstPam.maxval; -+ freqPamP->bytes_per_sample = pnm_bytespersample(freqPamP->maxval); -+ freqPamP->depth = firstPam.depth; -+ STRSCPY(freqPamP->tuple_type, firstPam.tuple_type); -+ -+ *formatP = firstPam.format; -+} -+ -+ -+ -+static void -+computeColorMapFromInput(FILE * const ifP, -+ bool const allColors, -+ int const reqColors, -+ enum MethodForLargest const methodForLargest, -+ enum MethodForRep const methodForRep, -+ enum MethodForSplit const methodForSplit, -+ int * const formatP, -+ struct pam * const freqPamP, -+ tupletable2 * const colormapP) { -+/*---------------------------------------------------------------------------- -+ Produce a colormap containing the best colors to represent the -+ image stream in file 'ifP'. Figure it out using the median cut -+ technique. -+ -+ The colormap will have 'reqcolors' or fewer colors in it, unless -+ 'allcolors' is true, in which case it will have all the colors that -+ are in the input. -+ -+ The colormap has the same maxval as the input. -+ -+ Put the colormap in newly allocated storage as a tupletable2 -+ and return its address as *colormapP. Return the number of colors in -+ it as *colorsP and its maxval as *colormapMaxvalP. -+ -+ Return the characteristics of the input file as -+ *formatP and *freqPamP. (This information is not really -+ relevant to our colormap mission; just a fringe benefit). -+-----------------------------------------------------------------------------*/ -+ tupletable2 colorfreqtable; -+ -+ computeHistogram(ifP, formatP, freqPamP, &colorfreqtable); -+ -+ if (allColors) { -+ *colormapP = colorfreqtable; -+ } else { -+ if (colorfreqtable.size <= reqColors) { -+ pm_message("Image already has few enough colors (<=%d). " -+ "Keeping same colors.", reqColors); -+ *colormapP = colorfreqtable; -+ } else { -+ pm_message("choosing %d colors...", reqColors); -+ mediancut(colorfreqtable, freqPamP->depth, -+ reqColors, methodForLargest, methodForRep, -+ methodForSplit, colormapP); -+ pnm_freetupletable2(freqPamP, colorfreqtable); -+ } -+ } -+} -+ -+ -+ -+static void -+sortColormap(tupletable2 const colormap, -+ sample const depth) { -+/*---------------------------------------------------------------------------- -+ Sort the colormap in place, in order of ascending Plane 0 value, -+ the Plane 1 value, etc. -+ -+ Use insertion sort. -+-----------------------------------------------------------------------------*/ -+ int i; -+ -+ pm_message("Sorting %u colors...", colormap.size); -+ -+ for (i = 0; i < colormap.size; ++i) { -+ int j; -+ for (j = i+1; j < colormap.size; ++j) { -+ unsigned int plane; -+ bool iIsGreater, iIsLess; -+ -+ iIsGreater = FALSE; iIsLess = FALSE; -+ for (plane = 0; -+ plane < depth && !iIsGreater && !iIsLess; -+ ++plane) { -+ if (colormap.table[i]->tuple[plane] > -+ colormap.table[j]->tuple[plane]) -+ iIsGreater = TRUE; -+ else if (colormap.table[i]->tuple[plane] < -+ colormap.table[j]->tuple[plane]) -+ iIsLess = TRUE; -+ } -+ if (iIsGreater) { -+ for (plane = 0; plane < depth; ++plane) { -+ sample const temp = colormap.table[i]->tuple[plane]; -+ colormap.table[i]->tuple[plane] = -+ colormap.table[j]->tuple[plane]; -+ colormap.table[j]->tuple[plane] = temp; -+ } -+ } -+ } -+ } -+} -+ -+ -+ -+static void -+colormapToSquare(struct pam * const pamP, -+ tupletable2 const colormap, -+ tuple *** const outputRasterP) { -+ { -+ unsigned int const intsqrt = (int)sqrt((float)colormap.size); -+ if (SQR(intsqrt) == colormap.size) -+ pamP->width = intsqrt; -+ else -+ pamP->width = intsqrt + 1; -+ } -+ { -+ unsigned int const intQuotient = colormap.size / pamP->width; -+ if (pamP->width * intQuotient == colormap.size) -+ pamP->height = intQuotient; -+ else -+ pamP->height = intQuotient + 1; -+ } -+ { -+ tuple ** outputRaster; -+ unsigned int row; -+ unsigned int colormapIndex; -+ -+ outputRaster = pnm_allocpamarray(pamP); -+ -+ colormapIndex = 0; /* initial value */ -+ -+ for (row = 0; row < pamP->height; ++row) { -+ unsigned int col; -+ for (col = 0; col < pamP->width; ++col) { -+ unsigned int plane; -+ for (plane = 0; plane < pamP->depth; ++plane) { -+ outputRaster[row][col][plane] = -+ colormap.table[colormapIndex]->tuple[plane]; -+ } -+ if (colormapIndex < colormap.size-1) -+ ++colormapIndex; -+ } -+ } -+ *outputRasterP = outputRaster; -+ } -+} -+ -+ -+ -+static void -+colormapToSingleRow(struct pam * const pamP, -+ tupletable2 const colormap, -+ tuple *** const outputRasterP) { -+ -+ tuple ** outputRaster; -+ unsigned int col; -+ -+ pamP->width = colormap.size; -+ pamP->height = 1; -+ -+ outputRaster = pnm_allocpamarray(pamP); -+ -+ for (col = 0; col < pamP->width; ++col) { -+ int plane; -+ for (plane = 0; plane < pamP->depth; ++plane) -+ outputRaster[0][col][plane] = colormap.table[col]->tuple[plane]; -+ } -+ *outputRasterP = outputRaster; -+} -+ -+ -+ -+static void -+colormapToImage(int const format, -+ const struct pam * const colormapPamP, -+ tupletable2 const colormap, -+ bool const sort, -+ bool const square, -+ struct pam * const outpamP, -+ tuple *** const outputRasterP) { -+/*---------------------------------------------------------------------------- -+ Create a tuple array and pam structure for an image which includes -+ one pixel of each of the colors in the colormap 'colormap'. -+ -+ May rearrange the contents of 'colormap'. -+-----------------------------------------------------------------------------*/ -+ outpamP->size = sizeof(*outpamP); -+ outpamP->len = PAM_STRUCT_SIZE(tuple_type); -+ outpamP->format = format, -+ outpamP->plainformat = FALSE; -+ outpamP->depth = colormapPamP->depth; -+ outpamP->maxval = colormapPamP->maxval; -+ outpamP->bytes_per_sample = pnm_bytespersample(outpamP->maxval); -+ STRSCPY(outpamP->tuple_type, colormapPamP->tuple_type); -+ -+ if (sort) -+ sortColormap(colormap, outpamP->depth); -+ -+ if (square) -+ colormapToSquare(outpamP, colormap, outputRasterP); -+ else -+ colormapToSingleRow(outpamP, colormap, outputRasterP); -+} -+ -+ -+ -+int -+main(int argc, const char * argv[] ) { -+ -+ struct CmdlineInfo cmdline; -+ FILE * ifP; -+ int format; -+ struct pam colormapPam; -+ struct pam outpam; -+ tuple ** colormapRaster; -+ tupletable2 colormap; -+ -+ pm_proginit(&argc, argv); -+ -+ parseCommandLine(argc, argv, &cmdline); -+ -+ ifP = pm_openr(cmdline.inputFileNm); -+ -+ computeColorMapFromInput(ifP, -+ cmdline.allcolors, cmdline.newcolors, -+ cmdline.methodForLargest, -+ cmdline.methodForRep, -+ cmdline.methodForSplit, -+ &format, &colormapPam, &colormap); -+ -+ pm_close(ifP); -+ -+ colormapToImage(format, &colormapPam, colormap, -+ cmdline.sort, cmdline.square, &outpam, &colormapRaster); -+ -+ if (cmdline.verbose) -+ pm_message("Generating %u x %u image", outpam.width, outpam.height); -+ -+ outpam.file = stdout; -+ -+ pnm_writepam(&outpam, colormapRaster); -+ -+ pnm_freetupletable2(&colormapPam, colormap); -+ -+ pnm_freepamarray(colormapRaster, &outpam); -+ -+ pm_close(stdout); -+ -+ return 0; -+} -+ -+ -+ -diff --git a/urt/Runput.c b/urt/Runput.c -index 3bc562a..645a376 100644 ---- a/urt/Runput.c -+++ b/urt/Runput.c -@@ -202,10 +202,11 @@ RunSetup(rle_hdr * the_hdr) - if ( the_hdr->background != 0 ) - { - register int i; -- register rle_pixel *background = -- (rle_pixel *)malloc( (unsigned)(the_hdr->ncolors + 1) ); -- register int *bg_color; -- /* -+ register rle_pixel *background; -+ register int *bg_color; -+ -+ overflow_add(the_hdr->ncolors,1); -+ background = (rle_pixel *)malloc( (unsigned)(the_hdr->ncolors + 1) ); /* - * If even number of bg color bytes, put out one more to get to - * 16 bit boundary. - */ -@@ -224,7 +225,7 @@ RunSetup(rle_hdr * the_hdr) - /* Big-endian machines are harder */ - register int i, nmap = (1 << the_hdr->cmaplen) * - the_hdr->ncmap; -- register char *h_cmap = (char *)malloc( nmap * 2 ); -+ register char *h_cmap = (char *)malloc2( nmap, 2 ); - if ( h_cmap == NULL ) - { - fprintf( stderr, -diff --git a/urt/rle.h b/urt/rle.h -index 0071774..6a905ba 100644 ---- a/urt/rle.h -+++ b/urt/rle.h -@@ -152,6 +152,17 @@ rle_hdr /* End of typedef. */ + + ++length; /* Add size of terminating NUL. */ + +diff -urNp a/urt/rle.h b/urt/rle.h +--- a/urt/rle.h 2025-02-03 09:24:28.360500401 +0100 ++++ b/urt/rle.h 2025-02-04 10:33:12.842479585 +0100 +@@ -153,6 +153,17 @@ rle_hdr /* End of typedef. * */ extern rle_hdr rle_dflt_hdr; @@ -6386,1061 +865,9 @@ index 0071774..6a905ba 100644 /* Declare RLE library routines. */ -diff --git a/urt/rle.h.orig b/urt/rle.h.orig -new file mode 100644 -index 0000000..59d2670 ---- /dev/null -+++ b/urt/rle.h.orig -@@ -0,0 +1,470 @@ -+/* -+ * This software is copyrighted as noted below. It may be freely copied, -+ * modified, and redistributed, provided that the copyright notice is -+ * preserved on all copies. -+ * -+ * There is no warranty or other guarantee of fitness for this software, -+ * it is provided solely "as is". Bug reports or fixes may be sent -+ * to the author, who may or may not act on them as he desires. -+ * -+ * You may not include this software in a program or other software product -+ * without supplying the source, or without informing the end-user that the -+ * source is available for no extra charge. -+ * -+ * If you modify this software, you should include a notice giving the -+ * name of the person performing the modification, the date of modification, -+ * and the reason for such modification. -+ */ -+/* -+ * rle.h - Global declarations for Utah Raster Toolkit RLE programs. -+ * -+ * Author: Todd W. Fuqua -+ * Computer Science Dept. -+ * University of Utah -+ * Date: Sun Jul 29 1984 -+ * Copyright (c) 1984 Todd W. Fuqua -+ * -+ * $Id: rle.h,v 3.0.1.5 1992/04/30 14:05:56 spencer Exp $ -+ */ -+ -+#ifndef RLE_H -+#define RLE_H -+ -+#include /* Declare FILE. */ -+#include -+ -+enum rle_dispatch { -+ NO_DISPATCH = -1, -+ RUN_DISPATCH = 0 -+}; -+ -+/* **************************************************************** -+ * TAG( rle_pixel rle_map ) -+ * -+ * Typedef for 8-bit (or less) pixel data. -+ * -+ * Typedef for 16-bit color map data. -+ */ -+typedef unsigned char rle_pixel; -+typedef unsigned short rle_map; -+ -+/* -+ * Defines for traditional channel numbers. -+ */ -+#define RLE_RED 0 /* Red channel traditionally here. */ -+#define RLE_GREEN 1 /* Green channel traditionally here. */ -+#define RLE_BLUE 2 /* Blue channel traditionally here. */ -+#define RLE_ALPHA -1 /* Alpha channel here. */ -+ -+/* -+ * Return values from rle_get_setup. -+ */ -+#define RLE_SUCCESS 0 -+#define RLE_NOT_RLE -1 -+#define RLE_NO_SPACE -2 -+#define RLE_EMPTY -3 -+#define RLE_EOF -4 -+ -+/* -+ * "Magic" value for is_init field. Pi * 2^29. -+ */ -+#define RLE_INIT_MAGIC 0x6487ED51L -+ -+/* -+ * TAG( rle_hdr ) -+ * -+ * Definition of header structure used by RLE routines. -+ */ -+ -+#ifndef c_plusplus -+typedef -+#endif -+ struct rle_hdr { -+ enum rle_dispatch dispatch; /* Type of file to create. */ -+ int ncolors; /* Number of color channels. */ -+ int * bg_color; /* Pointer to bg color vector. */ -+ int alpha; /* If !0, save alpha channel. */ -+ int background; /* 0->just save all pixels, */ -+ /* 1->overlay, 2->clear to bg first. */ -+ int xmin; /* Lower X bound (left.) */ -+ int xmax; /* Upper X bound (right.) */ -+ int ymin; /* Lower Y bound (bottom.) */ -+ int ymax; /* Upper Y bound (top.) */ -+ int ncmap; /* Number of color channels in color map. */ -+ /* Map only saved if != 0. */ -+ int cmaplen; /* Log2 of color map length. */ -+ rle_map * cmap; /* Pointer to color map array. */ -+ const char ** comments; /* Pointer to array of pointers to comments. */ -+ FILE * rle_file; /* Input or output file. */ -+ /* -+ * Bit map of channels to read/save. Indexed by (channel mod 256). -+ * Alpha channel sets bit 255. -+ * -+ * Indexing (0 <= c <= 255): -+ * bits[c/8] & (1 << (c%8)) -+ */ -+#define RLE_SET_BIT(glob,bit) \ -+ ((glob).bits[((bit)&0xff)/8] |= (1<<((bit)&0x7))) -+#define RLE_CLR_BIT(glob,bit) \ -+ ((glob).bits[((bit)&0xff)/8] &= ~(1<<((bit)&0x7))) -+#define RLE_BIT(glob,bit) \ -+ ((glob).bits[((bit)&0xff)/8] & (1<<((bit)&0x7))) -+ char bits[256/8]; -+ /* Set to magic pattern if following fields are initialized. */ -+ /* This gives a 2^(-32) chance of missing. */ -+ long int is_init; -+ /* Command, file name and image number for error messages. */ -+ const char *cmd; -+ const char *file_name; -+ int img_num; -+ /* -+ * Local storage for rle_getrow & rle_putrow. -+ * rle_getrow has -+ * scan_y int current Y scanline. -+ * vert_skip int number of lines to skip. -+ * rle_putrow has -+ * nblank int number of blank lines. -+ * brun short(*)[2] Array of background runs. -+ * fileptr long Position in output file. -+ */ -+ union { -+ struct { -+ int scan_y, -+ vert_skip; -+ char is_eof, /* Set when EOF or EofOp encountered. */ -+ is_seek; /* If true, can seek input file. */ -+ } get; -+ struct { -+ int nblank; -+ short (*brun)[2]; -+ long fileptr; -+ } put; -+ } priv; -+ } -+#ifndef c_plusplus -+rle_hdr /* End of typedef. */ -+#endif -+; -+ -+/* -+ * TAG( rle_dflt_hdr ) -+ * -+ * Global variable with possibly useful default values. -+ */ -+extern rle_hdr rle_dflt_hdr; -+ -+ -+/* Declare RLE library routines. */ -+ -+/***************************************************************** -+ * TAG( rle_get_error ) -+ * -+ * Print an error message based on the error code returned by -+ * rle_get_setup. -+ */ -+extern int rle_get_error( int code, -+ const char *pgmname, -+ const char *fname ); -+ -+/* From rle_getrow.c */ -+ -+/***************************************************************** -+ * TAG( rle_debug ) -+ * -+ * Turn RLE debugging on or off. -+ */ -+extern void rle_debug( int on_off ); -+ -+int -+rle_get_setup(rle_hdr * const the_hdr); -+ -+/***************************************************************** -+ * TAG( rle_get_setup_ok ) -+ * -+ * Call rle_get_setup. If it returns an error code, call -+ * rle_get_error to print the error message, then exit with the error -+ * code. -+ */ -+extern void rle_get_setup_ok( rle_hdr *the_hdr, -+ const char *prog_name, -+ const char *file_name); -+ -+/***************************************************************** -+ * TAG( rle_getrow ) -+ * -+ * Read a scanline worth of data from an RLE file. -+ */ -+extern int rle_getrow( rle_hdr * the_hdr, -+ rle_pixel * scanline[] ); -+ -+/* From rle_getskip.c */ -+ -+/***************************************************************** -+ * TAG( rle_getskip ) -+ * Skip a scanline, return the number of the next one. -+ */ -+extern unsigned int rle_getskip( rle_hdr *the_hdr ); -+ -+/* From rle_hdr.c. */ -+ -+/***************************************************************** -+ * TAG( rle_names ) -+ * -+ * Load the command and file names into the rle_hdr. -+ */ -+extern void rle_names( rle_hdr *the_hdr, -+ const char *pgmname, -+ const char *fname, -+ int img_num ); -+ -+/***************************************************************** -+ * TAG( rle_hdr_cp ) -+ * -+ * Make a "safe" copy of a rle_hdr structure. -+ */ -+extern rle_hdr * rle_hdr_cp( rle_hdr *from_hdr, -+ rle_hdr *to_hdr ); -+ -+/***************************************************************** -+ * TAG( rle_hdr_init ) -+ * -+ * Initialize a rle_hdr structure. -+ */ -+extern rle_hdr * rle_hdr_init( rle_hdr *the_hdr ); -+ -+/***************************************************************** -+ * TAG( rle_hdr_clear ) -+ * -+ */ -+extern void rle_hdr_clear( rle_hdr *the_hdr ); -+ -+/* From rle_putrow.c. */ -+ -+/***************************************************************** -+ * TAG( rgb_to_bw ) -+ * -+ * Converts RGB data to gray data via the NTSC Y transform. -+ */ -+extern void rgb_to_bw( rle_pixel *red_row, -+ rle_pixel *green_row, -+ rle_pixel *blue_row, -+ rle_pixel *bw_row, -+ int rowlen ); -+ -+/***************************************************************** -+ * TAG( rle_puteof ) -+ * -+ * Write an End-of-image opcode to the RLE file. -+ */ -+extern void rle_puteof( rle_hdr *the_hdr ); -+ -+/***************************************************************** -+ * TAG( rle_putrow ) -+ * -+ * Write a scanline of data to the RLE file. -+ */ -+extern void rle_putrow( rle_pixel *rows[], int rowlen, rle_hdr *the_hdr ); -+ -+/***************************************************************** -+ * TAG( rle_put_init ) -+ * -+ * Initialize header for output, but don't write it to the file. -+ */ -+extern void rle_put_init( rle_hdr * the_hdr ); -+ -+/***************************************************************** -+ * TAG( rle_put_setup ) -+ * -+ * Write header information to a new RLE image file. -+ */ -+extern void rle_put_setup( rle_hdr * the_hdr ); -+ -+/***************************************************************** -+ * TAG( rle_skiprow ) -+ * -+ * Skip nrow scanlines in the output file. -+ */ -+extern void rle_skiprow( rle_hdr *the_hdr, int nrow ); -+ -+/* From rle_cp.c */ -+/***************************************************************** -+ * TAG( rle_cp ) -+ * Copy image data from input to output with minimal interpretation. -+ */ -+extern void rle_cp( rle_hdr *in_hdr, rle_hdr *out_hdr ); -+ -+/* From rle_row_alc.c. */ -+/***************************************************************** -+ * TAG( rle_row_alloc ) -+ * -+ * Allocate scanline memory for use by rle_getrow. -+ */ -+extern int rle_row_alloc( rle_hdr * the_hdr, -+ rle_pixel *** scanp ); -+ -+/***************************************************************** -+ * TAG( rle_row_free ) -+ * -+ * Free the above. -+ */ -+extern void rle_row_free( rle_hdr *the_hdr, rle_pixel **scanp ); -+ -+/* From buildmap.c. */ -+/* -+ * buildmap - build a more usable colormap from data in the_hdr struct. -+ */ -+extern rle_pixel **buildmap( rle_hdr *the_hdr, -+ int minmap, -+ double orig_gamma, -+ double new_gamma ); -+ -+/* From rle_getcom.c. */ -+/***************************************************************** -+ * TAG( rle_getcom ) -+ * -+ * Get a specific comment from the image comments. -+ */ -+const char * -+rle_getcom(const char * const name, -+ rle_hdr * const the_hdr); -+ -+/* From rle_putcom.c. */ -+ -+/* Delete a specific comment from the image comments. */ -+const char * -+rle_delcom(const char * const name, -+ rle_hdr * const the_hdr); -+ -+/* Put (or replace) a comment into the image comments. */ -+const char * -+rle_putcom(const char * const value, -+ rle_hdr * const the_hdr); -+ -+/* From dither.c. */ -+/***************************************************************** -+ * TAG( bwdithermap ) -+ * Create a color map for ordered dithering in grays. -+ */ -+extern void bwdithermap( int levels, double gamma, int bwmap[], -+ int divN[256], int modN[256], int magic[16][16] ); -+/***************************************************************** -+ * TAG( ditherbw ) -+ * Dither a gray-scale value. -+ */ -+extern int ditherbw( int x, int y, int val, -+ int divN[256], int modN[256], int magic[16][16] ); -+/***************************************************************** -+ * TAG( dithergb ) -+ * Dither a color value. -+ */ -+extern int dithergb( int x, int y, int r, int g, int b, -+ int divN[256], int modN[256], int magic[16][16] ); -+/***************************************************************** -+ * TAG( dithermap ) -+ * Create a color map for ordered dithering in color. -+ */ -+extern void dithermap( int levels, double gamma, int rgbmap[][3], -+ int divN[256], int modN[256], int magic[16][16] ); -+/***************************************************************** -+ * TAG( make_square ) -+ * Make a 16x16 magic square for ordered dithering. -+ */ -+extern void make_square( double N, int divN[256], int modN[256], -+ int magic[16][16] ); -+ -+/* From float_to_exp.c. */ -+/***************************************************************** -+ * TAG( float_to_exp ) -+ * Convert a list of floating point numbers to "exp" format. -+ */ -+extern void float_to_exp( int count, float * floats, rle_pixel * pixels ); -+ -+/* From rle_open_f.c. */ -+/***************************************************************** -+ * TAG( rle_open_f ) -+ * -+ * Open an input/output file with default. -+ */ -+FILE * -+rle_open_f(const char * prog_name, const char * file_name, -+ const char * mode); -+ -+/***************************************************************** -+ * TAG( rle_open_f_noexit ) -+ * -+ * Open an input/output file with default. -+ */ -+FILE * -+rle_open_f_noexit(const char * const prog_name, -+ const char * const file_name, -+ const char * const mode); -+ -+/***************************************************************** -+ * TAG( rle_close_f ) -+ * -+ * Close a file opened by rle_open_f. If the file is stdin or stdout, -+ * it will not be closed. -+ */ -+extern void -+rle_close_f( FILE *fd ); -+ -+/* From colorquant.c. */ -+/***************************************************************** -+ * TAG( colorquant ) -+ * Compute a colormap for quantizing an image to a limited set of colors. -+ */ -+extern int colorquant( rle_pixel *red, rle_pixel *green, rle_pixel *blue, -+ unsigned long pixels, rle_pixel *colormap[3], -+ int colors, int bits, -+ rle_pixel *rgbmap, int fast, int otherimages ); -+ -+/* From rle_addhist.c. */ -+ -+/* Append history information to the HISTORY comment. */ -+void -+rle_addhist(char * argv[], -+ rle_hdr * const in_hdr, -+ rle_hdr * const out_hdr); -+ -+/* From cmd_name.c. */ -+/***************************************************************** -+ * TAG( cmd_name ) -+ * Extract command name from argv. -+ */ -+extern char *cmd_name( char **argv ); -+ -+/* From scanargs.c. */ -+/***************************************************************** -+ * TAG( scanargs ) -+ * Scan command argument list and parse arguments. -+ */ -+extern int scanargs( int argc, -+ char **argv, -+ const char *format, -+ ... ); -+ -+/* From hilbert.c */ -+/***************************************************************** -+ * TAG( hilbert_i2c ) -+ * Convert an index into a Hilbert curve to a set of coordinates. -+ */ -+extern void hilbert_c2i( int n, int m, int a[], long int *r ); -+ -+/***************************************************************** -+ * TAG( hilbert_c2i ) -+ * Convert coordinates of a point on a Hilbert curve to its index. -+ */ -+extern void hilbert_i2c( int n, int m, long int r, int a[] ); -+ -+/* From inv_cmap.c */ -+/***************************************************************** -+ * TAG( inv_cmap ) -+ * Compute an inverse colormap efficiently. -+ */ -+extern void inv_cmap( int colors, -+ unsigned char *colormap[3], -+ int bits, -+ unsigned long *dist_buf, -+ unsigned char *rgbmap ); -+ -+#endif /* RLE_H */ -diff --git a/urt/rle_addhist.c b/urt/rle_addhist.c -index b165175..e09ed94 100644 ---- a/urt/rle_addhist.c -+++ b/urt/rle_addhist.c -@@ -70,13 +70,18 @@ rle_addhist(char * argv[], - return; - - length = 0; -- for (i = 0; argv[i]; ++i) -+ for (i = 0; argv[i]; ++i) { -+ overflow_add(length, strlen(argv[i])); -+ overflow_add(length+1, strlen(argv[i])); - length += strlen(argv[i]) +1; /* length of each arg plus space. */ -+ } - - time(&temp); - timedate = ctime(&temp); - length += strlen(timedate); /* length of date and time in ASCII. */ -- -+ overflow_add(strlen(padding), 4); -+ overflow_add(strlen(histoire), strlen(padding) + 4); -+ overflow_add(length, strlen(histoire) + strlen(padding) + 4); - length += strlen(padding) + 3 + strlen(histoire) + 1; - /* length of padding, "on " and length of history name plus "="*/ - if (in_hdr) /* if we are interested in the old comments... */ -@@ -84,8 +89,10 @@ rle_addhist(char * argv[], - else - old = NULL; - -- if (old && *old) -+ if (old && *old) { -+ overflow_add(length, strlen(old)); - length += strlen(old); /* add length if there. */ -+ } - - ++length; /*Cater for the null. */ - -diff --git a/urt/rle_getrow.c b/urt/rle_getrow.c -index ae220f5..39010ba 100644 ---- a/urt/rle_getrow.c -+++ b/urt/rle_getrow.c -@@ -164,6 +164,7 @@ rle_get_setup(rle_hdr * const the_hdr) { - char * cp; - - VAXSHORT(comlen, infile); /* get comment length */ -+ overflow_add(comlen, 1); - evenlen = (comlen + 1) & ~1; /* make it even */ - if (evenlen) { - MALLOCARRAY(comment_buf, evenlen); -diff --git a/urt/rle_getrow.c.orig b/urt/rle_getrow.c.orig -new file mode 100644 -index 0000000..ae220f5 ---- /dev/null -+++ b/urt/rle_getrow.c.orig -@@ -0,0 +1,520 @@ -+/* -+ * This software is copyrighted as noted below. It may be freely copied, -+ * modified, and redistributed, provided that the copyright notice is -+ * preserved on all copies. -+ * -+ * There is no warranty or other guarantee of fitness for this software, -+ * it is provided solely "as is". Bug reports or fixes may be sent -+ * to the author, who may or may not act on them as he desires. -+ * -+ * You may not include this software in a program or other software product -+ * without supplying the source, or without informing the end-user that the -+ * source is available for no extra charge. -+ * -+ * If you modify this software, you should include a notice giving the -+ * name of the person performing the modification, the date of modification, -+ * and the reason for such modification. -+ * -+ * Modified at BRL 16-May-88 by Mike Muuss to avoid Alliant STDC desire -+ * to have all "void" functions so declared. -+ */ -+/* -+ * rle_getrow.c - Read an RLE file in. -+ * -+ * Author: Spencer W. Thomas -+ * Computer Science Dept. -+ * University of Utah -+ * Date: Wed Apr 10 1985 -+ * Copyright (c) 1985 Spencer W. Thomas -+ * -+ * $Id: rle_getrow.c,v 3.0.1.5 1992/03/04 19:33:08 spencer Exp spencer $ -+ */ -+ -+#include -+#include -+ -+#include "netpbm/pm.h" -+#include "netpbm/mallocvar.h" -+ -+#include "rle.h" -+#include "rle_code.h" -+#include "vaxshort.h" -+ -+/* Read a two-byte "short" that started in VAX (LITTLE_ENDIAN) order */ -+#define VAXSHORT( var, fp )\ -+ { var = fgetc(fp)&0xFF; var |= (fgetc(fp)) << 8; } -+ -+/* Instruction format -- first byte is opcode, second is datum. */ -+ -+#define OPCODE(inst) (inst[0] & ~LONG) -+#define LONGP(inst) (inst[0] & LONG) -+#define DATUM(inst) (inst[1] & 0xff) /* Make sure it's unsigned. */ -+ -+static int debug_f; /* If non-zero, print debug info. */ -+ -+int -+rle_get_setup(rle_hdr * const the_hdr) { -+/*----------------------------------------------------------------------------- -+ Read the initialization information from an RLE file. -+ Inputs: -+ the_hdr: Contains pointer to the input file. -+ Outputs: -+ the_hdr: Initialized with information from the input file. -+ Returns -+ 0 on success, -+ -1 if the file is not an RLE file, -+ -2 if malloc of the color map failed, -+ -3 if an immediate EOF is hit (empty input file) -+ -4 if an EOF is encountered reading the setup information. -+ Assumptions: -+ infile points to the "magic" number in an RLE file (usually byte 0 -+ in the file). -+ Algorithm: -+ Read in the setup info and fill in the_hdr. -+---------------------------------------------------------------------------- */ -+ struct XtndRsetup setup; -+ short magic; -+ FILE * infile = the_hdr->rle_file; -+ int i; -+ char * comment_buf; -+ -+ /* Clear old stuff out of the header. */ -+ rle_hdr_clear(the_hdr); -+ if (the_hdr->is_init != RLE_INIT_MAGIC) -+ rle_names(the_hdr, "Urt", "some file", 0); -+ ++the_hdr->img_num; /* Count images. */ -+ -+ VAXSHORT(magic, infile); -+ if (feof(infile)) -+ return RLE_EMPTY; -+ if (magic != RLE_MAGIC) -+ return RLE_NOT_RLE; -+ fread(&setup, 1, SETUPSIZE, infile); /* assume VAX packing */ -+ if (feof( infile)) -+ return RLE_EOF; -+ -+ /* Extract information from setup */ -+ the_hdr->ncolors = setup.h_ncolors; -+ for (i = 0; i < the_hdr->ncolors; ++i) -+ RLE_SET_BIT(*the_hdr, i); -+ -+ if (!(setup.h_flags & H_NO_BACKGROUND) && setup.h_ncolors > 0) { -+ rle_pixel * bg_color; -+ -+ MALLOCARRAY(the_hdr->bg_color, setup.h_ncolors); -+ if (!the_hdr->bg_color) -+ pm_error("Failed to allocation array for %u background colors", -+ setup.h_ncolors); -+ MALLOCARRAY(bg_color, 1 + (setup.h_ncolors / 2) * 2); -+ if (!bg_color) -+ pm_error("Failed to allocation array for %u background colors", -+ 1+(setup.h_ncolors / 2) * 2); -+ fread((char *)bg_color, 1, 1 + (setup.h_ncolors / 2) * 2, infile); -+ for (i = 0; i < setup.h_ncolors; ++i) -+ the_hdr->bg_color[i] = bg_color[i]; -+ free(bg_color); -+ } else { -+ getc(infile); /* skip filler byte */ -+ the_hdr->bg_color = NULL; -+ } -+ -+ if (setup.h_flags & H_NO_BACKGROUND) -+ the_hdr->background = 0; -+ else if (setup.h_flags & H_CLEARFIRST) -+ the_hdr->background = 2; -+ else -+ the_hdr->background = 1; -+ if (setup.h_flags & H_ALPHA) { -+ the_hdr->alpha = 1; -+ RLE_SET_BIT( *the_hdr, RLE_ALPHA ); -+ } else -+ the_hdr->alpha = 0; -+ -+ the_hdr->xmin = vax_gshort(setup.hc_xpos); -+ the_hdr->ymin = vax_gshort(setup.hc_ypos); -+ the_hdr->xmax = the_hdr->xmin + vax_gshort(setup.hc_xlen) - 1; -+ the_hdr->ymax = the_hdr->ymin + vax_gshort(setup.hc_ylen) - 1; -+ -+ the_hdr->ncmap = setup.h_ncmap; -+ the_hdr->cmaplen = setup.h_cmaplen; -+ if (the_hdr->ncmap > 0) { -+ int const maplen = the_hdr->ncmap * (1 << the_hdr->cmaplen); -+ -+ int i; -+ char *maptemp; -+ -+ MALLOCARRAY(the_hdr->cmap, maplen); -+ MALLOCARRAY(maptemp, 2 * maplen); -+ if (the_hdr->cmap == NULL || maptemp == NULL) { -+ pm_error("Malloc failed for color map of size %d*%d " -+ "in rle_get_setup, reading '%s'", -+ the_hdr->ncmap, (1 << the_hdr->cmaplen), -+ the_hdr->file_name ); -+ return RLE_NO_SPACE; -+ } -+ fread(maptemp, 2, maplen, infile); -+ for (i = 0; i < maplen; ++i) -+ the_hdr->cmap[i] = vax_gshort(&maptemp[i * 2]); -+ free(maptemp); -+ } -+ -+ /* Check for comments */ -+ if (setup.h_flags & H_COMMENT) { -+ short comlen, evenlen; -+ char * cp; -+ -+ VAXSHORT(comlen, infile); /* get comment length */ -+ evenlen = (comlen + 1) & ~1; /* make it even */ -+ if (evenlen) { -+ MALLOCARRAY(comment_buf, evenlen); -+ -+ if (comment_buf == NULL) { -+ pm_error("Malloc failed for comment buffer of size %d " -+ "in rle_get_setup, reading '%s'", -+ comlen, the_hdr->file_name ); -+ return RLE_NO_SPACE; -+ } -+ fread(comment_buf, 1, evenlen, infile); -+ /* Count the comments */ -+ for (i = 0, cp = comment_buf; cp < comment_buf + comlen; ++cp) -+ if (*cp == '\0') -+ ++i; -+ ++i; /* extra for NULL pointer at end */ -+ /* Get space to put pointers to comments */ -+ MALLOCARRAY(the_hdr->comments, i); -+ if (the_hdr->comments == NULL) { -+ pm_error("Malloc failed for %d comment pointers " -+ "in rle_get_setup, reading '%s'", -+ i, the_hdr->file_name ); -+ return RLE_NO_SPACE; -+ } -+ /* Get pointers to the comments */ -+ *the_hdr->comments = comment_buf; -+ for (i = 1, cp = comment_buf + 1; -+ cp < comment_buf + comlen; -+ ++cp) -+ if (*(cp - 1) == '\0') -+ the_hdr->comments[i++] = cp; -+ the_hdr->comments[i] = NULL; -+ } else -+ the_hdr->comments = NULL; -+ } else -+ the_hdr->comments = NULL; -+ -+ /* Initialize state for rle_getrow */ -+ the_hdr->priv.get.scan_y = the_hdr->ymin; -+ the_hdr->priv.get.vert_skip = 0; -+ the_hdr->priv.get.is_eof = 0; -+ the_hdr->priv.get.is_seek = ftell(infile) > 0; -+ debug_f = 0; -+ -+ if (!feof(infile)) -+ return RLE_SUCCESS; /* success! */ -+ else { -+ the_hdr->priv.get.is_eof = 1; -+ return RLE_EOF; -+ } -+} -+ -+ -+ -+void -+rle_get_setup_ok(rle_hdr * const the_hdr, -+ const char * const prog_name, -+ const char * const file_name) { -+/*----------------------------------------------------------------------------- -+ Read the initialization information from an RLE file. -+ -+ Inputs: -+ the_hdr: Contains pointer to the input file. -+ prog_name: Program name to be printed in the error message. -+ file_name: File name to be printed in the error message. -+ If NULL, the string "stdin" is generated. -+ -+ Outputs: -+ the_hdr: Initialized with information from the input file. -+ If reading the header fails, it prints an error message -+ and exits with the appropriate status code. -+ Algorithm: -+ rle_get_setup does all the work. -+---------------------------------------------------------------------------- */ -+ int code; -+ -+ /* Backwards compatibility: if is_init is not properly set, -+ * initialize the header. -+ */ -+ if (the_hdr->is_init != RLE_INIT_MAGIC) { -+ FILE * const f = the_hdr->rle_file; -+ rle_hdr_init( the_hdr ); -+ the_hdr->rle_file = f; -+ rle_names(the_hdr, prog_name, file_name, 0); -+ } -+ -+ code = rle_get_error(rle_get_setup(the_hdr), -+ the_hdr->cmd, the_hdr->file_name); -+ if (code) -+ exit(code); -+} -+ -+ -+ -+void -+rle_debug( on_off ) -+ int on_off; -+{ -+/*----------------------------------------------------------------------------- -+ Turn RLE debugging on or off. -+ Inputs: -+ on_off: if 0, stop debugging, else start. -+ Outputs: -+ Sets internal debug flag. -+ Assumptions: -+ [None] -+ Algorithm: -+ [None] -+---------------------------------------------------------------------------- */ -+ debug_f = on_off; -+ -+ /* Set line buffering on stderr. Character buffering is the default, and -+ * it is SLOOWWW for large amounts of output. -+ */ -+ setvbuf(stderr, NULL, _IOLBF, 0); -+} -+ -+ -+ -+int -+rle_getrow(rle_hdr * const the_hdr, -+ rle_pixel ** const scanline) { -+/*----------------------------------------------------------------------------- -+ Get a scanline from the input file. -+ Inputs: -+ the_hdr: Header structure containing information about -+ the input file. -+ Outputs: -+ scanline: an array of pointers to the individual color -+ scanlines. Scanline is assumed to have -+ the_hdr->ncolors pointers to arrays of rle_pixel, -+ each of which is at least the_hdr->xmax+1 long. -+ Returns the current scanline number. -+ Assumptions: -+ rle_get_setup has already been called. -+ Algorithm: -+ If a vertical skip is being executed, and clear-to-background is -+ specified (the_hdr->background is true), just set the -+ scanlines to the background color. If clear-to-background is -+ not set, just increment the scanline number and return. -+ -+ Otherwise, read input until a vertical skip is encountered, -+ decoding the instructions into scanline data. -+ -+ If ymax is reached (or, somehow, passed), continue reading and -+ discarding input until end of image. -+---------------------------------------------------------------------------- */ -+ FILE * const infile = the_hdr->rle_file; -+ -+ rle_pixel * scanc; -+ -+ int scan_x; /* current X position */ -+ int max_x; /* End of the scanline */ -+ int channel; /* current color channel */ -+ int ns; /* Number to skip */ -+ int nc; -+ short word, long_data; -+ char inst[2]; -+ -+ scan_x = the_hdr->xmin; /* initial value */ -+ max_x = the_hdr->xmax; /* initial value */ -+ channel = 0; /* initial value */ -+ /* Clear to background if specified */ -+ if (the_hdr->background != 1) { -+ if (the_hdr->alpha && RLE_BIT( *the_hdr, -1)) -+ memset((char *)scanline[-1] + the_hdr->xmin, 0, -+ the_hdr->xmax - the_hdr->xmin + 1); -+ for (nc = 0; nc < the_hdr->ncolors; ++nc) { -+ if (RLE_BIT( *the_hdr, nc)) { -+ /* Unless bg color given explicitly, use 0. */ -+ if (the_hdr->background != 2 || the_hdr->bg_color[nc] == 0) -+ memset((char *)scanline[nc] + the_hdr->xmin, 0, -+ the_hdr->xmax - the_hdr->xmin + 1); -+ else -+ memset((char *)scanline[nc] + the_hdr->xmin, -+ the_hdr->bg_color[nc], -+ the_hdr->xmax - the_hdr->xmin + 1); -+ } -+ } -+ } -+ -+ /* If skipping, then just return */ -+ if (the_hdr->priv.get.vert_skip > 0) { -+ --the_hdr->priv.get.vert_skip; -+ ++the_hdr->priv.get.scan_y; -+ if (the_hdr->priv.get.vert_skip > 0) { -+ if (the_hdr->priv.get.scan_y >= the_hdr->ymax) { -+ int const y = the_hdr->priv.get.scan_y; -+ while (rle_getskip(the_hdr) != 32768) -+ ; -+ return y; -+ } else -+ return the_hdr->priv.get.scan_y; -+ } -+ } -+ -+ /* If EOF has been encountered, return also */ -+ if (the_hdr->priv.get.is_eof) -+ return ++the_hdr->priv.get.scan_y; -+ -+ /* Otherwise, read and interpret instructions until a skipLines -+ instruction is encountered. -+ */ -+ if (RLE_BIT(*the_hdr, channel)) -+ scanc = scanline[channel] + scan_x; -+ else -+ scanc = NULL; -+ for (;;) { -+ inst[0] = getc(infile); -+ inst[1] = getc(infile); -+ if (feof(infile)) { -+ the_hdr->priv.get.is_eof = 1; -+ break; /* <--- one of the exits */ -+ } -+ -+ switch(OPCODE(inst)) { -+ case RSkipLinesOp: -+ if (LONGP(inst)) { -+ VAXSHORT(the_hdr->priv.get.vert_skip, infile); -+ } else -+ the_hdr->priv.get.vert_skip = DATUM(inst); -+ if (debug_f) -+ pm_message("Skip %d Lines (to %d)", -+ the_hdr->priv.get.vert_skip, -+ the_hdr->priv.get.scan_y + -+ the_hdr->priv.get.vert_skip); -+ -+ break; /* need to break for() here, too */ -+ -+ case RSetColorOp: -+ channel = DATUM(inst); /* select color channel */ -+ if (channel == 255) -+ channel = -1; -+ scan_x = the_hdr->xmin; -+ if (RLE_BIT(*the_hdr, channel)) -+ scanc = scanline[channel]+scan_x; -+ if (debug_f) -+ pm_message("Set color to %d (reset x to %d)", -+ channel, scan_x ); -+ break; -+ -+ case RSkipPixelsOp: -+ if (LONGP(inst)) { -+ VAXSHORT(long_data, infile); -+ scan_x += long_data; -+ scanc += long_data; -+ if (debug_f) -+ pm_message("Skip %d pixels (to %d)", long_data, scan_x); -+ } else { -+ scan_x += DATUM(inst); -+ scanc += DATUM(inst); -+ if (debug_f) -+ pm_message("Skip %d pixels (to %d)", DATUM(inst), scan_x); -+ } -+ break; -+ -+ case RByteDataOp: -+ if (LONGP(inst)) { -+ VAXSHORT(nc, infile); -+ } else -+ nc = DATUM(inst); -+ ++nc; -+ if (debug_f) { -+ if (RLE_BIT(*the_hdr, channel)) -+ pm_message("Pixel data %d (to %d):", nc, scan_x + nc); -+ else -+ pm_message("Pixel data %d (to %d)", nc, scan_x + nc); -+ } -+ if (RLE_BIT(*the_hdr, channel)) { -+ /* Don't fill past end of scanline! */ -+ if (scan_x + nc > max_x) { -+ ns = scan_x + nc - max_x - 1; -+ nc -= ns; -+ } else -+ ns = 0; -+ fread((char *)scanc, 1, nc, infile); -+ while (ns-- > 0) -+ getc(infile); -+ if (nc & 0x1) -+ getc(infile); /* throw away odd byte */ -+ } else { -+ if (the_hdr->priv.get.is_seek) -+ fseek(infile, ((nc + 1) / 2) * 2, 1); -+ else { -+ int ii; -+ for (ii = ((nc + 1) / 2) * 2; ii > 0; --ii) -+ getc(infile); /* discard it */ -+ } -+ } -+ scanc += nc; -+ scan_x += nc; -+ if (debug_f && RLE_BIT(*the_hdr, channel)) { -+ rle_pixel * cp; -+ for (cp = scanc - nc; nc > 0; --nc) -+ fprintf(stderr, "%02x", *cp++); -+ putc('\n', stderr); -+ } -+ break; -+ -+ case RRunDataOp: -+ if (LONGP(inst)) { -+ VAXSHORT(nc, infile); -+ } else -+ nc = DATUM(inst); -+ ++nc; -+ scan_x += nc; -+ -+ VAXSHORT(word, infile); -+ if (debug_f) -+ pm_message("Run length %d (to %d), data %02x", -+ nc, scan_x, word); -+ if (RLE_BIT(*the_hdr, channel)) { -+ if (scan_x > max_x) { -+ ns = scan_x - max_x - 1; -+ nc -= ns; -+ } else -+ ns = 0; -+ if (nc >= 10) { /* break point for 785, anyway */ -+ memset((char *)scanc, word, nc); -+ scanc += nc; -+ } else { -+ for (nc--; nc >= 0; --nc, ++scanc) -+ *scanc = word; -+ } -+ } -+ break; -+ -+ case REOFOp: -+ the_hdr->priv.get.is_eof = 1; -+ if (debug_f) -+ pm_message("End of Image"); -+ break; -+ -+ default: -+ pm_error("rle_getrow: Unrecognized opcode: %d, reading %s", -+ inst[0], the_hdr->file_name); -+ } -+ if (OPCODE(inst) == RSkipLinesOp || OPCODE(inst) == REOFOp) -+ break; /* <--- the other loop exit */ -+ } -+ -+ /* If at end, skip the rest of a malformed image. */ -+ if (the_hdr->priv.get.scan_y >= the_hdr->ymax) { -+ int const y = the_hdr->priv.get.scan_y; -+ while (rle_getskip(the_hdr) != 32768 ) -+ ; -+ return y; -+ } -+ -+ return the_hdr->priv.get.scan_y; -+} -+ -+ -+ -diff --git a/urt/rle_hdr.c b/urt/rle_hdr.c -index bdb728d..e3f5330 100644 ---- a/urt/rle_hdr.c -+++ b/urt/rle_hdr.c +diff -urNp a/urt/rle_hdr.c b/urt/rle_hdr.c +--- a/urt/rle_hdr.c 2025-02-03 09:24:28.360500401 +0100 ++++ b/urt/rle_hdr.c 2025-02-04 10:42:11.745682618 +0100 @@ -148,7 +148,7 @@ rle_hdr_cp(rle_hdr * const fromHdrP, if (toHdrP->cmap) { size_t const size = @@ -7450,11 +877,12 @@ index bdb728d..e3f5330 100644 if (!toHdrP->cmap) pm_error("Failed to allocate memory for %u color maps " "of length %u", toHdrP->ncmap, 1 << toHdrP->cmaplen); -@@ -164,11 +164,16 @@ rle_hdr_cp(rle_hdr * const fromHdrP, +@@ -163,12 +163,16 @@ rle_hdr_cp(rle_hdr * const fromHdrP, + const char ** cp; /* Count the comments. */ - for (cp = toHdrP->comments, size = 0; *cp; ++cp) -+ { +- for (cp = toHdrP->comments, size = 0; *cp; ++cp) ++ for (cp = toHdrP->comments, size = 0; *cp; ++cp) { + overflow_add(size,1); ++size; + } @@ -7467,2170 +895,26 @@ index bdb728d..e3f5330 100644 size *= sizeof(char *); toHdrP->comments = malloc(size); if (!toHdrP->comments) -diff --git a/urt/rle_hdr.c.orig b/urt/rle_hdr.c.orig -new file mode 100644 -index 0000000..1edb7a3 ---- /dev/null -+++ b/urt/rle_hdr.c.orig -@@ -0,0 +1,286 @@ -+/* -+ * This software is copyrighted as noted below. It may be freely copied, -+ * modified, and redistributed, provided that the copyright notice is -+ * preserved on all copies. -+ * -+ * There is no warranty or other guarantee of fitness for this software, -+ * it is provided solely "as is". Bug reports or fixes may be sent -+ * to the author, who may or may not act on them as he desires. -+ * -+ * You may not include this software in a program or other software product -+ * without supplying the source, or without informing the end-user that the -+ * source is available for no extra charge. -+ * -+ * If you modify this software, you should include a notice giving the -+ * name of the person performing the modification, the date of modification, -+ * and the reason for such modification. -+ */ -+/* -+ * rle_hdr.c - Functions to manipulate rle_hdr structures. -+ * -+ * Author: Spencer W. Thomas -+ * EECS Dept. -+ * University of Michigan -+ * Date: Mon May 20 1991 -+ * Copyright (c) 1991, University of Michigan -+ */ -+ -+#include -+ -+#include "nstring.h" -+#include "mallocvar.h" -+ -+#include "rle_config.h" -+#include "rle.h" -+ -+ -+ -+void -+rle_names(rle_hdr * const hdrP, -+ const char * const pgmname, -+ const char * const fname, -+ int const imgNum) { -+/*---------------------------------------------------------------------------- -+ * Load program and file names into header. -+ * Inputs: -+ * hdrP: Header to modify. -+ * pgmname: The program name. -+ * fname: The file name. -+ * imgNum: Number of the image within the file. -+ * Outputs: -+ * *hdrP: Modified header. -+-----------------------------------------------------------------------------*/ -+ -+ /* Algorithm: -+ If values previously filled in (by testing is_init field), -+ free them. Make copies of file name and program name, -+ modifying file name for standard i/o. Set is_init field. -+ */ -+ const char * newFname; -+ const char * newPgmname; -+ -+ /* Mark as filled in. */ -+ hdrP->is_init = RLE_INIT_MAGIC; -+ -+ /* Default file name for stdin/stdout. */ -+ if (!fname || streq(fname, "-") || strlen(fname) == 0) -+ newFname = "Standard I/O"; -+ else -+ newFname = fname; -+ -+ if (pgmname) -+ newPgmname = pgmname; -+ else -+ newPgmname = rle_dflt_hdr.cmd; -+ -+ /* Fill in with copies of the strings. */ -+ if (hdrP->cmd != newPgmname) -+ hdrP->cmd = pm_strdup(newPgmname); -+ -+ if (hdrP->file_name != newFname) -+ hdrP->cmd = pm_strdup(newFname); -+ -+ hdrP->img_num = imgNum; -+} -+ -+ -+ -+/* Used by rle_hdr_cp and rle_hdr_init to avoid recursion loops. */ -+static int noRecurse = 0; -+ -+ -+ -+rle_hdr * -+rle_hdr_cp(rle_hdr * const fromHdrP, -+ rle_hdr * const toHdrArgP) { -+/*---------------------------------------------------------------------------- -+ * Make a "safe" copy of a rle_hdr structure. -+ * Inputs: -+ * *fromHdrP: Header to be copied. -+ * Outputs: -+ * *toHdrPd: Copy of from_hdr, with all memory referred to -+ * by pointers copied. Also returned as function -+ * value. If NULL, a static header is used. -+ * Assumptions: -+ * It is safe to call rle_hdr_init on *toHdrP. -+-----------------------------------------------------------------------------*/ -+ /* Algorithm: -+ Initialize *toHdrP, copy *fromHdrP to it, then copy the memory -+ referred to by all non-null pointers. -+ */ -+ static rle_hdr dfltHdr; -+ rle_hdr * toHdrP; -+ const char * cmd; -+ const char * file; -+ unsigned int num; -+ -+ /* Save command, file name, and image number if already initialized. */ -+ if (toHdrArgP && toHdrArgP->is_init == RLE_INIT_MAGIC) { -+ cmd = toHdrArgP->cmd; -+ file = toHdrArgP->file_name; -+ num = toHdrArgP->img_num; -+ } else { -+ cmd = file = NULL; -+ num = 0; -+ } -+ -+ if (!noRecurse) { -+ ++noRecurse; -+ rle_hdr_init(toHdrArgP); -+ --noRecurse; -+ } -+ -+ toHdrP = toHdrArgP ? toHdrArgP : &dfltHdr; -+ -+ *toHdrP = *fromHdrP; -+ -+ if (toHdrP->bg_color) { -+ unsigned int i; -+ -+ MALLOCARRAY(toHdrP->bg_color, toHdrP->ncolors); -+ if (!toHdrP->bg_color) -+ pm_error("Failed to allocate array for %u background colors", -+ toHdrP->ncolors); -+ for (i = 0; i < toHdrP->ncolors; ++i) -+ toHdrP->bg_color[i] = fromHdrP->bg_color[i]; -+ } -+ -+ if (toHdrP->cmap) { -+ size_t const size = -+ toHdrP->ncmap * (1 << toHdrP->cmaplen) * sizeof(rle_map); -+ toHdrP->cmap = malloc(size); -+ if (!toHdrP->cmap) -+ pm_error("Failed to allocate memory for %u color maps " -+ "of length %u", toHdrP->ncmap, 1 << toHdrP->cmaplen); -+ memcpy(toHdrP->cmap, fromHdrP->cmap, size); -+ } -+ -+ /* Only copy array of pointers, as the original comment memory -+ * never gets overwritten. -+ */ -+ if (toHdrP->comments) { -+ unsigned int size; -+ const char ** cp; -+ -+ /* Count the comments. */ -+ for (cp = toHdrP->comments, size = 0; *cp; ++cp) -+ ++size; -+ -+ /* Check if there are really any comments. */ -+ if (size > 0) { -+ ++size; /* Copy the NULL pointer, too. */ -+ size *= sizeof(char *); -+ toHdrP->comments = malloc(size); -+ if (!toHdrP->comments) -+ pm_error("Failed to allocation %u bytes for comments", size); -+ memcpy(toHdrP->comments, fromHdrP->comments, size); -+ } else -+ toHdrP->comments = NULL; /* Blow off empty comment list. */ -+ } -+ -+ /* Restore the names to their original values. */ -+ toHdrP->cmd = cmd; -+ toHdrP->file_name = file; -+ -+ /* Lines above mean nothing much happens if cmd and file are != NULL. */ -+ rle_names(toHdrP, toHdrP->cmd, toHdrP->file_name, num); -+ -+ return toHdrP; -+} -+ -+ -+ -+void -+rle_hdr_clear(rle_hdr * const hdrP) { -+/*---------------------------------------------------------------------------- -+ * Clear out the allocated memory pieces of a header. -+ * -+ * This routine is intended to be used internally by the library, to -+ * clear a header before putting new data into it. It clears all the -+ * fields that would be set by reading in a new image header. -+ * Therefore, it does not clear the program and file names. -+ * -+ * Inputs: -+ * hdrP: To be cleared. -+ * Outputs: -+ * *hdrP: After clearing. -+ * Assumptions: -+ * If is_init field is RLE_INIT_MAGIC, the header has been -+ * properly initialized. This will fail every 2^(-32) times, on -+ * average. -+-----------------------------------------------------------------------------*/ -+ /* Algorithm: -+ Free memory and set to zero all pointers, except program and -+ file name. -+ */ -+ -+ /* Try to free memory. Assume if is_init is properly set that this -+ * header has been previously initialized, therefore it is safe to -+ * free memory. -+ */ -+ if (hdrP && hdrP->is_init == RLE_INIT_MAGIC) { -+ if (hdrP->bg_color ) -+ free(hdrP->bg_color); -+ hdrP->bg_color = NULL; -+ if (hdrP->cmap ) -+ free(hdrP->cmap); -+ hdrP->cmap = NULL; -+ /* Unfortunately, we don't know how to free the comment memory. */ -+ if (hdrP->comments) -+ free(hdrP->comments); -+ hdrP->comments = NULL; -+ } -+} -+ -+ -+ -+rle_hdr * -+rle_hdr_init(rle_hdr * const hdrP) { -+/*---------------------------------------------------------------------------- -+ * Initialize a rle_hdr structure. -+ * Inputs: -+ * hdrP: Header to be initialized. -+ * Outputs: -+ * *hdrP: Initialized header. -+ * Assumptions: -+ * If hdrP->is_init is RLE_INIT_MAGIC, the header has been -+ * previously initialized. -+ * If the_hdr is a copy of another rle_hdr structure, the copy -+ * was made with rle_hdr_cp. -+-----------------------------------------------------------------------------*/ -+ /* Algorithm: -+ Fill in fields of rle_dflt_hdr that could not be set by the loader -+ If the_hdr is rle_dflt_hdr, do nothing else -+ Else: -+ If hdrP is NULL, return a copy of rle_dflt_hdr in static storage -+ If hdrP->is_init is RLE_INIT_MAGIC, free all memory -+ pointed to by non-null pointers. -+ If this is a recursive call to rle_hdr_init, clear *hdrP and -+ return hdrP. -+ Else make a copy of rle_dflt_hdr and return its address. Make the -+ copy in static storage if hdrP is NULL, and in *hdrP otherwise. -+ */ -+ rle_hdr * retval; -+ -+ rle_dflt_hdr.rle_file = stdout; -+ -+ /* The rest of rle_dflt_hdr is set by the loader's data initialization */ -+ -+ if (hdrP == &rle_dflt_hdr) -+ retval = hdrP; -+ else { -+ rle_hdr_clear(hdrP); -+ -+ /* Call rle_hdr_cp only if not called from there. */ -+ if (!noRecurse) { -+ ++noRecurse; -+ retval = rle_hdr_cp(&rle_dflt_hdr, hdrP); -+ --noRecurse; -+ } else -+ retval = hdrP; -+ } -+ return retval; -+} -+ -+ -+ -diff --git a/urt/rle_hdr.c.rej b/urt/rle_hdr.c.rej -new file mode 100644 -index 0000000..62f2fb0 ---- /dev/null -+++ b/urt/rle_hdr.c.rej -@@ -0,0 +1,63 @@ -+--- urt/rle_hdr.c -++++ urt/rle_hdr.c -+@@ -80,7 +80,10 @@ int img_num; -+ /* Fill in with copies of the strings. */ -+ if ( the_hdr->cmd != pgmname ) -+ { -+- char *tmp = (char *)malloc( strlen( pgmname ) + 1 ); -++ char *tmp; -++ -++ overflow_add(strlen(pgmname), 1); -++ tmp = malloc( strlen(pgmname) + 1 ); -+ RLE_CHECK_ALLOC( pgmname, tmp, 0 ); -+ strcpy( tmp, pgmname ); -+ the_hdr->cmd = tmp; -+@@ -88,8 +91,10 @@ int img_num; -+ -+ if ( the_hdr->file_name != fname ) -+ { -+- char *tmp = (char *)malloc( strlen( fname ) + 1 ); -+- RLE_CHECK_ALLOC( pgmname, tmp, 0 ); -++ char *tmp; -++ overflow_add(strlen(fname), 1); -++ tmp = malloc( strlen( fname ) + 1 ); -++ RLE_CHECK_ALLOC( pgmname, tmp, 0 ); -+ strcpy( tmp, fname ); -+ the_hdr->file_name = tmp; -+ } -+@@ -153,6 +158,7 @@ rle_hdr *from_hdr, *to_hdr; -+ if ( to_hdr->bg_color ) -+ { -+ int size = to_hdr->ncolors * sizeof(int); -++ overflow2(to_hdr->ncolors, sizeof(int)); -+ to_hdr->bg_color = (int *)malloc( size ); -+ RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->bg_color, "background color" ); -+ memcpy( to_hdr->bg_color, from_hdr->bg_color, size ); -+@@ -161,7 +167,7 @@ rle_hdr *from_hdr, *to_hdr; -+ if ( to_hdr->cmap ) -+ { -+ int size = to_hdr->ncmap * (1 << to_hdr->cmaplen) * sizeof(rle_map); -+- to_hdr->cmap = (rle_map *)malloc( size ); -++ to_hdr->cmap = (rle_map *)malloc3( to_hdr->ncmap, 1<cmaplen, sizeof(rle_map)); -+ RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->cmap, "color map" ); -+ memcpy( to_hdr->cmap, from_hdr->cmap, size ); -+ } -+@@ -173,12 +179,17 @@ rle_hdr *from_hdr, *to_hdr; -+ { -+ int size = 0; -+ CONST_DECL char **cp; -+- for ( cp=to_hdr->comments; *cp; cp++ ) -++ for ( cp=to_hdr->comments; *cp; cp++ ) -++ { -++ overflow_add(size, 1); -+ size++; /* Count the comments. */ -++ } -+ /* Check if there are really any comments. */ -+ if ( size ) -+ { -++ overflow_add(size, 1); -+ size++; /* Copy the NULL pointer, too. */ -++ overflow2(size, sizeof(char *)); -+ size *= sizeof(char *); -+ to_hdr->comments = (CONST_DECL char **)malloc( size ); -+ RLE_CHECK_ALLOC( to_hdr->cmd, to_hdr->comments, "comments" ); -diff --git a/urt/rle_open_f.c b/urt/rle_open_f.c -index 1aeb644..c2ef37d 100644 ---- a/urt/rle_open_f.c -+++ b/urt/rle_open_f.c -@@ -1,7 +1,7 @@ --/* -+/* - * rle_open_f.c - Open a file with defaults. -- * -- * Author : Jerry Winters -+ * -+ * Author : Jerry Winters - * EECS Dept. - * University of Michigan - * Date: 11/14/89 -@@ -37,8 +37,8 @@ - - - static FILE * --my_popen(const char * const cmd, -- const char * const mode, -+my_popen(const char * const cmd, -+ const char * const mode, - int * const pid) { - - FILE *retfile; -@@ -55,7 +55,7 @@ my_popen(const char * const cmd, - - if (pm_pipe(pipefd) < 0 ) - return NULL; -- -+ - /* Flush known files. */ - fflush(stdout); - fflush(stderr); -@@ -86,7 +86,7 @@ my_popen(const char * const cmd, - if ( execl("/bin/sh", "sh", "-c", cmd, NULL) < 0 ) - exit(127); - /* NOTREACHED */ -- } -+ } - - /* Close file descriptors, and gen up a FILE ptr */ - if ( *mode == 'r' ) -@@ -163,72 +163,14 @@ dealWithSubprocess(const char * const file_name, - FILE ** const fpP, - bool * const noSubprocessP, - const char ** const errorP) { -- --#ifdef NO_OPEN_PIPES - *noSubprocessP = TRUE; --#else -- const char *cp; -- -- reapChildren(catchingChildrenP, pids); -- -- /* Real file, not stdin or stdout. If name ends in ".Z", -- * pipe from/to un/compress (depending on r/w mode). -- * -- * If it starts with "|", popen that command. -- */ -- -- cp = file_name + strlen(file_name) - 2; -- /* Pipe case. */ -- if (file_name[0] == '|') { -- pid_t thepid; /* PID from my_popen */ -- -- *noSubprocessP = FALSE; -- -- *fpP = my_popen(file_name + 1, mode, &thepid); -- if (*fpP == NULL) -- *errorP = "%s: can't invoke <<%s>> for %s: "; -- else { -- /* One more child to catch, eventually. */ -- if (*catchingChildrenP < MAX_CHILDREN) -- pids[(*catchingChildrenP)++] = thepid; -- } -- } else if (cp > file_name && *cp == '.' && *(cp + 1) == 'Z' ) { -- /* Compress case. */ -- pid_t thepid; /* PID from my_popen. */ -- const char * command; -- -- *noSubprocessP = FALSE; -- -- if (*mode == 'w') -- pm_asprintf(&command, "compress > %s", file_name); -- else if (*mode == 'a') -- pm_asprintf(&command, "compress >> %s", file_name); -- else -- pm_asprintf(&command, "compress -d < %s", file_name); -- -- *fpP = my_popen(command, mode, &thepid); -- -- if (*fpP == NULL) -- *errorP = "%s: can't invoke 'compress' program, " -- "trying to open %s for %s"; -- else { -- /* One more child to catch, eventually. */ -- if (*catchingChildrenP < MAX_CHILDREN) -- pids[(*catchingChildrenP)++] = thepid; -- } -- pm_strfree(command); -- } else { -- *noSubprocessP = TRUE; -- *errorP = NULL; -- } --#endif - } - - - - --/* -- * Purpose : Open a file for input or output as controlled by the mode -+/* -+ * Purpose : Open a file for input or ouput as controlled by the mode - * parameter. If no file name is specified (ie. file_name is null) then - * a pointer to stdin or stdout will be returned. The calling routine may - * call this routine with a file name of "-". For this case rle_open_f -@@ -246,11 +188,11 @@ dealWithSubprocess(const char * const file_name, - * - * output: - * a file pointer -- * -+ * - */ - FILE * --rle_open_f_noexit(const char * const prog_name, -- const char * const file_name, -+rle_open_f_noexit(const char * const prog_name, -+ const char * const file_name, - const char * const mode ) { - - FILE * retval; -@@ -265,12 +207,12 @@ rle_open_f_noexit(const char * const prog_name, - fp = stdout; /* Set the default value */ - else - fp = stdin; -- -+ - if (file_name != NULL && !streq(file_name, "-")) { - bool noSubprocess; - dealWithSubprocess(file_name, mode, &catching_children, pids, - &fp, &noSubprocess, &err_str); -- -+ - if (!err_str) { - if (noSubprocess) { - /* Ordinary, boring file case. */ -@@ -286,7 +228,7 @@ rle_open_f_noexit(const char * const prog_name, - mode_string[0] = mode[0]; - mode_string[1] = 'b'; - strcpy( mode_string + 2, mode + 1 ); -- -+ - fp = fopen(file_name, mode_string); - if (fp == NULL ) - err_str = "%s: can't open %s for %s: "; -@@ -325,7 +267,7 @@ rle_open_f(const char * prog_name, const char * file_name, const char * mode) - - /***************************************************************** - * TAG( rle_close_f ) -- * -+ * - * Close a file opened by rle_open_f. If the file is stdin or stdout, - * it will not be closed. - * Inputs: -@@ -347,6 +289,3 @@ rle_close_f( fd ) - else - fclose( fd ); - } -- -- -- -diff --git a/urt/rle_putcom.c b/urt/rle_putcom.c -index ab2eb20..ce83615 100644 ---- a/urt/rle_putcom.c -+++ b/urt/rle_putcom.c -@@ -98,12 +98,14 @@ rle_putcom(const char * const value, - const char * v; - const char ** old_comments; - int i; -- for (i = 2, cp = the_hdr->comments; *cp != NULL; ++i, ++cp) -+ for (i = 2, cp = the_hdr->comments; *cp != NULL; ++i, ++cp) { +diff -urNp a/urt/rle_putcom.c b/urt/rle_putcom.c +--- a/urt/rle_putcom.c 2025-02-03 09:24:28.360500401 +0100 ++++ b/urt/rle_putcom.c 2025-02-04 10:43:04.472477242 +0100 +@@ -101,6 +101,7 @@ rle_putcom(const char * const value, + for (i = 2, cp = hdrP->comments; + *cp != NULL && i < UINT_MAX; + ++i, ++cp) { + overflow_add(i, 1); if (match(value, *cp) != NULL) { v = *cp; *cp = value; - return v; - } -+ } - /* Not found */ - /* Can't realloc because somebody else might be pointing to this - * comments block. Of course, if this were true, then the -diff --git a/urt/scanargs.c b/urt/scanargs.c -index 1dcdd23..5e114bb 100644 ---- a/urt/scanargs.c -+++ b/urt/scanargs.c -@@ -1,24 +1,24 @@ --/* -+/* - * $Id: scanargs.c,v 3.0.1.3 1992/02/27 21:18:14 spencer Exp $ -- * Version 7 compatible -- * Argument scanner, scans argv style argument list. -- * -- * Some stuff is a kludge because sscanf screws up -- * -- * Gary Newman - 10/4/1979 - Ampex Corp. -- * -- * Modified by Spencer W. Thomas, Univ. of Utah, 5/81 to -- * add args introduced by a flag, add qscanargs call, -- * allow empty flags. -- * -- * If you make improvements we'd like to get them too. -- * Jay Lepreau lepreau@utah-20, decvax!harpo!utah-cs!lepreau -- * Spencer Thomas thomas@utah-20, decvax!harpo!utah-cs!thomas -- * -- * (I know the code is ugly, but it just grew, you see ...) -- * -- * Modified by: Spencer W. Thomas -- * Date: Feb 25 1983 -+ * Version 7 compatible -+ * Argument scanner, scans argv style argument list. -+ * -+ * Some stuff is a kludge because sscanf screws up -+ * -+ * Gary Newman - 10/4/1979 - Ampex Corp. -+ * -+ * Modified by Spencer W. Thomas, Univ. of Utah, 5/81 to -+ * add args introduced by a flag, add qscanargs call, -+ * allow empty flags. -+ * -+ * If you make improvements we'd like to get them too. -+ * Jay Lepreau lepreau@utah-20, decvax!harpo!utah-cs!lepreau -+ * Spencer Thomas thomas@utah-20, decvax!harpo!utah-cs!thomas -+ * -+ * (I know the code is ugly, but it just grew, you see ...) -+ * -+ * Modified by: Spencer W. Thomas -+ * Date: Feb 25 1983 - * 1. Fixed scanning of optional args. Now args introduced by a flag - * must follow the flag which introduces them and precede any other - * flag argument. It is still possible for a flag introduced -@@ -26,11 +26,11 @@ - * earlier in the format string. This implies that flags may not - * be conditional upon other flags, and a message will be generated - * if this is attempted. -- * -+ * - * 2. Usage message can be formatted by inserting newlines, tabs and - * spaces into the format string. This is especially useful for - * long argument lists. -- * -+ * - * 3. Added n/N types for "numeric" args. These args are scanned - * using the C language conventions - a number starting 0x is - * hexadecimal, a number starting with 0 is octal, otherwise it is -@@ -49,7 +49,7 @@ - #include "rle_config.h" - #include "rle.h" +diff -urNp a/urt/Runput.c b/urt/Runput.c +--- a/urt/Runput.c 2025-02-03 09:24:28.360500401 +0100 ++++ b/urt/Runput.c 2025-02-04 10:30:24.683997548 +0100 +@@ -236,7 +236,7 @@ RunSetup(rle_hdr * const hdrP) { + int * bg_color; --/* -+/* - * An explicit assumption is made in this code that all pointers look - * alike, except possible char * pointers. - */ -@@ -59,19 +59,18 @@ typedef int *ptr; - #define NO 0 - #define ERROR(msg) {fprintf(stderr, "%s\n", msg); goto error; } + assert(hdrP->ncolors < UINT_MAX); +- ++ overflow_add(hdrP->ncolors, 1); + MALLOCARRAY_NOFAIL(background, hdrP->ncolors + 1); --/* -+/* - * Storage allocation macros - */ --#define NEW( type, cnt ) (type *) malloc( (cnt) * sizeof( type ) ) --#define RENEW( type, ptr, cnt ) (type *) realloc( ptr, (cnt) * sizeof( type ) ) -- -+#define NEW( type, cnt ) (type *) malloc2( (cnt) , sizeof( type ) ) -+#define RENEW( type, ptr, cnt ) (type *) realloc2( ptr, (cnt), sizeof( type ) ) - static CONST_DECL char * prformat( CONST_DECL char *, int ); - static int isnum( CONST_DECL char *, int, int ); --static int _do_scanargs( int argc, char **argv, CONST_DECL char *format, -- va_list argl ); --void scan_usage( char **, CONST_DECL char * ); -+static int _do_scanargs( int argc, char **argv, CONST_DECL char *format, -+ va_list argl ); -+void scan_usage( char **, CONST_DECL char * ); - --/* -+/* - * Argument list is (argc, argv, format, ... ) - */ - int -@@ -84,8 +83,8 @@ scanargs ( int argc, char **argv, CONST_DECL char *format, ... ) - va_end( argl ); - return retval; - } -- --/* -+ -+/* - * This routine is necessary because of a pyramid compiler botch that - * uses parameter registers in a varargs routine. The extra - * subroutine call isolates the args on the register stack so they -@@ -94,583 +93,583 @@ scanargs ( int argc, char **argv, CONST_DECL char *format, ... ) - - static int - _do_scanargs( argc, argv, format, argl ) --int argc; /* Actual arguments */ -+int argc; /* Actual arguments */ - char **argv; - CONST_DECL char *format; - va_list argl; - { - -- int check; /* check counter to be sure all argvs -- are processed */ -+ int check; /* check counter to be sure all argvs -+ are processed */ - register CONST_DECL char *cp; - int cnt; -- int optarg = 0; /* where optional args start */ -- int nopt = 0; -- char tmpflg, /* temp flag */ -- typchr; /* type char from format string */ -+ int optarg = 0; /* where optional args start */ -+ int nopt = 0; -+ char tmpflg, /* temp flag */ -+ typchr; /* type char from format string */ - char c; -- bool * arg_used; /* array of flags */ -- ptr aptr = 0; /* pointer to return loc */ -+ bool * arg_used; /* array of flags */ -+ ptr aptr = 0; /* pointer to return loc */ - - bool required; -- int excnt; /* which flag is set */ -- unsigned int exflag; /* How many of a set of exclusive -- flags is set */ -- -- bool list_of; /* set if parsing off a list of args */ -- bool comma_list; /* set if AT&T style multiple args */ -- bool no_usage; /* If set, don't print usage msg. */ -- bool help = NO; /* If set, always print usage. */ -- int * cnt_arg = 0; /* where to stuff list count */ -- int list_cnt; /* how many in list */ -+ int excnt; /* which flag is set */ -+ bool exflag; /* when set, one of a set of exclusive -+ flags is set */ -+ -+ bool list_of; /* set if parsing off a list of args */ -+ bool comma_list; /* set if AT&T style multiple args */ -+ bool no_usage; /* If set, don't print usage msg. */ -+ bool help = NO; /* If set, always print usage. */ -+ int * cnt_arg = 0; /* where to stuff list count */ -+ int list_cnt; /* how many in list */ - /* These are used to build return lists */ - char ** strlist = 0; - int * intlist = 0; - long * longlist = 0; - float * fltlist = 0; - double *dbllist = 0; -- char * argp; /* Pointer to argument. */ -+ char * argp; /* Pointer to argument. */ - -- CONST_DECL char *ncp; /* remember cp during flag scanning */ -- static char cntrl[7] = "% %1s"; /* control string for scanf's */ -- char junk[2]; /* junk buffer for scanf's */ -+ CONST_DECL char *ncp; /* remember cp during flag scanning */ -+ static char cntrl[7] = "% %1s"; /* control string for scanf's */ -+ char junk[2]; /* junk buffer for scanf's */ - - /* Set up for argument counting. */ - arg_used = NEW( bool, argc ); - if (arg_used == NULL) - { -- fprintf(stderr, "malloc failed in scanargs, exiting\n"); -- exit(-1); -+ fprintf(stderr, "malloc failed in scanargs, exiting\n"); -+ exit(-1); - } - else - { -- for (cnt=0; cnt 0 ) -- switch ( *(cp++) ) -- { -- case '(': depth++; break; -- case ')': depth--; break; -- } -- break; -- } -- -- case '!': /* required argument */ -- required = YES; -- case '%': /* not required argument */ --reswitch: /* after finding '*' or ',' */ -- switch (typchr = *(cp++)) -- { -- case ',': /* argument is AT&T list of things */ -- comma_list = YES; -- case '*': /* argument is list of things */ -- list_of = YES; -- list_cnt = 0; /* none yet */ -- cnt_arg = va_arg( argl, int *); /* item count * here */ -- goto reswitch; /* try again */ -- -- case '$': /* "rest" of argument list */ -- while ( argc > 1 && !arg_used[argc-1] ) -- argc--; /* find last used argument */ -- *va_arg( argl, int * ) = argc; -- break; -- -- case '&': /* Return unused args. */ -- /* Count how many. Always include argv[0]. */ -- for ( nopt = cnt = 1; cnt < argc; cnt++ ) -- if ( !arg_used[cnt] ) -- nopt++; -- if ( nopt == 1 ) -- nopt = 0; /* Special case for no args. */ -- if ( nopt > 0 ) -- { -- strlist = NEW( char *, nopt + 1 ); -- /* Copy program name, for sure. */ -- strlist[0] = argv[0]; -- for ( nopt = cnt = 1; cnt < argc; cnt++ ) -- if ( !arg_used[cnt] ) -- { -- strlist[nopt++] = argv[cnt]; -- check += cnt; -- arg_used[cnt] = 1; -- } -- strlist[nopt] = NULL; -- } -- else -- strlist = NULL; /* No args, return empty. */ -- -- /* Return count and arg list. */ -- *va_arg( argl, int * ) = nopt; -- *va_arg( argl, char *** ) = strlist; -- break; -- -- case '-': /* argument is flag */ -- if (optarg > 0) -- ERROR("Format error: flag conditional on flag not allowed"); -- -- /* go back to label */ -- ncp = cp-1; /* remember */ -- cp -= 3; -- for (excnt = exflag = 0 -- ; *cp != ' ' && !(*cp=='-' &&(cp[-1]=='!'||cp[-1]=='%')); -- (--cp, excnt++)) -- { -- for (cnt = optarg+1; cnt < argc; cnt++) -- { -- /* flags all start with - */ -- if (*argv[cnt] == '-' && !arg_used[cnt] && -- !ISDIGIT(argv[cnt][1])) -- if (*(argv[cnt] + 1) == *cp) -- { -- if (*(argv[cnt] + 2) != 0) -- ERROR ("extra flags ignored"); -- if (exflag) -- ERROR ("more than one exclusive flag chosen"); -- exflag++; -- required = NO; -- check += cnt; -- arg_used[cnt] = 1; -- nopt = cnt; -- *va_arg( argl, int *) |= (1 << excnt); -- break; -- } -- } -- } -- if (required) -- ERROR ("flag argument missing"); -- cp = ncp; -- /* -- * If none of these flags were found, skip any -- * optional arguments (in the varargs list, too). -- */ -- if (!exflag) -- { -- (void)va_arg( argl, int * );/* skip the arg, too */ -- while (*++cp && ! ISSPACE(*cp)) -- if (*cp == '!' || *cp == '%') -- { -- if ( *++cp == '*' || *cp == ',' ) -- { -- cp++; -- (void)va_arg( argl, int * ); -- } -- /* -- * Assume that char * might be a -- * different size, but that all -- * other pointers are same size. -- */ -- if ( *cp == 's' ) -- (void)va_arg( argl, char * ); -- else -- (void)va_arg( argl, ptr ); -- } -- } -- else -- { -- optarg = nopt; -- cp++; /* skip over - */ -- } -- -- break; -- -- case 's': /* char string */ -- case 'd': /* decimal # */ -- case 'o': /* octal # */ -- case 'x': /* hexadecimal # */ -- case 'n': /* "number" in C syntax */ -- case 'f': /* floating # */ -- case 'D': /* long decimal # */ -- case 'O': /* long octal # */ -- case 'X': /* long hexadecimal # */ -- case 'N': /* long number in C syntax */ -- case 'F': /* double precision floating # */ -+ required = NO; /* reset per-arg flags */ -+ list_of = NO; -+ comma_list = NO; -+ list_cnt = 0; -+ switch (*(cp++)) -+ { -+ default: /* all other chars */ -+ break; -+ case ' ': /* separators */ -+ case '\t': -+ case '\n': -+ optarg = 0; /* end of optional arg string */ -+ break; -+ -+ case '(': /* Surrounds a comment. */ -+ { -+ int depth = 1; /* Count parenthesis depth. */ -+ while ( *cp && depth > 0 ) -+ switch ( *(cp++) ) -+ { -+ case '(': depth++; break; -+ case ')': depth--; break; -+ } -+ break; -+ } -+ -+ case '!': /* required argument */ -+ required = YES; -+ case '%': /* not required argument */ -+reswitch: /* after finding '*' or ',' */ -+ switch (typchr = *(cp++)) -+ { -+ case ',': /* argument is AT&T list of things */ -+ comma_list = YES; -+ case '*': /* argument is list of things */ -+ list_of = YES; -+ list_cnt = 0; /* none yet */ -+ cnt_arg = va_arg( argl, int *); /* item count * here */ -+ goto reswitch; /* try again */ -+ -+ case '$': /* "rest" of argument list */ -+ while ( argc > 1 && !arg_used[argc-1] ) -+ argc--; /* find last used argument */ -+ *va_arg( argl, int * ) = argc; -+ break; -+ -+ case '&': /* Return unused args. */ -+ /* Count how many. Always include argv[0]. */ -+ for ( nopt = cnt = 1; cnt < argc; cnt++ ) -+ if ( !arg_used[cnt] ) -+ nopt++; -+ if ( nopt == 1 ) -+ nopt = 0; /* Special case for no args. */ -+ if ( nopt > 0 ) -+ { -+ strlist = NEW( char *, nopt + 1 ); -+ /* Copy program name, for sure. */ -+ strlist[0] = argv[0]; -+ for ( nopt = cnt = 1; cnt < argc; cnt++ ) -+ if ( !arg_used[cnt] ) -+ { -+ strlist[nopt++] = argv[cnt]; -+ check += cnt; -+ arg_used[cnt] = 1; -+ } -+ strlist[nopt] = NULL; -+ } -+ else -+ strlist = NULL; /* No args, return empty. */ -+ -+ /* Return count and arg list. */ -+ *va_arg( argl, int * ) = nopt; -+ *va_arg( argl, char *** ) = strlist; -+ break; -+ -+ case '-': /* argument is flag */ -+ if (optarg > 0) -+ ERROR("Format error: flag conditional on flag not allowed"); -+ -+ /* go back to label */ -+ ncp = cp-1; /* remember */ -+ cp -= 3; -+ for (excnt = exflag = 0 -+ ; *cp != ' ' && !(*cp=='-' &&(cp[-1]=='!'||cp[-1]=='%')); -+ (--cp, excnt++)) -+ { -+ for (cnt = optarg+1; cnt < argc; cnt++) -+ { -+ /* flags all start with - */ -+ if (*argv[cnt] == '-' && !arg_used[cnt] && -+ !ISDIGIT(argv[cnt][1])) -+ if (*(argv[cnt] + 1) == *cp) -+ { -+ if (*(argv[cnt] + 2) != 0) -+ ERROR ("extra flags ignored"); -+ if (exflag) -+ ERROR ("more than one exclusive flag chosen"); -+ exflag++; -+ required = NO; -+ check += cnt; -+ arg_used[cnt] = 1; -+ nopt = cnt; -+ *va_arg( argl, int *) |= (1 << excnt); -+ break; -+ } -+ } -+ } -+ if (required) -+ ERROR ("flag argument missing"); -+ cp = ncp; -+ /* -+ * If none of these flags were found, skip any -+ * optional arguments (in the varargs list, too). -+ */ -+ if (!exflag) -+ { -+ (void)va_arg( argl, int * );/* skip the arg, too */ -+ while (*++cp && ! ISSPACE(*cp)) -+ if (*cp == '!' || *cp == '%') -+ { -+ if ( *++cp == '*' || *cp == ',' ) -+ { -+ cp++; -+ (void)va_arg( argl, int * ); -+ } -+ /* -+ * Assume that char * might be a -+ * different size, but that all -+ * other pointers are same size. -+ */ -+ if ( *cp == 's' ) -+ (void)va_arg( argl, char * ); -+ else -+ (void)va_arg( argl, ptr ); -+ } -+ } -+ else -+ { -+ optarg = nopt; -+ cp++; /* skip over - */ -+ } -+ -+ break; -+ -+ case 's': /* char string */ -+ case 'd': /* decimal # */ -+ case 'o': /* octal # */ -+ case 'x': /* hexadecimal # */ -+ case 'n': /* "number" in C syntax */ -+ case 'f': /* floating # */ -+ case 'D': /* long decimal # */ -+ case 'O': /* long octal # */ -+ case 'X': /* long hexadecimal # */ -+ case 'N': /* long number in C syntax */ -+ case 'F': /* double precision floating # */ - #if defined(sgi) && !defined(mips) -- /* Fix for broken SGI IRIS 2400/3000 floats */ -- if ( typchr == 'F' ) typchr = 'f'; -+ /* Fix for broken SGI IRIS 2400/3000 floats */ -+ if ( typchr == 'F' ) typchr = 'f'; - #endif /* sgi */ -- for (cnt = optarg+1; cnt < argc; cnt++) -- { -- argp = argv[cnt]; -- -- if ( isnum( argp, typchr, comma_list ) ) -- { -- ; /* it's ok, then */ -- } -- else if ( *argp == '-' && argp[1] != '\0' ) -- if ( optarg > 0 ) /* end optional args? */ -- { -- /* Eat the arg, too, if necessary */ -- if ( list_cnt == 0 ) { -- if ( typchr == 's' ) -- (void)va_arg( argl, char * ); -- else -- (void)va_arg( argl, ptr ); -+ for (cnt = optarg+1; cnt < argc; cnt++) -+ { -+ argp = argv[cnt]; -+ -+ if ( isnum( argp, typchr, comma_list ) ) -+ { -+ ; /* it's ok, then */ -+ } -+ else if ( *argp == '-' && argp[1] != '\0' ) -+ if ( optarg > 0 ) /* end optional args? */ -+ { -+ /* Eat the arg, too, if necessary */ -+ if ( list_cnt == 0 ) { -+ if ( typchr == 's' ) -+ (void)va_arg( argl, char * ); -+ else -+ (void)va_arg( argl, ptr ); - } -- break; -- } -- else -- continue; -- else if ( typchr != 's' ) -- continue; /* not number, keep looking */ -- -- /* -- * Otherwise usable argument may already -- * be used. (Must check this after -- * checking for flag, though.) -- */ -- if (arg_used[cnt]) continue; -- -- /* -- * If it's a comma-and-or-space-separated -- * list then count how many, and separate -- * the list into an array of strings. -- */ -- if ( comma_list ) -- { -- register char * s; -- int pass; -- -- /* -- * Copy the string so we remain nondestructive -- */ -- s = NEW( char, strlen(argp)+1 ); -- strcpy( s, argp ); -- argp = s; -- -- /* -- * On pass 0, just count them. On -- * pass 1, null terminate each string -- */ -- for ( pass = 0; pass <= 1; pass++ ) -- { -- for ( s = argp; *s != '\0'; ) -- { -- if ( pass ) -- strlist[list_cnt] = s; -- while ( (c = *s) != '\0' && c != ' ' && -- c != '\t' && c != ',' ) -- s++; -- if ( pass ) -- *s = '\0'; -- -- list_cnt++; /* count separators */ -- /* -- * Two commas in a row give a null -- * string, but two spaces -- * don't. Also skip spaces -- * after a comma. -- */ -- if ( c != '\0' ) -- while ( *++s == ' ' || *s == '\t' ) -- ; -- } -- if ( pass == 0 ) -- { -- strlist = NEW( char *, list_cnt ); -- list_cnt = 0; -- } -- } -- } -- else if ( list_of ) -- list_cnt++; /* getting them one at a time */ -- /* -- * If it's either type of list, then alloc -- * storage space for the returned values -- * (except that comma-separated string -- * lists already are done). -- */ -- if ( list_of ) -- { -- if ( list_cnt == 1 || comma_list ) -- switch( typchr ) -- { -- case 's': -- if ( !comma_list ) -- strlist = NEW( char *, 1 ); -- aptr = (ptr) &strlist[0]; -- break; -- case 'n': -- case 'd': -- case 'o': -- case 'x': -- intlist = NEW( int, list_cnt ); -- aptr = (ptr) &intlist[0]; -- break; -- case 'N': -- case 'D': -- case 'O': -- case 'X': -- longlist = NEW( long, list_cnt ); -- aptr = (ptr) &longlist[0]; -- break; -- case 'f': -- fltlist = NEW( float, list_cnt ); -- aptr = (ptr) &fltlist[0]; -- break; -- case 'F': -- dbllist = NEW( double, list_cnt ); -- aptr = (ptr) &dbllist[0]; -- break; -- } -- else -- switch( typchr ) -- { -- case 's': -- strlist = RENEW( char *, strlist, -- list_cnt ); -- aptr = (ptr) &strlist[list_cnt-1]; -- break; -- case 'n': -- case 'd': -- case 'o': -- case 'x': -- intlist = RENEW( int, intlist, -- list_cnt ); -- aptr = (ptr) &intlist[list_cnt-1]; -- break; -- case 'N': -- case 'D': -- case 'O': -- case 'X': -- longlist = RENEW( long, longlist, -- list_cnt ); -- aptr = (ptr) &longlist[list_cnt-1]; -- break; -- case 'f': -- fltlist = RENEW( float, fltlist, -- list_cnt ); -- aptr = (ptr) &fltlist[list_cnt-1]; -- break; -- case 'F': -- dbllist = RENEW( double, dbllist, -- list_cnt ); -- aptr = (ptr) &dbllist[list_cnt-1]; -- break; -- } -- } -- else -- aptr = va_arg( argl, ptr ); -- -- if ( typchr == 's' ) -- { -- if ( ! comma_list ) -- *(char **)aptr = argp; -- } -- else -- { -- nopt = 0; -- do { -- /* -- * Need to update aptr if parsing -- * a comma list -- */ -- if ( comma_list && nopt > 0 ) -- { -- argp = strlist[nopt]; -- switch( typchr ) -- { -- case 'n': -- case 'd': -- case 'o': -- case 'x': -- aptr = (ptr) &intlist[nopt]; -- break; -- case 'N': -- case 'D': -- case 'O': -- case 'X': -- aptr = (ptr) &longlist[nopt]; -- break; -- case 'f': -- aptr = (ptr) &fltlist[nopt]; -- break; -- case 'F': -- aptr = (ptr) &dbllist[nopt]; -- break; -- } -- } -- /* -- * Do conversion for n and N types -- */ -- tmpflg = typchr; -- if (typchr == 'n' || typchr == 'N' ) { -- if (*argp != '0') -- tmpflg = 'd'; -- else if (*(argp+1) == 'x' || -- *(argp+1) == 'X') -- { -- tmpflg = 'x'; -- argp += 2; -- } -- else -- tmpflg = 'o'; -+ break; -+ } -+ else -+ continue; -+ else if ( typchr != 's' ) -+ continue; /* not number, keep looking */ -+ -+ /* -+ * Otherwise usable argument may already -+ * be used. (Must check this after -+ * checking for flag, though.) -+ */ -+ if (arg_used[cnt]) continue; -+ -+ /* -+ * If it's a comma-and-or-space-separated -+ * list then count how many, and separate -+ * the list into an array of strings. -+ */ -+ if ( comma_list ) -+ { -+ register char * s; -+ int pass; -+ -+ /* -+ * Copy the string so we remain nondestructive -+ */ -+ s = NEW( char, strlen(argp)+1 ); -+ strcpy( s, argp ); -+ argp = s; -+ -+ /* -+ * On pass 0, just count them. On -+ * pass 1, null terminate each string -+ */ -+ for ( pass = 0; pass <= 1; pass++ ) -+ { -+ for ( s = argp; *s != '\0'; ) -+ { -+ if ( pass ) -+ strlist[list_cnt] = s; -+ while ( (c = *s) != '\0' && c != ' ' && -+ c != '\t' && c != ',' ) -+ s++; -+ if ( pass ) -+ *s = '\0'; -+ -+ list_cnt++; /* count separators */ -+ /* -+ * Two commas in a row give a null -+ * string, but two spaces -+ * don't. Also skip spaces -+ * after a comma. -+ */ -+ if ( c != '\0' ) -+ while ( *++s == ' ' || *s == '\t' ) -+ ; -+ } -+ if ( pass == 0 ) -+ { -+ strlist = NEW( char *, list_cnt ); -+ list_cnt = 0; -+ } -+ } -+ } -+ else if ( list_of ) -+ list_cnt++; /* getting them one at a time */ -+ /* -+ * If it's either type of list, then alloc -+ * storage space for the returned values -+ * (except that comma-separated string -+ * lists already are done). -+ */ -+ if ( list_of ) -+ { -+ if ( list_cnt == 1 || comma_list ) -+ switch( typchr ) -+ { -+ case 's': -+ if ( !comma_list ) -+ strlist = NEW( char *, 1 ); -+ aptr = (ptr) &strlist[0]; -+ break; -+ case 'n': -+ case 'd': -+ case 'o': -+ case 'x': -+ intlist = NEW( int, list_cnt ); -+ aptr = (ptr) &intlist[0]; -+ break; -+ case 'N': -+ case 'D': -+ case 'O': -+ case 'X': -+ longlist = NEW( long, list_cnt ); -+ aptr = (ptr) &longlist[0]; -+ break; -+ case 'f': -+ fltlist = NEW( float, list_cnt ); -+ aptr = (ptr) &fltlist[0]; -+ break; -+ case 'F': -+ dbllist = NEW( double, list_cnt ); -+ aptr = (ptr) &dbllist[0]; -+ break; -+ } -+ else -+ switch( typchr ) -+ { -+ case 's': -+ strlist = RENEW( char *, strlist, -+ list_cnt ); -+ aptr = (ptr) &strlist[list_cnt-1]; -+ break; -+ case 'n': -+ case 'd': -+ case 'o': -+ case 'x': -+ intlist = RENEW( int, intlist, -+ list_cnt ); -+ aptr = (ptr) &intlist[list_cnt-1]; -+ break; -+ case 'N': -+ case 'D': -+ case 'O': -+ case 'X': -+ longlist = RENEW( long, longlist, -+ list_cnt ); -+ aptr = (ptr) &longlist[list_cnt-1]; -+ break; -+ case 'f': -+ fltlist = RENEW( float, fltlist, -+ list_cnt ); -+ aptr = (ptr) &fltlist[list_cnt-1]; -+ break; -+ case 'F': -+ dbllist = RENEW( double, dbllist, -+ list_cnt ); -+ aptr = (ptr) &dbllist[list_cnt-1]; -+ break; -+ } -+ } -+ else -+ aptr = va_arg( argl, ptr ); -+ -+ if ( typchr == 's' ) -+ { -+ if ( ! comma_list ) -+ *(char **)aptr = argp; -+ } -+ else -+ { -+ nopt = 0; -+ do { -+ /* -+ * Need to update aptr if parsing -+ * a comma list -+ */ -+ if ( comma_list && nopt > 0 ) -+ { -+ argp = strlist[nopt]; -+ switch( typchr ) -+ { -+ case 'n': -+ case 'd': -+ case 'o': -+ case 'x': -+ aptr = (ptr) &intlist[nopt]; -+ break; -+ case 'N': -+ case 'D': -+ case 'O': -+ case 'X': -+ aptr = (ptr) &longlist[nopt]; -+ break; -+ case 'f': -+ aptr = (ptr) &fltlist[nopt]; -+ break; -+ case 'F': -+ aptr = (ptr) &dbllist[nopt]; -+ break; -+ } -+ } -+ /* -+ * Do conversion for n and N types -+ */ -+ tmpflg = typchr; -+ if (typchr == 'n' || typchr == 'N' ) { -+ if (*argp != '0') -+ tmpflg = 'd'; -+ else if (*(argp+1) == 'x' || -+ *(argp+1) == 'X') -+ { -+ tmpflg = 'x'; -+ argp += 2; -+ } -+ else -+ tmpflg = 'o'; - } -- if (typchr == 'N') -- tmpflg = toupper( tmpflg ); -- -- -- /* put in conversion */ -- if ( isupper( tmpflg ) ) -- { -- cntrl[1] = 'l'; -- cntrl[2] = tolower( tmpflg ); -- } -- else -- { -- cntrl[1] = tmpflg; -- cntrl[2] = ' '; -- } -- if (sscanf (argp, cntrl, aptr, junk) != 1) -- ERROR ("Bad numeric argument"); -- } while ( comma_list && ++nopt < list_cnt ); -- } -- check += cnt; -- arg_used[cnt] = 1; -- required = NO; -- /* -- * If not looking for multiple args, -- * then done, otherwise, keep looking. -- */ -- if ( !( list_of && !comma_list ) ) -- break; -- else -- continue; -- } -- if (required) -- switch (typchr) -- { -- case 'x': -- case 'X': -- ERROR ("missing hexadecimal argument"); -- case 's': -- ERROR ("missing string argument"); -- case 'o': -- case 'O': -- ERROR ("missing octal argument"); -- case 'd': -- case 'D': -- ERROR ("missing decimal argument"); -- case 'f': -- case 'F': -- ERROR ("missing floating argument"); -- case 'n': -- case 'N': -- ERROR ("missing numeric argument"); -- } -- if ( list_cnt > 0 ) -- { -- *cnt_arg = list_cnt; -- switch ( typchr ) -- { -- case 's': -- *va_arg( argl, char *** ) = strlist; -- break; -- case 'n': -- case 'd': -- case 'o': -- case 'x': -- *va_arg( argl, int ** ) = intlist; -- break; -- case 'N': -- case 'D': -- case 'O': -- case 'X': -- *va_arg( argl, long ** ) = longlist; -- break; -- case 'f': -- *va_arg( argl, float ** ) = fltlist; -- break; -- case 'F': -- *va_arg( argl, double **) = dbllist; -- break; -- } -- if ( typchr != 's' && comma_list ) -- free( (char *) strlist ); -- } -- else if ( cnt >= argc ) -- { -- /* Fell off end looking, so must eat the arg */ -- if ( typchr == 's' ) -- (void)va_arg( argl, char * ); -- else -- (void)va_arg( argl, ptr ); -- } -- break; -- default: /* error */ -- fprintf (stderr, -- "scanargs: Corrupt or invalid format spec\n"); -- return 0; -- } -- } -+ if (typchr == 'N') -+ tmpflg = toupper( tmpflg ); -+ -+ -+ /* put in conversion */ -+ if ( isupper( tmpflg ) ) -+ { -+ cntrl[1] = 'l'; -+ cntrl[2] = tolower( tmpflg ); -+ } -+ else -+ { -+ cntrl[1] = tmpflg; -+ cntrl[2] = ' '; -+ } -+ if (sscanf (argp, cntrl, aptr, junk) != 1) -+ ERROR ("Bad numeric argument"); -+ } while ( comma_list && ++nopt < list_cnt ); -+ } -+ check += cnt; -+ arg_used[cnt] = 1; -+ required = NO; -+ /* -+ * If not looking for multiple args, -+ * then done, otherwise, keep looking. -+ */ -+ if ( !( list_of && !comma_list ) ) -+ break; -+ else -+ continue; -+ } -+ if (required) -+ switch (typchr) -+ { -+ case 'x': -+ case 'X': -+ ERROR ("missing hexadecimal argument"); -+ case 's': -+ ERROR ("missing string argument"); -+ case 'o': -+ case 'O': -+ ERROR ("missing octal argument"); -+ case 'd': -+ case 'D': -+ ERROR ("missing decimal argument"); -+ case 'f': -+ case 'F': -+ ERROR ("missing floating argument"); -+ case 'n': -+ case 'N': -+ ERROR ("missing numeric argument"); -+ } -+ if ( list_cnt > 0 ) -+ { -+ *cnt_arg = list_cnt; -+ switch ( typchr ) -+ { -+ case 's': -+ *va_arg( argl, char *** ) = strlist; -+ break; -+ case 'n': -+ case 'd': -+ case 'o': -+ case 'x': -+ *va_arg( argl, int ** ) = intlist; -+ break; -+ case 'N': -+ case 'D': -+ case 'O': -+ case 'X': -+ *va_arg( argl, long ** ) = longlist; -+ break; -+ case 'f': -+ *va_arg( argl, float ** ) = fltlist; -+ break; -+ case 'F': -+ *va_arg( argl, double **) = dbllist; -+ break; -+ } -+ if ( typchr != 's' && comma_list ) -+ free( (char *) strlist ); -+ } -+ else if ( cnt >= argc ) -+ { -+ /* Fell off end looking, so must eat the arg */ -+ if ( typchr == 's' ) -+ (void)va_arg( argl, char * ); -+ else -+ (void)va_arg( argl, ptr ); -+ } -+ break; -+ default: /* error */ -+ fprintf (stderr, -+ "scanargs: Corrupt or invalid format spec\n"); -+ return 0; -+ } -+ } - } - - /* Count up empty flags */ - for (cnt=1; cnt argv[0] && *cp != '/'; cp-- ) -- ; /* find the last / */ -- if ( *cp == '/' ) -- cp++; -- fprintf( stderr, "%s", cp ); -- -- cp = format + 1; /* reset to where it should be */ -- } -- while (putc (*cp++, stderr) != ' '); -+ if ( *cp == '%' ) -+ { -+ /* -+ * This is bogus, but until everyone can agree on a name -+ * for (rindex/strrchr) .... -+ */ -+ for ( cp = argv[0]; *cp != '\0'; cp++ ) -+ ; /* find the end of the string */ -+ for ( ; cp > argv[0] && *cp != '/'; cp-- ) -+ ; /* find the last / */ -+ if ( *cp == '/' ) -+ cp++; -+ fprintf( stderr, "%s", cp ); -+ -+ cp = format + 1; /* reset to where it should be */ -+ } -+ while (putc (*cp++, stderr) != ' '); - } - else -- fprintf (stderr, "?? "); -+ fprintf (stderr, "?? "); - while (*cp == ' ') -- cp++; -+ cp++; - (void)prformat (cp, NO); - } - - static CONST_DECL char * - prformat (format, recurse) - CONST_DECL char *format; --int recurse; -+int recurse; - { - register CONST_DECL char *cp; - bool required, comma_list; -@@ -721,142 +720,142 @@ int recurse; - - cp = format; - if (recurse) -- putc (' ', stderr); -+ putc (' ', stderr); - - required = NO; - list_of = 0; - comma_list = NO; - while (*cp) - { -- switch (*cp) -- { -- default: -- cp++; -- break; -- case ' ': -- case '\n': -- case '\t': -- /* allow annotations */ -- for ( ; format < cp; format++ ) -- putc( *format, stderr ); -- putc(*cp, stderr); -- format = ++cp; -- break; -- -- case '(': -- /* Parentheses surround an arbitrary (parenthesis -- * balanced) comment. -- */ -- for ( ; format < cp; format++ ) -- putc( *format, stderr ); -- for ( cp++, depth = 1; *cp && depth > 0; ) -- { -- /* Don't print last close paren. */ -- if ( *cp != ')' || depth > 1 ) -- putc( *cp, stderr ); -- switch( *(cp++) ) -- { -- case '(': depth++; break; -- case ')': depth--; break; -- } -- } -- format = cp; -- break; -- -- case '!': -- required = YES; -- case '%': -+ switch (*cp) -+ { -+ default: -+ cp++; -+ break; -+ case ' ': -+ case '\n': -+ case '\t': -+ /* allow annotations */ -+ for ( ; format < cp; format++ ) -+ putc( *format, stderr ); -+ putc(*cp, stderr); -+ format = ++cp; -+ break; -+ -+ case '(': -+ /* Parentheses surround an arbitrary (parenthesis -+ * balanced) comment. -+ */ -+ for ( ; format < cp; format++ ) -+ putc( *format, stderr ); -+ for ( cp++, depth = 1; *cp && depth > 0; ) -+ { -+ /* Don't print last close paren. */ -+ if ( *cp != ')' || depth > 1 ) -+ putc( *cp, stderr ); -+ switch( *(cp++) ) -+ { -+ case '(': depth++; break; -+ case ')': depth--; break; -+ } -+ } -+ format = cp; -+ break; -+ -+ case '!': -+ required = YES; -+ case '%': - reswitch: -- switch (*++cp) -- { -- case ',': -- comma_list = YES; -- case '*': -- list_of++; -- goto reswitch; -- -- case '$': /* "rest" of argument list */ -- if (!required) -- putc ('[', stderr); -- for (; format < cp - 1 - list_of; format++) -- putc (*format, stderr); -- fputs( " ...", stderr ); -- if ( !required ) -- putc( ']', stderr ); -- break; -- -- case '-': /* flags */ -- if (!required) -- putc ('[', stderr); -- putc ('-', stderr); -- -- if (cp - format > 2 + list_of) -- putc ('{', stderr); -- cp = format; -- while (*cp != '%' && *cp != '!') -- putc (*cp++, stderr); -- if (cp - format > 1 + list_of) -- putc ('}', stderr); -- cp += 2; /* skip !- or %- */ -- if (*cp && !ISSPACE(*cp)) -- cp = prformat (cp, YES); -- /* this is a recursive call */ -- -- cp--; /* don't ignore next character */ -- -- if (!required) -- putc (']', stderr); -- break; -- case 's': /* char string */ -- case 'd': /* decimal # */ -- case 'o': /* octal # */ -- case 'x': /* hexadecimal # */ -- case 'f': /* floating # */ -- case 'D': /* long decimal # */ -- case 'O': /* long octal # */ -- case 'X': /* long hexadecimal # */ -- case 'F': /* double precision floating # */ -- case 'n': /* numeric arg (C format) */ -- case 'N': /* long numeric arg */ -- if (!required) -- putc ('[', stderr); -- for (; format < cp - 1 - list_of; format++) -- putc (*format, stderr); -- if ( list_of != 0 ) -- { -- if ( comma_list ) -- putc( ',', stderr ); -- else -- putc( ' ', stderr ); -- fputs( "...", stderr ); -- } -- if (!required) -- putc (']', stderr); -- break; -- default: -- break; -- } -- required = NO; -- list_of = NO; -- comma_list = NO; -- if (*cp) /* check for end of string */ -- format = ++cp; -- if (*cp && !ISSPACE(*cp)) -- putc (' ', stderr); -- } -- if (recurse && ISSPACE(*cp)) -- break; -+ switch (*++cp) -+ { -+ case ',': -+ comma_list++; -+ case '*': -+ list_of++; -+ goto reswitch; -+ -+ case '$': /* "rest" of argument list */ -+ if (!required) -+ putc ('[', stderr); -+ for (; format < cp - 1 - list_of; format++) -+ putc (*format, stderr); -+ fputs( " ...", stderr ); -+ if ( !required ) -+ putc( ']', stderr ); -+ break; -+ -+ case '-': /* flags */ -+ if (!required) -+ putc ('[', stderr); -+ putc ('-', stderr); -+ -+ if (cp - format > 2 + list_of) -+ putc ('{', stderr); -+ cp = format; -+ while (*cp != '%' && *cp != '!') -+ putc (*cp++, stderr); -+ if (cp - format > 1 + list_of) -+ putc ('}', stderr); -+ cp += 2; /* skip !- or %- */ -+ if (*cp && !ISSPACE(*cp)) -+ cp = prformat (cp, YES); -+ /* this is a recursive call */ -+ -+ cp--; /* don't ignore next character */ -+ -+ if (!required) -+ putc (']', stderr); -+ break; -+ case 's': /* char string */ -+ case 'd': /* decimal # */ -+ case 'o': /* octal # */ -+ case 'x': /* hexadecimal # */ -+ case 'f': /* floating # */ -+ case 'D': /* long decimal # */ -+ case 'O': /* long octal # */ -+ case 'X': /* long hexadecimal # */ -+ case 'F': /* double precision floating # */ -+ case 'n': /* numeric arg (C format) */ -+ case 'N': /* long numeric arg */ -+ if (!required) -+ putc ('[', stderr); -+ for (; format < cp - 1 - list_of; format++) -+ putc (*format, stderr); -+ if ( list_of != 0 ) -+ { -+ if ( comma_list ) -+ putc( ',', stderr ); -+ else -+ putc( ' ', stderr ); -+ fputs( "...", stderr ); -+ } -+ if (!required) -+ putc (']', stderr); -+ break; -+ default: -+ break; -+ } -+ required = NO; -+ list_of = NO; -+ comma_list = NO; -+ if (*cp) /* check for end of string */ -+ format = ++cp; -+ if (*cp && !ISSPACE(*cp)) -+ putc (' ', stderr); -+ } -+ if (recurse && ISSPACE(*cp)) -+ break; - } - if (!recurse) - { -- for ( ; format < cp; format++ ) -- putc( *format, stderr ); -- putc ('\n', stderr); -+ for ( ; format < cp; format++ ) -+ putc( *format, stderr ); -+ putc ('\n', stderr); - } - return (cp); - } - --/* -+/* - * isnum - determine whether a string MIGHT represent a number. - * typchr indicates the type of argument we are looking for, and - * determines the legal character set. If comma_list is YES, then -@@ -873,46 +872,46 @@ int comma_list; - - switch( typchr ) - { -- case 'n': -- case 'N': -- allowed = " \t,+-x0123456789abcdefABCDEF"; -- break; -- case 'd': -- case 'D': -- allowed = " \t,+-0123456789"; -- break; -- case 'o': -- case 'O': -- allowed = " \t,01234567"; -- break; -- case 'x': -- case 'X': -- allowed = " \t,0123456789abcdefABCDEF"; -- break; -- case 'f': -- case 'F': -- allowed = " \t,+-eE.0123456789"; -- break; -- case 's': /* only throw out decimal numbers */ -- default: -- allowed = " \t,+-.0123456789"; -- break; -+ case 'n': -+ case 'N': -+ allowed = " \t,+-x0123456789abcdefABCDEF"; -+ break; -+ case 'd': -+ case 'D': -+ allowed = " \t,+-0123456789"; -+ break; -+ case 'o': -+ case 'O': -+ allowed = " \t,01234567"; -+ break; -+ case 'x': -+ case 'X': -+ allowed = " \t,0123456789abcdefABCDEF"; -+ break; -+ case 'f': -+ case 'F': -+ allowed = " \t,+-eE.0123456789"; -+ break; -+ case 's': /* only throw out decimal numbers */ -+ default: -+ allowed = " \t,+-.0123456789"; -+ break; - } - digits = allowed; - while ( *digits != '0' ) -- digits++; -+ digits++; - if ( ! comma_list ) -- allowed += 3; /* then don't allow space, tab, comma */ -+ allowed += 3; /* then don't allow space, tab, comma */ - - while ( *str != '\0' ) - { -- for ( cp = allowed; *cp != '\0' && *cp != *str; cp++ ) -- ; -- if ( *cp == '\0' ) -- return NO; /* if not in allowed chars, not number */ -- if ( cp - digits >= 0 ) -- hasdigit = YES; -- str++; -+ for ( cp = allowed; *cp != '\0' && *cp != *str; cp++ ) -+ ; -+ if ( *cp == '\0' ) -+ return NO; /* if not in allowed chars, not number */ -+ if ( cp - digits >= 0 ) -+ hasdigit = YES; -+ str++; - } - return hasdigit; - } + /* If even number of bg color bytes, put out one more to get to diff --git a/netpbm-security-scripts.patch b/netpbm-security-scripts.patch deleted file mode 100644 index 0ba822a..0000000 --- a/netpbm-security-scripts.patch +++ /dev/null @@ -1,267 +0,0 @@ -diff --git a/editor/ppmfade b/editor/ppmfade -index dcd7bf2..5091651 100755 ---- a/editor/ppmfade -+++ b/editor/ppmfade -@@ -40,6 +40,7 @@ exec perl -w -x -S -- "$0" "$@" - # - ############################################################################## - use strict; -+use File::Temp "tempdir"; - - sub doVersionHack($) { - my ($argvR) = @_; -@@ -149,20 +150,26 @@ if ($first_file ne "undefined") { - - print("Frames are " . $width . "W x " . $height . "H\n"); - -+# -+# We create a tmp-directory right here -+# -+my $tmpdir = tempdir("ppmfade.XXXXXX", CLEANUP => 1); -+ -+ - if ($first_file eq "undefined") { - print "Fading from black to "; -- system("ppmmake \\#000 $width $height >junk1$$.ppm"); -+ system("ppmmake \\#000 $width $height >$tmpdir/junk1$$.ppm"); - } else { - print "Fading from $first_file to "; -- system("cp", $first_file, "junk1$$.ppm"); -+ system("cp", $first_file, "$tmpdir/junk1$$.ppm"); - } - - if ($last_file eq "undefined") { - print "black.\n"; -- system("ppmmake \\#000 $width $height >junk2$$.ppm"); -+ system("ppmmake \\#000 $width $height >$tmpdir/junk2$$.ppm"); - } else { - print "$last_file\n"; -- system("cp", $last_file, "junk2$$.ppm"); -+ system("cp", $last_file, "$tmpdir/junk2$$.ppm"); - } - - # -@@ -170,14 +177,14 @@ if ($last_file eq "undefined") { - # - - # Here's what our temporary files are: --# junk1$$.ppm: The original (fade-from) image --# junk2$$.ppm: The target (fade-from) image --# junk3$$.ppm: The frame of the fade for the current iteration of the --# the for loop. --# junk1a$$.ppm: If the fade involves a ppmmix sequence from one intermediate --# image to another, this is the first frame of that --# sequence. --# junk2a$$.ppm: This is the last frame of the above-mentioned ppmmix sequence -+# $tmpdir/junk1$$.ppm: The original (fade-from) image -+# $tmpdir/junk2$$.ppm: The target (fade-from) image -+# $tmpdir/junk3$$.ppm: The frame of the fade for the current iteration of the -+# the for loop. -+# $tmpdir/junk1a$$.ppm: If the fade involves a ppmmix sequence from one intermediate -+# image to another, this is the first frame of that -+# sequence. -+# $tmpdir/junk2a$$.ppm: This is the last frame of the above-mentioned ppmmix sequence - - my $i; # Frame number - for ($i = 1; $i <= $nframes; $i++) { -@@ -185,147 +192,147 @@ for ($i = 1; $i <= $nframes; $i++) { - if ($mode eq $SPREAD) { - if ($i <= 10) { - my $n = $spline20[$i] * 100; -- system("ppmspread $n junk1$$.ppm >junk3$$.ppm"); -+ system("ppmspread $n $tmpdir/junk1$$.ppm >$tmpdir/junk3$$.ppm"); - } elsif ($i <= 20) { - my $n; - $n = $spline20[$i] * 100; -- system("ppmspread $n junk1$$.ppm >junk1a$$.ppm"); -+ system("ppmspread $n $tmpdir/junk1$$.ppm >$tmpdir/junk1a$$.ppm"); - $n = (1-$spline20[$i-10]) * 100; -- system("ppmspread $n junk2$$.ppm >junk2a$$.ppm"); -+ system("ppmspread $n $tmpdir/junk2$$.ppm >$tmpdir/junk2a$$.ppm"); - $n = $spline10[$i-10]; -- system("ppmmix $n junk1a$$.ppm junk2a$$.ppm >junk3$$.ppm"); -+ system("ppmmix $n $tmpdir/junk1a$$.ppm $tmpdir/junk2a$$.ppm >$tmpdir/junk3$$.ppm"); - } else { - my $n = (1-$spline20[$i-10])*100; -- system("ppmspread $n junk2$$.ppm >junk3$$.ppm"); -+ system("ppmspread $n $tmpdir/junk2$$.ppm >$tmpdir/junk3$$.ppm"); - } - } elsif ($mode eq $SHIFT) { - if ($i <= 10) { - my $n = $spline20[$i] * 100; -- system("ppmshift $n junk1$$.ppm >junk3$$.ppm"); -+ system("ppmshift $n $tmpdir/junk1$$.ppm >$tmpdir/junk3$$.ppm"); - } elsif ($i <= 20) { - my $n; - $n = $spline20[$i] * 100; -- system("ppmshift $n junk1$$.ppm >junk1a$$.ppm"); -+ system("ppmshift $n $tmpdir/junk1$$.ppm >$tmpdir/junk1a$$.ppm"); - $n = (1-$spline20[$i-10])*100; -- system("ppmshift $n junk2$$.ppm >junk2a$$.ppm"); -+ system("ppmshift $n $tmpdir/junk2$$.ppm >$tmpdir/junk2a$$.ppm"); - $n = $spline10[$i-10]; -- system("ppmmix $n junk1a$$.ppm junk2a$$.ppm >junk3$$.ppm"); -+ system("ppmmix $n $tmpdir/junk1a$$.ppm $tmpdir/junk2a$$.ppm >$tmpdir/junk3$$.ppm"); - } else { - my $n = (1-$spline20[$i-10]) * 100; -- system("ppmshift $n junk2$$.ppm >junk3$$.ppm"); -+ system("ppmshift $n $tmpdir/junk2$$.ppm >$tmpdir/junk3$$.ppm"); - } - } elsif ($mode eq $RELIEF) { - if ($i == 1) { -- system("ppmrelief junk1$$.ppm >junk1r$$.ppm"); -+ system("ppmrelief $tmpdir/junk1$$.ppm >$tmpdir/junk1r$$.ppm"); - } - if ($i <= 10) { - my $n = $spline10[$i]; -- system("ppmmix $n junk1$$.ppm junk1r$$.ppm >junk3$$.ppm"); -+ system("ppmmix $n $tmpdir/junk1$$.ppm $tmpdir/junk1r$$.ppm >$tmpdir/junk3$$.ppm"); - } elsif ($i <= 20) { - my $n = $spline10[$i-10]; -- system("ppmmix $n junk1r$$.ppm junk2r$$.ppm >junk3$$.ppm"); -+ system("ppmmix $n $tmpdir/junk1r$$.ppm $tmpdir/junk2r$$.ppm >$tmpdir/junk3$$.ppm"); - } else { - my $n = $spline10[$i-20]; -- system("ppmmix $n junk2r$$.ppm junk2$$.ppm >junk3$$.ppm"); -+ system("ppmmix $n $tmpdir/junk2r$$.ppm $tmpdir/junk2$$.ppm >$tmpdir/junk3$$.ppm"); - } - if ($i == 10) { -- system("ppmrelief junk2$$.ppm >junk2r$$.ppm"); -+ system("ppmrelief $tmpdir/junk2$$.ppm >$tmpdir/junk2r$$.ppm"); - } - } elsif ($mode eq $OIL) { - if ($i == 1) { -- system("ppmtopgm junk1$$.ppm | pgmoil >junko$$.ppm"); -- system("rgb3toppm junko$$.ppm junko$$.ppm junko$$.ppm " . -- ">junk1o$$.ppm"); -+ system("ppmtopgm $tmpdir/junk1$$.ppm | pgmoil >$tmpdir/junko$$.ppm"); -+ system("rgb3toppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm " . -+ ">$tmpdir/junk1o$$.ppm"); - } - if ($i <= 10) { - my $n = $spline10[$i]; -- system("ppmmix $n junk1$$.ppm junk1o$$.ppm >junk3$$.ppm"); -+ system("ppmmix $n $tmpdir/junk1$$.ppm $tmpdir/junk1o$$.ppm >$tmpdir/junk3$$.ppm"); - } elsif ($i <= 20) { - my $n = $spline10[$i-10]; -- system("ppmmix $n junk1o$$.ppm junk2o$$.ppm >junk3$$.ppm"); -+ system("ppmmix $n $tmpdir/junk1o$$.ppm $tmpdir/junk2o$$.ppm >$tmpdir/junk3$$.ppm"); - } else { - my $n = $spline10[$i-20]; -- system("ppmmix $n junk2o$$.ppm junk2$$.ppm >junk3$$.ppm"); -+ system("ppmmix $n $tmpdir/junk2o$$.ppm $tmpdir/junk2$$.ppm >$tmpdir/junk3$$.ppm"); - } - if ($i == 10) { -- system("ppmtopgm junk2$$.ppm | pgmoil >junko$$.ppm"); -- system("rgb3toppm junko$$.ppm junko$$.ppm junko$$.ppm " . -- ">junk2o$$.ppm"); -+ system("ppmtopgm $tmpdir/junk2$$.ppm | pgmoil >$tmpdir/junko$$.ppm"); -+ system("rgb3toppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm " . -+ ">$tmpdir/junk2o$$.ppm"); - } - } elsif ($mode eq $EDGE) { - if ($i == 1) { -- system("ppmtopgm junk1$$.ppm | pgmedge >junko$$.ppm"); -- system("rgb3toppm junko$$.ppm junko$$.ppm junko$$.ppm " . -- ">junk1o$$.ppm"); -+ system("ppmtopgm $tmpdir/junk1$$.ppm | pgmedge >$tmpdir/junko$$.ppm"); -+ system("rgb3toppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm " . -+ ">$tmpdir/junk1o$$.ppm"); - } - if ($i <= 10) { - my $n = $spline10[$i]; -- system("ppmmix $n junk1$$.ppm junk1o$$.ppm >junk3$$.ppm"); -+ system("ppmmix $n $tmpdir/junk1$$.ppm $tmpdir/junk1o$$.ppm >$tmpdir/junk3$$.ppm"); - } elsif ($i <= 20) { - my $n = $spline10[$i-10]; -- system("ppmmix $n junk1o$$.ppm junk2o$$.ppm >junk3$$.ppm"); -+ system("ppmmix $n $tmpdir/junk1o$$.ppm $tmpdir/junk2o$$.ppm >$tmpdir/junk3$$.ppm"); - } else { - my $n = $spline10[$i-20]; -- system("ppmmix $n junk2o$$.ppm junk2$$.ppm >junk3$$.ppm"); -+ system("ppmmix $n $tmpdir/junk2o$$.ppm $tmpdir/junk2$$.ppm >$tmpdir/junk3$$.ppm"); - } - if ($i == 10) { -- system("ppmtopgm junk2$$.ppm | pgmedge >junko$$.ppm"); -- system("rgb3toppm junko$$.ppm junko$$.ppm junko$$.ppm " . -- ">junk2o$$.ppm"); -+ system("ppmtopgm $tmpdir/junk2$$.ppm | pgmedge >$tmpdir/junko$$.ppm"); -+ system("rgb3toppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm " . -+ ">$tmpdir/junk2o$$.ppm"); - } - } elsif ($mode eq $BENTLEY) { - if ($i == 1) { -- system("ppmtopgm junk1$$.ppm | pgmbentley >junko$$.ppm"); -- system("rgb3toppm junko$$.ppm junko$$.ppm junko$$.ppm " . -- ">junk1o$$.ppm"); -+ system("ppmtopgm $tmpdir/junk1$$.ppm | pgmbentley >$tmpdir/junko$$.ppm"); -+ system("rgb3toppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm " . -+ ">$tmpdir/junk1o$$.ppm"); - } - if ($i <= 10) { - my $n = $spline10[$i]; -- system("ppmmix $n junk1$$.ppm junk1o$$.ppm >junk3$$.ppm"); -+ system("ppmmix $n $tmpdir/junk1$$.ppm $tmpdir/junk1o$$.ppm >$tmpdir/junk3$$.ppm"); - } elsif ($i <= 20) { - my $n = $spline10[$i-10]; -- system("ppmmix $n junk1o$$.ppm junk2o$$.ppm >junk3$$.ppm"); -+ system("ppmmix $n $tmpdir/junk1o$$.ppm $tmpdir/junk2o$$.ppm >$tmpdir/junk3$$.ppm"); - } else { - my $n = $spline10[$i-20]; -- system("ppmmix $n junk2o$$.ppm junk2$$.ppm >junk3$$.ppm"); -+ system("ppmmix $n $tmpdir/junk2o$$.ppm $tmpdir/junk2$$.ppm >$tmpdir/junk3$$.ppm"); - } - if ($i == 10) { -- system("ppmtopgm junk2$$.ppm | pgmbentley >junko$$.ppm"); -- system("rgb3toppm junko$$.ppm junko$$.ppm junko$$.ppm " . -- ">junk2o$$.ppm"); -+ system("ppmtopgm $tmpdir/junk2$$.ppm | pgmbentley >$tmpdir/junko$$.ppm"); -+ system("rgb3toppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm $tmpdir/junko$$.ppm " . -+ ">$tmpdir/junk2o$$.ppm"); - } - } elsif ($mode eq $BLOCK) { - if ($i <= 10) { - my $n = 1 - 1.9*$spline20[$i]; -- system("pamscale $n junk1$$.ppm | " . -- "pamscale -width $width -height $height >junk3$$.ppm"); -+ system("pamscale $n $tmpdir/junk1$$.ppm | " . -+ "pamscale -width $width -height $height >$tmpdir/junk3$$.ppm"); - } elsif ($i <= 20) { - my $n = $spline10[$i-10]; -- system("ppmmix $n junk1a$$.ppm junk2a$$.ppm >junk3$$.ppm"); -+ system("ppmmix $n $tmpdir/junk1a$$.ppm $tmpdir/junk2a$$.ppm >$tmpdir/junk3$$.ppm"); - } else { - my $n = 1 - 1.9*$spline20[31-$i]; -- system("pamscale $n junk2$$.ppm | " . -- "pamscale -width $width -height $height >junk3$$.ppm"); -+ system("pamscale $n $tmpdir/junk2$$.ppm | " . -+ "pamscale -width $width -height $height >$tmpdir/junk3$$.ppm"); - } - if ($i == 10) { -- system("cp", "junk3$$.ppm", "junk1a$$.ppm"); -- system("pamscale $n junk2$$.ppm | " . -- "pamscale -width $width -height $height >junk2a$$.ppm"); -+ system("cp", "$tmpdir/junk3$$.ppm", "$tmpdir/junk1a$$.ppm"); -+ system("pamscale $n $tmpdir/junk2$$.ppm | " . -+ "pamscale -width $width -height $height >$tmpdir/junk2a$$.ppm"); - } - } elsif ($mode eq $MIX) { - my $fade_factor = sqrt(1/($nframes-$i+1)); -- system("ppmmix $fade_factor junk1$$.ppm junk2$$.ppm >junk3$$.ppm"); -+ system("ppmmix $fade_factor $tmpdir/junk1$$.ppm $tmpdir/junk2$$.ppm >$tmpdir/junk3$$.ppm"); - } else { - print("Internal error: impossible mode value '$mode'\n"); - } - - my $outfile = sprintf("%s.%04d.ppm", $base_name, $i); -- system("cp", "junk3$$.ppm", $outfile); -+ system("cp", "$tmpdir/junk3$$.ppm", $outfile); - } - - # - # Clean up shop. - # --system("rm junk*$$.ppm"); -+system("rm $tmpdir/junk*$$.ppm"); - - exit(0); diff --git a/netpbm-shlib-ldflags.patch b/netpbm-shlib-ldflags.patch new file mode 100644 index 0000000..ffad115 --- /dev/null +++ b/netpbm-shlib-ldflags.patch @@ -0,0 +1,13 @@ +diff --git a/config.mk.in b/config.mk.in +index 50687ba..d35c982 100644 +--- a/config.mk.in ++++ b/config.mk.in +@@ -250,7 +250,7 @@ EXE = + + # Here, $(SONAME) resolves to the soname for the shared library being created. + # The following are gcc options. This works on GNU libc systems. +-LDSHLIB = -shared -Wl,-soname,$(SONAME) ++LDSHLIB = $(LDFLAGS) -shared -Wl,-soname,$(SONAME) + # You need -nostart instead of -shared on BeOS. Though the BeOS compiler is + # ostensibly gcc, it has the -nostart option, which is not mentioned in gcc + # documentation and doesn't exist in at least one non-BeOS installation. diff --git a/netpbm-userguide.patch b/netpbm-userguide.patch deleted file mode 100644 index c160e13..0000000 --- a/netpbm-userguide.patch +++ /dev/null @@ -1,150 +0,0 @@ -diff --git a/userguide/pammixmulti.html b/userguide/pammixmulti.html -index 97cf412..d2a2ba0 100755 ---- a/userguide/pammixmulti.html -+++ b/userguide/pammixmulti.html -@@ -2,13 +2,13 @@ - Pammixmulti User Manual - -

    pammixmulti

    --Updated: 18 November 2018
    --
    -+ -+Updated: 18 November 2018
    - Table Of Contents - - --

    NAME

    --

    pammixmulti - blend together multiple PAM images -+

    NAME

    -+

    pammixmulti - blend together multiple PAM images

    - - -

    SYNOPSIS

    -@@ -22,11 +22,11 @@ Updated: 18 November 2018
    -

    Minimum unique abbreviation of an option is acceptable. You can use a - single hyphen instead of double hyphens to denote options. You can use white - space in place of the equals sign to separate an option name from its --value. -+value.

    - - -

    DESCRIPTION

    --

    This file is part of Netpbm. -+

    This file is part of Netpbm.

    - -

    pammixmulti mixes two or more images to produce a new image. The - program provides multiple ways to interpret "mix." -@@ -37,7 +37,7 @@ program provides multiple ways to interpret "mix." -

    In addition to the options common to all programs based on libnetpbm - (most notably -quiet, see - Common Options), pammixmulti recognizes the following --command line options: -+command line options:

    - -
    -
    --blend=average|random|mask
    -@@ -50,7 +50,7 @@ output is produced by selecting the corresponding pixel from one of the input - images, chosen at random on a per-pixel basis. With - --blend=mask, each pixel in the output is produced by a - weighted average of the corresponding pixels from all the input images based --on the grayscale level of an additional mask image. -+on the grayscale level of an additional mask image.

    - - -
    --maskfile=filename
    -@@ -60,7 +60,7 @@ grayscale mask file to control the blending of each pixel. (If the file is - not grayscale, the first channel is treated as gray). Where the mask file is - black, the first image is selected. Where the mask file is white, the last - image is selected. Intermediate levels of gray select intermediate --images. -+images.

    - - -
    --stdev=number
    -@@ -77,7 +77,7 @@ that includes roughly equal amounts of the corresponding pixel from images 1 - and 2 but less of the corresponding pixel from image 3. As number - tends towards the number of input images (going beyond that has diminishing - impact), the output tends to look more --like --blend=average. number defaults to 0.25. -+like --blend=average. number defaults to 0.25.

    - - -
    --randomseed integer -@@ -91,39 +91,39 @@ like --blend=average. number defaults to 0.25. - -

    ARGUMENTS

    - --

    You supply the names of the files to mix as non-option arguments. -+

    You supply the names of the files to mix as non-option arguments.

    - - -

    EXAMPLES

    - --

    Average a bunch of PPM images to produce a new PAM image: -+

    Average a bunch of PPM images to produce a new PAM image:

    -
    
    -     pammixmulti input*.ppm >output.ppm
    - 
    - -

    Mix these same images by taking each pixel from a randomly selected input --image: -+image:

    - -
    
    -     pammixmulti --blend=random input*.ppm >output.ppm
    - 
    - -

    Use a mask image to control the fading among input images on a --pixel-by-pixel basis: -+pixel-by-pixel basis:

    - -
    
    -     pammixmulti --blend=mask --maskfile=mask.pgm >output.pam \
    -        one.pam two.pam three.pam four.pam
    - 
    - --

    Do the same but with more abrupt transitions: -+

    Do the same but with more abrupt transitions:

    - -
    
    -     pammixmulti --blend=mask --maskfile=mask.pgm --stdev=0.0 >output.pam \
    -        one.pam two.pam three.pam four.pam
    - 
    - --

    and now with more gradual transitions: -+

    and now with more gradual transitions:

    - -
    
    -     pammixmulti --blend=mask --maskfile=mask.pgm --stdev=1.0 >output.pam \
    -@@ -138,7 +138,7 @@ pixel-by-pixel basis:
    - 
    - 

    AUTHOR

    - --

    Copyright 2018 Scott Pakin, scott+pbm@pakin.org. -+

    Copyright 2018 Scott Pakin, scott+pbm@pakin.org.

    - -

    SEE ALSO

    - -@@ -152,14 +152,14 @@ pixel-by-pixel basis: -

    Table Of Contents

    - - - - diff --git a/netpbm.spec b/netpbm.spec index 8c65173..110e827 100644 --- a/netpbm.spec +++ b/netpbm.spec @@ -1,9 +1,9 @@ Summary: A library for handling different graphics file formats Name: netpbm -Version: 10.93.00 +Version: 11.13.00 Release: 1%{?dist} # See copyright_summary for details -License: BSD and GPLv2 and IJG and MIT and Public Domain +License: BSD-3-Clause AND GPL-2.0-only AND LGPL-2.1-or-later AND GPL-3.0-or-later AND IJG AND MIT AND NTP AND PostgreSQL AND LicenseRef-MIT-CRL-Xim AND LicenseRef-Fedora-Public-Domain URL: http://netpbm.sourceforge.net/ # Source0 is prepared by # svn checkout https://svn.code.sf.net/p/netpbm/code/advanced netpbm-%%{version} @@ -11,7 +11,6 @@ URL: http://netpbm.sourceforge.net/ # svn checkout https://svn.code.sf.net/p/netpbm/code/trunk/test netpbm-%%{version}/test # and removing the .svn directories ( find -name "\.svn" -type d -print0 | xargs -0 rm -rf ) Source0: netpbm-%{version}.tar.xz -Patch0: netpbm-security-scripts.patch Patch1: netpbm-security-code.patch Patch2: netpbm-ppmfadeusage.patch Patch3: netpbm-CVE-2017-2587.patch @@ -24,15 +23,14 @@ Patch9: netpbm-xwdfix.patch Patch10: netpbm-multilib.patch Patch11: netpbm-glibc.patch Patch12: netpbm-docfix.patch -Patch13: netpbm-cmuwtopbm.patch -Patch14: netpbm-pamtojpeg2k.patch -Patch15: netpbm-manfix.patch -Patch16: netpbm-manual-pages.patch -Patch17: netpbm-jasper.patch -Patch18: netpbm-userguide.patch -Patch19: netpbm-libdir-so.patch +Patch13: netpbm-pamtojpeg2k.patch +Patch14: netpbm-manfix.patch +Patch15: netpbm-jasper.patch +Patch16: netpbm-libdir-so.patch +Patch17: netpbm-c99.patch +Patch18: netpbm-shlib-ldflags.patch -BuildRequires: make +BuildRequires: make BuildRequires: libjpeg-devel, libpng-devel, libtiff-devel, flex, gcc, jbigkit-devel BuildRequires: libX11-devel, perl-generators, python3, jasper-devel, libxml2-devel BuildRequires: perl(Config), perl(Cwd), perl(English), perl(Fcntl), perl(File::Basename) @@ -94,6 +92,7 @@ rm -rf converter/other/jpeg2000/libjasper/ rm -rf converter/other/jbig/libjbig/ %build +%set_build_flags ./configure < - 11.13.00-1 +- New upstream release 11.13.00 + +* Tue Oct 14 2025 Josef Ridky - 11.12.00-1 +- New upstream release 11.12.00 + +* Thu Jul 24 2025 Fedora Release Engineering - 11.10.00-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + +* Tue Apr 08 2025 Josef Ridky - 11.10.00-1 +- New upstream release 11.10.00 (#2355869) + +* Thu Feb 06 2025 Josef Ridky - 11.09.00-2 +- add LDFLAGS patch (RHEL-70899) + +* Tue Jan 28 2025 Josef Ridky - 11.09.00-1 +- New upstream release 11.09.00 (#2218312) +- Review and update license field + +* Fri Jan 17 2025 Fedora Release Engineering - 11.02.00-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + +* Fri Dec 13 2024 Lukáš Zaoral - 11.02.00-9 +- build netpbm with correct LDFLAGS (RHEL-70899) + +* Mon Sep 02 2024 Miroslav Suchý - 11.02.00-8 +- convert license to SPDX + +* Thu Jul 18 2024 Fedora Release Engineering - 11.02.00-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + +* Thu Jan 25 2024 Fedora Release Engineering - 11.02.00-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Sun Jan 21 2024 Florian Weimer - 11.02.00-5 +- GCC 14 compatibility fixes: + Drop netpbm-cmuwtopbm.patch to fix an out-of-bounds stack write (#2259450) + Stub out unused converter/other/jpeg2000/libjasper_compat.c (#2259448) + +* Sun Jan 21 2024 Fedora Release Engineering - 11.02.00-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Tue Nov 28 2023 Orion Poplawski - 11.02.00-3 +- Rebuild for jasper 4.1 + +* Thu Jul 20 2023 Fedora Release Engineering - 11.02.00-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Mon Mar 27 2023 Josef Ridky - 11.02.00-1 +- New upstream release 11.02.00 (#2157125) + +* Thu Jan 19 2023 Fedora Release Engineering - 11.01.00-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Mon Jan 02 2023 Josef Ridky - 11.01.00-1 +- New upstream release 11.01.00 (#2157125) + +* Fri Dec 02 2022 Florian Weimer - 11.00.00-2 +- Port downstream-specific patches to C99 + +* Tue Oct 04 2022 Josef Ridky - 11.00.00-1 +- New upstream release 11.00.00 (#2130384) + +* Fri Jul 22 2022 Fedora Release Engineering - 10.99.00-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Tue Jun 28 2022 Josef Ridky - 10.99.00-1 +- New upstream release 10.99.00 (#2068865) +- Use %%set_build_flags to set environment variables + +* Sun Feb 13 2022 Josef Ridky - 10.97.00-4 +- Bump spec for new jasper + +* Fri Feb 11 2022 Josef Ridky - 10.97.00-3 +- Rebuild for new jasper + +* Thu Jan 20 2022 Fedora Release Engineering - 10.97.00-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Mon Jan 03 2022 Josef Ridky - 10.97.00-1 +- New upstream release 10.97.00 (#2035806) + +* Mon Oct 04 2021 Josef Ridky - 10.96.00-1 +- New upstream release 10.96.00 (#2007871) + +* Thu Jul 22 2021 Fedora Release Engineering - 10.95.00-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Thu Jul 15 2021 Josef Ridky - 10.95.00-1 +- New upstream release 10.95.00 (#1977974) + +* Wed Mar 31 2021 Josef Ridky - 10.94.05-1 +- New upstream release 10.94.05 (#1943837) + * Mon Jan 25 2021 Josef Ridky - 10.93.00-1 - New upstream release 10.93.00 (#1911159) diff --git a/sources b/sources index d5383d7..4e39977 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (netpbm-10.93.00.tar.xz) = 18ff08b1d3672d792dab78b69eb4ef1a9874266b1dfbf5801a53ca172c0dcbbae8d1269297a56e06ed45ccfdff6a6ae5399e60b4bafdcb9d2cb9de800e2bc07c +SHA512 (netpbm-11.13.00.tar.xz) = 0914061c7c8d638147afb76cbf23609b3ae43aca4120e4297fd5db6887d5381469d6944cdbdc1c66d26f54ec68d62355693c08b830dde823061e37c51480b678