From cbbfb19878d7106f344ba63f2ca7f78d4e139a81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20=C5=98=C3=ADdk=C3=BD?= Date: Mon, 9 Dec 2019 07:51:38 +0100 Subject: [PATCH] New upstream release 10.88.00 --- .gitignore | 1 + netpbm-security-code.patch | 3797 +++++++++++++++++++++++++++++++----- netpbm.spec | 5 +- sources | 2 +- 4 files changed, 3329 insertions(+), 476 deletions(-) diff --git a/.gitignore b/.gitignore index 41e3700..2abb181 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ /netpbm-10.84.03.tar.xz /netpbm-10.86.00.tar.xz /netpbm-10.87.00.tar.xz +/netpbm-10.88.00.tar.xz diff --git a/netpbm-security-code.patch b/netpbm-security-code.patch index 1ca88f0..51ef43e 100644 --- a/netpbm-security-code.patch +++ b/netpbm-security-code.patch @@ -1,7 +1,6 @@ -diff --git a/analyzer/pgmtexture.c b/analyzer/pgmtexture.c -index 5883327..eb8cf70 100644 ---- a/analyzer/pgmtexture.c -+++ b/analyzer/pgmtexture.c +diff -urNp a/analyzer/pgmtexture.c b/analyzer/pgmtexture.c +--- a/analyzer/pgmtexture.c 2019-12-06 09:04:58.779176370 +0100 ++++ b/analyzer/pgmtexture.c 2019-12-06 08:38:15.080037633 +0100 @@ -98,6 +98,8 @@ vector(unsigned int const nl, assert(nh >= nl); @@ -27,10 +26,9 @@ index 5883327..eb8cf70 100644 /* 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 d862213..5f1a51a 100644 ---- a/converter/other/gemtopnm.c -+++ b/converter/other/gemtopnm.c +diff -urNp a/converter/other/gemtopnm.c b/converter/other/gemtopnm.c +--- a/converter/other/gemtopnm.c 2019-12-06 09:04:58.749176101 +0100 ++++ b/converter/other/gemtopnm.c 2019-12-06 08:38:15.081037642 +0100 @@ -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 @@ -92,6 +90,13 @@ index d862213..5f1a51a 100644 - pm_usage (usage); - ++argn; - } +- +- if (argc == argn) +- f = stdin; +- else { +- f = pm_openr (argv[argn]); +- ++argn; +- } + while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0') + { + if (pm_keymatch(argv[1], "-debug", 2)) @@ -100,13 +105,7 @@ index d862213..5f1a51a 100644 + pm_usage (usage); + ++argn; + } - -- if (argc == argn) -- f = stdin; -- else { -- f = pm_openr (argv[argn]); -- ++argn; -- } ++ + if (argc == argn) + f = stdin; + else { @@ -340,17 +339,16 @@ index d862213..5f1a51a 100644 } -@@ -303,5 +304,3 @@ getinit (file, colsP, rowsP, padrightP, patlenP, planesP) +@@ -303,5 +304,3 @@ getinit (file, colsP, rowsP, padrightP, } } - - -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, +diff -urNp a/converter/other/jpegtopnm.c b/converter/other/jpegtopnm.c +--- a/converter/other/jpegtopnm.c 2019-12-06 09:04:58.748176092 +0100 ++++ b/converter/other/jpegtopnm.c 2019-12-06 08:38:15.082037651 +0100 +@@ -862,6 +862,8 @@ convertImage(FILE * /* Calculate output image dimensions so we can allocate space */ jpeg_calc_output_dimensions(cinfoP); @@ -359,10 +357,9 @@ index 98552c0..311298c 100644 /* Start decompressor */ jpeg_start_decompress(cinfoP); -diff --git a/converter/other/pbmtopgm.c b/converter/other/pbmtopgm.c -index 69b20fb..382a487 100644 ---- a/converter/other/pbmtopgm.c -+++ b/converter/other/pbmtopgm.c +diff -urNp a/converter/other/pbmtopgm.c b/converter/other/pbmtopgm.c +--- a/converter/other/pbmtopgm.c 2019-12-06 09:04:58.746176074 +0100 ++++ b/converter/other/pbmtopgm.c 2019-12-06 08:38:15.082037651 +0100 @@ -47,6 +47,7 @@ main(int argc, char *argv[]) { "than the image height (%u rows)", height, rows); @@ -371,10 +368,9 @@ index 69b20fb..382a487 100644 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 ac02e42..a2f045b 100644 ---- a/converter/other/pnmtoddif.c -+++ b/converter/other/pnmtoddif.c +diff -urNp a/converter/other/pnmtoddif.c b/converter/other/pnmtoddif.c +--- a/converter/other/pnmtoddif.c 2019-12-06 09:04:58.747176083 +0100 ++++ b/converter/other/pnmtoddif.c 2019-12-06 08:38:15.083037661 +0100 @@ -629,6 +629,7 @@ main(int argc, char *argv[]) { switch (PNM_FORMAT_TYPE(format)) { case PBM_TYPE: @@ -391,11 +387,10 @@ index ac02e42..a2f045b 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 4482624..757d08d 100644 ---- a/converter/other/pnmtojpeg.c -+++ b/converter/other/pnmtojpeg.c -@@ -606,7 +606,11 @@ read_scan_script(j_compress_ptr const cinfo, +diff -urNp a/converter/other/pnmtojpeg.c b/converter/other/pnmtojpeg.c +--- a/converter/other/pnmtojpeg.c 2019-12-06 09:04:58.750176110 +0100 ++++ b/converter/other/pnmtojpeg.c 2019-12-06 08:38:15.084037670 +0100 +@@ -606,7 +606,11 @@ read_scan_script(j_compress_ptr const ci want JPOOL_PERMANENT. */ const unsigned int scan_info_size = nscans * sizeof(jpeg_scan_info); @@ -408,7 +403,7 @@ index 4482624..757d08d 100644 (jpeg_scan_info *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, scan_info_size); -@@ -938,6 +942,8 @@ compute_rescaling_array(JSAMPLE ** const rescale_p, const pixval maxval, +@@ -938,6 +942,8 @@ compute_rescaling_array(JSAMPLE ** const const long half_maxval = maxval / 2; long val; @@ -417,7 +412,7 @@ index 4482624..757d08d 100644 *rescale_p = (JSAMPLE *) (cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_IMAGE, (size_t) (((long) maxval + 1L) * -@@ -1016,6 +1022,7 @@ convert_scanlines(struct jpeg_compress_struct * const cinfo_p, +@@ -1016,6 +1022,7 @@ convert_scanlines(struct jpeg_compress_s */ /* Allocate the libpnm output and compressor input buffers */ @@ -425,11 +420,10 @@ index 4482624..757d08d 100644 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 de0dfd8..09c28d5 100644 ---- a/converter/other/pnmtops.c -+++ b/converter/other/pnmtops.c -@@ -294,17 +294,21 @@ parseCommandLine(int argc, const char ** argv, +diff -urNp a/converter/other/pnmtops.c b/converter/other/pnmtops.c +--- a/converter/other/pnmtops.c 2019-12-06 09:04:58.750176110 +0100 ++++ b/converter/other/pnmtops.c 2019-12-06 08:38:15.085037679 +0100 +@@ -294,17 +294,21 @@ parseCommandLine(int argc, const char ** validateCompDimension(width, 72, "-width value"); validateCompDimension(height, 72, "-height value"); @@ -452,10 +446,9 @@ index de0dfd8..09c28d5 100644 cmdlineP->imageheight = imageheight * 72; } else -diff --git a/converter/other/rletopnm.c b/converter/other/rletopnm.c -index 018456c..35ea7f7 100644 ---- a/converter/other/rletopnm.c -+++ b/converter/other/rletopnm.c +diff -urNp a/converter/other/rletopnm.c b/converter/other/rletopnm.c +--- a/converter/other/rletopnm.c 2019-12-06 09:04:58.749176101 +0100 ++++ b/converter/other/rletopnm.c 2019-12-06 08:38:15.086037688 +0100 @@ -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, @@ -465,10 +458,9 @@ index 018456c..35ea7f7 100644 */ /* * 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 +diff -urNp a/converter/other/sirtopnm.c b/converter/other/sirtopnm.c +--- a/converter/other/sirtopnm.c 2019-12-06 09:04:58.748176092 +0100 ++++ b/converter/other/sirtopnm.c 2019-12-06 08:38:15.086037688 +0100 @@ -69,6 +69,7 @@ char* argv[]; } break; @@ -477,11 +469,10 @@ index fafcc91..9fe49d0 100644 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 c1e7af8..ef9253b 100644 ---- a/converter/other/tifftopnm.c -+++ b/converter/other/tifftopnm.c -@@ -1372,7 +1372,9 @@ convertRasterByRows(pnmOut * const pnmOutP, +diff -urNp a/converter/other/tifftopnm.c b/converter/other/tifftopnm.c +--- a/converter/other/tifftopnm.c 2019-12-06 09:04:58.748176092 +0100 ++++ b/converter/other/tifftopnm.c 2019-12-06 08:38:15.087037697 +0100 +@@ -1372,7 +1372,9 @@ convertRasterByRows(pnmOut * const if (scanbuf == NULL) pm_error("can't allocate memory for scanline buffer"); @@ -492,11 +483,10 @@ index c1e7af8..ef9253b 100644 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 df3c737..6c19ade 100644 ---- a/converter/other/xwdtopnm.c -+++ b/converter/other/xwdtopnm.c -@@ -210,6 +210,10 @@ processX10Header(X10WDFileHeader * const h10P, +diff -urNp a/converter/other/xwdtopnm.c b/converter/other/xwdtopnm.c +--- a/converter/other/xwdtopnm.c 2019-12-06 09:04:58.747176083 +0100 ++++ b/converter/other/xwdtopnm.c 2019-12-06 08:38:15.088037706 +0100 +@@ -210,6 +210,10 @@ processX10Header(X10WDFileHeader * cons *colorsP = pnm_allocrow(2); PNM_ASSIGN1((*colorsP)[0], 0); PNM_ASSIGN1((*colorsP)[1], *maxvalP); @@ -507,7 +497,7 @@ index df3c737..6c19ade 100644 *padrightP = (((h10P->pixmap_width + 15) / 16) * 16 - h10P->pixmap_width) * 8; *bits_per_itemP = 16; -@@ -635,6 +639,7 @@ processX11Header(X11WDFileHeader * const h11P, +@@ -635,6 +639,7 @@ processX11Header(X11WDFileHeader * cons *colsP = h11FixedP->pixmap_width; *rowsP = h11FixedP->pixmap_height; @@ -515,10 +505,9 @@ index df3c737..6c19ade 100644 *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 d8e0657..12c7468 100644 ---- a/converter/pbm/mdatopbm.c -+++ b/converter/pbm/mdatopbm.c +diff -urNp a/converter/pbm/mdatopbm.c b/converter/pbm/mdatopbm.c +--- a/converter/pbm/mdatopbm.c 2019-12-06 09:04:58.742176038 +0100 ++++ b/converter/pbm/mdatopbm.c 2019-12-06 08:38:15.088037706 +0100 @@ -245,10 +245,13 @@ main(int argc, char **argv) { pm_readlittleshort(infile, &yy); nInCols = yy; } @@ -534,10 +523,9 @@ index d8e0657..12c7468 100644 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 +diff -urNp a/converter/pbm/mgrtopbm.c b/converter/pbm/mgrtopbm.c +--- a/converter/pbm/mgrtopbm.c 2019-12-06 09:04:58.743176047 +0100 ++++ b/converter/pbm/mgrtopbm.c 2019-12-06 08:38:15.088037706 +0100 @@ -65,6 +65,8 @@ readMgrHeader(FILE * const ifP, if (head.h_high < ' ' || head.l_high < ' ') pm_error("Invalid width field in MGR header"); @@ -547,31 +535,9 @@ index 9f7004a..60e8477 100644 *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 @@ - - #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 9eab041..13b0257 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 2019-12-06 09:04:58.743176047 +0100 ++++ b/converter/pbm/pbmtogem.c 2019-12-06 08:38:15.089037715 +0100 @@ -79,6 +79,7 @@ putinit (int const rows, int const cols) bitsperitem = 0; bitshift = 7; @@ -580,10 +546,9 @@ index 9eab041..13b0257 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 23b2ee9..d2ee91f 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 2019-12-06 09:04:58.742176038 +0100 ++++ b/converter/pbm/pbmtogo.c 2019-12-06 08:38:15.089037715 +0100 @@ -158,6 +158,7 @@ main(int argc, bitrow = pbm_allocrow(cols); @@ -592,10 +557,9 @@ index 23b2ee9..d2ee91f 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 +diff -urNp a/converter/pbm/pbmtolj.c b/converter/pbm/pbmtolj.c +--- a/converter/pbm/pbmtolj.c 2019-12-06 09:04:58.743176047 +0100 ++++ b/converter/pbm/pbmtolj.c 2019-12-06 08:38:15.090037725 +0100 @@ -120,7 +120,11 @@ parseCommandLine(int argc, char ** argv, static void allocateBuffers(unsigned int const cols) { @@ -608,10 +572,9 @@ 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 +diff -urNp a/converter/pbm/pbmtomda.c b/converter/pbm/pbmtomda.c +--- a/converter/pbm/pbmtomda.c 2019-12-06 09:04:58.742176038 +0100 ++++ b/converter/pbm/pbmtomda.c 2019-12-06 08:38:15.091037734 +0100 @@ -179,6 +179,7 @@ int main(int argc, char **argv) nOutRowsUnrounded = bScale ? nInRows/2 : nInRows; @@ -620,10 +583,9 @@ index 3ad5149..9efe5cf 100644 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..1c8d236 100644 ---- a/converter/pbm/pbmtoppa/pbm.c -+++ b/converter/pbm/pbmtoppa/pbm.c +diff -urNp a/converter/pbm/pbmtoppa/pbm.c b/converter/pbm/pbmtoppa/pbm.c +--- a/converter/pbm/pbmtoppa/pbm.c 2019-12-06 09:04:58.745176065 +0100 ++++ b/converter/pbm/pbmtoppa/pbm.c 2019-12-06 08:38:15.091037734 +0100 @@ -11,185 +11,128 @@ #include #include @@ -697,18 +659,35 @@ index ae36e0d..1c8d236 100644 - } - 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; ++ ++ 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; -static int -getbytes(FILE * const ifP, @@ -747,23 +726,11 @@ index ae36e0d..1c8d236 100644 - 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; ++ return 1; + } +- +- -int -pbm_readline(pbm_stat * const pbmStatP, - unsigned char * const data) { @@ -810,11 +777,6 @@ index ae36e0d..1c8d236 100644 - retval = 0; - } - } -- } -- return retval; -+ return 1; - } - +static int getbytes(FILE *fptr,int width,unsigned char* data) +{ + unsigned char mask,acc,*place; @@ -839,12 +801,13 @@ index ae36e0d..1c8d236 100644 + acc=0; + mask=0x80; + } -+ } + } +- return retval; + } + 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 */ @@ -864,6 +827,16 @@ index ae36e0d..1c8d236 100644 + return 1; + } ++ switch(pbm->version) ++ { ++ case P1: ++ if(getbytes(pbm->fptr,pbm->width,data)) ++ { ++ pbm->current_line++; ++ return 1; ++ } ++ return 0; + -void -pbm_unreadline(pbm_stat * const pbmStatP, - void * const data) { @@ -877,17 +850,6 @@ index ae36e0d..1c8d236 100644 - 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; @@ -896,7 +858,8 @@ index ae36e0d..1c8d236 100644 + { + pbm->current_line++; + return 1; -+ } + } +-} + fprintf(stderr,"pbm_readline(): error reading line data (%d)\n",tmp2); + return 0; @@ -919,10 +882,9 @@ index ae36e0d..1c8d236 100644 + 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 +diff -urNp a/converter/pbm/pbmtoppa/pbmtoppa.c b/converter/pbm/pbmtoppa/pbmtoppa.c +--- a/converter/pbm/pbmtoppa/pbmtoppa.c 2019-12-06 09:04:58.745176065 +0100 ++++ b/converter/pbm/pbmtoppa/pbmtoppa.c 2019-12-06 08:38:15.092037743 +0100 @@ -453,6 +453,7 @@ main(int argc, char *argv[]) { pm_error("main(): unrecognized parameter '%s'", argv[argn]); } @@ -931,10 +893,9 @@ index ff4a599..aa510ec 100644 Pwidth=(Width+7)/8; printer.fptr=out; -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 +diff -urNp a/converter/pbm/pbmtoxbm.c b/converter/pbm/pbmtoxbm.c +--- a/converter/pbm/pbmtoxbm.c 2019-12-06 09:04:58.744176056 +0100 ++++ b/converter/pbm/pbmtoxbm.c 2019-12-06 08:38:15.092037743 +0100 @@ -352,6 +352,8 @@ convertRaster(FILE * const ifP, unsigned char * bitrow; @@ -944,10 +905,29 @@ index ecb72b3..fc0eb9c 100644 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 +diff -urNp a/converter/pbm/pbmto4425.c b/converter/pbm/pbmto4425.c +--- a/converter/pbm/pbmto4425.c 2019-12-06 09:04:58.742176038 +0100 ++++ b/converter/pbm/pbmto4425.c 2019-12-06 08:38:15.089037715 +0100 +@@ -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 -urNp a/converter/pbm/pktopbm.c b/converter/pbm/pktopbm.c +--- a/converter/pbm/pktopbm.c 2019-12-06 09:04:58.744176056 +0100 ++++ b/converter/pbm/pktopbm.c 2019-12-06 08:38:15.093037752 +0100 @@ -280,6 +280,7 @@ main(int argc, char *argv[]) { if (flagbyte == 7) { /* long form preamble */ integer packetlength = get32() ; /* character packet length */ @@ -956,10 +936,9 @@ index 712f339..b6fcb02 100644 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 +diff -urNp a/converter/pbm/thinkjettopbm.l b/converter/pbm/thinkjettopbm.l +--- a/converter/pbm/thinkjettopbm.l 2019-12-06 09:04:58.743176047 +0100 ++++ b/converter/pbm/thinkjettopbm.l 2019-12-06 08:38:15.093037752 +0100 @@ -114,7 +114,9 @@ DIG [0-9] \033\*b{DIG}+W { int l; @@ -980,10 +959,9 @@ index 5de4f2b..7f31de5 100644 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 +diff -urNp a/converter/pbm/ybmtopbm.c b/converter/pbm/ybmtopbm.c +--- a/converter/pbm/ybmtopbm.c 2019-12-06 09:04:58.742176038 +0100 ++++ b/converter/pbm/ybmtopbm.c 2019-12-06 08:38:15.093037752 +0100 @@ -43,6 +43,7 @@ getinit(FILE * const ifP, pm_error("EOF / read error"); @@ -992,10 +970,9 @@ index 2a42908..cf1ff03 100644 } -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 +diff -urNp a/converter/pgm/lispmtopgm.c b/converter/pgm/lispmtopgm.c +--- a/converter/pgm/lispmtopgm.c 2019-12-06 09:04:58.746176074 +0100 ++++ b/converter/pgm/lispmtopgm.c 2019-12-06 08:38:15.094037761 +0100 @@ -58,6 +58,7 @@ main( argc, argv ) pm_error( "depth (%d bits) is too large", depth); @@ -1004,7 +981,7 @@ index 40dd3fb..b5469f7 100644 grayrow = pgm_allocrow( ( cols + 7 ) / 8 * 8 ); for ( row = 0; row < rows; ++row ) -@@ -102,6 +103,8 @@ getinit( file, colsP, rowsP, depthP, padrightP ) +@@ -102,6 +103,8 @@ getinit( file, colsP, rowsP, depthP, pad if ( *depthP == 0 ) *depthP = 1; /* very old file */ @@ -1013,10 +990,9 @@ index 40dd3fb..b5469f7 100644 *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 +diff -urNp a/converter/pgm/psidtopgm.c b/converter/pgm/psidtopgm.c +--- a/converter/pgm/psidtopgm.c 2019-12-06 09:04:58.745176065 +0100 ++++ b/converter/pgm/psidtopgm.c 2019-12-06 08:38:15.094037761 +0100 @@ -78,6 +78,7 @@ main(int argc, pm_error("bits/sample (%d) is too large.", bitspersample); @@ -1025,23 +1001,9 @@ index 07417d1..25bb311 100644 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 92d4d6f..60853dd 100644 ---- a/converter/ppm/ilbmtoppm.c -+++ b/converter/ppm/ilbmtoppm.c +diff -urNp a/converter/ppm/ilbmtoppm.c b/converter/ppm/ilbmtoppm.c +--- a/converter/ppm/ilbmtoppm.c 2019-12-06 09:04:58.766176253 +0100 ++++ b/converter/ppm/ilbmtoppm.c 2019-12-06 08:38:15.096037779 +0100 @@ -608,6 +608,7 @@ decode_row(FILE * const ifP, rawtype *chp; @@ -1084,7 +1046,7 @@ index 92d4d6f..60853dd 100644 MALLOCARRAY_NOFAIL(redtable, redmaxval +1); MALLOCARRAY_NOFAIL(greentable, greenmaxval +1); MALLOCARRAY_NOFAIL(bluetable, bluemaxval +1); -@@ -1802,7 +1823,9 @@ PCHG_ConvertSmall(PCHGHeader * const pchgP, +@@ -1802,7 +1823,9 @@ PCHG_ConvertSmall(PCHGHeader * const ChangeCount32 = *data++; remDataSize -= 2; @@ -1112,11 +1074,9 @@ index 92d4d6f..60853dd 100644 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 +diff -urNp a/converter/ppm/ilbmtoppm.c.rej b/converter/ppm/ilbmtoppm.c.rej +--- a/converter/ppm/ilbmtoppm.c.rej 1970-01-01 01:00:00.000000000 +0100 ++++ b/converter/ppm/ilbmtoppm.c.rej 2019-12-06 08:38:15.096037779 +0100 @@ -0,0 +1,46 @@ +--- converter/ppm/ilbmtoppm.c ++++ converter/ppm/ilbmtoppm.c @@ -1164,10 +1124,9 @@ index 0000000..972cad0 + 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 +diff -urNp a/converter/ppm/imgtoppm.c b/converter/ppm/imgtoppm.c +--- a/converter/ppm/imgtoppm.c 2019-12-06 09:04:58.764176235 +0100 ++++ b/converter/ppm/imgtoppm.c 2019-12-06 08:38:15.097037789 +0100 @@ -84,6 +84,7 @@ main(int argc, char ** argv) { len = atoi((char*) buf ); if ( fread( buf, len, 1, ifp ) != 1 ) @@ -1184,11 +1143,22 @@ index 7078b88..eb8509e 100644 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) +diff -urNp a/converter/ppm/Makefile b/converter/ppm/Makefile +--- a/converter/ppm/Makefile 2019-12-06 09:04:58.766176253 +0100 ++++ b/converter/ppm/Makefile 2019-12-06 08:38:15.095037770 +0100 +@@ -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 -urNp a/converter/ppm/pcxtoppm.c b/converter/ppm/pcxtoppm.c +--- a/converter/ppm/pcxtoppm.c 2019-12-06 09:04:58.766176253 +0100 ++++ b/converter/ppm/pcxtoppm.c 2019-12-06 08:38:15.097037789 +0100 +@@ -409,6 +409,7 @@ pcx_planes_to_pixels(pixels, bitplanes, /* * clear the pixel buffer */ @@ -1204,19 +1174,17 @@ index e252ba2..270ae3b 100644 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 b8fb864..177bc30 100644 ---- a/converter/ppm/picttoppm.c -+++ b/converter/ppm/picttoppm.c +diff -urNp a/converter/ppm/picttoppm.c b/converter/ppm/picttoppm.c +--- a/converter/ppm/picttoppm.c 2019-12-06 09:04:58.764176235 +0100 ++++ b/converter/ppm/picttoppm.c 2019-12-06 08:38:15.099037807 +0100 @@ -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 b8b94f7..62ce77e 100644 ---- a/converter/ppm/pjtoppm.c -+++ b/converter/ppm/pjtoppm.c +diff -urNp a/converter/ppm/pjtoppm.c b/converter/ppm/pjtoppm.c +--- a/converter/ppm/pjtoppm.c 2019-12-06 09:04:58.764176235 +0100 ++++ b/converter/ppm/pjtoppm.c 2019-12-06 08:38:15.100037816 +0100 @@ -11,87 +11,65 @@ */ @@ -1547,11 +1515,10 @@ index b8b94f7..62ce77e 100644 - - - -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) { +diff -urNp a/converter/ppm/ppmtoeyuv.c b/converter/ppm/ppmtoeyuv.c +--- a/converter/ppm/ppmtoeyuv.c 2019-12-06 09:04:58.764176235 +0100 ++++ b/converter/ppm/ppmtoeyuv.c 2019-12-06 08:38:15.100037816 +0100 +@@ -114,6 +114,7 @@ create_multiplication_tables(const pixva int index; @@ -1559,10 +1526,9 @@ index f5ce115..6f072be 100644 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 +diff -urNp a/converter/ppm/ppmtolj.c b/converter/ppm/ppmtolj.c +--- a/converter/ppm/ppmtolj.c 2019-12-06 09:04:58.766176253 +0100 ++++ b/converter/ppm/ppmtolj.c 2019-12-06 08:38:15.101037825 +0100 @@ -182,6 +182,7 @@ int main(int argc, char *argv[]) { ppm_readppminit( ifp, &cols, &rows, &maxval, &format ); pixelrow = ppm_allocrow( cols ); @@ -1571,10 +1537,9 @@ index 7ed814e..b4e7db1 100644 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 5b0b324..11db755 100644 ---- a/converter/ppm/ppmtomitsu.c -+++ b/converter/ppm/ppmtomitsu.c +diff -urNp a/converter/ppm/ppmtomitsu.c b/converter/ppm/ppmtomitsu.c +--- a/converter/ppm/ppmtomitsu.c 2019-12-06 09:04:58.766176253 +0100 ++++ b/converter/ppm/ppmtomitsu.c 2019-12-06 08:38:15.101037825 +0100 @@ -685,6 +685,8 @@ main(int argc, char * argv[]) { medias = MSize_User; @@ -1584,11 +1549,10 @@ index 5b0b324..11db755 100644 medias.maxcols *= 2; medias.maxrows *= 2; } -diff --git a/converter/ppm/ppmtopcx.c b/converter/ppm/ppmtopcx.c -index fa68edc..97dfb2b 100644 ---- a/converter/ppm/ppmtopcx.c -+++ b/converter/ppm/ppmtopcx.c -@@ -425,6 +425,8 @@ ppmTo16ColorPcx(pixel ** const pixels, +diff -urNp a/converter/ppm/ppmtopcx.c b/converter/ppm/ppmtopcx.c +--- a/converter/ppm/ppmtopcx.c 2019-12-06 09:04:58.765176244 +0100 ++++ b/converter/ppm/ppmtopcx.c 2019-12-06 08:38:15.102037834 +0100 +@@ -425,6 +425,8 @@ ppmTo16ColorPcx(pixel ** cons else Planes = 1; } } @@ -1597,10 +1561,9 @@ index fa68edc..97dfb2b 100644 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 +diff -urNp a/converter/ppm/ppmtopict.c b/converter/ppm/ppmtopict.c +--- a/converter/ppm/ppmtopict.c 2019-12-06 09:04:58.766176253 +0100 ++++ b/converter/ppm/ppmtopict.c 2019-12-06 08:38:15.103037843 +0100 @@ -450,6 +450,8 @@ main(int argc, const char ** argv) { putShort(stdout, 0); /* mode */ @@ -1610,10 +1573,9 @@ index 36464b6..c91ccf2 100644 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 +diff -urNp a/converter/ppm/ppmtopj.c b/converter/ppm/ppmtopj.c +--- a/converter/ppm/ppmtopj.c 2019-12-06 09:04:58.765176244 +0100 ++++ b/converter/ppm/ppmtopj.c 2019-12-06 08:38:15.103037843 +0100 @@ -179,6 +179,7 @@ char *argv[]; pixels = ppm_readppm( ifp, &cols, &rows, &maxval ); @@ -1622,10 +1584,9 @@ index d116773..fc84cac 100644 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 +diff -urNp a/converter/ppm/ppmtopjxl.c b/converter/ppm/ppmtopjxl.c +--- a/converter/ppm/ppmtopjxl.c 2019-12-06 09:04:58.764176235 +0100 ++++ b/converter/ppm/ppmtopjxl.c 2019-12-06 08:38:15.104037853 +0100 @@ -267,6 +267,9 @@ main(int argc, const char * argv[]) { if (maxval > PCL_MAXVAL) pm_error("color range too large; reduce with ppmcscale"); @@ -1659,10 +1620,9 @@ index 90bcef0..72d0027 100644 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 +diff -urNp a/converter/ppm/ppmtowinicon.c b/converter/ppm/ppmtowinicon.c +--- a/converter/ppm/ppmtowinicon.c 2019-12-06 09:04:58.765176244 +0100 ++++ b/converter/ppm/ppmtowinicon.c 2019-12-06 08:38:15.104037853 +0100 @@ -12,6 +12,7 @@ #include @@ -1671,7 +1631,7 @@ index c673798..af2b445 100644 #include "pm_c_util.h" #include "winico.h" -@@ -214,6 +215,7 @@ createAndBitmap (gray ** const ba, int const cols, int const rows, +@@ -214,6 +215,7 @@ createAndBitmap (gray ** const ba, int c MALLOCARRAY_NOFAIL(rowData, rows); icBitmap->xBytes = xBytes; icBitmap->data = rowData; @@ -1679,7 +1639,7 @@ index c673798..af2b445 100644 icBitmap->size = xBytes * rows; for (y=0;yxBytes = xBytes; icBitmap->data = rowData; @@ -1687,7 +1647,7 @@ index c673798..af2b445 100644 icBitmap->size = xBytes * rows; for (y=0;yxBytes = xBytes; icBitmap->data = rowData; @@ -1695,7 +1655,7 @@ index c673798..af2b445 100644 icBitmap->size = xBytes * rows; for (y=0;ybitcount = bpp; entry->ih = createInfoHeader(entry, xorBitmap, andBitmap); entry->colors = palette->colors; @@ -1708,11 +1668,10 @@ index c673798..af2b445 100644 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) { +diff -urNp a/converter/ppm/ppmtoxpm.c b/converter/ppm/ppmtoxpm.c +--- a/converter/ppm/ppmtoxpm.c 2019-12-06 09:04:58.765176244 +0100 ++++ b/converter/ppm/ppmtoxpm.c 2019-12-06 08:38:15.105037862 +0100 +@@ -198,6 +198,7 @@ genNumstr(unsigned int const input, int unsigned int i; /* Allocate memory for printed number. Abort if error. */ @@ -1728,10 +1687,9 @@ index 0e31692..1b3923f 100644 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 +diff -urNp a/converter/ppm/qrttoppm.c b/converter/ppm/qrttoppm.c +--- a/converter/ppm/qrttoppm.c 2019-12-06 09:04:58.765176244 +0100 ++++ b/converter/ppm/qrttoppm.c 2019-12-06 08:38:15.105037862 +0100 @@ -46,7 +46,7 @@ main( argc, argv ) ppm_writeppminit( stdout, cols, rows, maxval, 0 ); @@ -1741,10 +1699,9 @@ index 935463e..653084c 100644 if ( buf == (unsigned char *) 0 ) pm_error( "out of memory" ); -diff --git a/converter/ppm/sldtoppm.c b/converter/ppm/sldtoppm.c -index 2dc049f..2a482be 100644 ---- a/converter/ppm/sldtoppm.c -+++ b/converter/ppm/sldtoppm.c +diff -urNp a/converter/ppm/sldtoppm.c b/converter/ppm/sldtoppm.c +--- a/converter/ppm/sldtoppm.c 2019-12-06 09:04:58.764176235 +0100 ++++ b/converter/ppm/sldtoppm.c 2019-12-06 08:38:15.106037871 +0100 @@ -154,127 +154,85 @@ vscale(int * const px, @@ -1952,10 +1909,9 @@ index 2dc049f..2a482be 100644 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 75faac6..5758739 100644 ---- a/converter/ppm/ximtoppm.c -+++ b/converter/ppm/ximtoppm.c +diff -urNp a/converter/ppm/ximtoppm.c b/converter/ppm/ximtoppm.c +--- a/converter/ppm/ximtoppm.c 2019-12-06 09:04:58.766176253 +0100 ++++ b/converter/ppm/ximtoppm.c 2019-12-06 08:38:15.106037871 +0100 @@ -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); @@ -1988,11 +1944,10 @@ index 75faac6..5758739 100644 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 db5b5b3..5fc0267 100644 ---- a/editor/pamcut.c -+++ b/editor/pamcut.c -@@ -773,6 +773,8 @@ cutOneImage(FILE * const ifP, +diff -urNp a/editor/pamcut.c b/editor/pamcut.c +--- a/editor/pamcut.c 2019-12-06 09:04:58.737175993 +0100 ++++ b/editor/pamcut.c 2019-12-06 08:38:15.107037880 +0100 +@@ -773,6 +773,8 @@ cutOneImage(FILE * const ifP outpam = inpam; /* Initial value -- most fields should be same */ outpam.file = ofP; @@ -2001,11 +1956,10 @@ index db5b5b3..5fc0267 100644 outpam.width = rightcol - leftcol + 1; outpam.height = bottomrow - toprow + 1; -diff --git a/editor/pnmgamma.c b/editor/pnmgamma.c -index b357b0d..ec612d3 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 2019-12-06 09:04:58.736175984 +0100 ++++ b/editor/pnmgamma.c 2019-12-06 08:38:15.107037880 +0100 +@@ -596,6 +596,7 @@ createGammaTables(enum transferFunction xelval ** const btableP) { /* Allocate space for the tables. */ @@ -2013,11 +1967,10 @@ index b357b0d..ec612d3 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 2019-12-06 09:04:58.735175975 +0100 ++++ b/editor/pnmhisteq.c 2019-12-06 08:38:15.108037889 +0100 +@@ -107,6 +107,7 @@ computeLuminosityHistogram(xel * const * unsigned int pixelCount; unsigned int * lumahist; @@ -2025,10 +1978,9 @@ 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 +diff -urNp a/editor/pnmindex.csh b/editor/pnmindex.csh +--- a/editor/pnmindex.csh 2019-12-06 09:04:58.735175975 +0100 ++++ b/editor/pnmindex.csh 2019-12-06 08:38:15.108037889 +0100 @@ -1,5 +1,7 @@ #!/bin/csh -f # @@ -2037,10 +1989,9 @@ index c6f1e84..c513a84 100755 # 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 9c7a77e..1aa578c 100644 ---- a/editor/pnmpad.c -+++ b/editor/pnmpad.c +diff -urNp a/editor/pnmpad.c b/editor/pnmpad.c +--- a/editor/pnmpad.c 2019-12-06 09:04:58.737175993 +0100 ++++ b/editor/pnmpad.c 2019-12-06 08:38:15.109037898 +0100 @@ -634,6 +634,8 @@ main(int argc, const char ** argv) { computePadSizes(cmdline, cols, rows, &lpad, &rpad, &tpad, &bpad); @@ -2050,10 +2001,9 @@ index 9c7a77e..1aa578c 100644 newcols = cols + lpad + rpad; if (PNM_FORMAT_TYPE(format) == PBM_TYPE) -diff --git a/editor/pnmremap.c b/editor/pnmremap.c -index 0038f4d..a5950be 100644 ---- a/editor/pnmremap.c -+++ b/editor/pnmremap.c +diff -urNp a/editor/pnmremap.c b/editor/pnmremap.c +--- a/editor/pnmremap.c 2019-12-06 09:04:58.737175993 +0100 ++++ b/editor/pnmremap.c 2019-12-06 08:38:15.109037898 +0100 @@ -468,6 +468,7 @@ fserr_init(struct pam * const pamP, unsigned int const fserrSize = pamP->width + 2; @@ -2070,11 +2020,9 @@ index 0038f4d..a5950be 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 +diff -urNp a/editor/pnmremap.c.rej b/editor/pnmremap.c.rej +--- a/editor/pnmremap.c.rej 1970-01-01 01:00:00.000000000 +0100 ++++ b/editor/pnmremap.c.rej 2019-12-06 08:38:15.109037898 +0100 @@ -0,0 +1,10 @@ +--- editor/pnmremap.c ++++ editor/pnmremap.c @@ -2086,11 +2034,10 @@ index 0000000..c627c20 + 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 2019-12-06 09:04:58.734175966 +0100 ++++ b/editor/pnmscalefixed.c 2019-12-06 08:38:15.109037898 +0100 +@@ -214,6 +214,7 @@ compute_output_dimensions(const struct c const int rows, const int cols, int * newrowsP, int * newcolsP) { @@ -2098,7 +2045,7 @@ index 884ca31..747cd8f 100644 if (cmdline.pixels) { if (rows * cols <= cmdline.pixels) { *newrowsP = rows; -@@ -265,6 +266,8 @@ compute_output_dimensions(const struct cmdline_info cmdline, +@@ -265,6 +266,8 @@ compute_output_dimensions(const struct c if (*newcolsP < 1) *newcolsP = 1; if (*newrowsP < 1) *newrowsP = 1; @@ -2117,11 +2064,10 @@ index 884ca31..747cd8f 100644 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) { +diff -urNp a/editor/ppmdither.c b/editor/ppmdither.c +--- a/editor/ppmdither.c 2019-12-06 09:04:58.736175984 +0100 ++++ b/editor/ppmdither.c 2019-12-06 08:38:15.110037907 +0100 +@@ -356,6 +356,11 @@ dithMatrix(unsigned int const dithPower) (dithDim * sizeof(*dithMat)) + /* pointers */ (dithDim * dithDim * sizeof(**dithMat)); /* data */ @@ -2133,10 +2079,9 @@ index ec1b977..e701e09 100644 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 +diff -urNp a/editor/specialty/pamoil.c b/editor/specialty/pamoil.c +--- a/editor/specialty/pamoil.c 2019-12-06 09:04:58.739176011 +0100 ++++ b/editor/specialty/pamoil.c 2019-12-06 08:38:15.110037907 +0100 @@ -112,6 +112,7 @@ main(int argc, char *argv[] ) { tuples = pnm_readpam(ifp, &inpam, PAM_STRUCT_SIZE(tuple_type)); pm_close(ifp); @@ -2145,11 +2090,10 @@ index 6cb8d3a..6f4bde9 100644 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) { +diff -urNp a/lib/libpam.c b/lib/libpam.c +--- a/lib/libpam.c 2019-12-06 09:04:58.781176388 +0100 ++++ b/lib/libpam.c 2019-12-06 08:38:15.111037917 +0100 +@@ -225,7 +225,8 @@ allocPamRow(const struct pam * const pam unsigned int const bytesPerTuple = allocationDepth(pamP) * sizeof(sample); tuple * tuplerow; @@ -2159,11 +2103,10 @@ index a8f140b..e6986f1 100644 if (tuplerow != NULL) { /* Now we initialize the pointers to the individual tuples -diff --git a/lib/libpammap.c b/lib/libpammap.c -index 2222491..ba27a4c 100644 ---- a/lib/libpammap.c -+++ b/lib/libpammap.c -@@ -108,7 +108,9 @@ allocTupleIntListItem(struct pam * const pamP) { +diff -urNp a/lib/libpammap.c b/lib/libpammap.c +--- a/lib/libpammap.c 2019-12-06 09:04:58.781176388 +0100 ++++ b/lib/libpammap.c 2019-12-06 08:38:15.111037917 +0100 +@@ -108,7 +108,9 @@ allocTupleIntListItem(struct pam * const */ struct tupleint_list_item * retval; @@ -2174,11 +2117,10 @@ index 2222491..ba27a4c 100644 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) { +diff -urNp a/lib/libpm.c b/lib/libpm.c +--- a/lib/libpm.c 2019-12-06 09:04:58.781176388 +0100 ++++ b/lib/libpm.c 2019-12-06 08:38:15.111037917 +0100 +@@ -888,5 +888,53 @@ pm_parse_height(const char * const arg) return height; } @@ -2232,11 +2174,10 @@ index 47a2f49..a263598 100644 + 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); +diff -urNp a/lib/pm.h b/lib/pm.h +--- a/lib/pm.h 2019-12-06 09:04:58.780176379 +0100 ++++ b/lib/pm.h 2019-12-06 08:38:15.112037926 +0100 +@@ -442,5 +442,12 @@ pm_parse_height(const char * const arg); } #endif @@ -2249,11 +2190,460 @@ index 3fc92fb..1e30ce9 100644 + #endif -diff --git a/other/pnmcolormap.c b/other/pnmcolormap.c -index f687f03..20cbfbd 100644 ---- a/other/pnmcolormap.c -+++ b/other/pnmcolormap.c -@@ -840,6 +840,7 @@ colormapToSquare(struct pam * const pamP, +diff -urNp a/lib/pm.h.orig b/lib/pm.h.orig +--- a/lib/pm.h.orig 1970-01-01 01:00:00.000000000 +0100 ++++ b/lib/pm.h.orig 2019-12-06 08:37:56.816870379 +0100 +@@ -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 -urNp a/other/pnmcolormap.c b/other/pnmcolormap.c +--- a/other/pnmcolormap.c 2019-12-06 09:04:58.789176460 +0100 ++++ b/other/pnmcolormap.c 2019-12-06 08:38:15.112037926 +0100 +@@ -1002,6 +1002,7 @@ colormapToSquare(struct pam * const pamP pamP->width = intsqrt; else pamP->width = intsqrt + 1; @@ -2261,61 +2651,1156 @@ index f687f03..20cbfbd 100644 } { unsigned int const intQuotient = colormap.size / pamP->width; -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; +diff -urNp a/other/pnmcolormap.c.orig b/other/pnmcolormap.c.orig +--- a/other/pnmcolormap.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ b/other/pnmcolormap.c.orig 2019-12-06 08:37:56.824870452 +0100 +@@ -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; ++ } ++ } ++ } ++ } ++} ++ ++ ++ ++#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); ++} ++ ++ + -+ 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 0766d22..c80a5fa 100644 ---- a/urt/rle.h -+++ b/urt/rle.h -@@ -160,6 +160,17 @@ rle_hdr /* End of typedef. */ - */ - extern rle_hdr rle_dflt_hdr; - +/* -+ * Provided by pm library -+ */ ++** 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. ++*/ + -+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 ++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 -urNp a/urt/rle_addhist.c b/urt/rle_addhist.c +--- a/urt/rle_addhist.c 2019-12-06 09:04:58.741176029 +0100 ++++ b/urt/rle_addhist.c 2019-12-06 08:38:15.113037935 +0100 @@ -70,13 +70,18 @@ rle_addhist(char * argv[], return; @@ -2349,11 +3834,10 @@ index b165175..e09ed94 100644 ++length; /*Cater for the null. */ -diff --git a/urt/rle_getrow.c b/urt/rle_getrow.c -index 679811c..cc1f5cb 100644 ---- a/urt/rle_getrow.c -+++ b/urt/rle_getrow.c -@@ -160,6 +160,7 @@ rle_get_setup(rle_hdr * const the_hdr) { +diff -urNp a/urt/rle_getrow.c b/urt/rle_getrow.c +--- a/urt/rle_getrow.c 2019-12-06 09:04:58.740176020 +0100 ++++ b/urt/rle_getrow.c 2019-12-06 08:38:15.113037935 +0100 +@@ -164,6 +164,7 @@ rle_get_setup(rle_hdr * const the_hdr) { char * cp; VAXSHORT(comlen, infile); /* get comment length */ @@ -2361,76 +3845,1415 @@ index 679811c..cc1f5cb 100644 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 1611324..7c9c010 100644 ---- a/urt/rle_hdr.c -+++ b/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; +diff -urNp a/urt/rle_getrow.c.orig b/urt/rle_getrow.c.orig +--- a/urt/rle_getrow.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ b/urt/rle_getrow.c.orig 2019-12-06 08:37:56.784870085 +0100 +@@ -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 $ ++ */ + -+ 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. */ ++#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; + } - /* Check if there are really any comments. */ - if ( size ) - { -+ overflow_add(size, 1); - size++; /* Copy the NULL pointer, too. */ ++ 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 -urNp a/urt/rle.h b/urt/rle.h +--- a/urt/rle.h 2019-12-06 09:04:58.741176029 +0100 ++++ b/urt/rle.h 2019-12-06 08:38:15.113037935 +0100 +@@ -153,6 +153,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 -urNp a/urt/rle_hdr.c b/urt/rle_hdr.c +--- a/urt/rle_hdr.c 2019-12-06 09:04:58.741176029 +0100 ++++ b/urt/rle_hdr.c 2019-12-06 09:04:18.225811488 +0100 +@@ -148,7 +148,7 @@ rle_hdr_cp(rle_hdr * const fromHdrP, + if (toHdrP->cmap) { + size_t const size = + toHdrP->ncmap * (1 << toHdrP->cmaplen) * sizeof(rle_map); +- toHdrP->cmap = malloc(size); ++ toHdrP->cmap = malloc3(toHdrP->ncmap, 1<cmaplen, sizeof(rle_map)); + 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, + + /* Count the comments. */ + 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 *); - 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 ae8548b..c2ef37d 100644 ---- a/urt/rle_open_f.c -+++ b/urt/rle_open_f.c -@@ -163,65 +163,7 @@ dealWithSubprocess(const char * const file_name, + size *= sizeof(char *); + toHdrP->comments = malloc(size); + if (!toHdrP->comments) +diff -urNp a/urt/rle_hdr.c.orig b/urt/rle_hdr.c.orig +--- a/urt/rle_hdr.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ b/urt/rle_hdr.c.orig 2019-12-06 08:38:15.114037944 +0100 +@@ -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 -urNp a/urt/rle_hdr.c.rej b/urt/rle_hdr.c.rej +--- a/urt/rle_hdr.c.rej 1970-01-01 01:00:00.000000000 +0100 ++++ b/urt/rle_hdr.c.rej 2019-12-06 08:38:15.114037944 +0100 +@@ -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 -urNp a/urt/rle.h.orig b/urt/rle.h.orig +--- a/urt/rle.h.orig 1970-01-01 01:00:00.000000000 +0100 ++++ b/urt/rle.h.orig 2019-12-06 08:37:56.784870085 +0100 +@@ -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 -urNp a/urt/rle_open_f.c b/urt/rle_open_f.c +--- a/urt/rle_open_f.c 2019-12-06 09:04:58.740176020 +0100 ++++ b/urt/rle_open_f.c 2019-12-06 08:38:15.114037944 +0100 +@@ -163,65 +163,7 @@ dealWithSubprocess(const char * const f FILE ** const fpP, bool * const noSubprocessP, const char ** const errorP) { @@ -2496,10 +5319,9 @@ index ae8548b..c2ef37d 100644 } -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 +diff -urNp a/urt/rle_putcom.c b/urt/rle_putcom.c +--- a/urt/rle_putcom.c 2019-12-06 09:04:58.740176020 +0100 ++++ b/urt/rle_putcom.c 2019-12-06 08:38:15.114037944 +0100 @@ -98,12 +98,14 @@ rle_putcom(const char * const value, const char * v; const char ** old_comments; @@ -2516,10 +5338,37 @@ index ab2eb20..ce83615 100644 /* 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..5e114bb 100644 ---- a/urt/scanargs.c -+++ b/urt/scanargs.c +diff -urNp a/urt/Runput.c b/urt/Runput.c +--- a/urt/Runput.c 2019-12-06 09:04:58.741176029 +0100 ++++ b/urt/Runput.c 2019-12-06 08:38:15.113037935 +0100 +@@ -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 -urNp a/urt/scanargs.c b/urt/scanargs.c +--- a/urt/scanargs.c 2019-12-06 09:04:58.740176020 +0100 ++++ b/urt/scanargs.c 2019-12-06 08:38:15.115037953 +0100 @@ -62,9 +62,8 @@ typedef int *ptr; /* * Storage allocation macros diff --git a/netpbm.spec b/netpbm.spec index baaf050..745b2c3 100644 --- a/netpbm.spec +++ b/netpbm.spec @@ -1,6 +1,6 @@ Summary: A library for handling different graphics file formats Name: netpbm -Version: 10.87.00 +Version: 10.88.00 Release: 1%{?dist} # See copyright_summary for details License: BSD and GPLv2 and IJG and MIT and Public Domain @@ -228,6 +228,9 @@ popd %doc userguide/* %changelog +* Mon Dec 09 2019 Josef Ridky - 10.88.00-1 +- New upstream release (#1756647) + * Wed Aug 21 2019 Josef Ridky - 10.87.00-1 - New upstream release (#1725280) diff --git a/sources b/sources index c5c4c64..106725f 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (netpbm-10.87.00.tar.xz) = 8245dd4b181d9e9b74b47af3e04e94143f03197ac4bc1f50009d66e16ec156c4d4a8fcefcfa90f6fea902f12cf3e5d3f34d220b1ed3333e2fe2d23da2293ea24 +SHA512 (netpbm-10.88.00.tar.xz) = ab50ccadd2782f62beedccc37e36fd668b1afd28cf59cef8c0218b8aa322b2fb952ed36c46b922b61430831daa0f3b67296798aea6b254b748b5a63c349452e3