diff options
138 files changed, 3551 insertions, 1231 deletions
diff --git a/GNUmakefile b/GNUmakefile index 864adea6..8cda072d 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -260,10 +260,10 @@ endif .PHONY: install-merge install-nonmerge install-merge: install.merge install.lib install.data \ - install.manweb install.man + install.manwebmain install.manweb install.man install-nonmerge: install.bin install.lib install.data \ - install.manweb install.man + install.manwebmain install.manweb install.man .PHONY: merge merge: lib/all netpbm @@ -369,7 +369,7 @@ install.lib: endif .PHONY: install.manweb -install.manweb: $(PKGDIR)/man/web/netpbm.url $(PKGDIR)/bin/doc.url +install.manwebmain: $(PKGDIR)/man/web/netpbm.url $(PKGDIR)/bin/doc.url $(PKGDIR)/man/web/netpbm.url: $(PKGDIR)/man/web echo "$(NETPBM_DOCURL)" > $@ @@ -418,6 +418,12 @@ install.sharedlibstub: $(MAKE) -C lib -f $(SRCDIR)/lib/Makefile \ SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) install.sharedlibstub +# Make the 'deb' target after making 'package'. It generates a .deb +# file in the current directory. +.PHONY: deb +deb: + buildtools/debian/mkdeb --buildtools=buildtools --pkgdir=$(PKGDIR) + .PHONY: check check: # This works on typical Linux systems @@ -434,6 +440,7 @@ clean: localclean localclean: rm -f netpbm build_started build_complete rm -f pm_config.h inttypes_netpbm.h version.h + rm -f *.deb # Note that removing config.mk must be the last thing we do, # because no other makes will work after that is done. diff --git a/analyzer/pgmhist.c b/analyzer/pgmhist.c index f3a67383..1e779655 100644 --- a/analyzer/pgmhist.c +++ b/analyzer/pgmhist.c @@ -20,7 +20,7 @@ -struct cmdline_info { +struct CmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. */ @@ -29,13 +29,14 @@ struct cmdline_info { unsigned int median; unsigned int quartile; unsigned int decile; + unsigned int forensic; }; static void parseCommandLine(int argc, const char ** argv, - struct cmdline_info * const cmdlineP) { + struct CmdlineInfo * const cmdlineP) { /*---------------------------------------------------------------------------- Note that the file spec array we return is stored in the storage that was passed to us as the argv array. @@ -43,7 +44,7 @@ parseCommandLine(int argc, const char ** argv, optStruct3 opt; /* set by OPTENT3 */ optEntry * option_def; unsigned int option_def_index; - + MALLOCARRAY_NOFAIL(option_def, 100); option_def_index = 0; /* incremented by OPTENT3 */ @@ -56,6 +57,8 @@ parseCommandLine(int argc, const char ** argv, &cmdlineP->quartile, 0); OPTENT3(0, "decile", OPT_FLAG, NULL, &cmdlineP->decile, 0); + OPTENT3(0, "forensic", OPT_FLAG, NULL, + &cmdlineP->forensic, 0); opt.opt_table = option_def; opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ @@ -68,7 +71,7 @@ parseCommandLine(int argc, const char ** argv, pm_error("You may specify only one of -median, -quartile, " "and -decile"); - if (argc-1 == 0) + if (argc-1 == 0) cmdlineP->inputFileName = "-"; else if (argc-1 != 1) pm_error("Program takes zero or one argument (filename). You " @@ -81,39 +84,80 @@ parseCommandLine(int argc, const char ** argv, +static gray +universalMaxval(gray const maxval, + int const format) { +/*---------------------------------------------------------------------------- + A maxval that makes it impossible for a pixel to be invalid in an image that + states it maxval as 'maxval' and has format 'format'. + + E.g. in a one-byte-per-sample image, it's not possible to read a sample + value greater than 255, so a maxval of 255 makes it impossible for a sample + to be invalid. + + But: we never go above 65535, which means our maxval isn't entirely + universal. If the image is plain PGM, it could contain a pixel that + exceeds even that. +-----------------------------------------------------------------------------*/ + assert(0 < maxval && maxval < 65536); + + if (format == RPGM_FORMAT) { + /* Raw PGM stream has either one or two bytes per pixel, depending + upon its stated maxval. + */ + if (maxval > 255) + return 65535; + else + return 255; + } else if (format == RPBM_FORMAT) { + /* A Raw PBM stream has one bit per pixel, which libnetpbm renders + as 0 or 255 when we read it. + */ + assert(maxval == 255); + return 255; + } else { + /* A plain PGM or PBM stream has essentially unlimited range in the + tokens that are supposed to be sample values. We arbitrarily draw + the line at 65535. + */ + return 65535; + } +} + + + static void -buildHistogram(FILE * const ifP, - unsigned int ** const histP, - gray * const maxvalP) { +buildHistogram(FILE * const ifP, + int const format, + unsigned int const cols, + unsigned int const rows, + gray const mmaxval, + unsigned long int ** const histP) { +/*---------------------------------------------------------------------------- + Compute the histogram of sample values in the input stream *ifP as *histP, + in newly malloced storage. + Assume the image maxval is 'mmaxval'. Assume *ifP is positioned to the + start of the raster. +-----------------------------------------------------------------------------*/ gray * grayrow; - int rows, cols; - int format; unsigned int row; unsigned int i; - unsigned int * hist; /* malloc'ed array */ - gray maxval; - - pgm_readpgminit(ifP, &cols, &rows, &maxval, &format); - - if (UINT_MAX / cols < rows) - pm_error("Too many pixels (%u x %u) in image. " - "Maximum computable is %u", - cols, rows, UINT_MAX); + unsigned long int * hist; /* malloc'ed array */ grayrow = pgm_allocrow(cols); - MALLOCARRAY(hist, maxval + 1); + MALLOCARRAY(hist, mmaxval + 1); if (hist == NULL) pm_error("out of memory"); - for (i = 0; i <= maxval; ++i) + for (i = 0; i <= mmaxval; ++i) hist[i] = 0; for (row = 0; row < rows; ++row) { unsigned int col; - pgm_readpgmrow(ifP, grayrow, cols, maxval, format); + pgm_readpgmrow(ifP, grayrow, cols, mmaxval, format); for (col = 0; col < cols; ++col) { /* Because total pixels in image is limited: */ @@ -124,49 +168,33 @@ buildHistogram(FILE * const ifP, } pgm_freerow(grayrow); - *histP = hist; - *maxvalP = maxval; -} - - - -static unsigned int -sum(unsigned int const hist[], - gray const maxval) { - - unsigned int sum; - unsigned int sampleVal; - - for (sampleVal = 0, sum = 0; sampleVal <= maxval; ++sampleVal) - sum += hist[sampleVal]; - - return sum; + *histP = hist; } static void -findQuantiles(unsigned int const n, - unsigned int const hist[], - gray const maxval, - gray * const quantile) { +findQuantiles(unsigned int const n, + unsigned long int const hist[], + unsigned long int const totalCt, + gray const mmaxval, + gray * const quantile) { /*---------------------------------------------------------------------------- Find the order-n quantiles (e.g. n == 4 means quartiles) of the pixel sample values, given that hist[] is the histogram of them (hist[N] is the number of pixels that have sample value N). - 'maxval' is the maxval of the image, so the size of hist[] is 'maxval' + 1. + 'mmaxval' is the highest index in hist[] (so its size is 'mmaxval' + 1, + and there are no pixels greater than 'mmaxval' in the image). We return the ith quantile as quantile[i]. For example, for quartiles, quantile[3] is the least sample value for which at least 3/4 of the pixels - are less than or equal to it. + are less than or equal to it. quantile[] must be allocated at least to size 'n'. - We return + 'n' must not be more than 100. -----------------------------------------------------------------------------*/ - unsigned int const totalCt = sum(hist, maxval); - unsigned int quantSeq; /* 0 is first quantile, 1 is second quantile, etc. */ @@ -183,9 +211,9 @@ findQuantiles(unsigned int const n, cumCt = hist[0]; /* initial value */ for (quantSeq = 1; quantSeq <= n; ++quantSeq) { - unsigned long int const q = totalCt/n; - unsigned long int const r = totalCt%n; - unsigned long int const quantCt = q*quantSeq + (r*quantSeq +n -1)/n; + unsigned long int const q = totalCt / n; + unsigned long int const r = totalCt % n; + unsigned long int const quantCt = q*quantSeq + (r*quantSeq + n - 1)/n; /* This is how many pixels are (ignoring quantization) in the quantile. E.g. for the 3rd quartile, it is 3/4 of the pixels in the image. @@ -195,14 +223,11 @@ findQuantiles(unsigned int const n, for preventing overflow for slight innacuracies in floating point arithmetic causes problems when used as loop counter and array index. - - The maximum value for n is currently 10; in the future this - may be brought up to 100. */ assert(quantCt <= totalCt); - /* at sampleVal == maxval, cumCt == totalCt, so because - quantCt <= 'totalCt', 'sampleVal' cannot go above maxval. + /* at sampleVal == mmaxval, cumCt == totalCt, so because + quantCt <= 'totalCt', 'sampleVal' cannot go above mmaxval. */ while (cumCt < quantCt) { @@ -210,7 +235,7 @@ findQuantiles(unsigned int const n, cumCt += hist[sampleVal]; } - assert(sampleVal <= maxval); + assert(sampleVal <= mmaxval); /* 'sampleVal' is the lowest sample value for which at least 'quantCt' pixels have that sample value or less. 'cumCt' is the number @@ -223,9 +248,10 @@ findQuantiles(unsigned int const n, static void -countCumulative(unsigned int const hist[], - gray const maxval, - unsigned int ** const rcountP) { +countCumulative(unsigned long int const hist[], + gray const mmaxval, + unsigned long int const totalPixelCt, + unsigned long int ** const rcountP) { /*---------------------------------------------------------------------------- From the histogram hist[] (hist[N] is the number of pixels of sample value N), compute the cumulative distribution *rcountP ((*rcountP)[N] @@ -233,17 +259,17 @@ countCumulative(unsigned int const hist[], *rcountP is newly malloced memory. -----------------------------------------------------------------------------*/ - unsigned int * rcount; - unsigned int cumCount; + unsigned long int * rcount; + unsigned long int cumCount; int i; - - MALLOCARRAY(rcount, maxval + 1); + + MALLOCARRAY(rcount, mmaxval + 1); if (rcount == NULL) pm_error("out of memory"); - for (i = maxval, cumCount = 0; i >= 0; --i) { + for (i = mmaxval, cumCount = 0; i >= 0; --i) { /* Because total pixels in image is limited: */ - assert(UINT_MAX - hist[i] >= cumCount); + assert(ULONG_MAX - hist[i] >= cumCount); cumCount += hist[i]; rcount[i] = cumCount; @@ -255,11 +281,11 @@ countCumulative(unsigned int const hist[], static void -reportHistHumanFriendly(unsigned int const hist[], - unsigned int const rcount[], - gray const maxval) { +reportHistHumanFriendly(unsigned long int const hist[], + unsigned long int const rcount[], + gray const maxval) { - unsigned int const totalPixels = rcount[0]; + unsigned long int const totalPixelCt = rcount[0]; unsigned int cumCount; unsigned int i; @@ -271,9 +297,48 @@ reportHistHumanFriendly(unsigned int const hist[], if (hist[i] > 0) { cumCount += hist[i]; printf( - "%5d %5d %5.3g%% %5.3g%%\n", i, hist[i], - (float) cumCount * 100.0 / totalPixels, - (float) rcount[i] * 100.0 / totalPixels); + "%5d %5ld %5.3g%% %5.3g%%\n", i, hist[i], + (float) cumCount * 100.0 / totalPixelCt, + (float) rcount[i] * 100.0 / totalPixelCt); + } + } +} + + +static void +reportHistForensicHumanFriendly(unsigned long int const hist[], + unsigned long int const rcount[], + gray const maxval, + gray const mmaxval) { + + unsigned long int const totalPixelCt = rcount[0]; + + unsigned long int cumCount; + unsigned int i; + + printf("value count b%% w%% \n"); + printf("----- ----- ------ ------\n"); + + for (i = 0, cumCount = 0; i <= maxval; ++i) { + if (hist[i] > 0) { + cumCount += hist[i]; + printf( + "%5d %5ld %5.3g%% %5.3g%%\n", i, hist[i], + (float) cumCount * 100.0 / totalPixelCt, + (float) rcount[i] * 100.0 / totalPixelCt); + } + } + if (totalPixelCt > cumCount) { + printf("----- -----\n"); + + for (i = maxval; i <= mmaxval; ++i) { + if (hist[i] > 0) { + cumCount += hist[i]; + printf( + "%5d %5ld %5.3g%% %5.3g%%\n", i, hist[i], + (float) cumCount * 100.0 / totalPixelCt, + (float) rcount[i] * 100.0 / totalPixelCt); + } } } } @@ -281,13 +346,13 @@ reportHistHumanFriendly(unsigned int const hist[], static void -reportHistMachineFriendly(unsigned int const hist[], - gray const maxval) { +reportHistMachineFriendly(unsigned long int const hist[], + gray const maxval) { unsigned int i; for (i = 0; i <= maxval; ++i) { - printf("%u %u\n", i, hist[i]); + printf("%u %lu\n", i, hist[i]); } } @@ -345,60 +410,132 @@ reportDecilesHumanFriendly(gray const decile[]) { -int -main(int argc, const char ** argv) { +static void +summarizeInvalidPixels(unsigned long int const hist[], + unsigned long int const rcount[], + gray const mmaxval, + gray const maxval) { +/*---------------------------------------------------------------------------- + Print total count of valid and invalid pixels, if there are any + invalid ones. +-----------------------------------------------------------------------------*/ + unsigned long int const invalidPixelCt = + mmaxval > maxval ? rcount[maxval+1] : 0; + + if (invalidPixelCt > 0) { + unsigned long int const totalPixelCt = rcount[0]; + unsigned long int const validPixelCt = totalPixelCt - invalidPixelCt; + + printf("\n"); + printf("** Image stream contains invalid sample values " + "(above maxval %u)\n", maxval); + printf("Valid sample values: %lu (%5.4g%%)\n", + validPixelCt, (float)validPixelCt / totalPixelCt * 100.0); + printf("Invalid sample values: %lu (%5.4g%%)\n", + invalidPixelCt, (float)invalidPixelCt / totalPixelCt * 100.0); + } +} - struct cmdline_info cmdline; - FILE * ifP; - gray maxval; - unsigned int * hist; /* malloc'ed array */ - pm_proginit(&argc, argv); - parseCommandLine(argc, argv, &cmdline); +static void +reportFromHistogram(const unsigned long int * const hist, + gray const mmaxval, + gray const maxval, + unsigned long int const totalPixelCt, + struct CmdlineInfo const cmdline) { +/*---------------------------------------------------------------------------- + Analyze histogram 'hist', which has 'mmaxval' buckets, and report + what we find. - ifP = pm_openr(cmdline.inputFileName); + 'maxval' is the maxval that the image states (but note that we tolerate + invalid sample values greater than maxval, which could be as high as + 'mmaxval'). - buildHistogram(ifP, &hist, &maxval); + 'cmdline' tells what kind of reporting to do. +-----------------------------------------------------------------------------*/ if (cmdline.median) { gray median[2]; - findQuantiles(2, hist, maxval, median); + findQuantiles(2, hist, totalPixelCt, mmaxval, median); if (cmdline.machine) reportQuantilesMachineFriendly(median, 1); else reportMedianHumanFriendly(median[0]); } else if (cmdline.quartile) { gray quartile[4]; - findQuantiles(4, hist, maxval, quartile); + findQuantiles(4, hist, totalPixelCt, mmaxval, quartile); if (cmdline.machine) reportQuantilesMachineFriendly(quartile, 4); else reportQuartilesHumanFriendly(quartile); } else if (cmdline.decile) { gray decile[10]; - findQuantiles(10, hist, maxval, decile); + findQuantiles(10, hist, totalPixelCt, mmaxval, decile); if (cmdline.machine) reportQuantilesMachineFriendly(decile, 10); else reportDecilesHumanFriendly(decile); } else { if (cmdline.machine) - reportHistMachineFriendly(hist, maxval); + reportHistMachineFriendly(hist, mmaxval); else { - unsigned int * rcount; /* malloc'ed array */ - countCumulative(hist, maxval, &rcount); - reportHistHumanFriendly(hist, rcount, maxval); + unsigned long int * rcount; /* malloc'ed array */ + countCumulative(hist, mmaxval, totalPixelCt, &rcount); + if (cmdline.forensic) + reportHistForensicHumanFriendly(hist, rcount, maxval, mmaxval); + else + reportHistHumanFriendly(hist, rcount, maxval); + + summarizeInvalidPixels(hist, rcount, mmaxval, maxval); free(rcount); } } +} + + + +int +main(int argc, const char ** argv) { + + struct CmdlineInfo cmdline; + FILE * ifP; + int rows, cols; + int format; + gray maxval; + /* Stated maxval of the image */ + gray mmaxval; + /* Maxval we assume, which may be greater than the stated maxval + so that we can process invalid pixels in the image that exceed + the maxval. + */ + unsigned long int totalPixelCt; + unsigned long int * hist; /* malloc'ed array */ + + pm_proginit(&argc, argv); + + parseCommandLine(argc, argv, &cmdline); + + ifP = pm_openr(cmdline.inputFileName); + + pgm_readpgminit(ifP, &cols, &rows, &maxval, &format); + + if (ULONG_MAX / cols < rows) + pm_error("Too many pixels (%u x %u) in image. " + "Maximum computable is %lu", + cols, rows, ULONG_MAX); + + totalPixelCt = cols * rows; + + mmaxval = cmdline.forensic ? universalMaxval(maxval, format) : maxval; + + buildHistogram(ifP, format, cols, rows, mmaxval, &hist); + + reportFromHistogram(hist, mmaxval, maxval, totalPixelCt, cmdline); free(hist); pm_close(ifP); return 0; } - - - diff --git a/analyzer/ppmhist.c b/analyzer/ppmhist.c index 2f6c9348..cc47bb82 100644 --- a/analyzer/ppmhist.c +++ b/analyzer/ppmhist.c @@ -20,17 +20,18 @@ enum sort {SORT_BY_FREQUENCY, SORT_BY_RGB}; -enum colorFmt {FMT_DECIMAL, FMT_HEX, FMT_FLOAT, FMT_PPMPLAIN}; +enum ColorFmt {FMT_DECIMAL, FMT_HEX, FMT_FLOAT, FMT_PPMPLAIN}; struct cmdline_info { /* All the information the user supplied in the command line, in a form easy for the program to use. */ const char * inputFileName; /* Name of input file */ - unsigned int noheader; /* -noheader option */ - enum colorFmt colorFmt; - unsigned int colorname; /* -colorname option */ - enum sort sort; /* -sort option */ + unsigned int noheader; + enum ColorFmt colorFmt; + unsigned int colorname; + enum sort sort; + unsigned int forensic; }; @@ -45,7 +46,7 @@ parseCommandLine(int argc, const char ** argv, optStruct3 opt; /* set by OPTENT3 */ optEntry * option_def; unsigned int option_def_index; - + unsigned int hexcolorOpt, floatOpt, mapOpt, nomapOpt; const char * sort_type; @@ -59,6 +60,7 @@ parseCommandLine(int argc, const char ** argv, OPTENT3(0, "float", OPT_FLAG, NULL, &floatOpt, 0); OPTENT3(0, "colorname", OPT_FLAG, NULL, &cmdlineP->colorname, 0); OPTENT3(0, "sort", OPT_STRING, &sort_type, NULL, 0); + OPTENT3(0, "forensic", OPT_FLAG, NULL, &cmdlineP->forensic, 0); opt.opt_table = option_def; opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ @@ -69,8 +71,9 @@ parseCommandLine(int argc, const char ** argv, pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + free(option_def); - if (argc-1 == 0) + if (argc-1 == 0) cmdlineP->inputFileName = "-"; else if (argc-1 != 1) pm_error("Program takes zero or one argument (filename). You " @@ -84,9 +87,12 @@ parseCommandLine(int argc, const char ** argv, cmdlineP->colorFmt = FMT_HEX; else if (floatOpt) cmdlineP->colorFmt = FMT_FLOAT; - else if (mapOpt) + else if (mapOpt) { + if (cmdlineP->forensic) + pm_error("You cannot specify -map and -forensic together"); + cmdlineP->colorFmt = FMT_PPMPLAIN; - else + } else cmdlineP->colorFmt = FMT_DECIMAL; if (strcmp(sort_type, "frequency") == 0) @@ -161,8 +167,137 @@ rgbcompare(const void * const a, +static pixval +universalMaxval(pixval const maxval, + int const format) { +/*---------------------------------------------------------------------------- + A maxval that makes it impossible for a pixel to be invalid in an image that + states it maxval as 'maxval' and has format 'format'. + + E.g. in a one-byte-per-sample image, it's not possible to read a sample + value greater than 255, so a maxval of 255 makes it impossible for a sample + to be invalid. + + But: we never go above 65535, which means our maxval isn't entirely + universal. If the image is plain PPM, it could contain a pixel that + exceeds even that. +-----------------------------------------------------------------------------*/ + assert(0 < maxval && maxval < 65536); + + if (format == RPPM_FORMAT || format == RPGM_FORMAT) { + /* Raw PPM stream has either one or two bytes per pixel, depending + upon its stated maxval. + */ + if (maxval > 255) + return 65535; + else + return 255; + } else if (format == RPBM_FORMAT) { + /* A Raw PBM stream has one bit per pixel, which libnetpbm renders + as 0 or 255 when we read it. + */ + assert(maxval == 255); + return 255; + } else { + /* A plain PPM stream has essentially unlimited range in the + tokens that are supposed to be sample values. We arbitrarily draw + the line at 65535. + */ + return 65535; + } +} + + + +static bool +colorIsValid(pixel const color, + pixval const maxval) { + + pixval const r = PPM_GETR(color); + pixval const g = PPM_GETG(color); + pixval const b = PPM_GETB(color); + + return r <= maxval && g <= maxval && b <= maxval; +} + + + +static void +separateInvalidItems(colorhist_vector const chv, + colorhist_vector const chvInvalid, + pixval const maxval, + unsigned int const colorCt, + unsigned int * const validColorCtP) { +/*---------------------------------------------------------------------------- + Move invalid color entries from chv to chvInvalid. + Count how many color entries are valid. +-----------------------------------------------------------------------------*/ + unsigned int i; + unsigned int validCt; + unsigned int invalidCt; + + for (i = 0, validCt = 0, invalidCt = 0; i < colorCt; ++i) { + if (!colorIsValid(chv[i].color, maxval)) + chvInvalid[invalidCt++] = chv[i]; + else + chv[validCt++] = chv[i]; + } + *validColorCtP = validCt; +} + + + +static void +sortHistogramForensic(enum sort const sortFn, + colorhist_vector const chv, + colorhist_vector const chvInvalid, + pixval const maxval, + unsigned int const colorCt, + unsigned int * const validColorCtP) { + + unsigned int validColorCt; + + separateInvalidItems(chv, chvInvalid, maxval, colorCt, &validColorCt); + + { + int (*compare_function)(const void *, const void *); + + switch (sortFn) { + case SORT_BY_FREQUENCY: compare_function = countcompare; break; + case SORT_BY_RGB: compare_function = rgbcompare; break; + } + + qsort((void*) chv, validColorCt, + sizeof(struct colorhist_item), compare_function); + + qsort((void*) chvInvalid, colorCt - validColorCt, + sizeof(struct colorhist_item), compare_function); + } + *validColorCtP = validColorCt; +} + + + +static void +sortHistogramNormal(enum sort const sortFn, + colorhist_vector const chv, + unsigned int const colorCt) { + + int (*compare_function)(const void *, const void *); + + switch (sortFn) { + case SORT_BY_FREQUENCY: compare_function = countcompare; break; + case SORT_BY_RGB: compare_function = rgbcompare; break; + } + + qsort((void*) chv, colorCt, sizeof(struct colorhist_item), + compare_function); +} + + + static const char * -colornameLabel(pixel const color, +colornameLabel(pixel const color, pixval const maxval, unsigned int const nDictColor, pixel const dictColors[], @@ -172,15 +307,15 @@ colornameLabel(pixel const color, dictionary to it. If the name returned is not the exact color, prefix it with "*". Otherwise, prefix it with " ". - 'nDictColor', dictColors[], and dictColorNames[] are the color + 'nDictColor', dictColors[], and dictColorNames[] are the color dictionary. Return the name in static storage within this subroutine. -----------------------------------------------------------------------------*/ static char retval[32]; int colorIndex; - - pixel color255; + + pixel color255; /* The color, normalized to a maxval of 255: the maxval of a color dictionary. */ @@ -190,31 +325,31 @@ colornameLabel(pixel const color, colorIndex = ppm_findclosestcolor(dictColors, nDictColor, &color); assert(colorIndex >= 0 && colorIndex < nDictColor); - + if (PPM_EQUAL(dictColors[colorIndex], color)) STRSCPY(retval, " "); else STRSCPY(retval, "*"); - + STRSCAT(retval, dictColornames[colorIndex]); - + return retval; } - + static void -printColors(colorhist_vector const chv, - int const nColors, +printColors(colorhist_vector const chv, + int const colorCt, pixval const maxval, - enum colorFmt const colorFmt, + enum ColorFmt const colorFmt, unsigned int const nKnown, pixel const knownColors[], const char * const colornames[]) { int i; - for (i = 0; i < nColors; i++) { + for (i = 0; i < colorCt; i++) { pixval const r = PPM_GETR(chv[i].color); pixval const g = PPM_GETG(chv[i].color); pixval const b = PPM_GETB(chv[i].color); @@ -226,7 +361,7 @@ printColors(colorhist_vector const chv, const char * colornameValue; if (colornames) - colornameValue = colornameLabel(chv[i].color, maxval, + colornameValue = colornameLabel(chv[i].color, maxval, nKnown, knownColors, colornames); else colornameValue = ""; @@ -257,23 +392,97 @@ printColors(colorhist_vector const chv, +static void +summarizeInvalidPixels(unsigned long int const validPixelCt, + unsigned long int const invalidPixelCt, + pixval const maxval) { +/*---------------------------------------------------------------------------- + Print total count of valid and invalid pixels, if there are any + invalid ones. +-----------------------------------------------------------------------------*/ + if (invalidPixelCt > 0) { + unsigned long int const totalPixelCt = validPixelCt + invalidPixelCt; + + printf("\n"); + printf("** Image stream contains invalid sample values " + "(above maxval %u)\n", maxval); + printf("** Valid sample values : %lu (%5.4g%%)\n", + validPixelCt, (float) validPixelCt / totalPixelCt * 100.0); + printf("** Invalid sample values : %lu (%5.4g%%)\n", + invalidPixelCt, (float) invalidPixelCt / totalPixelCt * 100.0); + } +} + + + +static void +printInvalidSamples(colorhist_vector const chv, + colorhist_vector const chvInvalid, + int const totalColorCt, + unsigned int const validColorCt, + pixval const maxval, + enum ColorFmt const colorFmt) { + + unsigned int const invalidColorCt = totalColorCt - validColorCt; + + unsigned int i; + unsigned long int validPixelCt; + unsigned long int invalidPixelCt; + + for (i = 0, validPixelCt = 0; i < validColorCt; ++i) + validPixelCt += chv[i].value; + + for (i = 0, invalidPixelCt = 0; i < invalidColorCt; ++i) { + pixval const r = PPM_GETR(chvInvalid[i].color); + pixval const g = PPM_GETG(chvInvalid[i].color); + pixval const b = PPM_GETB(chvInvalid[i].color); + unsigned int const count = chvInvalid[i].value; + + invalidPixelCt += chvInvalid[i].value; + + switch(colorFmt) { + case FMT_FLOAT: + printf(" %1.3f %1.3f %1.3f\t\t%7d\n", + (double)r / maxval, + (double)g / maxval, + (double)b / maxval, + count); + break; + case FMT_HEX: + printf(" %04x %04x %04x\t\t%7d\n", + r, g, b, count); + break; + case FMT_DECIMAL: + printf(" %5d %5d %5d\t\t%7d\n", + r, g, b, count); + break; + case FMT_PPMPLAIN: + assert(false); + break; + } + } + + summarizeInvalidPixels(validPixelCt, invalidPixelCt, maxval); +} + + + int main(int argc, const char *argv[]) { struct cmdline_info cmdline; FILE * ifP; colorhist_vector chv; + colorhist_vector chvInvalid; int rows, cols; pixval maxval; + pixval mmaxval; int format; - int nColors; - int (*compare_function)(const void *, const void *); - /* The compare function to be used with qsort() to sort the - histogram for output - */ - unsigned int nDictColor; + int colorCt; + unsigned int dictColorCt; const char ** dictColornames; pixel * dictColors; + unsigned int validColorCt; pm_proginit(&argc, argv); @@ -283,23 +492,29 @@ main(int argc, const char *argv[]) { ppm_readppminit(ifP, &cols, &rows, &maxval, &format); - chv = ppm_computecolorhist2(ifP, cols, rows, maxval, format, 0, &nColors); + mmaxval = cmdline.forensic ? universalMaxval(maxval, format) : maxval; + + chv = ppm_computecolorhist2(ifP, cols, rows, mmaxval, format, 0, &colorCt); pm_close(ifP); - switch (cmdline.sort) { - case SORT_BY_FREQUENCY: - compare_function = countcompare; break; - case SORT_BY_RGB: - compare_function = rgbcompare; break; - } + /* Sort and produce histogram. */ + if (cmdline.forensic) { + MALLOCARRAY(chvInvalid, colorCt); + if (chvInvalid == NULL) + pm_error("out of memory generating histogram"); - qsort((char*) chv, nColors, sizeof(struct colorhist_item), - compare_function); + sortHistogramForensic(cmdline.sort, chv, chvInvalid, + maxval, colorCt, &validColorCt); + } else { + chvInvalid = NULL; + sortHistogramNormal(cmdline.sort, chv, colorCt); + validColorCt = colorCt; + } /* And print the histogram. */ - if (cmdline.colorFmt == FMT_PPMPLAIN) - printf("P3\n# color map\n%d 1\n%d\n", nColors, maxval); + if (cmdline.colorFmt == FMT_PPMPLAIN) + printf("P3\n# color map\n%d 1\n%d\n", colorCt, maxval); if (!cmdline.noheader) { const char commentDelim = cmdline.colorFmt == FMT_PPMPLAIN ? '#' : ' '; @@ -309,16 +524,20 @@ main(int argc, const char *argv[]) { commentDelim, cmdline.colorname ? "----" : ""); } if (cmdline.colorname) { - bool mustOpenTrue = TRUE; - ppm_readcolordict(NULL, mustOpenTrue, - &nDictColor, &dictColornames, &dictColors, NULL); + bool const mustOpenTrue = TRUE; + ppm_readcolordict(NULL, mustOpenTrue, + &dictColorCt, &dictColornames, &dictColors, NULL); } else { dictColors = NULL; dictColornames = NULL; } - - printColors(chv, nColors, maxval, - cmdline.colorFmt, nDictColor, dictColors, dictColornames); + + printColors(chv, validColorCt, maxval, + cmdline.colorFmt, dictColorCt, dictColors, dictColornames); + + if (colorCt > validColorCt) + printInvalidSamples(chv, chvInvalid, colorCt, validColorCt, + maxval, cmdline.colorFmt); if (dictColors) free(dictColors); @@ -327,5 +546,11 @@ main(int argc, const char *argv[]) { ppm_freecolorhist(chv); + if (chvInvalid) + ppm_freecolorhist(chvInvalid); + return 0; } + + + diff --git a/buildtools/README.pkg b/buildtools/README.pkg index e544cbb7..f098e04b 100644 --- a/buildtools/README.pkg +++ b/buildtools/README.pkg @@ -111,15 +111,26 @@ The parts to be installed are: One of the Netpbm programs is Manweb, which is designed to be a - replacement for the classic Man program that can access both - traditional man pages and worldwide web documentation in the - Netpbm style with the familiar 'man jpegtopnm' kind of command. - To set up your system for this, you will have to be sure to create - the /usr/man/web directory, with 'netpbm.url' in it. Also, If you - install Manweb as 'man', there is no point to installing the + replacement for the classic Man program that can access both traditional + man pages and worldwide web documentation in the Netpbm style with the + familiar 'man jpegtopnm' kind of command. The package contains the files + necessary to use Manweb to access Netpbm documention on the web (on + netpbm.sourceforge.net). These files are the contents of the man/web + directory and the file 'bin/doc.url'. You should install the + 'bin/doc.url' file if you are installing the Netpbm executables in a + directory all their own. You should install the 'man/web' files if you + are installing the Netpbm executables in some global directory such as + 'usr/bin'. You should install neither of these if you don't intend to use + Manweb. + + If you install Manweb as 'man', there is no point to installing the pointer man pages -- they will never be used. - + If you want to use Manweb to view the Netpbm manual but use a local + copy of the manual instead of accessing it on the web, you can get the + HTML files from the Sourceforge Subversion repository and install those + instead of the .url files that appear in the 'man/web' directory of the + package. The instructions above suggest putting the Netpbm parts in common directories such as /usr/bin, mingled with other packages. This is @@ -134,21 +145,34 @@ entire installation when you don't want it anymore, and to keep multiple versions around. -netpbm.config +netpbm.pkgconfig +---------------- + +You should create a file named 'netpbm.pkgconfig' out of the template file +'pkgconfig_template' in the package directory, and install netpbm.pkgconfig in +your pkg-config directory (typically /usr/lib/pkgconfig). Programs that want +to find out where you installed some part of Netpbm can use a 'pkg-config +netpbm ...' command to find out. For example, a make file for a program that +uses the Netpbm programming library might use this facility to generate the +necessary compiler and linker options to access that library. + +The pkg-config facility is fairly widely used, especially with things related +to the X Window System. + + +netpbm-config ------------- -You should create a shell script named 'netpbm.config' out of the -template file 'config_template' in the package directory, and install -netpbm.config in your executable search path. Programs that want to -find out where you installed some part of Netpbm can invoke -netpbm.config and it will tell them. For example, a make file for a -program that uses the Netpbm programming library might use -netpbm.config to generate the necessary compiler and linker options to -access that library. - -Using netpbm.config, it's possible to have a viable Netpbm -installation where netpbm.config is the only file in any default -search path. - -The xxx.config file concept is a relatively new but growing convention, -seen mostly in software related to the X Window System. +You should create a shell script named 'netpbm-config' out of the template +file 'config_template' in the package directory, and install netpbm-config in +your executable search path. Programs that want to find out where you +installed some part of Netpbm can invoke netpbm-config and it will tell them. +For example, a make file for a program that uses the Netpbm programming +library might use netpbm-config to generate the necessary compiler and linker +options to access that library. + +Using netpbm-config, it's possible to have a viable Netpbm installation where +netpbm.config is the only file in any default search path. + +The xxx-config concept (in general, not just Netpbm) has largely been replaced +by the pkg-config concept (see netpbm.pkgconfig above). diff --git a/buildtools/configure.pl b/buildtools/configure.pl index b03630d8..d4e9bee3 100755 --- a/buildtools/configure.pl +++ b/buildtools/configure.pl @@ -353,7 +353,7 @@ sub testCompile($$$) { sub testCompileLink($$$) { my ($flags, $cSourceCodeR, $successR) = @_; #----------------------------------------------------------------------------- -# Do a test compile of the program in @{$cSourceCodeR}. +# Do a test compile and link of the program in @{$cSourceCodeR}. # # Return $$successR == $TRUE iff the compile succeeds (exit code 0). #----------------------------------------------------------------------------- @@ -1629,6 +1629,56 @@ sub testJpegHdr($) { +sub warnJpegNotInDefaultPath($) { + my ($jpegLib) = @_; + + print("You said your JPEG library is '$jpegLib', which says it is " + . "in the linker's default search path, but a test link we did " + . "failed as if it is not. If it isn't, the build will fail\n"); +} + + + +sub testJpegLink($) { + my ($jpegLib) = @_; +#----------------------------------------------------------------------------- +# See if we can link the JPEG library with the information user gave us. +# $jpegLib is the answer to the "what is your JPEG library" prompt, so +# it is either a library file name such as "libjpeg.so", in the linker's +# default search path, or it is an absolute path name such as +# "/usr/jpeg/lib/libjpeg.so". +# +# We actually test only the default search path case, since users often +# incorrectly specify that by taking the default. +#----------------------------------------------------------------------------- + if ($jpegLib =~ m{( lib | cyg ) (.+) \. ( so | a )$}x) { + my $libName = $2; + + # It's like "libjpeg.so", so is a library in the default search path. + # $libName is "jpeg" in this example. + + # First we test our test tool. We can do this only with GCC. + + my @emptySource; + + testCompileLink('-nostartfiles', \@emptySource, \my $controlWorked); + + if ($controlWorked) { + # The "control" case worked. Now see if it still works when we add + # the JPEG library. + + testCompileLink("-nostartfiles -l$libName", \@emptySource, + \my $workedWithJpeg); + + if (!$workedWithJpeg) { + warnJpegNotInDefaultPath($jpegLib); + } + } + } +} + + + sub testCompileZlibH($$) { my ($cflags, $successR) = @_; #----------------------------------------------------------------------------- @@ -1895,6 +1945,8 @@ sub testConfiguration($$$$$$) { if (defined($jpeglib)) { testJpegHdr($jpeghdr_dir); + + testJpegLink($jpeglib); } if (defined($pnglib) && defined($zlib)) { testPngHdr($pnghdr_dir, $zhdr_dir); @@ -2289,7 +2341,7 @@ if ($platform eq "GNU") { # only Ppmtompeg and it isn't clear that using long instead of int is # ever right anyway. - push(@config_mk, "OMIT_NETWORK = y\n"); + push(@config_mk, "OMIT_NETWORK = Y\n"); push(@config_mk, "LINKER_CAN_DO_EXPLICIT_LIBRARY=Y\n"); } elsif ($platform eq "IRIX") { # push(@config_mk, "INSTALL = install\n"); @@ -2303,7 +2355,7 @@ if ($platform eq "GNU") { makeCompilerGcc(\@config_mk); } push(@config_mk, "EXE = .exe\n"); - push(@config_mk, "OMIT_NETWORK = y\n"); + push(@config_mk, "OMIT_NETWORK = Y\n"); # # Though it may not have the link as "ginstall", "install" in a Windows # # Unix environment is usually GNU install. # my $ginstall_result = `ginstall --version 2>/dev/null`; diff --git a/buildtools/debian/README b/buildtools/debian/README new file mode 100644 index 00000000..1c600c6b --- /dev/null +++ b/buildtools/debian/README @@ -0,0 +1,122 @@ +Files in this directory are for creating a Debian package (.deb file), +which one can use to install Netpbm on a Debian system (or a system running +a derivative of Debian, such as Ubuntu or Mint). + +You can of course install on one of these systems by running 'installnetpbm', +or otherwise inserting all the files in the proper place in your system file +tree, but having a Debian package allows you to manage those files using +Debian's normal package management. The package management system will know +where the Netpbm files came from, and you can upgrade or remove Netpbm easily. +The package management system will also be aware of prerequisites of Netpbm +and ensure that you don't have Debian's own inferior version of Netpbm +installed (which would cause conflicts). + +The package we create is named 'netpbm-sf' (where the "sf" is from +"SourceForge"), to be distinct from the package named "netpbm" which is part +of Debian. + +To install Netpbm as a Debian package: + + 1) Follow the regular instructions to build and package Netpbm + (configure, make, make package). + + 2) With the root of the built Netpbm build tree as your current + directory: + + $ make deb + + (This defaults to getting Netpbm from /tmp/netpbm, which is also where + 'make package' defaults to putting it). + + 3) $ dpkg --install netpbm-sfXXXX.deb + + (netpbm-sfXXXX.deb is the file created by 'makedeb', in the current + directory). + + +PREREQUSISITES +-------------- + +The following information was taken from the Wheezy version of Debian, in +January 2014. + +You don't actually need the current version of any of these. For example, +while we list package libjpeg8-dev, the package libjpeg62-dev works fine. + + +Building +-------- + +You need the following Debian packages to build all of Netpbm. + +You could omit some of these and, in the Netpbm build configuration dialog, +indicate you don't have them, and the build will simply omit some parts. +For example, if you don't install libx11-dev, the Netpbm build process +will not build the 'pamx' program. + + libjpeg8-dev + libpng12-0-dev + libsvga1-dev + libtiff5-dev + libx11-dev + libxml2a-dev + zlib1g-dev + + +In addition, you need the following build tools: + + make + gcc + flex + perl + pkg-config + + + +Running +------- + +The following Debian packages are the known prerequisites for running Netpbm +(and the package created by 'mkdeb' knows this). + + libc6 + libjpeg8 + libpng12-0 + libsvga1 + libtiff5 + libx11-6 + zlib1g + ghostscript + perl + perl-base + bash + +Note that many of these are needed only for a few parts of Netpbm, and it will +be pretty obvious what the problem is when you need the prerequisite package +and don't have it, so if you don't want to install a prerequisite, it would +probably be fine to force install Netpbm, ignoring the prerequisites. + + +CONFLICTS WITH DEBIAN'S NETPBM +------------------------------ + +Debian has several packages of Netpbm, all based on a slightly modified +Sourceforge Netpbm 9.25 from 2002 (don't be confused by Debian's numbering +system, which makes it look like it is Netpbm 10). If you want to install +Sourceforge Netpbm on your system, you will want first to remove any of these +you have installed: + + netpbm + netpbm-dev + libnetpbm9 + libnetpbm10 + +Sourceforge Netpbm should be backward compatible with all of those. Note that +'mkdeb' makes only one package. It contains the programs, the runtime +libraries, and the development files. + +We have not yet worked out what has to be done about the fact that the Debian +packaging system thinks the Debian Netpbm packages are prerequisites for +things. If you install Sourceforge Netpbm via the package created by mkdeb, +you should tell the Netpbm maintainer whatever you learn about that. + diff --git a/buildtools/debian/mkdeb b/buildtools/debian/mkdeb new file mode 100755 index 00000000..9c7b1735 --- /dev/null +++ b/buildtools/debian/mkdeb @@ -0,0 +1,541 @@ +#!/usr/bin/perl +############################################################################### +# mkdeb +############################################################################### +# +# This generates a Debian packge file (.deb) to install Sourceforge +# Netpbm on a Debian system. +# +# This is especially useful because Debian does not have a good Debian +# package (what Debian contains is derived from Sourceforge Netpbm ca. +# 2002). +# +############################################################################### + +use strict; +use warnings; +use English; +use Getopt::Long; + +my $TRUE=1; my $FALSE = 0; + + + +sub parseCommandLine(@) { + + local @ARGV = @_; # GetOptions takes input from @ARGV only + + my %cmdline; + + my $validOptions = GetOptions(\%cmdline, + "buildtools=s", + "arch=s", + "pkgdir=s", + ); + + if (!$validOptions) { + print(STDERR "Invalid option syntax.\n"); + exit(1); + } + if (@ARGV > 0) { + print(STDERR "This program takes no non-option arguments. " . + "You specified ", + scalar(@ARGV), "\n"); + exit(1); + } + + return(\%cmdline); +} + + + +sub writeFile($$$$) { + my ($fileLinesR, $fileName, $executable, $errorR) = @_; + + my $success = open(FILE, ">$fileName"); + if ($success) { + if ($executable eq 'EXECUTABLE') { + chmod(0755, $fileName); + } else { + chmod(0644, $fileName); + } + foreach (@{$fileLinesR}) { print FILE; } + close(FILE); + } else { + $$errorR = "Unable to open the file " . + "'$fileName' for writing. Errno=$ERRNO\n"; + } +} + + + +sub netpbmVersion($) { + my ($pkgdir) = @_; + + my $versionFileName = "$pkgdir/VERSION"; + + my $versionOpened = open(VERSION, "<$versionFileName"); + + my $retval; + my $error; + + if (!$versionOpened) { + $error = "Unable to open '$versionFileName' for reading. " . + "Errno=$ERRNO\n"; + } else { + my $version = <VERSION>; + chomp($version); + + if ($version =~ m{^Netpbm (\S*)}) { + my ($versionNumber) = ($1); + $retval = $versionNumber; + } else { + die("Can't understand format of '$versionFileName': '$version'"); + } + close(VERSION); + } + + if ($error) { + print("Failed to determine the version of Netpbm from the package, " + . "so that will not be correct in netpbm.config and netpbm.pc. " + . $error . "\n"); + $retval = "???"; + } + return $retval; +} + + + +sub control($$) { + my ($release, $architecture) = @_; + +# The Debian packaging system doesn't provide a way to express Netpbm's actual +# prerequisites. For example, Netpbm needs Version 6.2 or better of Libjpeg, +# but there is no way to state that here. Instead, we state Libjpeg 8. +# This makes the Netpbm package less useful. + + my %control; + + my $debianNativeNetpbm = + 'netpbm, ' . + 'libnetpbm10, ' . + 'libnetpbm10-dev, ' . + 'netpbm-dev, ' . + 'netpbm-nonfree, ' . + 'pbmwbmp, ' . + 'pnmtopng, ' . + 'ucbmpeg'; + + $control{'Package'} = 'netpbm-sf'; + $control{'Version'} = $release; + $control{'Architecture'} = $architecture; + $control{'Maintainer'} = 'Bryan Henderson <bryanh@giraffe-data.com>'; + $control{'Installed-Size'} = '6164'; + $control{'Depends'} = + 'libc6, ' . + 'libjpeg8, ' . + 'libpng12-0, ' . + 'libsvga1, ' . + 'libtiff5, ' . + 'libx11-6, ' . + 'libxml2a, ' . + 'zlib1g, ' . + 'ghostscript, ' . + 'perl, ' . + 'perl-base, ' . + 'bash' + ; + $control{'Recommends'} = ''; + $control{'Recommends'} = ''; + $control{'Conflicts'} = $debianNativeNetpbm; + $control{'Replaces'} = $debianNativeNetpbm; + $control{'Provides'} = + 'netpbm, ' . + 'pbmwbmp, ' . + 'pnmtopng, ' . + 'netpbm-dev, ' . + 'libnetpbm10' + ; + $control{'Section'} = 'graphics'; + $control{'Priority'} = 'optional'; + $control{'Section'} = 'graphics'; + $control{'Description'} = 'Graphics conversion tools between image formats + Netpbm is a toolkit for manipulation of graphic images, including + conversion of images between a variety of different formats. There + are over 300 separate tools in the package including converters for + more than 80 graphics formats. This is the Super Stable version from + the Sourceforge Netpbm project, unmodified.'; + + return \%control; +} + + + +sub writeControlFile($$) { + my ($controlR, $fileName) = @_; + + open(CTL, '>', $fileName) + or die "Can't open '$fileName': $ERRNO"; + + while (my ($key, $value) = each %{$controlR}) { + print CTL ("$key: $value\n"); + } + + close(CTL); +} + + + +sub createScripts($$) { + my ($dpkgDirName, $buildToolsDir) = @_; + + my @scriptList = ('postinst', 'postrm'); + + my @scriptFileList = map("$buildToolsDir/debian/$_", @scriptList); + + system('cp', @scriptFileList, "$dpkgDirName/DEBIAN/") && + die("Failed to copy postinst, etc. to '$dpkgDirName/DEBIAN'."); + + my @createdFileList = map("$dpkgDirName/DEBIAN/$_", @scriptList); + + chmod(0755, @createdFileList); +} + + + +sub createDirOrDie($) { + my ($newDirName) = @_; + + mkdir($newDirName) + or die("Couldn't create directory '$newDirName'. $ERRNO"); + + chmod(0755, $newDirName); +} + + + +sub +processTemplate($$$) { + my ($templateR, $infoR, $outputR) = @_; + + my @output; + + foreach (@{$templateR}) { + if (m{^@}) { + # Comment -- ignore it. + } else { + if (defined($infoR->{VERSION})) { + s/\@VERSION\@/$infoR->{VERSION}/; + } + if (defined($infoR->{BINDIR})) { + s/\@BINDIR@/$infoR->{BINDIR}/; + } + if (defined($infoR->{LIBDIR})) { + s/\@LIBDIR@/$infoR-.{LIBDIR}/; + } + if (defined($infoR->{LINKDIR})) { + s/\@LINKDIR@/$infoR->{LINKDIR}/; + } + if (defined($infoR->{DATADIR})) { + s/\@DATADIR@/$infoR->{DATADIR}/; + } + if (defined($infoR->{INCLUDEDIR})) { + s/\@INCLUDEDIR@/$infoR->{INCLUDEDIR}/; + } + if (defined($infoR->{MANDIR})) { + s/\@MANDIR@/$infoR->{MANDIR}/; + } + push(@output, $_); + } + } + $$outputR = \@output; +} + + + + + +sub makeConfig($$$) { + my ($fileName, $templateSubsR, $netpbmPkgDir) = @_; +#----------------------------------------------------------------------------- +# Install 'netpbm-config' -- a program you run to tell you things about +# how Netpbm is installed. +#----------------------------------------------------------------------------- + my $error; + + my $configTemplateFilename = $netpbmPkgDir . "/config_template"; + + my $templateOpened = open(TEMPLATE, "<$configTemplateFilename"); + if (!$templateOpened) { + $error = "Can't open template file '$configTemplateFilename'.\n"; + } else { + my @template = <TEMPLATE>; + + close(TEMPLATE); + + processTemplate(\@template, $templateSubsR, \my $fileContentsR); + + writeFile($fileContentsR, $fileName, 'EXECUTABLE', \$error); + } + if ($error) { + print(STDERR "Failed to create the Netpbm configuration program. " . + "$error\n"); + } +} + + + +sub makePkgConfig($$$) { + my ($fileName, $templateSubsR, $netpbmPkgDir) = @_; +#----------------------------------------------------------------------------- +# Install a pkg-config file (netpbm.pc) - used by the 'pkg-config' program to +# find out various things about how Netpbm is installed. +#----------------------------------------------------------------------------- + my $error; + + my $pcTemplateFilename = "$netpbmPkgDir/pkgconfig_template"; + + my $templateOpened = open(TEMPLATE, "<$pcTemplateFilename"); + if (!$templateOpened) { + $error = "Can't open template file '$pcTemplateFilename'.\n"; + } else { + my @template = <TEMPLATE>; + + close(TEMPLATE); + + processTemplate(\@template, $templateSubsR, + \my $fileContentsR); + + writeFile($fileContentsR, $fileName, 'NOTEXECUTABLE', \$error); + } + if ($error) { + print(STDERR "Failed to create the Netpbm Pkg-config file. " . + "$error\n"); + } +} + + + +sub makeManweb($$) { + my ($dpkgDirName, $netpbmPkgDir) = @_; +#----------------------------------------------------------------------------- +# Set up things so one can read the manual with e.g. +# +# $ manweb pnmtojpeg +#----------------------------------------------------------------------------- + my @manwebConfContents; + + push(@manwebConfContents, "#Configuration file for Manweb\n"); + push(@manwebConfContents, "webdir=/usr/man/web\n"); + + createDirOrDie("$dpkgDirName/etc"); + + my $manwebConfFileName = "$dpkgDirName/etc/manweb.conf"; + + writeFile(\@manwebConfContents, $manwebConfFileName, + 'NOTEXECUTABLE', \my $error); + + if ($error) { + die("Failed to create Manweb configuration file $manwebConfFileName"); + } + createDirOrDie("$dpkgDirName/usr/man"); + + system('cp', '--archive', + "$netpbmPkgDir/man/web", "$dpkgDirName/usr/man/web") && + die("Failed to copy executables from '$netpbmPkgDir/bin' " . + "to '$dpkgDirName/usr/bin'"); +} + + + +sub buildDpkgBuildTree($$$$$) { + my ($dpkgDirName, $release, $netpbmPkgDir, $architecture, + $buildToolsDir) = @_; +#----------------------------------------------------------------------------- +# Create the directory tree that is the input to Dpkg-deb --build. +# This tree contains all the files to be installed, _plus_ the control +# subdirectory named DEBIAN. +#----------------------------------------------------------------------------- + print("Creating file tree for input to dpkg-deb --build as " . + "'$dpkgDirName'\n"); + + createDirOrDie($dpkgDirName); + + createDirOrDie("$dpkgDirName/DEBIAN"); + + my $controlR = control($release, $architecture); + + writeControlFile($controlR, "$dpkgDirName/DEBIAN/control"); + + createScripts($dpkgDirName, $buildToolsDir); + + createDirOrDie("$dpkgDirName/usr"); + + system('cp', '--archive', + "$netpbmPkgDir/bin", "$dpkgDirName/usr/bin") && + die("Failed to copy executables from '$netpbmPkgDir/bin' " . + "to '$dpkgDirName/usr/bin'"); + + # doc.url is inappropriate with the program installed into the global + # /usr/bin . + unlink("$dpkgDirName/usr/bin/doc.url"); + + system("cp", "--archive", "$netpbmPkgDir/include", + "$dpkgDirName/usr/include") && + die("Failed to copy header files from " . + "'$netpbmPkgDir/include' " . + "to '$dpkgDirName/usr/include'"); + + system("cp", "--archive", + "$netpbmPkgDir/lib", "$dpkgDirName/usr/lib") && + die("Failed to copy libraries from '$netpbmPkgDir/lib' " . + "to '$dpkgDirName/usr/lib'"); + + my @linkFileList = glob("$netpbmPkgDir/link/*"); + + if (@linkFileList > 0) { + system("cp", "--archive", + @linkFileList, "$dpkgDirName/usr/lib/") && + die("Failed to copy libraries from '$netpbmPkgDir/link' " . + "to '$dpkgDirName/usr/lib'"); + } + createDirOrDie("$dpkgDirName/usr/share"); + + system("cp", "--archive", + "$netpbmPkgDir/misc", "$dpkgDirName/usr/share/netpbm") && + die("Failed to copy files from '$netpbmPkgDir/misc' " . + "to '$dpkgDirName/usr/share/netpbm'"); + + # We install Netpbm in the default search path, so most of the values + # 'netpbm-config' returns are null strings. + my $templateSubsR = + {VERSION => $release, + BINDIR => '', + LIBDIR => '', + LINKDIR => '', + DATADIR => '/usr/share/netpbm', + INCLUDEDIR => '', + MANDIR => ''}; + + makeConfig("$dpkgDirName/usr/bin/netpbm-config", $templateSubsR, + $netpbmPkgDir); + + createDirOrDie("$dpkgDirName/usr/lib/pkgconfig"); + + makePkgConfig("$dpkgDirName/usr/lib/pkgconfig/netpbm.pc", $templateSubsR, + $netpbmPkgDir); + + makeManweb($dpkgDirName, $netpbmPkgDir); +} + + + +sub debianArchOfThisMachine() { + + # A lazy implementation that handles only the most common cases + + my $retval; + + my $arch = qx{'arch'}; + chomp($arch); + + if ($arch eq 'x86_64') { + $retval = 'amd64'; + } elsif ($arch =~ m{i.86}) { + $retval = 'i386'; + } else { + die("Can't determine the Debian architecture classification of this " . + "system. You'll have to give a -arch option"); + } + return $retval; +} + + + +sub buildToolsDir($) { + my ($cmdlineR) = @_; + + my $retval; + + if (exists($cmdlineR->{'buildtools'})) { + $retval = $cmdlineR->{'buildtools'}; + } else { + if (-f('./debian/mkdeb')) { + $retval = '.'; + } else { + die("The current directory does not appear to be 'buildtools' " . + "subdirectory of a Netpbm source tree, so you will have " . + "to use the -buildtools option to identify it"); + } + } + return $retval; +} + + + +sub netpbmPkgDir($) { + my ($cmdlineR) = @_; + + my $retval; + + if (exists($cmdlineR->{'pkgdir'})) { + $retval = $cmdlineR->{'pkgdir'}; + } else { + my $tmpdir = $ENV{TMPDIR} || "/tmp"; + + my $defaultPkgDir = "$tmpdir/netpbm"; + + if (-d($defaultPkgDir)) { + $retval = $defaultPkgDir; + } else { + die("No directory '$defaultPkgDir' exists. " . + "You can specify the Netpbm package directory " . + "(what 'make package' created), with a -pkgdir option"); + } + } + return $retval; +} + + + +sub arch($) { + my ($cmdlineR) = @_; + + my $retval; + + if (exists($cmdlineR->{'arch'})) { + $retval = $cmdlineR->{'arch'}; + } else { + $retval = debianArchOfThisMachine(); + } + + return $retval; +} + + + +############################################################################### +# MAIN PROGRAM +############################################################################### + +my $cmdlineR = parseCommandLine(@ARGV); + +my $buildTools = buildToolsDir($cmdlineR); + +my $netpbmPkgDir = netpbmPkgDir($cmdlineR); + +my $arch = arch($cmdlineR); + +my $release = netpbmVersion($netpbmPkgDir); + +my $dpkgDirName = "/tmp/netpbm-sf-$release"; + +buildDpkgBuildTree($dpkgDirName, $release, $netpbmPkgDir, $arch, + $buildTools); + +my $debFileName = 'netpbm-sf-' . $release . '_' . $arch . '.deb'; + +system('dpkg-deb', '--build', $dpkgDirName, $debFileName) && + die("dpgk-deb --build with input '$dpkgDirName' failed."); + +system('rm', '--recursive', $dpkgDirName); diff --git a/buildtools/debian/postinst b/buildtools/debian/postinst new file mode 100755 index 00000000..60836d52 --- /dev/null +++ b/buildtools/debian/postinst @@ -0,0 +1,5 @@ +#!/bin/sh +set -e +if [ "$1" = "configure" ]; then + ldconfig +fi diff --git a/buildtools/debian/postrm b/buildtools/debian/postrm new file mode 100755 index 00000000..5f0c15e7 --- /dev/null +++ b/buildtools/debian/postrm @@ -0,0 +1,5 @@ +#!/bin/sh +set -e +if [ "$1" = "remove" ]; then + ldconfig +fi diff --git a/common.mk b/common.mk index c096bd6e..51fbc438 100644 --- a/common.mk +++ b/common.mk @@ -449,7 +449,17 @@ ifeq ($(SYMLINKEXE)x,x) SYMLINKEXE := $(SYMLINK) endif -$(PKGDIR)/%: +# An implicit rule for $(PKGDIR)/% does not work because it causes Make +# sometimes to believe the directory it creates from this rule is an unneeded +# intermediate file and try to delete it later. So we explicitly list the +# possible directories under $(PKGDIR): + +PKGMANSUBDIRS = man1 man3 man5 web + +PKGSUBDIRS = bin include include/netpbm lib link misc \ + $(PKGMANSUBDIRS:%=$(PKGMANDIR)/%) + +$(PKGSUBDIRS:%=$(PKGDIR)/%): $(SRCDIR)/buildtools/mkinstalldirs $@ .PHONY: install.merge @@ -493,11 +503,13 @@ MANUALS1 = $(BINARIES) $(SCRIPTS) PKGMANDIR = man -install.man1: $(PKGDIR)/$(PKGMANDIR)/man1 $(MANUALS1:%=%_installman1) +install.man1: $(MANUALS1:%=%_installman1) + +install.man3: $(MANUALS3:%=%_installman3) -install.man3: $(PKGDIR)/$(PKGMANDIR)/man3 $(MANUALS3:%=%_installman3) +install.man5: $(MANUALS5:%=%_installman5) -install.man5: $(PKGDIR)/$(PKGMANDIR)/man5 $(MANUALS5:%=%_installman5) +install.manweb: $(MANUALS1:%=%_installmanweb) $(SUBDIRS:%=%/install.manweb) %_installman1: $(PKGDIR)/$(PKGMANDIR)/man1 perl -w $(SRCDIR)/buildtools/makepointerman $(@:%_installman1=%) \ @@ -511,6 +523,10 @@ install.man5: $(PKGDIR)/$(PKGMANDIR)/man5 $(MANUALS5:%=%_installman5) perl -w $(SRCDIR)/buildtools/makepointerman $(@:%_installman5=%) \ $(NETPBM_DOCURL) $< 5 $(MANPAGE_FORMAT) $(INSTALL_PERM_MAN) +%_installmanweb: $(PKGDIR)/$(PKGMANDIR)/web + echo $(NETPBM_DOCURL)$(@:%_installmanweb=%).html \ + >$</$(@:%_installmanweb=%).url + .PHONY: clean ifneq ($(EXE)x,x) @@ -556,6 +572,9 @@ endif %/install.man: $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) +%/install.manweb: + $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ + SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) %/install.data: $(MAKE) -C $(dir $@) -f $(SRCDIR)/$(SUBDIR)/$(dir $@)Makefile \ SRCDIR=$(SRCDIR) BUILDDIR=$(BUILDDIR) $(notdir $@) diff --git a/converter/other/cameratopam/camera.c b/converter/other/cameratopam/camera.c index 254b6710..4008dbb2 100644 --- a/converter/other/cameratopam/camera.c +++ b/converter/other/cameratopam/camera.c @@ -687,15 +687,22 @@ static int radc_token (int tree) void kodak_radc_load_raw() { - int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val; + int row, col, tree, nreps, rep, step, c, s, r, x, y, val; + unsigned int i; short last[3] = { 16,16,16 }, mul[3], buf[3][3][386]; init_decoder(); getbits(ifp, -1); - for (i=0; i < sizeof(buf)/sizeof(short); i++) - buf[0][0][i] = 2048; + for (i = 0; i < 3; ++i) { + unsigned int j; + for (j = 0; j < 3; ++j) { + unsigned int k; + buf[i][j][k] = 2048; + } + } for (row=0; row < height; row+=4) { - for (i=0; i < 3; i++) + unsigned int i; + for (i = 0; i < 3; ++i) mul[i] = getbits(ifp, 6); FORC3 { val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c]; diff --git a/converter/other/cameratopam/foveon.c b/converter/other/cameratopam/foveon.c index 78e40baf..aa42da36 100644 --- a/converter/other/cameratopam/foveon.c +++ b/converter/other/cameratopam/foveon.c @@ -474,9 +474,13 @@ foveon_interpolate(float coeff[3][4]) { black = calloc (height, sizeof *black); for (row=0; row < height; row++) { - for (i=0; i < 6; i++) - ddft[0][0][i] = ddft[1][0][i] + - row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]); + unsigned int i; + for (i=0; i < 3; ++i) { + unsigned int j; + for (j = 0; j < 2; ++j) + ddft[0][i][j] = ddft[1][i][j] + + row / (height-1.0) * (ddft[2][i][j] - ddft[1][i][j]); + } FORC3 black[row][c] = ( foveon_avg (image[row*width]+c, dscr[0], cfilt) + foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3 @@ -522,9 +526,13 @@ foveon_interpolate(float coeff[3][4]) { FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0); for (row=0; row < height; row++) { - for (i=0; i < 6; i++) - ddft[0][0][i] = ddft[1][0][i] + - row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]); + unsigned int i; + for (i = 0; i < 3; ++i) { + unsigned int j; + for (j = 0; j < 2; ++j) + ddft[0][i][j] = ddft[1][i][j] + + row / (height-1.0) * (ddft[2][i][j] - ddft[1][i][j]); + } pix = (short*)image[row*width]; memcpy (prev, pix, sizeof prev); frow = row / (height-1.0) * (dim[2]-1); diff --git a/converter/other/pnmtopng.README b/converter/other/pnmtopng.README deleted file mode 100644 index bfa524dc..00000000 --- a/converter/other/pnmtopng.README +++ /dev/null @@ -1,101 +0,0 @@ -Pnmtopng and Pngtopnm are based on programs of the same name in the -Pnmtopng package owned by Alexander Lehmann and Willem Van Schaik, -available at http://www.libpng.org/pub/png/src on 2001.07.14. - -I added it to and adapted it to Netpbm on 2000.03.02 to make it more -easily available to people. I applied a patch on 2000.06.03 to bring -it up the 2.37.4 release of that package. I updated it again on -2001.07.14 to bring it up to Release 2.37.5. There is no process in -place to bring improvements to the base package into the Netpbm -version, but there hasn't been a lot of update activity anyway. - -Attached below is the file README from Release 2.37.5 of the base -package. - -Here are the differences between the base and the Netpbm version: - - I added an "unsigned" to make formal and actual arguments to png_sig_cmp() - match and quiet a compiler warning. - - I fixed an "include" statement so the dependencies work out right. - - I removed the BIGGRAYS stuff, which became obsolete in Netpbm 9.0 - - I replaced a PPM_MAXVAL with PPM_OVERALLMAXAL to handle the new 16 bits - formats. - - macro VERSION is defined directly in pngtopnm.c and pnmtopng.c instead - of being included via file version.h. - - Pnmtopng, since June 2001, reads one row at a time instead of holding - the entire image in memory. That makes it work with large bitmaps - where it would otherwise run out of memory. It also works faster with - bitmaps since a bit takes up only a bit of memory in a cached input - file, but 96 bits of memory after reading it into a Netpbm data - structure. - - The base Pnmtopng ignores -transparent if it specifies a color that - isn't in the image. Netpbm's Pnmtopng selects a nearby color that _is_ - in the image, which is what base Pnmtopng did before October 2000. - Netpbm's Pnmtopng lets you put an '=' sign before the color to specify - that you don't want a nearby color to be chosen, i.e. you want the - base Pnmtopng function. This is consistent with Pnmtogif. - -There were some other changes necessary before Netpbm 9.0, but the change -of the xelval type from 1 byte to 4 made them unnecessary. - - -** PNMTOPNG / PNGTOPNM -** version 2.37.5 - 24 October 2000 - -[This is a semi-official bug-fix and enhancement release; I sort of took over - maintenance of this package while Willem was on an extended bike trip, and - for now I'm continuing with periodic, small updates. Version 2.37 (March - 1998) was never publicly released, partly because Willem had hoped to quiet - gcc's "<var> might be clobbered by `longjmp'" warnings. Those are fixed in - 2.37.2; under Solaris, they resulted in stack corruption even when there was - no error in the image files or libraries. Version 2.37.3 fixes a minor bug - w.r.t. error exits and generally does cleaner error exits (close files, etc.) - Version 2.37.4 fixes a bug that caused 16-shade grayscale images to be written - as 8-bit grayscale instead of (smaller) 4-bit colormapped images (bug report, - analysis and fix by Rafal Rzeczkowski), and it supports the new/upcoming - pbmplus release. Version 2.37.5 fixes a bug in -transparent handling (pnmtopng - no longer chooses an approximate color if the specified one isn't present) and - quiets a gcc warning in the non-16-bit version. - --Greg Roelofs] - -The utilities pnmtopng and pngtopnm are based on other pbm tools and require -the libraries included in the pbmplus/netpbm package. Also required are the -png library and the zlib compression library. - -These can be found at: - ftp://swrinde.nde.swri.edu/pub/png/src/libpng-* - ftp://swrinde.nde.swri.edu/pub/png/src/zlib-* - ftp://ftp.x.org/contrib/utilities/netpbm-1mar1994* -or see - http://www.libpng.org/pub/png/apps/pnmtopng.html - http://netpbm.sourceforge.net/ - http://www.acme.com/software/pbmplus/ [update coming soon?] - -To compile and install a makefile is provided. Do check the directories -where you have put the required libraries. Then either accommodate the -makefile or make links from generic names (e.g., zlib) to version-specific -directories (e.g., zlib-1.1.3), which is the recommended way. - -For testing purposes, have a look at the test-set PngSuite.tar.gz, which -contains a small test-image for every PNG color type and for most PNG chunk -types. It can be found at: - http://www.schaik.com/pngsuite/pngsuite.html - ftp://swrinde.nde.swri.edu/pub/png/images/suite/ - -Other web pages with PNG images are at: - http://www.libpng.org/pub/png/png-textures.html - http://www.libpng.org/pub/png/pngs-img.html - http://www.libpng.org/pub/png/pngpic2.html - http://www.libpng.org/pub/png/colorcube/ - http://www.libpng.org/pub/png/pngmisc.html#images - ------- -Alexander Lehmann <lehmann@usa.net> -Willem van Schaik <willem@schaik.com> -Greg Roelofs <newt@pobox.com> diff --git a/converter/other/pstopnm.c b/converter/other/pstopnm.c index d867b37b..27e98611 100644 --- a/converter/other/pstopnm.c +++ b/converter/other/pstopnm.c @@ -33,6 +33,8 @@ #include "shhopt.h" #include "nstring.h" +static bool verbose; + enum Orientation {PORTRAIT, LANDSCAPE, UNSPECIFIED}; struct Box { /* Description of a rectangle within an image; all coordinates @@ -46,6 +48,19 @@ struct Box { int ury; /* upper right Y coord */ }; +struct Dimensions { +/*---------------------------------------------------------------------------- + Horizontal and vertical dimensions of something, both in pixels and + spatial distance (points). + + Sizes are in pixels. Resolutions are in dots per inch (pixels per inch); +-----------------------------------------------------------------------------*/ + unsigned int xsize; + unsigned int ysize; + unsigned int xres; + unsigned int yres; +}; + struct CmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. @@ -220,8 +235,7 @@ parseCommandLine(int argc, char ** argv, static void addPsToFileName(char const origFileName[], - const char ** const newFileNameP, - bool const verbose) { + const char ** const newFileNameP) { /*---------------------------------------------------------------------------- If origFileName[] does not name an existing file, but the same name with ".ps" added to the end does, return the name with the .ps @@ -256,30 +270,31 @@ addPsToFileName(char const origFileName[], static void -computeSizeResFromSizeSpec(unsigned int const requestedXsize, - unsigned int const requestedYsize, - unsigned int const imageWidth, - unsigned int const imageHeight, - unsigned int * const xsizeP, - unsigned int * const ysizeP, - unsigned int * const xresP, - unsigned int * const yresP) { +computeSizeResFromSizeSpec(unsigned int const requestedXsize, + unsigned int const requestedYsize, + unsigned int const imageWidth, + unsigned int const imageHeight, + struct Dimensions * const imageDimP) { if (requestedXsize) { - *xsizeP = requestedXsize; - *xresP = (unsigned int) (requestedXsize * 72 / imageWidth + 0.5); + imageDimP->xsize = requestedXsize; + imageDimP->xres = (unsigned int) + (requestedXsize * 72 / imageWidth + 0.5); if (!requestedYsize) { - *yresP = *xresP; - *ysizeP = (unsigned int) (imageHeight * (float)*yresP/72 + 0.5); + imageDimP->yres = imageDimP->xres; + imageDimP->ysize = (unsigned int) + (imageHeight * (float)imageDimP->yres/72 + 0.5); } } if (requestedYsize) { - *ysizeP = requestedYsize; - *yresP = (unsigned int) (requestedYsize * 72 / imageHeight + 0.5); + imageDimP->ysize = requestedYsize; + imageDimP->yres = (unsigned int) + (requestedYsize * 72 / imageHeight + 0.5); if (!requestedXsize) { - *xresP = *yresP; - *xsizeP = (unsigned int) (imageWidth * (float)*xresP/72 + 0.5); + imageDimP->xres = imageDimP->yres; + imageDimP->xsize = (unsigned int) + (imageWidth * (float)imageDimP->xres/72 + 0.5); } } } @@ -287,42 +302,36 @@ computeSizeResFromSizeSpec(unsigned int const requestedXsize, static void -computeSizeResBlind(unsigned int const xmax, - unsigned int const ymax, - unsigned int const imageWidth, - unsigned int const imageHeight, - bool const nocrop, - unsigned int * const xsizeP, - unsigned int * const ysizeP, - unsigned int * const xresP, - unsigned int * const yresP) { - - *xresP = *yresP = MIN(xmax * 72 / imageWidth, - ymax * 72 / imageHeight); +computeSizeResBlind(unsigned int const xmax, + unsigned int const ymax, + unsigned int const imageWidth, + unsigned int const imageHeight, + bool const nocrop, + struct Dimensions * const imageDimP) { + + imageDimP->xres = imageDimP->yres = MIN(xmax * 72 / imageWidth, + ymax * 72 / imageHeight); if (nocrop) { - *xsizeP = xmax; - *ysizeP = ymax; + imageDimP->xsize = xmax; + imageDimP->ysize = ymax; } else { - *xsizeP = (unsigned int) (imageWidth * (float)*xresP / 72 + 0.5); - *ysizeP = (unsigned int) (imageHeight * (float)*yresP / 72 + 0.5); + imageDimP->xsize = (unsigned int) + (imageWidth * (float)imageDimP->xres / 72 + 0.5); + imageDimP->ysize = (unsigned int) + (imageHeight * (float)imageDimP->yres / 72 + 0.5); } } static void -computeSizeRes(struct CmdlineInfo const cmdline, - enum Orientation const orientation, - struct Box const borderedBox, - unsigned int * const xsizeP, - unsigned int * const ysizeP, - unsigned int * const xresP, - unsigned int * const yresP) { +computeSizeRes(struct CmdlineInfo const cmdline, + struct Box const borderedBox, + struct Dimensions * const imageDimP) { /*---------------------------------------------------------------------------- - Figure out how big the output image should be (return as - *xsizeP and *ysizeP) and what output device resolution Ghostscript - should assume (return as *xresP, *yresP). + Figure out how big the output image should be and what output device + resolution Ghostscript should assume (return as *imageDimP). A resolution number is the number of pixels per inch that the a printer prints. Since we're emulating a printed page with a PNM @@ -337,38 +346,33 @@ computeSizeRes(struct CmdlineInfo const cmdline, tell Ghostscript that our horizontal output device resolution is 500 pixels per inch. - *xresP and *yresP are in dots per inch. + X and Y in all returned values is with respect to the image, not the + page. Note that the image might be placed sideways on the page, so that + page X and Y would be reversed from image X and Y. -----------------------------------------------------------------------------*/ - unsigned int sx, sy; - /* The horizontal and vertical sizes of the input image, in points - (1/72 inch) - */ - - if (orientation == LANDSCAPE) { - sx = borderedBox.ury - borderedBox.lly; - sy = borderedBox.urx - borderedBox.llx; - } else { - sx = borderedBox.urx - borderedBox.llx; - sy = borderedBox.ury - borderedBox.lly; - } + /* The horizontal and vertical sizes of the input image, in points + (1/72 inch) + */ + unsigned int const sx = borderedBox.urx - borderedBox.llx; + unsigned int const sy = borderedBox.ury - borderedBox.lly; if (cmdline.dpi) { /* User gave resolution; we figure out output image size */ - *xresP = *yresP = cmdline.dpi; - *xsizeP = (int) (cmdline.dpi * sx / 72 + 0.5); - *ysizeP = (int) (cmdline.dpi * sy / 72 + 0.5); + imageDimP->xres = imageDimP->yres = cmdline.dpi; + imageDimP->xsize = ROUNDU(cmdline.dpi * sx / 72.0); + imageDimP->ysize = ROUNDU(cmdline.dpi * sy / 72.0); } else if (cmdline.xsize || cmdline.ysize) computeSizeResFromSizeSpec(cmdline.xsize, cmdline.ysize, sx, sy, - xsizeP, ysizeP, xresP, yresP); + imageDimP); else computeSizeResBlind(cmdline.xmax, cmdline.ymax, sx, sy, cmdline.nocrop, - xsizeP, ysizeP, xresP, yresP); + imageDimP); if (cmdline.verbose) { pm_message("output is %u pixels wide X %u pixels high", - *xsizeP, *ysizeP); + imageDimP->xsize, imageDimP->ysize); pm_message("output device resolution is %u dpi horiz, %u dpi vert", - *xresP, *yresP); + imageDimP->xres, imageDimP->yres); } } @@ -377,8 +381,7 @@ computeSizeRes(struct CmdlineInfo const cmdline, enum PostscriptLanguage {COMMON_POSTSCRIPT, ENCAPSULATED_POSTSCRIPT}; static enum PostscriptLanguage -languageDeclaration(char const inputFileName[], - bool const verbose) { +languageDeclaration(char const inputFileName[]) { /*---------------------------------------------------------------------------- Return the Postscript language in which the file declares it is written. (Except that if the file is on Standard Input or doesn't validly declare @@ -421,8 +424,7 @@ languageDeclaration(char const inputFileName[], static struct Box computeBoxToExtract(struct Box const cmdlineExtractBox, - char const inputFileName[], - bool const verbose) { + char const inputFileName[]) { struct Box retval; @@ -572,8 +574,7 @@ computeOrientation(struct CmdlineInfo const cmdline, static struct Box addBorders(struct Box const inputBox, float const xborderScale, - float const yborderScale, - bool const verbose) { + float const yborderScale) { /*---------------------------------------------------------------------------- Return a box which is 'inputBox' plus some borders. @@ -592,16 +593,13 @@ addBorders(struct Box const inputBox, assert(inputBox.urx >= inputBox.llx); assert(inputBox.ury >= inputBox.lly); - assert(inputBox.llx >= leftRightBorderSize); - assert(inputBox.lly >= topBottomBorderSize); - - retval.llx = inputBox.llx - leftRightBorderSize; - retval.lly = inputBox.lly - topBottomBorderSize; - retval.urx = inputBox.urx + leftRightBorderSize; - retval.ury = inputBox.ury + topBottomBorderSize; + retval.llx = inputBox.llx - (int)leftRightBorderSize; + retval.lly = inputBox.lly - (int)topBottomBorderSize; + retval.urx = inputBox.urx + (int)leftRightBorderSize; + retval.ury = inputBox.ury + (int)topBottomBorderSize; if (verbose) - pm_message("With borders, extracted box is ((%u,%u),(%u,%u))", + pm_message("With borders, extracted box is ((%d,%d),(%d,%d))", retval.llx, retval.lly, retval.urx, retval.ury); return retval; @@ -609,32 +607,45 @@ addBorders(struct Box const inputBox, -static const char * -computePstrans(struct Box const box, - enum Orientation const orientation, - int const xsize, - int const ysize, - int const xres, - int const yres) { +static void +writePstrans(struct Box const box, + struct Dimensions const d, + enum Orientation const orientation, + FILE * const pipeToGsP) { - const char * retval; + int const xsize = d.xsize; + int const ysize = d.ysize; + int const xres = d.xres; + int const yres = d.yres; - if (orientation == PORTRAIT) { + const char * pstrans; + + switch (orientation) { + case PORTRAIT: { int llx, lly; llx = box.llx - (xsize * 72 / xres - (box.urx - box.llx)) / 2; lly = box.lly - (ysize * 72 / yres - (box.ury - box.lly)) / 2; - pm_asprintf(&retval, "%d neg %d neg translate", llx, lly); - } else { + pm_asprintf(&pstrans, "%d neg %d neg translate", llx, lly); + } break; + case LANDSCAPE: { int llx, ury; - llx = box.llx - (ysize * 72 / yres - (box.urx - box.llx)) / 2; - ury = box.ury + (xsize * 72 / xres - (box.ury - box.lly)) / 2; - pm_asprintf(&retval, "90 rotate %d neg %d neg translate", llx, ury); + llx = box.llx - (xsize * 72 / xres - (box.urx - box.llx)) / 2; + ury = box.ury + (ysize * 72 / yres - (box.ury - box.lly)) / 2; + pm_asprintf(&pstrans, "90 rotate %d neg %d neg translate", llx, ury); + } break; + case UNSPECIFIED: + assert(false); } - if (retval == NULL) + if (pstrans == pm_strsol) pm_error("Unable to allocate memory for pstrans"); - return retval; + if (verbose) + pm_message("Postscript prefix command: '%s'", pstrans); + + fprintf(pipeToGsP, "%s\n", pstrans); + + pm_strfree(pstrans); } @@ -753,16 +764,19 @@ findGhostscriptProg(const char ** const retvalP) { static void -execGhostscript(int const inputPipeFd, - char const ghostscriptDevice[], - char const outfileArg[], - int const xsize, - int const ysize, - int const xres, - int const yres, - unsigned int const textalphabits, - bool const verbose) { - +execGhostscript(int const inputPipeFd, + char const ghostscriptDevice[], + char const outfileArg[], + struct Dimensions const pageDim, + unsigned int const textalphabits) { +/*---------------------------------------------------------------------------- + Exec the Ghostscript program and have it execute the Postscript program + that it receives on 'inputPipeFd', then exit. + + 'pageDim' describes the print area. X and Y in 'pageDim' are with respect + to the page, independent of whether the program we receive on 'inputPipeFd' + puts an image in there sideways. +-----------------------------------------------------------------------------*/ const char * arg0; const char * ghostscriptProg; const char * deviceopt; @@ -781,8 +795,8 @@ execGhostscript(int const inputPipeFd, pm_asprintf(&arg0, "gs"); pm_asprintf(&deviceopt, "-sDEVICE=%s", ghostscriptDevice); pm_asprintf(&outfileopt, "-sOutputFile=%s", outfileArg); - pm_asprintf(&gopt, "-g%dx%d", xsize, ysize); - pm_asprintf(&ropt, "-r%dx%d", xres, yres); + pm_asprintf(&gopt, "-g%dx%d", pageDim.xsize, pageDim.ysize); + pm_asprintf(&ropt, "-r%dx%d", pageDim.xres, pageDim.yres); pm_asprintf(&textalphabitsopt, "-dTextAlphaBits=%u", textalphabits); /* -dSAFER causes Postscript to disable %pipe and file operations, @@ -810,23 +824,120 @@ execGhostscript(int const inputPipeFd, static void -executeGhostscript(char const pstrans[], +feedPsToGhostScript(const char * const inputFileName, + struct Box const borderedBox, + struct Dimensions const imageDim, + enum Orientation const orientation, + int const pipeToGhostscriptFd, + enum PostscriptLanguage const language) { +/*---------------------------------------------------------------------------- + Send a Postscript program to the Ghostscript process running on the + other end of the pipe 'pipeToGhostscriptFd'. That program is mostly + the contents of file 'inputFileName' (special value "-" means Standard + Input), but we may add a little to it. + + The image has dimensions 'imageDim' and is oriented on the page according + to 'orientation' ('imageDim' X and Y are with respect to the image itself, + without regard to how it is oriented on the page). +-----------------------------------------------------------------------------*/ + FILE * pipeToGsP; /* Pipe to Ghostscript's standard input */ + FILE * ifP; + bool eof; /* End of file on input */ + + pipeToGsP = fdopen(pipeToGhostscriptFd, "w"); + if (pipeToGsP == NULL) + pm_error("Unable to open stream on pipe to Ghostscript process."); + + ifP = pm_openr(inputFileName); + /* + In encapsulated Postscript, we the encapsulator are supposed to + handle showing the page (which we do by passing a showpage + statement to Ghostscript). Any showpage statement in the + input must be defined to have no effect. + + See "Enscapsulated PostScript Format File Specification", + v. 3.0, 1 May 1992, in particular Example 2, p. 21. I found + it at + http://partners.adobe.com/asn/developer/pdfs/tn/5002.EPSF_Spec.pdf + The example given is a much fancier solution than we need + here, I think, so I boiled it down a bit. JM + */ + if (language == ENCAPSULATED_POSTSCRIPT) + fprintf(pipeToGsP, "\n/b4_Inc_state save def /showpage { } def\n"); + + writePstrans(borderedBox, imageDim, orientation, pipeToGsP); + + /* If our child dies, it closes the pipe and when we next write to it, + we get a SIGPIPE. We must survive that signal in order to report + on the fate of the child. So we ignore SIGPIPE: + */ + signal(SIGPIPE, SIG_IGN); + + eof = FALSE; + while (!eof) { + char buffer[4096]; + size_t readCt; + + readCt = fread(buffer, 1, sizeof(buffer), ifP); + if (readCt == 0) + eof = TRUE; + else + fwrite(buffer, 1, readCt, pipeToGsP); + } + pm_close(ifP); + + if (language == ENCAPSULATED_POSTSCRIPT) + fprintf(pipeToGsP, "\nb4_Inc_state restore showpage\n"); + + fclose(pipeToGsP); +} + + + +static struct Dimensions +pageDimFromImageDim(struct Dimensions const imageDim, + enum Orientation const orientation) { +/*---------------------------------------------------------------------------- + The dimensions of the page of an image whose dimensions are + 'imageDim', if we place it on the page with orientation 'orientation'. + + (I.e. swap and X and Y if landscape orientation). + + 'orientation' must not be UNSPECIFIED. +-----------------------------------------------------------------------------*/ + struct Dimensions retval; + + switch (orientation) { + case PORTRAIT: + retval = imageDim; + break; + case LANDSCAPE: + retval.xsize = imageDim.ysize; + retval.ysize = imageDim.xsize; + retval.xres = imageDim.yres; + retval.yres = imageDim.xres; + break; + case UNSPECIFIED: + assert(false); + break; + } + + return retval; +} + + + +static void +executeGhostscript(char const inputFileName[], + struct Box const borderedBox, + struct Dimensions const imageDim, + enum Orientation const orientation, char const ghostscriptDevice[], char const outfileArg[], - int const xsize, - int const ysize, - int const xres, - int const yres, unsigned int const textalphabits, - char const inputFileName[], - enum PostscriptLanguage const language, - bool const verbose) { + enum PostscriptLanguage const language) { - int gsTermStatus; /* termination status of Ghostscript process */ - FILE * pipeToGsP; /* Pipe to Ghostscript's standard input */ - FILE * ifP; int rc; - int eof; /* End of file on input */ int pipefd[2]; if (strlen(outfileArg) > 80) @@ -845,65 +956,23 @@ executeGhostscript(char const pstrans[], /* Child process */ close(pipefd[1]); execGhostscript(pipefd[0], ghostscriptDevice, outfileArg, - xsize, ysize, xres, yres, textalphabits, - verbose); + pageDimFromImageDim(imageDim, orientation), + textalphabits); } else { + /* parent process */ pid_t const ghostscriptPid = rc; int const pipeToGhostscriptFd = pipefd[1]; - /* parent process */ - close(pipefd[0]); - - pipeToGsP = fdopen(pipeToGhostscriptFd, "w"); - if (pipeToGsP == NULL) - pm_error("Unable to open stream on pipe to Ghostscript process."); - - ifP = pm_openr(inputFileName); - /* - In encapsulated Postscript, we the encapsulator are supposed to - handle showing the page (which we do by passing a showpage - statement to Ghostscript). Any showpage statement in the - input must be defined to have no effect. - - See "Enscapsulated PostScript Format File Specification", - v. 3.0, 1 May 1992, in particular Example 2, p. 21. I found - it at - http://partners.adobe.com/asn/developer/pdfs/tn/5002.EPSF_Spec.pdf - The example given is a much fancier solution than we need - here, I think, so I boiled it down a bit. JM - */ - if (language == ENCAPSULATED_POSTSCRIPT) - fprintf(pipeToGsP, "\n/b4_Inc_state save def /showpage { } def\n"); - - if (verbose) - pm_message("Postscript prefix command: '%s'", pstrans); - - fprintf(pipeToGsP, "%s\n", pstrans); - /* If our child dies, it closes the pipe and when we next write to it, - we get a SIGPIPE. We must survive that signal in order to report - on the fate of the child. So we ignore SIGPIPE: - */ - signal(SIGPIPE, SIG_IGN); + int gsTermStatus; /* termination status of Ghostscript process */ + pid_t rc; - eof = FALSE; - while (!eof) { - char buffer[4096]; - int bytes_read; - - bytes_read = fread(buffer, 1, sizeof(buffer), ifP); - if (bytes_read == 0) - eof = TRUE; - else - fwrite(buffer, 1, bytes_read, pipeToGsP); - } - pm_close(ifP); + close(pipefd[0]); - if (language == ENCAPSULATED_POSTSCRIPT) - fprintf(pipeToGsP, "\nb4_Inc_state restore showpage\n"); + feedPsToGhostScript(inputFileName, borderedBox, + imageDim, orientation, + pipeToGhostscriptFd, language); - fclose(pipeToGsP); - - waitpid(ghostscriptPid, &gsTermStatus, 0); + rc = waitpid(ghostscriptPid, &gsTermStatus, 0); if (rc < 0) pm_error("Wait for Ghostscript process to terminated failed. " "errno = %d (%s)", errno, strerror(errno)); @@ -930,8 +999,8 @@ main(int argc, char ** argv) { struct CmdlineInfo cmdline; const char * inputFileName; /* malloc'ed */ /* The file specification of our Postscript input file */ - unsigned int xres, yres; /* Resolution in pixels per inch */ - unsigned int xsize, ysize; /* output image size in pixels */ + struct Dimensions imageDim; + /* Size and resolution of the input image */ struct Box extractBox; /* coordinates of the box within the input we are to extract; i.e. that will become the output. @@ -943,30 +1012,25 @@ main(int argc, char ** argv) { enum Orientation orientation; const char * ghostscriptDevice; const char * outfileArg; - const char * pstrans; pnm_init(&argc, argv); parseCommandLine(argc, argv, &cmdline); - addPsToFileName(cmdline.inputFileName, &inputFileName, cmdline.verbose); + verbose = cmdline.verbose; + + addPsToFileName(cmdline.inputFileName, &inputFileName); - extractBox = computeBoxToExtract(cmdline.extractBox, inputFileName, - cmdline.verbose); + extractBox = computeBoxToExtract(cmdline.extractBox, inputFileName); - language = languageDeclaration(inputFileName, cmdline.verbose); + language = languageDeclaration(inputFileName); orientation = computeOrientation(cmdline, extractBox); - borderedBox = addBorders(extractBox, cmdline.xborder, cmdline.yborder, - cmdline.verbose); + borderedBox = addBorders(extractBox, cmdline.xborder, cmdline.yborder); - computeSizeRes(cmdline, orientation, borderedBox, - &xsize, &ysize, &xres, &yres); + computeSizeRes(cmdline, borderedBox, &imageDim); - pstrans = computePstrans(borderedBox, orientation, - xsize, ysize, xres, yres); - outfileArg = computeOutfileArg(cmdline); ghostscriptDevice = @@ -974,14 +1038,12 @@ main(int argc, char ** argv) { pm_message("Writing %s format", ghostscriptDevice); - executeGhostscript(pstrans, ghostscriptDevice, outfileArg, - xsize, ysize, xres, yres, cmdline.textalphabits, - inputFileName, - language, cmdline.verbose); + executeGhostscript(inputFileName, borderedBox, imageDim, orientation, + ghostscriptDevice, outfileArg, cmdline.textalphabits, + language); pm_strfree(ghostscriptDevice); pm_strfree(outfileArg); - pm_strfree(pstrans); return 0; } diff --git a/converter/ppm/ppmtompeg/Makefile b/converter/ppm/ppmtompeg/Makefile index a1004fdd..4f244ae9 100644 --- a/converter/ppm/ppmtompeg/Makefile +++ b/converter/ppm/ppmtompeg/Makefile @@ -51,7 +51,7 @@ MP_ENCODE_OBJS = \ MP_OTHER_OBJS = mpeg.o subsample.o param.o rgbtoycc.o \ readframe.o combine.o jrevdct.o frame.o fsize.o frametype.o \ specifics.o rate.o opts.o input.o -ifeq ($(OMIT_NETWORK),y) +ifeq ($(OMIT_NETWORK),Y) MP_OTHER_OBJS += noparallel.o else MP_OTHER_OBJS += parallel.o psocket.o diff --git a/doc/HISTORY b/doc/HISTORY index 9928f0a8..b5b9b43a 100644 --- a/doc/HISTORY +++ b/doc/HISTORY @@ -4,58 +4,83 @@ Netpbm. CHANGE HISTORY -------------- -14.03.02 BJH Release 10.65.07 +14.03.30 BJH Release 10.66.00 + + Add pamvalidate. Thanks Prophet of the Way <afu@wta.att.ne.jp>. + + Add pamfix: Does what pamfixtrunc did, plus repairs excessive + sample values. + + pamfixtrunc: implement as call to new pamfix. + + pgmhist, ppmhist: Add -forensic: Analyze invalid >maxval pixels. + Thanks Prophet of the Way <afu@wta.att.ne.jp>. + + pgmramp: add -diagonal. Thanks Prophet of the Way + <afu@wta.att.ne.jp>. + + libnetpbm: Read functions validate that sample values do not + exceed maxval. Thanks Prophet of the Way <afu@wta.att.ne.jp>. + + libnetpbm: Validate image dimensions are small enough that you + can allocate a row buffer. Thanks Prophet of the Way + <afu@wta.att.ne.jp>. pgmhist: fix incorrect report of quantiles or crash due to array bounds violation in some builds. Thanks Prophet of the Way <afu@wta.att.ne.jp>. Always broken. Quantile reporting was new in Netpbm 10.61 (December 2012). - Windows build: fix missing .exe on copies of programs under - their old names. - -14.03.01 BJH Release 10.65.06 - pgmhist: fix buffer overrun with -median. Always broken. -median was new in Netpbm 10.61 (December 2012). -14.02.24 BJH Release 10.65.05 + pnmmargin: fix for size 0 and superfluous "unexpected operator" + message with size != 0. Introduced in 10.42. - pgmtexture: fix buffer overflow. Always broken. (Program - was added in primordial Netpbm in 1991). + pstopnm: fix wrong interpretations of -xsize and -ysize when + rendering image in landscape (rotated). This can appear as + stretching and squashing. Probably always broken. - Windows build: fix Ppmtompeg build failure in non-Cygwin build - due to missing sys/utsname.h. + pstopnm: fix wrong orientation sometimes when you specify + both -xsize and -ysize. Introduced in 10.65. -14.02.09 BJH Release 10.65.04 + pgmramp: fix bogus output with really large images. Thanks + Prophet of the Way <afu@wta.att.ne.jp>. ppmrelief: fix out-of-bound values in output. Always broken. + ppmrelief was new in primordial Netpbm in 1989. Thanks Prophet of the Way <afu@wta.att.ne.jp>. ppmrelief: fix crash when input image is too small. Always - broken. Thanks Prophet of the Way <afu@wta.att.ne.jp>. + broken. ppmrelief was new in primordial Netpbm in 1989. Thanks + Prophet of the Way <afu@wta.att.ne.jp>. + + pgmtexture: fix buffer overflow. Always broken. (Program + was added in primordial Netpbm in 1991). pamdeinterlace: fix incorrect output with -takeodd and image has only one row. Always broken (pamdeinterlace was introduced in Netpbm 9.21 (January 2001)). Thanks Prophet of the Way <afu@wta.att.ne.jp>. -14.01.06 BJH Release 10.65.03 + configure: warn if user says JPEG library is in the linker's + default search path, but it isn't. + + build/install: add tools for creating a Debian package. make package: Include template for pkgconfig file. + make package: Include a man/web directory with .url files for + each manual page. + test: Add -portrait to invocations of pstopnm in order to get proper round trips. -14.01.01 BJH Release 10.65.02 - - pnmmargin: fix for size 0 and superfluous "unexpected operator" - message with size != 0. Introduced in 10.42. - -13.12.28 BJH Release 10.65.01 + Windows build: fix Ppmtompeg build failure in non-Cygwin build + due to missing sys/utsname.h. - pstopnm: fix wrong orientation sometimes when you specify - both -xsize and -ysize. Introduced in 10.65.00. + Windows build: fix missing .exe on copies of programs under + their old names. 13.12.26 BJH Release 10.65.00 @@ -228,7 +253,7 @@ CHANGE HISTORY build: fix problem with creating lib/util that already exists. Broken in Netpbm 10.62. -12.03.28 BJH Release 10.62.00 +13.03.28 BJH Release 10.62.00 pnmtorast: set don't care bytes to zero to make output repeatable. @@ -247,7 +272,7 @@ CHANGE HISTORY pamstereogram: fix bug: garbage in -verbose listing. Broken since Netpbm 10.61 - MinGW build: various fixes. + Windows MinGW build: various fixes. 12.12.30 BJH Release 10.61.00 @@ -1201,6 +1226,8 @@ CHANGE HISTORY too large for computation. Thanks Prophet of the Way <afu@wta.att.ne.jp>. + pnmmargin: don't crash with zero margin request. + pnmtile: deal with zero width/height. pbmtext: fix negative -space. diff --git a/doc/INSTALL b/doc/INSTALL index f8397ca2..33bb4bc7 100644 --- a/doc/INSTALL +++ b/doc/INSTALL @@ -20,10 +20,16 @@ finally to install it into your system. -If you're building Latest Netpbm (as opposed to Stable Netpbm), there -are probably known bugs. Some may even prevent Netpbm from building. -These are listed in the release notes for the release on Sourceforge. -Check it out. +If you have a Debian-like system, that uses Dpkg for package management, +it's better to create a Debian package file and install it as follows in +place of the 'installnetpbm' step above. + + make deb + dpkg --install netpbm-sf-*.deb + +More information on building and installing on Debian are in the file +buildtools/debian/README in the source tree. + The 'configure' program is not GNU Autoconf -- it is a simple program specific to Netpbm that prompts you for information about your system. diff --git a/editor/pnmmargin b/editor/pnmmargin index b31deefd..0f57d1d4 100755 --- a/editor/pnmmargin +++ b/editor/pnmmargin @@ -31,30 +31,30 @@ while true ; do plainopt="-plain" shift ;; - -w|-wh|-whi|-whit|-white ) - color="-white" - shift - ;; - -b|-bl|-bla|-blac|-black ) - color="-black" - shift - ;; - -c|-co|-col|-colo|-color ) - shift - if [ ! ${1-""} ] ; then - echo "usage: $0 [-white|-black|-color <colorspec>] <size> [pnmfile]" 1>&2 - exit 1 - fi - color="$1" - shift - ;; - -* ) - echo "usage: $0 [-white|-black|-color <colorspec>] <size> [pnmfile]" 1>&2 - exit 1 - ;; - * ) - break - ;; + -w|-wh|-whi|-whit|-white ) + color="-white" + shift + ;; + -b|-bl|-bla|-blac|-black ) + color="-black" + shift + ;; + -c|-co|-col|-colo|-color ) + shift + if [ ! ${1-""} ] ; then + echo "usage: $0 [-white|-black|-color <colorspec>] <size> [pnmfile]" 1>&2 + exit 1 + fi + color="$1" + shift + ;; + -* ) + echo "usage: $0 [-white|-black|-color <colorspec>] <size> [pnmfile]" 1>&2 + exit 1 + ;; + * ) + break + ;; esac done @@ -82,7 +82,7 @@ if [ $size -eq 0 ] ; then else # If -white or -black, write output with pnmpad and exit. # Otherwise construct spacer files. - + case "$color" in -gofigure ) pnmcut 0 0 1 1 $tmp1 | pnmtile $size 1 > $tmp2 @@ -97,12 +97,10 @@ else ;; esac pamflip -rotate90 $tmp2 > $tmp3 - + # Cat things together. pnmcat -lr $tmp2 $tmp1 $tmp2 > $tmp4 pnmcat -tb $plainopt $tmp3 $tmp4 $tmp3 fi - - diff --git a/editor/specialty/ppmrelief.c b/editor/specialty/ppmrelief.c index 1c408aec..14a6d0a8 100644 --- a/editor/specialty/ppmrelief.c +++ b/editor/specialty/ppmrelief.c @@ -1,4 +1,4 @@ -/* ppmrelief.c - generate a relief map of a portable pixmap +/* ppmrelief.c - generate a relief map of a PPM image ** ** Copyright (C) 1990 by Wilson H. Bent, Jr. ** @@ -11,86 +11,104 @@ */ #include <stdio.h> + #include "pm_c_util.h" #include "ppm.h" + + +static pixval +clip(int const p, + pixval const maxval) { + + return MAX(0, MIN(maxval, p)); +} + + + int -main(int argc, char * argv[]) { - - FILE* ifp; - pixel** inputbuf; - pixel* outputrow; - int argn, rows, cols, format, row; - register int col; - pixval maxval, mv2; +main(int argc, const char * argv[]) { + + FILE * ifP; + pixel ** inputbuf; + pixel * outputrow; + int argn, format, rows, cols; + unsigned int row, col; + pixval maxval; const char* const usage = "[ppmfile]"; - ppm_init( &argc, argv ); + pm_proginit(&argc, argv); argn = 1; if ( argn != argc ) { - ifp = pm_openr( argv[argn] ); + ifP = pm_openr( argv[argn] ); ++argn; } else - ifp = stdin; + ifP = stdin; if ( argn != argc ) pm_usage( usage ); - - ppm_readppminit( ifp, &cols, &rows, &maxval, &format ); + + ppm_readppminit(ifP, &cols, &rows, &maxval, &format ); if (cols < 3 || rows < 3 ) pm_error("Input image too small: %u x %u. Must be at least 3x3", cols, rows); - mv2 = maxval / 2; - /* Allocate space for 3 input rows, plus an output row. */ - inputbuf = ppm_allocarray( cols, 3 ); - outputrow = ppm_allocrow( cols ); + inputbuf = ppm_allocarray(cols, 3); + outputrow = ppm_allocrow(cols); - ppm_writeppminit( stdout, cols, rows, maxval, 0 ); + ppm_writeppminit(stdout, cols, rows, maxval, 0); /* Read in the first two rows. */ - ppm_readppmrow( ifp, inputbuf[0], cols, maxval, format ); - ppm_readppmrow( ifp, inputbuf[1], cols, maxval, format ); + ppm_readppmrow(ifP, inputbuf[0], cols, maxval, format); + ppm_readppmrow(ifP, inputbuf[1], cols, maxval, format); /* Write out the first row, all zeros. */ - for ( col = 0; col < cols; ++col ) + for (col = 0; col < cols; ++col) PPM_ASSIGN( outputrow[col], 0, 0, 0 ); - ppm_writeppmrow( stdout, outputrow, cols, maxval, 0 ); + + ppm_writeppmrow(stdout, outputrow, cols, maxval, 0); /* Now the rest of the image - read in the 3rd row of inputbuf, - ** and convolve with the first row into the output buffer. + and convolve with the first row into the output buffer. */ - for ( row = 2 ; row < rows; ++row ) { - pixval r, g, b; - int rowa, rowb; - - rowa = row % 3; - rowb = (row + 2) % 3; - ppm_readppmrow( ifp, inputbuf[rowa], cols, maxval, format ); - - for ( col = 0; col < cols - 2; ++col ) { - r = MAX(0, MIN(maxval, PPM_GETR( inputbuf[rowa][col] ) + - ( mv2 - PPM_GETR( inputbuf[rowb][col + 2] ) ))); - g = MAX(0, MIN(maxval, PPM_GETG( inputbuf[rowa][col] ) + - ( mv2 - PPM_GETG( inputbuf[rowb][col + 2] ) ))); - b = MAX(0, MIN(maxval, PPM_GETB( inputbuf[rowa][col] ) + - ( mv2 - PPM_GETB( inputbuf[rowb][col + 2] ) ))); - PPM_ASSIGN( outputrow[col + 1], r, g, b ); + for (row = 2 ; row < rows; ++row) { + pixval const mv2 = maxval / 2; + unsigned int const rowa = row % 3; + unsigned int const rowb = (rowa + 2) % 3; + + ppm_readppmrow(ifP, inputbuf[rowa], cols, maxval, format); + + for (col = 0; col < cols - 2; ++col) { + pixel const inputA = inputbuf[rowa][col]; + pixel const inputB = inputbuf[rowb][col + 2]; + + pixval const r = + clip(PPM_GETR(inputA) + (mv2 - PPM_GETR(inputB)), maxval); + pixval const g = + clip(PPM_GETG(inputA) + (mv2 - PPM_GETG(inputB)), maxval); + pixval const b = + clip(PPM_GETB(inputA) + (mv2 - PPM_GETB(inputB)), maxval); + + PPM_ASSIGN(outputrow[col + 1], r, g, b); } - ppm_writeppmrow( stdout, outputrow, cols, maxval, 0 ); + ppm_writeppmrow(stdout, outputrow, cols, maxval, 0); } /* And write the last row, zeros again. */ - for ( col = 0; col < cols; ++col ) - PPM_ASSIGN( outputrow[col], 0, 0, 0 ); - ppm_writeppmrow( stdout, outputrow, cols, maxval, 0 ); + for (col = 0; col < cols; ++col) + PPM_ASSIGN(outputrow[col], 0, 0, 0); + + ppm_writeppmrow(stdout, outputrow, cols, maxval, 0); + + ppm_freerow(outputrow); + ppm_freearray(inputbuf, 3); - pm_close( ifp ); - pm_close( stdout ); + pm_close(ifP); + pm_close(stdout); - exit( 0 ); + return 0; } diff --git a/generator/pgmkernel.c b/generator/pgmkernel.c index 4f40f003..ec634c16 100644 --- a/generator/pgmkernel.c +++ b/generator/pgmkernel.c @@ -174,14 +174,14 @@ writeKernel(FILE * const ofP, unsigned int const halfRows) { unsigned int row; - + pgm_writepgminit(stdout, cols, rows, maxval, 0); for (row = 0; row < halfRows; ++row) pgm_writepgmrow(stdout, halfKernel[row], cols, maxval, 0); /* Now write out the same rows in reverse order. */ - + for (; row < rows; ++row) pgm_writepgmrow(stdout, halfKernel[rows-1-row], cols, maxval, 0); } @@ -193,12 +193,15 @@ main(int argc, const char * argv[]) { struct CmdlineInfo cmdline; unsigned int arows; - int arow; + unsigned int arow; double xcenter, ycenter; /* row, column "number" of center of kernel */ double tMax; /* The maximum t value over all pixels */ - gray ** destarray; + gray ** halfKernel; + /* The upper half of the kernel we generate. The lower half is + just the mirror image of this. + */ pm_proginit(&argc, argv); @@ -213,27 +216,28 @@ main(int argc, const char * argv[]) { arows = (cmdline.rows + 1) / 2; /* Half the number of rows. Add 1 if odd. */ - destarray = pgm_allocarray(cmdline.cols, arows); + halfKernel = pgm_allocarray(cmdline.cols, arows); for (arow = 0; arow < arows; ++arow) { double const dy2 = SQR(arow - ycenter); unsigned int col; - - for (col = 0; col < cmdline.cols; ++col) { + for (col = 0; col < (cmdline.cols +1) / 2; ++col) { double const dx2 = SQR(col - xcenter); double const normalized = t(dx2, dy2, cmdline.weight) / 2 / tMax; - destarray[arow][col] = destarray[arow][cmdline.cols - col - 1] = - ROUNDU(cmdline.maxval * (0.5 + normalized)); + gray const grayval = ROUNDU(cmdline.maxval * (0.5 + normalized)); + + halfKernel[arow][col ] = grayval; + halfKernel[arow][cmdline.cols - col - 1] = grayval; } } writeKernel(stdout, cmdline.cols, cmdline.rows, cmdline.maxval, - destarray, arows); + halfKernel, arows); - pgm_freearray(destarray, arows); + pgm_freearray(halfKernel, arows); return 0; } diff --git a/generator/pgmmake.c b/generator/pgmmake.c index e33f64e0..f8f8b09c 100644 --- a/generator/pgmmake.c +++ b/generator/pgmmake.c @@ -46,16 +46,18 @@ parseCommandLine(int argc, char ** argv, pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + free (option_def); + if (!maxvalSpec) cmdlineP->maxval = PGM_MAXMAXVAL; else { if (cmdlineP->maxval > PGM_OVERALLMAXVAL) pm_error("The value you specified for -maxval (%u) is too big. " "Max allowed is %u", cmdlineP->maxval, PGM_OVERALLMAXVAL); - + if (cmdlineP->maxval < 1) pm_error("You cannot specify 0 for -maxval"); - } + } if (argc-1 < 3) pm_error("Need 3 arguments: gray level, width, height."); @@ -82,7 +84,7 @@ main(int argc, char *argv[]) { struct cmdlineInfo cmdline; gray * grayrow; - unsigned int row; + unsigned int col, row; pgm_init(&argc, argv); @@ -91,12 +93,12 @@ main(int argc, char *argv[]) { pgm_writepgminit(stdout, cmdline.cols, cmdline.rows, cmdline.maxval, 0); grayrow = pgm_allocrow(cmdline.cols); - for (row = 0; row < cmdline.rows; ++row) { - unsigned int col; - for (col = 0; col < cmdline.cols; ++col) - grayrow[col] = cmdline.grayLevel; + /* All rows are identical. Fill once. */ + for (col = 0; col < cmdline.cols; ++col) + grayrow[col] = cmdline.grayLevel; + + for (row = 0; row < cmdline.rows; ++row) pgm_writepgmrow(stdout, grayrow, cmdline.cols, cmdline.maxval, 0); - } pgm_freerow(grayrow); pm_close(stdout); diff --git a/generator/pgmramp.c b/generator/pgmramp.c index 56d6f8e2..225542fe 100644 --- a/generator/pgmramp.c +++ b/generator/pgmramp.c @@ -16,7 +16,7 @@ #include "pgm.h" #include "shhopt.h" -enum ramptype {RT_LR, RT_TB, RT_RECT, RT_ELLIP}; +enum ramptype {RT_LR, RT_TB, RT_DIAG, RT_RECT, RT_ELLIP}; struct cmdlineInfo { @@ -39,7 +39,7 @@ parseCommandLine(int argc, char ** argv, program can use easily, struct cmdlineInfo. Validate arguments along the way and exit program with message if invalid. - Note that some string information we return as *cmdlineP is in the storage + Note that some string information we return as *cmdlineP is in the storage argv[] points to. -----------------------------------------------------------------------------*/ optEntry *option_def = malloc(100*sizeof(optEntry)); @@ -47,13 +47,14 @@ parseCommandLine(int argc, char ** argv, */ optStruct3 opt; - unsigned int lrSpec, tbSpec, rectangleSpec, ellipseSpec; + unsigned int lrSpec, tbSpec, diagonalSpec, rectangleSpec, ellipseSpec; unsigned int maxvalSpec; unsigned int option_def_index; option_def_index = 0; /* incremented by OPTENTRY */ OPTENT3(0, "lr", OPT_FLAG, NULL, &lrSpec, 0); OPTENT3(0, "tb", OPT_FLAG, NULL, &tbSpec, 0); + OPTENT3(0, "diagonal", OPT_FLAG, NULL, &diagonalSpec, 0); OPTENT3(0, "rectangle", OPT_FLAG, NULL, &rectangleSpec, 0); OPTENT3(0, "ellipse", OPT_FLAG, NULL, &ellipseSpec, 0); OPTENT3(0, "maxval", OPT_UINT, &cmdlineP->maxval, &maxvalSpec, 0); @@ -65,15 +66,20 @@ parseCommandLine(int argc, char ** argv, pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ - if (lrSpec + tbSpec + rectangleSpec + ellipseSpec == 0) - pm_error("You must specify one of -lr, -tb, -rectangle, or -ellipse"); - if (lrSpec + tbSpec + rectangleSpec + ellipseSpec > 1) + free (option_def); + + if (lrSpec + tbSpec + diagonalSpec + rectangleSpec + ellipseSpec == 0) + pm_error("You must specify one of " + "-lr, -tb, -diagonal, -rectangle, or -ellipse"); + if (lrSpec + tbSpec + diagonalSpec + rectangleSpec + ellipseSpec > 1) pm_error("You may specify at most one of " - "-lr, -tb, -rectangle, or -ellipse"); + "-lr, -tb, -diagonal, -rectangle, or -ellipse"); if (lrSpec) cmdlineP->ramptype = RT_LR; else if (tbSpec) cmdlineP->ramptype = RT_TB; + else if (diagonalSpec) + cmdlineP->ramptype = RT_DIAG; else if (rectangleSpec) cmdlineP->ramptype = RT_RECT; else if (ellipseSpec) @@ -87,10 +93,10 @@ parseCommandLine(int argc, char ** argv, if (cmdlineP->maxval > PGM_OVERALLMAXVAL) pm_error("The value you specified for -maxval (%u) is too big. " "Max allowed is %u", cmdlineP->maxval, PGM_OVERALLMAXVAL); - + if (cmdlineP->maxval < 1) pm_error("You cannot specify 0 for -maxval"); - } + } if (argc-1 < 2) pm_error("Need two arguments: width and height."); @@ -105,7 +111,7 @@ parseCommandLine(int argc, char ** argv, -int +int main(int argc, char *argv[]) { struct cmdlineInfo cmdline; @@ -119,31 +125,36 @@ main(int argc, char *argv[]) { colso2 = MAX(1, cmdline.cols / 2); rowso2 = MAX(1, cmdline.rows / 2); - + pgm_writepgminit(stdout, cmdline.cols, cmdline.rows, cmdline.maxval, 0); grayrow = pgm_allocrow(cmdline.cols); - + for (row = 0; row < cmdline.rows; ++row) { unsigned int col; for (col = 0; col < cmdline.cols; ++col) { switch (cmdline.ramptype) { case RT_LR: - grayrow[col] = - col * cmdline.maxval / MAX(cmdline.cols-1, 1); + /* Fill row buffer once. All rows are identical. */ + if (row == 0) + grayrow[col] = + (float) col * cmdline.maxval / MAX(cmdline.cols-1, 1); break; case RT_TB: - grayrow[col] = - row * cmdline.maxval / MAX(cmdline.rows-1, 1); + grayrow[col] = + (float) row * cmdline.maxval / MAX(cmdline.rows-1, 1); + break; + case RT_DIAG: + grayrow[col] = + ((float) col + row) * cmdline.maxval / + MAX((float) cmdline.cols + cmdline.rows-2, 1); break; - case RT_RECT: { float const r = fabs((int)(rowso2 - row)) / rowso2; float const c = fabs((int)(colso2 - col)) / colso2; - grayrow[col] = + grayrow[col] = cmdline.maxval - (r + c) / 2.0 * cmdline.maxval; - } - break; - + } break; + case RT_ELLIP: { float const r = fabs((int)(rowso2 - row)) / rowso2; float const c = fabs((int)(colso2 - col)) / colso2; @@ -153,12 +164,11 @@ main(int argc, char *argv[]) { if ( v < 0.0 ) v = 0.0; else if ( v > 1.0 ) v = 1.0; grayrow[col] = cmdline.maxval - v * cmdline.maxval; + } break; } - break; - } - } + } pgm_writepgmrow(stdout, grayrow, cmdline.cols, cmdline.maxval, 0); - } + } pgm_freerow(grayrow); pm_close(stdout); diff --git a/generator/ppmmake.c b/generator/ppmmake.c index 9c8a2edb..2d4bbca8 100644 --- a/generator/ppmmake.c +++ b/generator/ppmmake.c @@ -58,16 +58,18 @@ parseCommandLine(int argc, char ** argv, pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + free (option_def); + if (!maxvalSpec) cmdlineP->maxval = PPM_MAXMAXVAL; else { if (cmdlineP->maxval > PPM_OVERALLMAXVAL) pm_error("The value you specified for -maxval (%u) is too big. " "Max allowed is %u", cmdlineP->maxval, PPM_OVERALLMAXVAL); - + if (cmdlineP->maxval < 1) pm_error("You cannot specify 0 for -maxval"); - } + } if (argc-1 < 3) pm_error("Need 3 arguments: color, width, height."); @@ -88,7 +90,7 @@ main(int argc, char *argv[]) { struct cmdlineInfo cmdline; pixel * pixrow; - unsigned int row; + unsigned int row, col; ppm_init(&argc, argv); @@ -97,12 +99,12 @@ main(int argc, char *argv[]) { ppm_writeppminit(stdout, cmdline.cols, cmdline.rows, cmdline.maxval, 0); pixrow = ppm_allocrow(cmdline.cols); - for (row = 0; row < cmdline.rows; ++row) { - unsigned int col; - for (col = 0; col < cmdline.cols; ++col) - pixrow[col] = cmdline.color; + /* All rows are identical. Fill once. */ + for (col = 0; col < cmdline.cols; ++col) + pixrow[col] = cmdline.color; + + for (row = 0; row < cmdline.rows; ++row) ppm_writeppmrow(stdout, pixrow, cmdline.cols, cmdline.maxval, 0); - } ppm_freerow(pixrow); pm_close(stdout); diff --git a/lib/Makefile b/lib/Makefile index 6512949f..d5f47813 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -13,7 +13,7 @@ else LIBNETPBM = $(NETPBMSHLIBPREFIX)netpbm$(DLLVER).$(NETPBMLIBSUFFIX) endif -ifeq ($(STATICLIB_TOO),y) +ifeq ($(STATICLIB_TOO),Y) EXTRA_STATICLIB = libnetpbm.$(STATICLIBSUFFIX) else EXTRA_STATICLIB = @@ -130,7 +130,7 @@ libnetpbm.$(NETPBMLIBSUFFIX).$(MAJ).$(MIN): $(LIBOBJECTS) $(LIBOBJECTS_X) endif ifeq ($(NETPBMLIBTYPE),dll) -ifeq ($(STATICLIB_TOO),y) +ifeq ($(STATICLIB_TOO),Y) $(NETPBMSHLIBPREFIX)netpbm$(DLLVER).dll: $(LIBOBJECTS) $(LIBOBJECTS_X) libnetpbm.$(STATICLIBSUFFIX) else $(NETPBMSHLIBPREFIX)netpbm$(DLLVER).dll: $(LIBOBJECTS) $(LIBOBJECTS_X) @@ -170,16 +170,16 @@ endif # STATICLIB_SUFFIX may just be arbitrary. #----------------------------------------------------------------------------- ifeq ($(NETPBMLIBTYPE),unixstatic) - BUILD_STATICLIB = y + BUILD_STATICLIB = Y else - ifeq ($(STATICLIB_TOO),y) - BUILD_STATICLIB = y + ifeq ($(STATICLIB_TOO),Y) + BUILD_STATICLIB = Y else BUILD_STATICLIB = n endif endif -ifeq ($(BUILD_STATICLIB),y) +ifeq ($(BUILD_STATICLIB),Y) libnetpbm.$(STATICLIBSUFFIX): $(LIBOBJECTS) $(LIBOBJECTS_X) -rm -f $@ $(AR) rc $@ $(LIBOBJECTS) $(LIBOBJECTS_X) @@ -190,7 +190,7 @@ endif # To avoid major hassles with having ppmdcfont available here, we just # ship a pre-made standardppmfont.c, so this rule will not normally be # used. -standardppmdfont.c:standard.ppmdfont +standardppmdfont.c: standard.ppmdfont ppmdcfont <$< >$@ # Note that we create a new compile.h only for the first make after a diff --git a/lib/libpamread.c b/lib/libpamread.c index 3c8e2e33..cbac18c1 100644 --- a/lib/libpamread.c +++ b/lib/libpamread.c @@ -202,6 +202,51 @@ parse4BpsRow(const struct pam * const pamP, static void +validatePamRow(const struct pam * const pamP, + tuple * const tuplerow, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Check for sample values above maxval in input. + + Note: a program that wants to deal with invalid sample values itself can + simply make sure it sets pamP->maxval sufficiently high, so this validation + never fails. +-----------------------------------------------------------------------------*/ + /* To save time, skip the test for if the maxval is a saturated value + (255, 65535) or format is PBM. + + This is an expensive test, but is skipped in most cases: in practice + maxvals other than 255 or 65535 are uncommon. Thus we do this in a + separate pass through the row rather than while reading in the row. + */ + + if (pamP->maxval == (((sample) 0x1) << pamP->bytes_per_sample*8) - 1 || + PAM_FORMAT_TYPE(pamP->format) == PBM_FORMAT) { + /* There's no way a sample can be invalid, so we don't need to + look at the samples individually. + */ + *errorP = NULL; + } else { + unsigned int col; + for (col = 0; col < pamP->width; ++col) { + unsigned int plane; + for (plane = 0; plane < pamP->depth; ++plane) { + if (tuplerow[col][plane] > pamP->maxval) { + pm_asprintf(errorP, + "Plane %u sample value %lu exceeds the " + "image maxval of %lu", + plane, tuplerow[col][plane], pamP->maxval); + return; + } + } + } + *errorP = NULL; + } +} + + + +static void readRawNonPbmRow(const struct pam * const pamP, tuple * const tuplerow) { @@ -234,8 +279,10 @@ readRawNonPbmRow(const struct pam * const pamP, case 4: parse4BpsRow(pamP, tuplerow, inbuf); break; default: pm_asprintf(&error, "invalid bytes per sample passed to " - "pnm_formatpamrow(): %u", pamP->bytes_per_sample); + "pnm_formatpamrow(): %u", pamP->bytes_per_sample); } + if (error == NULL) + validatePamRow(pamP, tuplerow, &error); } } pnm_freerowimage(inbuf); @@ -264,7 +311,7 @@ pnm_readpamrow(const struct pam * const pamP, /* For speed, we don't check any of the inputs for consistency here (unless it's necessary to avoid crashing). Any consistency checking should have been done by a prior call to - pnm_writepaminit(). + pnm_readpaminit(). */ /* Need a special case for raw PBM because it has multiple tuples (8) diff --git a/lib/libpgm1.c b/lib/libpgm1.c index 987ee04e..57344c16 100644 --- a/lib/libpgm1.c +++ b/lib/libpgm1.c @@ -100,10 +100,13 @@ validateComputableSize(unsigned int const cols, you expect. That failed expectation can be disastrous if you use it to allocate memory. + It is very normal to allocate space for a pixel row, so we make sure + the size of a pixel row, in bytes, can be represented by an 'int'. + A common operation is adding 1 or 2 to the highest row or column number in the image, so we make sure that's possible. -----------------------------------------------------------------------------*/ - if (cols > INT_MAX - 2) + if (cols > INT_MAX / (sizeof(gray)) || cols > INT_MAX - 2) pm_error("image width (%u) too large to be processed", cols); if (rows > INT_MAX - 2) pm_error("image height (%u) too large to be processed", rows); @@ -172,11 +175,44 @@ pgm_readpgminit(FILE * const fileP, static void +validateRpgmRow(gray * const grayrow, + unsigned int const cols, + gray const maxval, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Check for sample values above maxval in input. + + Note: a program that wants to deal with invalid sample values itself can + simply make sure it uses a sufficiently high maxval on the read function + call, so this validation never fails. +-----------------------------------------------------------------------------*/ + if (maxval == 255 || maxval == 65535) { + /* There's no way a sample can be invalid, so we don't need to look at + the samples individually. + */ + *errorP = NULL; + } else { + unsigned int col; + for (col = 0; col < cols; ++col) { + if (grayrow[col] > maxval) { + pm_asprintf(errorP, + "gray value %u is greater than maxval (%u)", + grayrow[col], maxval); + return; + } + } + *errorP = NULL; + } +} + + + +static void readRpgmRow(FILE * const fileP, - gray * const grayrow, - int const cols, - gray const maxval, - int const format) { + gray * const grayrow, + int const cols, + gray const maxval, + int const format) { unsigned int const bytesPerSample = maxval < 256 ? 1 : 2; int const bytesPerRow = cols * bytesPerSample; @@ -198,7 +234,6 @@ readRpgmRow(FILE * const fileP, pm_asprintf(&error, "Error reading row. Short read of %u bytes " "instead of %u", (unsigned)rc, bytesPerRow); else { - error = NULL; if (maxval < 256) { unsigned int col; for (col = 0; col < cols; ++col) @@ -218,6 +253,7 @@ readRpgmRow(FILE * const fileP, grayrow[col] = g; } } + validateRpgmRow(grayrow, cols, maxval, &error); } free(rowBuffer); } @@ -241,7 +277,7 @@ readPbmRow(FILE * const fileP, jmp_buf * origJmpbufP; bit * bitrow; - bitrow = pbm_allocrow(cols); + bitrow = pbm_allocrow_packed(cols); if (setjmp(jmpbuf) != 0) { pbm_freerow(bitrow); pm_setjmpbuf(origJmpbufP); @@ -251,10 +287,14 @@ readPbmRow(FILE * const fileP, pm_setjmpbufsave(&jmpbuf, &origJmpbufP); - pbm_readpbmrow(fileP, bitrow, cols, format); - for (col = 0; col < cols; ++col) - grayrow[col] = (bitrow[col] == PBM_WHITE ) ? maxval : 0; + pbm_readpbmrow_packed(fileP, bitrow, cols, format); + for (col = 0; col < cols; ++col) { + grayrow[col] = + ((bitrow[col/8] >> (7 - col%8)) & 0x1) == PBM_WHITE ? + maxval : 0 + ; + } pm_setjmpbuf(origJmpbufP); } pbm_freerow(bitrow); diff --git a/lib/libpnm1.c b/lib/libpnm1.c index 536e5dc4..29fee13a 100644 --- a/lib/libpnm1.c +++ b/lib/libpnm1.c @@ -72,10 +72,13 @@ validateComputableSize(unsigned int const cols, you expect. That failed expectation can be disastrous if you use it to allocate memory. + It is very normal to allocate space for a pixel row, so we make sure + the size of a pixel row, in bytes, can be represented by an 'int'. + A common operation is adding 1 or 2 to the highest row or column number in the image, so we make sure that's possible. -----------------------------------------------------------------------------*/ - if (cols > INT_MAX - 2) + if (cols > INT_MAX/(sizeof(pixval) * 3) || cols > INT_MAX - 2) pm_error("image width (%u) too large to be processed", cols); if (rows > INT_MAX - 2) pm_error("image height (%u) too large to be processed", rows); @@ -178,10 +181,10 @@ readpbmrow(FILE * const fileP, jmp_buf * origJmpbufP; bit * bitrow; - bitrow = pbm_allocrow(cols); + bitrow = pbm_allocrow_packed(cols); if (setjmp(jmpbuf) != 0) { - pbm_freerow(bitrow); + pbm_freerow_packed(bitrow); pm_setjmpbuf(origJmpbufP); pm_longjmp(); } else { @@ -189,11 +192,14 @@ readpbmrow(FILE * const fileP, pm_setjmpbufsave(&jmpbuf, &origJmpbufP); - pbm_readpbmrow(fileP, bitrow, cols, format); - - for (col = 0; col < cols; ++col) - PNM_ASSIGN1(xelrow[col], bitrow[col] == PBM_BLACK ? 0 : maxval); + pbm_readpbmrow_packed(fileP, bitrow, cols, format); + for (col = 0; col < cols; ++col) { + pixval const g = + ((bitrow[col/8] >> (7 - col%8)) & 0x1) == PBM_WHITE ? + maxval : 0; + PNM_ASSIGN1(xelrow[col], g); + } pm_setjmpbuf(origJmpbufP); } pbm_freerow(bitrow); diff --git a/lib/libppm1.c b/lib/libppm1.c index 195aec70..ff940540 100644 --- a/lib/libppm1.c +++ b/lib/libppm1.c @@ -100,10 +100,13 @@ validateComputableSize(unsigned int const cols, you expect. That failed expectation can be disastrous if you use it to allocate memory. + It is very normal to allocate space for a pixel row, so we make sure + the size of a pixel row, in bytes, can be represented by an 'int'. + A common operation is adding 1 or 2 to the highest row or column number in the image, so we make sure that's possible. -----------------------------------------------------------------------------*/ - if (cols > INT_MAX - 2) + if (cols > INT_MAX/(sizeof(pixval) * 3) || cols > INT_MAX - 2) pm_error("image width (%u) too large to be processed", cols); if (rows > INT_MAX - 2) pm_error("image height (%u) too large to be processed", rows); @@ -224,6 +227,52 @@ interpRasterRowRaw(const unsigned char * const rowBuffer, static void +validateRppmRow(pixel * const pixelrow, + unsigned int const cols, + pixval const maxval, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Check for sample values above maxval in input. + + Note: a program that wants to deal with invalid sample values itself can + simply make sure it uses a sufficiently high maxval on the read function + call, so this validation never fails. +-----------------------------------------------------------------------------*/ + if (maxval == 255 || maxval == 65535) { + /* There's no way a sample can be invalid, so we don't need to look at + the samples individually. + */ + *errorP = NULL; + } else { + unsigned int col; + + for (col = 0, *errorP = NULL; col < cols && !*errorP; ++col) { + pixval const r = PPM_GETR(pixelrow[col]); + pixval const g = PPM_GETG(pixelrow[col]); + pixval const b = PPM_GETB(pixelrow[col]); + + if (r > maxval) + pm_asprintf( + errorP, + "Red sample value %u is greater than maxval (%u)", + r, maxval); + else if (g > maxval) + pm_asprintf( + errorP, + "Green sample value %u is greater than maxval (%u)", + g, maxval); + else if (b > maxval) + pm_asprintf( + errorP, + "Blue sample value %u is greater than maxval (%u)", + b, maxval); + } + } +} + + + +static void readRppmRow(FILE * const fileP, pixel * const pixelrow, unsigned int const cols, @@ -259,7 +308,8 @@ readRppmRow(FILE * const fileP, "instead of %u", (unsigned)bytesRead, bytesPerRow); else { interpRasterRowRaw(rowBuffer, pixelrow, cols, bytesPerSample); - error = NULL; + + validateRppmRow(pixelrow, cols, maxval, &error); } } free(rowBuffer); @@ -319,10 +369,10 @@ readPbmRow(FILE * const fileP, jmp_buf * origJmpbufP; bit * bitrow; - bitrow = pbm_allocrow(cols); + bitrow = pbm_allocrow_packed(cols); if (setjmp(jmpbuf) != 0) { - pbm_freerow(bitrow); + pbm_freerow_packed(bitrow); pm_setjmpbuf(origJmpbufP); pm_longjmp(); } else { @@ -330,10 +380,12 @@ readPbmRow(FILE * const fileP, pm_setjmpbufsave(&jmpbuf, &origJmpbufP); - pbm_readpbmrow(fileP, bitrow, cols, format); + pbm_readpbmrow_packed(fileP, bitrow, cols, format); for (col = 0; col < cols; ++col) { - pixval const g = (bitrow[col] == PBM_WHITE) ? maxval : 0; + pixval const g = + ((bitrow[col/8] >> (7 - col%8)) & 0x1) == PBM_WHITE ? + maxval : 0; PPM_ASSIGN(pixelrow[col], g, g, g); } pm_setjmpbuf(origJmpbufP); diff --git a/lib/standardppmdfont.c b/lib/standardppmdfont.c index aa4707e2..bc0c8ff8 100644 --- a/lib/standardppmdfont.c +++ b/lib/standardppmdfont.c @@ -1,4 +1,4 @@ -/* THIS FILE WAS GENERATED BY 'ppmdcfont' from a ppmfont file. */ +/* THIS FILE WAS GENERATED BY 'ppmdcfont' from a ppmdfont file. */ #include "ppmdfont.h" diff --git a/other/Makefile b/other/Makefile index 1c25d6a6..69562be0 100644 --- a/other/Makefile +++ b/other/Makefile @@ -24,8 +24,8 @@ endif # build. PORTBINARIES = pamarith pambayer pamchannel pamdepth \ - pamendian pamexec pamfixtrunc pamlookup pampick pamsplit \ - pamstack pamsummcol pnmcolormap \ + pamendian pamexec pamfix pamlookup pampick pamsplit \ + pamstack pamsummcol pamvalidate pnmcolormap \ ppmdcfont ppmddumpfont ppmdmkfont BINARIES = $(PORTBINARIES) @@ -34,7 +34,7 @@ ifneq ($(LINUXSVGALIB),NONE) BINARIES += ppmsvgalib endif -SCRIPTS = ppmtomap +SCRIPTS = ppmtomap pamfixtrunc OBJECTS = $(BINARIES:%=%.o) diff --git a/other/pamchannel.c b/other/pamchannel.c index 3adb0e66..e89a979b 100644 --- a/other/pamchannel.c +++ b/other/pamchannel.c @@ -14,14 +14,14 @@ #include <string.h> #include "pm_c_util.h" -#include "pam.h" -#include "shhopt.h" #include "mallocvar.h" +#include "shhopt.h" +#include "pam.h" #define MAX_CHANNELS 16 /* The most channels we allow user to specify */ -struct cmdlineInfo { +struct CmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. */ @@ -37,7 +37,7 @@ struct cmdlineInfo { static void parseCommandLine(int argc, const char ** argv, - struct cmdlineInfo * const cmdlineP) { + struct CmdlineInfo * const cmdlineP) { /*---------------------------------------------------------------------------- Note that the file spec array we return is stored in the storage that was passed to us as the argv array. @@ -176,7 +176,7 @@ doOneImage(FILE * const ifP, int main(int argc, const char *argv[]) { - struct cmdlineInfo cmdline; + struct CmdlineInfo cmdline; FILE * ifP; int eof; diff --git a/other/pamfix.c b/other/pamfix.c new file mode 100644 index 00000000..8db67e08 --- /dev/null +++ b/other/pamfix.c @@ -0,0 +1,291 @@ +/*============================================================================ + pamfix +============================================================================== + Salvage a Netpbm image that is corrupted in certain ways. + + By Bryan Henderson, January 2007. + + Contributed to the public domain by its author. +============================================================================*/ + +#include <setjmp.h> + +#include "pm_c_util.h" +#include "pam.h" +#include "shhopt.h" +#include "mallocvar.h" + +struct cmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char * inputFileName; /* File name of input file */ + unsigned int verbose; + unsigned int truncate; + unsigned int changemaxval; + unsigned int clip; +}; + + + +static void +parseCommandLine(int argc, char ** const argv, + struct cmdlineInfo * const cmdlineP) { +/*---------------------------------------------------------------------------- + Note that the file spec array we return is stored in the storage that + was passed to us as the argv array. +-----------------------------------------------------------------------------*/ + optEntry * option_def; + + optStruct3 opt; + + unsigned int option_def_index; + + MALLOCARRAY(option_def, 100); + + option_def_index = 0; /* incremented by OPTENTRY */ + + OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); + OPTENT3(0, "truncate", OPT_FLAG, NULL, &cmdlineP->truncate, 0); + OPTENT3(0, "changemaxval", OPT_FLAG, NULL, &cmdlineP->changemaxval, 0); + OPTENT3(0, "clip", OPT_FLAG, NULL, &cmdlineP->clip, 0); + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ + opt.allowNegNum = FALSE; /* We don't parms that are negative numbers */ + + pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + free(option_def); + + if (argc-1 == 0) + cmdlineP->inputFileName = "-"; + else if (argc-1 != 1) + pm_error("Program takes zero or one argument (filename). You " + "specified %d", argc-1); + else + cmdlineP->inputFileName = argv[1]; + + if (cmdlineP->changemaxval && cmdlineP->clip) + pm_error("You cannot specify both -changemaxval and -clip"); +} + + + +static unsigned int readErrRow; +static bool readErrVerbose; + +static pm_usererrormsgfn handleRowErrMsg; + +static void +handleRowErrMsg(const char * const msg) { + if (readErrVerbose) + pm_message("Error reading row %u: %s", readErrRow, msg); +} + + +static sample +highestSampleInRow(const struct pam * const pamP, + tuple * const tuplerow) { + + unsigned int col; + sample highestSoFar; + + for (col = 0, highestSoFar = 0; col < pamP->width; ++col) { + unsigned int plane; + for (plane = 0; plane < pamP->depth; ++plane) + highestSoFar = MAX(highestSoFar, tuplerow[col][plane]); + } + return highestSoFar; +} + + + +static void +analyzeRaster(const struct pam * const pamP, + unsigned int * const goodRowCountP, + sample * const highestSampleP, + bool const mustAbortOnReadError, + bool const verbose) { +/*---------------------------------------------------------------------------- + Go through the raster at which the stream described by *tweakedPamP is + presently positioned and count how many rows can be successfully read + (including validating the samples against pamP->maxval) and determine the + highest sample value in those rows. + + Leave the stream positioned arbitrarily. +-----------------------------------------------------------------------------*/ + tuple * tuplerow; + unsigned int row; + jmp_buf jmpbuf; + int rc; + + tuplerow = pnm_allocpamrow(pamP); + + pm_setusererrormsgfn(handleRowErrMsg); + + rc = setjmp(jmpbuf); + if (rc == 0) { + pm_setjmpbuf(&jmpbuf); + + readErrVerbose = mustAbortOnReadError || verbose; + *goodRowCountP = 0; /* initial value */ + *highestSampleP = 0; /* initial value */ + + for (row = 0; row < pamP->height; ++row) { + readErrRow = row; + pnm_readpamrow(pamP, tuplerow); + /* The above does not return if it can't read the next row from + the file. Instead, it longjmps out of this loop. + + Update return stats now in case the next iteration longjmps out. + */ + *highestSampleP = + MAX(*highestSampleP, + highestSampleInRow(pamP, tuplerow)); + ++*goodRowCountP; + } + } else { + /* pnm_readpamrow() encountered an error and longjmped */ + if (mustAbortOnReadError) { + /* handleRowErrMsg() has issued the error message */ + exit(1); + } + } + pm_setjmpbuf(NULL); + + pm_setusererrormsgfn(NULL); + + pnm_freepamrow(tuplerow); +} + + + +static void +clipPamRow(const struct pam * const pamP, + tuple * const tuplerow, + unsigned int const row, + bool const verbose) { +/*---------------------------------------------------------------------------- + Clip every sample value in tuplerow[] to the maxval. + + If 'verbose' is true, issue messages about every clipping, indicating it + is in row 'row'. +-----------------------------------------------------------------------------*/ + unsigned int col; + + for (col = 0; col < pamP->width; ++col) { + unsigned int plane; + for (plane = 0; plane < pamP->depth; ++plane) { + if (tuplerow[col][plane] > pamP->maxval) { + if (verbose) + pm_message("Clipping: Row %u Col %u Plane %u. " + "Sample value %lu exceeds the " + "image maxval of %lu", + row, col, plane, tuplerow[col][plane], + pamP->maxval); + tuplerow[col][plane] = pamP->maxval; + } + } + } +} + + + +static void +copyGoodRows(const struct pam * const inpamP, + const struct pam * const outpamP, + bool const verbose) { +/*---------------------------------------------------------------------------- + Copy the raster of the input stream described by *inpamP to the output + stream described by *outpamP. Copy only as many rows as *outpamP allows; + assume *outpamP specifies at most the number of rows of input. +-----------------------------------------------------------------------------*/ + tuple * tuplerow; + unsigned int row; + + tuplerow = pnm_allocpamrow(inpamP); + + for (row = 0; row < outpamP->height; ++row) { + pnm_readpamrow(inpamP, tuplerow); + clipPamRow(outpamP, tuplerow, row, verbose); + pnm_writepamrow(outpamP, tuplerow); + } + + pnm_freepamrow(tuplerow); +} + + + +int +main(int argc, char * argv[]) { + struct cmdlineInfo cmdline; + struct pam inpam; + struct pam outpam; + struct pam tweakedPam; + FILE * ifP; + pm_filepos rasterPos; + unsigned int goodRowCount; + sample highestSample; + + pnm_init(&argc, argv); + + parseCommandLine(argc, argv, &cmdline); + + ifP = pm_openr_seekable(cmdline.inputFileName); + + pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); + + pm_tell2(ifP, &rasterPos, sizeof(rasterPos)); + + /* Tweak maxval to circumvent out-of-bounds sample value check + in libpam. See function validatePamRow() in libpamread.c . + + Ideally we would like to set tweaked-maxval higher for the + plain (text) formats. We make a compromise to keep things + simple. + */ + + tweakedPam = inpam; /* initial value */ + + if ((cmdline.clip || cmdline.changemaxval) + && PNM_FORMAT_TYPE(inpam.format) != PBM_TYPE) + tweakedPam.maxval = + (((sample) 1) << tweakedPam.bytes_per_sample * 8) - 1; + + analyzeRaster(&tweakedPam, &goodRowCount, &highestSample, + !cmdline.truncate, cmdline.verbose); + + if (goodRowCount == 0) + pm_error("Cannot read a single row from the image%s", + cmdline.verbose ? "" : ". Use -verbose to find out why"); + + if (goodRowCount < inpam.height) + pm_message("Copying %u good rows; %u bottom rows missing%s", + goodRowCount, inpam.height - goodRowCount, + cmdline.verbose ? "" : ". Use -verbose to find out why"); + + pm_seek2(ifP, &rasterPos, sizeof(rasterPos)); + + outpam = inpam; /* initial value */ + + outpam.file = stdout; + outpam.height = goodRowCount; + if (cmdline.changemaxval && highestSample > outpam.maxval) { + pm_message("Raising maxval from %lu to %lu to legitimize " + "all sample values", + outpam.maxval, highestSample); + outpam.maxval = highestSample; + } + + pnm_writepaminit(&outpam); + + copyGoodRows(&tweakedPam, &outpam, cmdline.verbose); + + pm_close(inpam.file); + + return 0; +} + + + diff --git a/other/pamfixtrunc b/other/pamfixtrunc new file mode 100755 index 00000000..1aa3ff94 --- /dev/null +++ b/other/pamfixtrunc @@ -0,0 +1,50 @@ +#!/bin/sh + +############################################################################## +# This is essentially a Perl program. We exec the Perl interpreter specifying +# this same file as the Perl program and use the -x option to cause the Perl +# interpreter to skip down to the Perl code. The reason we do this instead of +# just making /usr/bin/perl the script interpreter (instead of /bin/sh) is +# that the user may have multiple Perl interpreters and the one he wants to +# use is properly located in the PATH. The user's choice of Perl interpreter +# may be crucial, such as when the user also has a PERL5LIB environment +# variable and it selects modules that work with only a certain main +# interpreter program. +# +# An alternative some people use is to have /usr/bin/env as the script +# interpreter. We don't do that because we think the existence and +# compatibility of /bin/sh is more reliable. +# +# Note that we aren't concerned about efficiency because the user who needs +# high efficiency can use directly the programs that this program invokes. +# +############################################################################## + +exec perl -w -x -S -- "$0" "$@" + +#!/usr/bin/perl +############################################################################## +# This is nothing but a compatibility interface for Pamfixtrunc. +# An old program coded to call Pamfixtrunc will continue working because +# this interface exists. All new (or newly modified) programs should +# call Pamfix instead. +############################################################################## + +use strict; +use File::Basename; +use Cwd 'abs_path'; + +my @pamFixOptions; + +@pamFixOptions = @ARGV; # initial value + +push(@pamFixOptions, '-truncate'); + +# We want to get Pamfix from the same directory we came from if +# it's there. Frequently, the directory containing Netpbm programs is +# not in the PATH and we were invoked by absolute path. + +my $my_directory = abs_path(dirname($0)); +$ENV{"PATH"} = $my_directory . ":" . $ENV{"PATH"}; + +exit(system('pamfix', @pamFixOptions)>>8); diff --git a/other/pamfixtrunc.c b/other/pamfixtrunc.c deleted file mode 100644 index 8d58b447..00000000 --- a/other/pamfixtrunc.c +++ /dev/null @@ -1,176 +0,0 @@ -/*============================================================================ - pamfixtrunc -============================================================================== - Fix a Netpbm image that has been truncated, e.g. by I/O error. - - By Bryan Henderson, January 2007. - - Contributed to the public domain by its author. - -============================================================================*/ - -#include <setjmp.h> - -#include "pm_c_util.h" -#include "pam.h" -#include "shhopt.h" -#include "mallocvar.h" - -struct cmdlineInfo { - /* All the information the user supplied in the command line, - in a form easy for the program to use. - */ - const char * inputFilespec; /* Filespec of input file */ - unsigned int verbose; -}; - - - -static void -parseCommandLine(int argc, char ** const argv, - struct cmdlineInfo * const cmdlineP) { -/*---------------------------------------------------------------------------- - Note that the file spec array we return is stored in the storage that - was passed to us as the argv array. ------------------------------------------------------------------------------*/ - optEntry * option_def; - - optStruct3 opt; - - unsigned int option_def_index; - - MALLOCARRAY(option_def, 100); - - option_def_index = 0; /* incremented by OPTENTRY */ - - 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 don't parms that are negative numbers */ - - pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0); - /* Uses and sets argc, argv, and some of *cmdlineP and others. */ - - if (argc-1 == 0) - cmdlineP->inputFilespec = "-"; - else if (argc-1 != 1) - pm_error("Program takes zero or one argument (filename). You " - "specified %d", argc-1); - else - cmdlineP->inputFilespec = argv[1]; -} - - - -static unsigned int readErrRow; -static bool readErrVerbose; - -static pm_usererrormsgfn discardMsg; - -static void -discardMsg(const char * const msg) { - if (readErrVerbose) - pm_message("Error reading row %u: %s", readErrRow, msg); -} - - - -static void -countRows(const struct pam * const inpamP, - bool const verbose, - unsigned int * const goodRowCountP) { - - tuple * tuplerow; - unsigned int row; - jmp_buf jmpbuf; - int rc; - unsigned int goodRowCount; - - tuplerow = pnm_allocpamrow(inpamP); - - pm_setusererrormsgfn(discardMsg); - - rc = setjmp(jmpbuf); - if (rc == 0) { - pm_setjmpbuf(&jmpbuf); - - readErrVerbose = verbose; - goodRowCount = 0; /* initial value */ - for (row = 0; row < inpamP->height; ++row) { - readErrRow = row; - pnm_readpamrow(inpamP, tuplerow); - /* The above does not return if it can't read the next row from - the file. Instead, it longjmps out of this loop. - */ - ++goodRowCount; - } - } - *goodRowCountP = goodRowCount; - - pnm_freepamrow(tuplerow); -} - - - -static void -copyGoodRows(const struct pam * const inpamP, - FILE * const ofP, - unsigned int const goodRowCount) { - - struct pam outpam; - tuple * tuplerow; - unsigned int row; - - outpam = *inpamP; /* initial value */ - - outpam.file = ofP; - outpam.height = goodRowCount; - - tuplerow = pnm_allocpamrow(inpamP); - - pnm_writepaminit(&outpam); - - for (row = 0; row < outpam.height; ++row) { - pnm_readpamrow(inpamP, tuplerow); - pnm_writepamrow(&outpam, tuplerow); - } - - pnm_freepamrow(tuplerow); -} - - - -int -main(int argc, char * argv[]) { - struct cmdlineInfo cmdline; - struct pam inpam; - FILE * ifP; - pm_filepos rasterPos; - unsigned int goodRowCount; - - pnm_init(&argc, argv); - - parseCommandLine(argc, argv, &cmdline); - - ifP = pm_openr_seekable(cmdline.inputFilespec); - - pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); - - pm_tell2(ifP, &rasterPos, sizeof(rasterPos)); - - countRows(&inpam, cmdline.verbose, &goodRowCount); - - pm_message("Copying %u good rows; %u bottom rows missing", - goodRowCount, inpam.height - goodRowCount); - - pm_seek2(ifP, &rasterPos, sizeof(rasterPos)); - - copyGoodRows(&inpam, stdout, goodRowCount); - - pm_close(inpam.file); - - return 0; -} - - diff --git a/other/pamvalidate.c b/other/pamvalidate.c new file mode 100644 index 00000000..a7b08b8e --- /dev/null +++ b/other/pamvalidate.c @@ -0,0 +1,86 @@ +/*============================================================================= + pamvalidate +=============================================================================== + Part of the Netpbm package. + + Copy PAM and PNM (i.e. PBM, PGM, or PPM) images from Standard Input + to Standard Output. No output when input is invalid. + + Contributed to the public domain by its author. +=============================================================================*/ + +#include <string.h> +#include "pm_c_util.h" +#include "pam.h" + + + +int +main(int argc, const char * argv[]) { + + FILE * const tmpfile = pm_tmpfile(); + int eof; /* no more images in input stream */ + struct pam inpam; /* Input PAM image */ + struct pam outpam; /* Output PAM image */ + + pm_proginit(&argc, argv); + + if (argc-1 != 0) + pm_error("Program takes no arguments. Input is from Standard Input"); + + for (eof = FALSE; !eof; ) { + pnm_readpaminit(stdin, &inpam, PAM_STRUCT_SIZE(tuple_type)); + + outpam = inpam; /* initial value */ + outpam.file = tmpfile; + + pnm_writepaminit(&outpam); + + if (PNM_FORMAT_TYPE(inpam.format) == PBM_TYPE) { + /* Fast method for PBM */ + unsigned char * const inrow = pbm_allocrow_packed(inpam.width); + + unsigned int row; + + for (row = 0; row < inpam.height; ++row) { + pbm_readpbmrow_packed(inpam.file, inrow, inpam.width, + inpam.format); + pbm_writepbmrow_packed(tmpfile, inrow, inpam.width, 0); + } + pbm_freerow(inrow); + + } else { + /* General case. Logic works for PBM */ + tuple * const tuplerow = pnm_allocpamrow(&inpam); + + unsigned int row; + + for (row = 0; row < inpam.height; ++row) { + pnm_readpamrow(&inpam, tuplerow); + pnm_writepamrow(&outpam, tuplerow); + } + pnm_freepamrow(tuplerow); + } + pnm_nextimage(stdin, &eof); + } + + fseek(tmpfile, 0, SEEK_SET); + + while (!feof(tmpfile) && !ferror(tmpfile) && !ferror(stdout)) { + char buffer[4096]; + size_t bytesReadCt; + + bytesReadCt = fread(buffer, 1, sizeof(buffer), tmpfile); + + if (ferror(tmpfile)) + pm_error("Error reading from temporary file. " + "Incomplete output. " + "Errno = %s (%d)", strerror(errno), errno); + else + fwrite(buffer, 1, bytesReadCt, stdout); + } + pm_close(tmpfile); + pm_close(stdout); + + return 0; +} diff --git a/test/411toppm.test b/test/411toppm.test index ce374f29..335cdcc8 100755 --- a/test/411toppm.test +++ b/test/411toppm.test @@ -2,6 +2,9 @@ # This script tests: 411toppm # Also requires: + alias 411toppm="${PBM_TESTPREFIX}411toppm" + shopt -s expand_aliases + # Test 1. should produce: 240376509 9229 # The above value is what 411toppm has been always producing. # 411toppm's author Steve Allen says he was not able to obtain accurate @@ -9,4 +12,4 @@ # # See comment at head of source file 411toppm.c. -head -c 4608 /dev/zero | ${PBM_TESTPREFIX}411toppm -quiet | cksum +head -c 4608 /dev/zero | 411toppm -quiet | cksum diff --git a/test/Execute-Tests b/test/Execute-Tests index 7a1a3793..68dd5581 100755 --- a/test/Execute-Tests +++ b/test/Execute-Tests @@ -118,12 +118,25 @@ export PATH=${srcdir}:$PATH # By default the tests are executed in the order described in the # file Test-Order. Copy this file from the source directory # to the work directory. +# +# The string "target" is a comma-separated list of target programs. +# When set only tests for programs in the list will be run. # # The --no-clobber version comes useful when the user wants a modified # (pared-down) version of Test-Order. -cp ${srcdir}/Test-Order ./Test-Order -#cp --no-clobber ${srcdir}/Test-Order ./Test-Order +if [ ! -z $target ] + then echo $target | sed 's/,/\n/g' | \ + sed 's/^/\${PBM_TESTPREFIX}/' | \ + grep -f - ${srcdir}/*.test -l | \ + while read i ; do echo ${i##*/} ; done | + grep -f - ${srcdir}/Test-Order > ./Test-Order ; + else + cp ${srcdir}/Test-Order ./Test-Order ; + #cp --no-clobber ${srcdir}/Test-Order ./Test-Order ; +fi + +#let array[5]=0 for t in `grep -v "^#" ./Test-Order | fgrep ".test"` do @@ -134,6 +147,7 @@ case $result in if [ $? -eq 0 ] then let result=0; rm ${t%.test}.out ; else let result=1; + grep "^##" ${srcdir}/$t # Print failure message. fi let testable=1 ;; 80) let result=4 ; let testable=0;; @@ -173,7 +187,7 @@ echo ================== for s in 0 1 2 3 4 5 do - if [[ ${array[${s}]} -gt 0 || s -eq 1 ]] + if [[ ${array[${s}]} -gt 0 || s -eq 1 || s -eq 5 ]] then echo ${status[${s}]} ${array[${s}]} fi done diff --git a/test/Test-Order b/test/Test-Order index 31cd5324..ff4b9855 100644 --- a/test/Test-Order +++ b/test/Test-Order @@ -61,12 +61,17 @@ pnmremap2.test pnmtile.test ppmbrighten.test ppmdither.test +ppmrelief.test pamedge.test ppmdim.test pnmshear.test ppmmix.test +# Symmetry test + +symmetry.test + # Format converter tests pbmtog3.test @@ -104,6 +109,7 @@ gem-roundtrip.test gif-roundtrip.test gif-quant-roundtrip.test hdiff-roundtrip.test +jbig-roundtrip.test leaf-roundtrip.test mgr-roundtrip.test mrf-roundtrip.test diff --git a/test/atk-roundtrip.test b/test/atk-roundtrip.test index f64b0c3c..3d15eec4 100755 --- a/test/atk-roundtrip.test +++ b/test/atk-roundtrip.test @@ -2,5 +2,9 @@ # This script tests: pbmtoatk atktopbm # Also requires: + alias atktopbm="${PBM_TESTPREFIX}atktopbm" + alias pbmtoatk="${PBM_TESTPREFIX}pbmtoatk" + shopt -s expand_aliases + # Should print 2425386270 41, cksum of testgrid.pbm -${PBM_TESTPREFIX}pbmtoatk testgrid.pbm | ${PBM_TESTPREFIX}atktopbm | cksum +pbmtoatk testgrid.pbm | atktopbm | cksum diff --git a/test/avs-roundtrip.test b/test/avs-roundtrip.test index 33f9e581..44b4d8a4 100755 --- a/test/avs-roundtrip.test +++ b/test/avs-roundtrip.test @@ -2,6 +2,11 @@ # This script tests: pamtoavs avstopam # Also requires: pamtopnm + alias avstopam="${PBM_TESTPREFIX}avstopam" + alias pamtoavs="${PBM_TESTPREFIX}pamtoavs" + alias pamtopnm="${PBM_BINPREFIX}pamtopnm" + shopt -s expand_aliases + # Should produce 1926073387 101484, cksum of testimg.ppm -${PBM_TESTPREFIX}pamtoavs testimg.ppm | \ - ${PBM_TESTPREFIX}avstopam | ${PBM_BINPREFIX}pamtopnm | cksum +pamtoavs testimg.ppm | \ + avstopam | pamtopnm | cksum diff --git a/test/bmp-roundtrip.test b/test/bmp-roundtrip.test index af0e6948..291f2669 100755 --- a/test/bmp-roundtrip.test +++ b/test/bmp-roundtrip.test @@ -2,5 +2,9 @@ # This script tests: bmptopnm ppmtobmp # Also requires: -${PBM_TESTPREFIX}ppmtobmp testimg.ppm | ${PBM_TESTPREFIX}bmptopnm | cksum -${PBM_TESTPREFIX}ppmtobmp testgrid.pbm | ${PBM_TESTPREFIX}bmptopnm | cksum \ No newline at end of file + alias bmptopnm="${PBM_TESTPREFIX}bmptopnm" + alias ppmtobmp="${PBM_TESTPREFIX}ppmtobmp" + shopt -s expand_aliases + +ppmtobmp testimg.ppm | bmptopnm | cksum +ppmtobmp testgrid.pbm | bmptopnm | cksum diff --git a/test/cmuw-roundtrip.test b/test/cmuw-roundtrip.test index 85de9706..ebb5eecf 100755 --- a/test/cmuw-roundtrip.test +++ b/test/cmuw-roundtrip.test @@ -2,5 +2,9 @@ # This script tests: pbmtocmuwm cmuwmtopbm # Also requires: + alias cmuwmtopbm="${PBM_TESTPREFIX}cmuwmtopbm" + alias pbmtocmuwm="${PBM_TESTPREFIX}pbmtocmuwm" + shopt -s expand_aliases + # Should print 2425386270 41, cksum of testgrid.pbm -${PBM_TESTPREFIX}pbmtocmuwm testgrid.pbm | ${PBM_TESTPREFIX}cmuwmtopbm | cksum +pbmtocmuwm testgrid.pbm | cmuwmtopbm | cksum diff --git a/test/cut-paste-roundtrip.test b/test/cut-paste-roundtrip.test index d5d5989f..15e53219 100755 --- a/test/cut-paste-roundtrip.test +++ b/test/cut-paste-roundtrip.test @@ -2,5 +2,9 @@ # This script tests: pamcut pnmpaste # Also requires: -${PBM_TESTPREFIX}pamcut 50 40 100 70 testimg.ppm | \ -${PBM_TESTPREFIX}pnmpaste -replace - 50 40 testimg.ppm | cksum + alias pamcut="${PBM_TESTPREFIX}pamcut" + alias pnmpaste="${PBM_TESTPREFIX}pnmpaste" + shopt -s expand_aliases + +pamcut 50 40 100 70 testimg.ppm | \ +pnmpaste -replace - 50 40 testimg.ppm | cksum diff --git a/test/eyuvtoppm.test b/test/eyuvtoppm.test index 5009d3ba..79c30237 100755 --- a/test/eyuvtoppm.test +++ b/test/eyuvtoppm.test @@ -2,6 +2,9 @@ # This script tests: eyuvtoppm # Also requires: + alias eyuvtoppm="${PBM_TESTPREFIX}eyuvtoppm" + shopt -s expand_aliases + # Should produce 1719878124 253455 -head -c 126720 /dev/zero | ${PBM_TESTPREFIX}eyuvtoppm -quiet | cksum +head -c 126720 /dev/zero | eyuvtoppm -quiet | cksum diff --git a/test/facesaver-roundtrip.test b/test/facesaver-roundtrip.test index 410ba897..362edaf5 100755 --- a/test/facesaver-roundtrip.test +++ b/test/facesaver-roundtrip.test @@ -2,7 +2,12 @@ # This script tests: pgmtofs fstopgm # Also requires: ppmtopgm + alias fstopgm="${PBM_TESTPREFIX}fstopgm" + alias pgmtofs="${PBM_TESTPREFIX}pgmtofs" + alias ppmtopgm="${PBM_BINPREFIX}ppmtopgm" + shopt -s expand_aliases + # Should produce 2871603838 33838, cksum of testimg.pgm -${PBM_BINPREFIX}ppmtopgm testimg.ppm | \ - ${PBM_TESTPREFIX}pgmtofs | ${PBM_TESTPREFIX}fstopgm | cksum \ No newline at end of file +ppmtopgm testimg.ppm | \ + pgmtofs | fstopgm | cksum diff --git a/test/fits-roundtrip.test b/test/fits-roundtrip.test index 0c244c5a..65589823 100755 --- a/test/fits-roundtrip.test +++ b/test/fits-roundtrip.test @@ -2,5 +2,9 @@ # This script tests: pamtofits fitstopnm # Also requires: + alias fitstopnm="${PBM_TESTPREFIX}fitstopnm" + alias pamtofits="${PBM_TESTPREFIX}pamtofits" + shopt -s expand_aliases + # Should produce 1926073387 101484, cksum of testimg.ppm -${PBM_TESTPREFIX}pamtofits testimg.ppm | ${PBM_TESTPREFIX}fitstopnm | cksum +pamtofits testimg.ppm | fitstopnm | cksum diff --git a/test/g3-roundtrip.test b/test/g3-roundtrip.test index e00997f6..323a26bf 100755 --- a/test/g3-roundtrip.test +++ b/test/g3-roundtrip.test @@ -2,14 +2,19 @@ # This script tests: g3topbm pbmtog3 # Also requires: pnmcrop -${PBM_TESTPREFIX}pbmtog3 -nofixedwidth testgrid.pbm | \ -${PBM_TESTPREFIX}g3topbm -width=14 | cmp -s - testgrid.pbm + alias g3topbm="${PBM_TESTPREFIX}g3topbm" + alias pbmtog3="${PBM_TESTPREFIX}pbmtog3" + alias pnmcrop="${PBM_BINPREFIX}pnmcrop" + shopt -s expand_aliases + +pbmtog3 -nofixedwidth testgrid.pbm | \ +g3topbm -width=14 | cmp -s - testgrid.pbm echo $? -${PBM_TESTPREFIX}pbmtog3 -nofixedwidth -reversebits testgrid.pbm | \ -${PBM_TESTPREFIX}g3topbm -width=14 -reversebits | cmp -s - testgrid.pbm +pbmtog3 -nofixedwidth -reversebits testgrid.pbm | \ +g3topbm -width=14 -reversebits | cmp -s - testgrid.pbm echo $? -${PBM_TESTPREFIX}pbmtog3 testgrid.pbm | \ -${PBM_TESTPREFIX}g3topbm | ${PBM_BINPREFIX}pnmcrop -white -right -bottom | \ +pbmtog3 testgrid.pbm | \ +g3topbm | pnmcrop -white -right -bottom | \ cmp -s - testgrid.pbm ; echo $? diff --git a/test/gem-roundtrip.test b/test/gem-roundtrip.test index 05f1d28c..97f894c2 100755 --- a/test/gem-roundtrip.test +++ b/test/gem-roundtrip.test @@ -2,5 +2,9 @@ # This script tests: pbmtogem gemtopbm # Also requires: gemtopnm + alias gemtopbm="${PBM_TESTPREFIX}gemtopbm" + alias pbmtogem="${PBM_TESTPREFIX}pbmtogem" + shopt -s expand_aliases + # Should print 2425386270 41, cksum of testgrid.pbm -${PBM_TESTPREFIX}pbmtogem testgrid.pbm | ${PBM_TESTPREFIX}gemtopbm | cksum +pbmtogem testgrid.pbm | gemtopbm | cksum diff --git a/test/gif-quant-roundtrip.test b/test/gif-quant-roundtrip.test index 5e093b29..b5f69edd 100755 --- a/test/gif-quant-roundtrip.test +++ b/test/gif-quant-roundtrip.test @@ -2,12 +2,17 @@ # This script tests: giftopnm pamtogif pnmquant # Also requires: pnmcolormap pnmremap + alias giftopnm="${PBM_TESTPREFIX}giftopnm" + alias pamtogif="${PBM_TESTPREFIX}pamtogif" + alias pnmquant="${PBM_TESTPREFIX}pnmquant" + shopt -s expand_aliases + # Should print 0 colors=15 # any value between 2 - 256 works -${PBM_TESTPREFIX}pnmquant $colors testimg.ppm > ${tmpdir}/quant.ppm && -${PBM_TESTPREFIX}pamtogif ${tmpdir}/quant.ppm | ${PBM_TESTPREFIX}giftopnm | \ +pnmquant $colors testimg.ppm > ${tmpdir}/quant.ppm && +pamtogif ${tmpdir}/quant.ppm | giftopnm | \ cmp -s - ${tmpdir}/quant.ppm > /dev/null echo $? diff --git a/test/gif-roundtrip.ok b/test/gif-roundtrip.ok index cf95bb37..ece7593c 100644 --- a/test/gif-roundtrip.ok +++ b/test/gif-roundtrip.ok @@ -1,4 +1,11 @@ 2871603838 33838 +2871603838 33838 +2871603838 33838 +2871603838 33838 1926073387 101484 2425386270 41 +2425386270 41 +2425386270 41 +2425386270 41 +2425386270 41 P1 4 1 0101 \ No newline at end of file diff --git a/test/gif-roundtrip.test b/test/gif-roundtrip.test index a32d574a..574638ac 100755 --- a/test/gif-roundtrip.test +++ b/test/gif-roundtrip.test @@ -2,11 +2,28 @@ # This script tests: giftopnm pamtogif # Also requires: ppmtopgm ppmtorgb3 rgb3toppm pbmmake + alias giftopnm="${PBM_TESTPREFIX}giftopnm" + alias pamtogif="${PBM_TESTPREFIX}pamtogif" + alias pbmmake="${PBM_BINPREFIX}pbmmake" + alias ppmtopgm="${PBM_BINPREFIX}ppmtopgm" + alias ppmtorgb3="${PBM_BINPREFIX}ppmtorgb3" + alias rgb3toppm="${PBM_BINPREFIX}rgb3toppm" + alias pnminvert="${PBM_BINPREFIX}pnminvert" + shopt -s expand_aliases + # Test 1. Should produce 2871603838 33838 # which is the result of ppmtopgm testimg.ppm | cksum +# four times + +ppmtopgm testimg.ppm | tee ${tmpdir}/testimg.pgm | pamtogif | giftopnm | cksum +pamtogif -interlace ${tmpdir}/testimg.pgm | giftopnm | cksum +pamtogif -sort ${tmpdir}/testimg.pgm | tee ${tmpdir}/testimg.gif | \ + giftopnm | cksum +echo "junk" >> ${tmpdir}/testimg.gif && \ + giftopnm -image=1 -quitearly ${tmpdir}/testimg.gif | cksum -${PBM_BINPREFIX}ppmtopgm testimg.ppm | \ - ${PBM_TESTPREFIX}pamtogif | ${PBM_TESTPREFIX}giftopnm | cksum +rm ${tmpdir}/testimg.pgm +rm ${tmpdir}/testimg.gif # Test 2. Break up input image into three monochrome planes, # maxval 255. Transform each plane to gif and back to pgm. @@ -14,26 +31,32 @@ ${PBM_BINPREFIX}ppmtopgm testimg.ppm | \ # Should print 1926073387 101484 cp testimg.ppm ${tmpdir} && -${PBM_BINPREFIX}ppmtorgb3 ${tmpdir}/testimg.ppm && -${PBM_TESTPREFIX}pamtogif ${tmpdir}/testimg.red | \ - ${PBM_TESTPREFIX}giftopnm > ${tmpdir}/out.red && -${PBM_TESTPREFIX}pamtogif ${tmpdir}/testimg.grn | - ${PBM_TESTPREFIX}giftopnm > ${tmpdir}/out.grn && -${PBM_TESTPREFIX}pamtogif ${tmpdir}/testimg.blu | \ - ${PBM_TESTPREFIX}giftopnm | \ - ${PBM_BINPREFIX}rgb3toppm ${tmpdir}/testimg.red ${tmpdir}/testimg.grn - | \ +ppmtorgb3 ${tmpdir}/testimg.ppm && +pamtogif ${tmpdir}/testimg.red | \ + giftopnm > ${tmpdir}/out.red && +pamtogif ${tmpdir}/testimg.grn | + giftopnm > ${tmpdir}/out.grn && +pamtogif ${tmpdir}/testimg.blu | \ + giftopnm | \ + rgb3toppm ${tmpdir}/testimg.red ${tmpdir}/testimg.grn - | \ cksum rm ${tmpdir}/testimg.{ppm,red,grn,blu} ${tmpdir}/out.{red,grn} -# Test 3. Should produce 2425386270 41 -${PBM_TESTPREFIX}pamtogif testgrid.pbm | ${PBM_TESTPREFIX}giftopnm | cksum +# Test 3. Should produce 2425386270 41 five times. + +pamtogif testgrid.pbm | giftopnm | cksum +pamtogif -nolzw testgrid.pbm | giftopnm | cksum +pamtogif -transparent=black testgrid.pbm | giftopnm | cksum +pamtogif -alpha=testgrid.pbm testgrid.pbm | giftopnm | cksum +pamtogif -transparent=white testgrid.pbm | giftopnm -alpha=- | \ + pnminvert | cksum # Test 4. # In this gif file the code length changes after the last image data. # Image data: 3 bits, end code 4 bits. # Should produce P1 4 1 0 1 0 1 -${PBM_BINPREFIX}pbmmake -g 4 1 | \ - ${PBM_TESTPREFIX}pamtogif | ${PBM_TESTPREFIX}giftopnm -plain | \ +pbmmake -g 4 1 | \ + pamtogif | giftopnm -plain | \ tr '\n' ' ' diff --git a/test/hdiff-roundtrip.test b/test/hdiff-roundtrip.test index dbe74701..3a27a955 100755 --- a/test/hdiff-roundtrip.test +++ b/test/hdiff-roundtrip.test @@ -2,5 +2,9 @@ # This script tests: hdifftopam pamtohdiff # Also requires: -${PBM_TESTPREFIX}pamtohdiff testimg.ppm | \ - ${PBM_TESTPREFIX}hdifftopam -pnm | cksum \ No newline at end of file + alias hdifftopam="${PBM_TESTPREFIX}hdifftopam" + alias pamtohdiff="${PBM_TESTPREFIX}pamtohdiff" + shopt -s expand_aliases + +pamtohdiff testimg.ppm | \ + hdifftopam -pnm | cksum diff --git a/test/jbig-roundtrip.ok b/test/jbig-roundtrip.ok new file mode 100644 index 00000000..a951db19 --- /dev/null +++ b/test/jbig-roundtrip.ok @@ -0,0 +1,2 @@ +2425386270 41 +2871603838 33838 diff --git a/test/jbig-roundtrip.test b/test/jbig-roundtrip.test new file mode 100755 index 00000000..766148c6 --- /dev/null +++ b/test/jbig-roundtrip.test @@ -0,0 +1,14 @@ +#! /bin/bash +# This script tests: pnmtojbig jbigtopnm +# Also requires: ppmtopgm + + alias pnmtojbig="${PBM_TESTPREFIX}pnmtojbig" + alias jbigtopnm="${PBM_TESTPREFIX}jbigtopnm" + alias ppmtopgm="${PBM_BINPREFIX}ppmtopgm" + shopt -s expand_aliases + +# Test 1. Should print 2425386270 41 +pnmtojbig testgrid.pbm | jbigtopnm | cksum + +# Test 2. Should print 2871603838 33838 +ppmtopgm testimg.ppm | pnmtojbig | jbigtopnm | cksum \ No newline at end of file diff --git a/test/leaf-roundtrip.test b/test/leaf-roundtrip.test index 6fb7547c..f8ac11d4 100755 --- a/test/leaf-roundtrip.test +++ b/test/leaf-roundtrip.test @@ -2,5 +2,9 @@ # This script tests: ppmtoleaf leaftoppm # Also requires: + alias leaftoppm="${PBM_TESTPREFIX}leaftoppm" + alias ppmtoleaf="${PBM_TESTPREFIX}ppmtoleaf" + shopt -s expand_aliases + # Should produce 1926073387 101484, cksum of testimg.ppm -${PBM_TESTPREFIX}ppmtoleaf testimg.ppm | ${PBM_TESTPREFIX}leaftoppm | cksum +ppmtoleaf testimg.ppm | leaftoppm | cksum diff --git a/test/mgr-roundtrip.test b/test/mgr-roundtrip.test index 2ca3d4b3..4f5fdd81 100755 --- a/test/mgr-roundtrip.test +++ b/test/mgr-roundtrip.test @@ -2,5 +2,9 @@ # This script tests: pbmtomgr mgrtopbm # Also requires: + alias mgrtopbm="${PBM_TESTPREFIX}mgrtopbm" + alias pbmtomgr="${PBM_TESTPREFIX}pbmtomgr" + shopt -s expand_aliases + # Should print 2425386270 41, cksum of testgrid.pbm -${PBM_TESTPREFIX}pbmtomgr testgrid.pbm | ${PBM_TESTPREFIX}mgrtopbm | cksum +pbmtomgr testgrid.pbm | mgrtopbm | cksum diff --git a/test/mrf-roundtrip.test b/test/mrf-roundtrip.test index 80dca546..5b9f77f4 100755 --- a/test/mrf-roundtrip.test +++ b/test/mrf-roundtrip.test @@ -2,5 +2,9 @@ # This script tests: pbmtomrf mrftopbm # Also requires: + alias mrftopbm="${PBM_TESTPREFIX}mrftopbm" + alias pbmtomrf="${PBM_TESTPREFIX}pbmtomrf" + shopt -s expand_aliases + # Should print 2425386270 41, cksum of testgrid.pbm -${PBM_TESTPREFIX}pbmtomrf testgrid.pbm | ${PBM_TESTPREFIX}mrftopbm | cksum +pbmtomrf testgrid.pbm | mrftopbm | cksum diff --git a/test/pad-crop-roundtrip.test b/test/pad-crop-roundtrip.test index 2b3c777b..ae19f7d5 100755 --- a/test/pad-crop-roundtrip.test +++ b/test/pad-crop-roundtrip.test @@ -2,7 +2,11 @@ # This script tests: pnmcrop pnmmargin # Also requires: pnmpad -${PBM_TESTPREFIX}pnmmargin -white 10 testimg.ppm | \ - ${PBM_TESTPREFIX}pnmcrop | cksum -${PBM_TESTPREFIX}pnmmargin -white 10 testgrid.pbm | \ - ${PBM_TESTPREFIX}pnmcrop | cksum + alias pnmcrop="${PBM_TESTPREFIX}pnmcrop" + alias pnmmargin="${PBM_TESTPREFIX}pnmmargin" + shopt -s expand_aliases + +pnmmargin -white 10 testimg.ppm | \ + pnmcrop | cksum +pnmmargin -white 10 testgrid.pbm | \ + pnmcrop | cksum diff --git a/test/pamchannel.test b/test/pamchannel.test index f83dd3b6..e3da552c 100755 --- a/test/pamchannel.test +++ b/test/pamchannel.test @@ -2,6 +2,10 @@ # This script tests: pamchannel # Also requires: pamtopnm + alias pamchannel="${PBM_TESTPREFIX}pamchannel" + alias pamtopnm="${PBM_BINPREFIX}pamtopnm" + shopt -s expand_aliases + # Extract planes one by one. # Convert output to pgm to make it identical to ppmtorgb3 output. @@ -16,17 +20,17 @@ # Test 1. red channel # Should produce 1571496937 33838 -${PBM_TESTPREFIX}pamchannel -infile testimg.ppm 0 | \ - ${PBM_BINPREFIX}pamtopnm --assume | cksum +pamchannel -infile testimg.ppm 0 | \ + pamtopnm --assume | cksum # Test 2. green channel # Should produce 394856971 33838 -${PBM_TESTPREFIX}pamchannel -infile testimg.ppm 1 | \ - ${PBM_BINPREFIX}pamtopnm --assume | cksum +pamchannel -infile testimg.ppm 1 | \ + pamtopnm --assume | cksum # Test 3. blue channel # Should produce 3164158573 33838 -${PBM_TESTPREFIX}pamchannel -infile testimg.ppm 2 | \ - ${PBM_BINPREFIX}pamtopnm --assume | cksum +pamchannel -infile testimg.ppm 2 | \ + pamtopnm --assume | cksum diff --git a/test/pamcut.test b/test/pamcut.test index 080bcad8..5a94de46 100755 --- a/test/pamcut.test +++ b/test/pamcut.test @@ -2,13 +2,17 @@ # This script tests: pamcut pbmmake # Also requires: + alias pamcut="${PBM_TESTPREFIX}pamcut" + alias pbmmake="${PBM_TESTPREFIX}pbmmake" + shopt -s expand_aliases + # Test 1. Should print 2958909756 124815 -${PBM_TESTPREFIX}pamcut -top 0 -left 0 -width 260 -height 160 \ +pamcut -top 0 -left 0 -width 260 -height 160 \ -pad testimg.ppm | cksum # Test 2. Should print 1550940962 10933 -${PBM_TESTPREFIX}pamcut -top 200 -left 120 -width 40 -height 40 \ +pamcut -top 200 -left 120 -width 40 -height 40 \ -pad testimg.ppm | cksum # Test 3. Should print 708474423 14 -${PBM_TESTPREFIX}pamcut -top 5 -left 5 -bottom 5 -right 5 testimg.ppm | cksum +pamcut -top 5 -left 5 -bottom 5 -right 5 testimg.ppm | cksum # Test 3. Should print 3412257956 129 -${PBM_TESTPREFIX}pbmmake -g 50 50 | ${PBM_TESTPREFIX}pamcut 5 5 30 30 | cksum +pbmmake -g 50 50 | pamcut 5 5 30 30 | cksum diff --git a/test/pamdepth-roundtrip.test b/test/pamdepth-roundtrip.test index 2795d659..6330aaf9 100755 --- a/test/pamdepth-roundtrip.test +++ b/test/pamdepth-roundtrip.test @@ -2,11 +2,15 @@ # This script tests: pamdepth pgmtopbm # Also requires: + alias pamdepth="${PBM_TESTPREFIX}pamdepth" + alias pgmtopbm="${PBM_TESTPREFIX}pgmtopbm" + shopt -s expand_aliases + for i in 300 500 1023 4095 5000 16383 65535 do -${PBM_TESTPREFIX}pamdepth $i testimg.ppm | \ - ${PBM_TESTPREFIX}pamdepth 255 | cksum +pamdepth $i testimg.ppm | \ + pamdepth 255 | cksum done -${PBM_TESTPREFIX}pamdepth 255 testgrid.pbm | ${PBM_TESTPREFIX}pamdepth 1 | \ - ${PBM_TESTPREFIX}pgmtopbm -th -val=0.5 | cksum +pamdepth 255 testgrid.pbm | pamdepth 1 | \ + pgmtopbm -th -val=0.5 | cksum diff --git a/test/pamdice-roundtrip.test b/test/pamdice-roundtrip.test index 06fef8b2..7319249a 100755 --- a/test/pamdice-roundtrip.test +++ b/test/pamdice-roundtrip.test @@ -2,8 +2,12 @@ # This script tests: pamdice pamundice # Also requires: -${PBM_TESTPREFIX}pamdice testimg.ppm -outstem=${tmpdir}/a -width=50 -height=40 -${PBM_TESTPREFIX}pamundice ${tmpdir}/a_%1d_%1a.ppm -down=4 -across=5 | cksum + alias pamdice="${PBM_TESTPREFIX}pamdice" + alias pamundice="${PBM_TESTPREFIX}pamundice" + shopt -s expand_aliases + +pamdice testimg.ppm -outstem=${tmpdir}/a -width=50 -height=40 +pamundice ${tmpdir}/a_%1d_%1a.ppm -down=4 -across=5 | cksum rm ${tmpdir}/a_?_?.ppm diff --git a/test/pamditherbw.test b/test/pamditherbw.test index 5335f12d..fef71efa 100755 --- a/test/pamditherbw.test +++ b/test/pamditherbw.test @@ -2,30 +2,34 @@ # This script tests: pamditherbw # Also requires: ppmtopgm + alias pamditherbw="${PBM_TESTPREFIX}pamditherbw" + alias ppmtopgm="${PBM_BINPREFIX}ppmtopgm" + shopt -s expand_aliases + # Make test input -${PBM_BINPREFIX}ppmtopgm testimg.ppm >${tmpdir}/testimg.pgm +ppmtopgm testimg.ppm >${tmpdir}/testimg.pgm # Test 1. Simple threshold -${PBM_TESTPREFIX}pamditherbw -threshold -val=0.5 \ +pamditherbw -threshold -val=0.5 \ ${tmpdir}/testimg.pgm | cksum # Test 2. Floyd-Steinberg -#${PBM_TESTPREFIX}pamditherbw -floyd -val=0.5 ${tmpdir}/testimg.pgm | cksum +#pamditherbw -floyd -val=0.5 ${tmpdir}/testimg.pgm | cksum # Test 3. Atkinson -#${PBM_TESTPREFIX}pamditherbw -atkinson -val=0.5 ${tmpdir}/testimg.pgm | cksum +#pamditherbw -atkinson -val=0.5 ${tmpdir}/testimg.pgm | cksum # Test 4. Hilbert -${PBM_TESTPREFIX}pamditherbw -hilbert ${tmpdir}/testimg.pgm | cksum +pamditherbw -hilbert ${tmpdir}/testimg.pgm | cksum # Test 5. Dither-8 -${PBM_TESTPREFIX}pamditherbw -dither8 ${tmpdir}/testimg.pgm | cksum +pamditherbw -dither8 ${tmpdir}/testimg.pgm | cksum # Test 6. Cluster4 -${PBM_TESTPREFIX}pamditherbw -cluster4 ${tmpdir}/testimg.pgm | cksum +pamditherbw -cluster4 ${tmpdir}/testimg.pgm | cksum # Test 7. Atkinson -#${PBM_TESTPREFIX}pamditherbw -atkinson -val=0.5 ${tmpdir}/testimg.pgm | cksum +#pamditherbw -atkinson -val=0.5 ${tmpdir}/testimg.pgm | cksum # Remove test file rm ${tmpdir}/testimg.pgm diff --git a/test/pamedge.test b/test/pamedge.test index da1c0145..d230424b 100755 --- a/test/pamedge.test +++ b/test/pamedge.test @@ -2,6 +2,14 @@ # This script tests: pamedge # Also requires: pbmpscale pbmtext pgmtopbm pgmtopgm ppmtopgm -${PBM_BINPREFIX}pbmtext " F " -nom | ${PBM_BINPREFIX}pbmpscale 5 | \ -${PBM_BINPREFIX}pgmtopgm | ${PBM_TESTPREFIX}pamedge | \ -${PBM_BINPREFIX}ppmtopgm | ${PBM_BINPREFIX}pgmtopbm -th -val=.5 -plain + alias pamedge="${PBM_TESTPREFIX}pamedge" + alias pbmpscale="${PBM_BINPREFIX}pbmpscale" + alias pbmtext="${PBM_BINPREFIX}pbmtext" + alias pgmtopbm="${PBM_BINPREFIX}pgmtopbm" + alias pgmtopgm="${PBM_BINPREFIX}pgmtopgm" + alias ppmtopgm="${PBM_BINPREFIX}ppmtopgm" + shopt -s expand_aliases + +pbmtext " F " -nom | pbmpscale 5 | \ +pgmtopgm | pamedge | \ +ppmtopgm | pgmtopbm -th -val=.5 -plain diff --git a/test/pamenlarge.test b/test/pamenlarge.test index c3efc4b2..c1958d14 100755 --- a/test/pamenlarge.test +++ b/test/pamenlarge.test @@ -2,11 +2,15 @@ # This script tests: pamenlarge # Also requires: ppmtopgm + alias pamenlarge="${PBM_TESTPREFIX}pamenlarge" + alias ppmtopgm="${PBM_BINPREFIX}ppmtopgm" + shopt -s expand_aliases + # Test 1. Should print 3424505894 913236 -${PBM_TESTPREFIX}pamenlarge 3 testimg.ppm | cksum +pamenlarge 3 testimg.ppm | cksum # Test 2. Should print 4152147096 304422 -${PBM_BINPREFIX}ppmtopgm testimg.ppm | ${PBM_TESTPREFIX}pamenlarge 3 | cksum +ppmtopgm testimg.ppm | pamenlarge 3 | cksum # Test 3. Should print 3342398172 297 -${PBM_TESTPREFIX}pamenlarge 3 testgrid.pbm | cksum +pamenlarge 3 testgrid.pbm | cksum # Test 4. Should print 237488670 3133413 -${PBM_TESTPREFIX}pamenlarge 3 -plain testimg.ppm | cksum +pamenlarge 3 -plain testimg.ppm | cksum diff --git a/test/pamfile.test b/test/pamfile.test index 36ee557c..689578f1 100755 --- a/test/pamfile.test +++ b/test/pamfile.test @@ -2,6 +2,10 @@ # This script tests: pamfile # Also requires: ppmtopgm -${PBM_TESTPREFIX}pamfile testimg.ppm -${PBM_TESTPREFIX}pamfile testgrid.pbm -${PBM_BINPREFIX}ppmtopgm testimg.ppm | ${PBM_TESTPREFIX}pamfile + alias pamfile="${PBM_TESTPREFIX}pamfile" + alias ppmtopgm="${PBM_BINPREFIX}ppmtopgm" + shopt -s expand_aliases + +pamfile testimg.ppm +pamfile testgrid.pbm +ppmtopgm testimg.ppm | pamfile diff --git a/test/pamflip-roundtrip.test b/test/pamflip-roundtrip.test index 7a17359f..2b18eb8d 100755 --- a/test/pamflip-roundtrip.test +++ b/test/pamflip-roundtrip.test @@ -2,33 +2,36 @@ # This script tests: pamflip # Also requires: -${PBM_TESTPREFIX}pamflip -lr testimg.ppm | ${PBM_TESTPREFIX}pamflip -lr | cksum -${PBM_TESTPREFIX}pamflip -tb testimg.ppm | ${PBM_TESTPREFIX}pamflip -tb | cksum -${PBM_TESTPREFIX}pamflip -r180 testimg.ppm | \ - ${PBM_TESTPREFIX}pamflip -r180 | cksum -${PBM_TESTPREFIX}pamflip -xy testimg.ppm | ${PBM_TESTPREFIX}pamflip -xy | cksum -${PBM_TESTPREFIX}pamflip -r90 testimg.ppm | \ - ${PBM_TESTPREFIX}pamflip -r90 | \ - ${PBM_TESTPREFIX}pamflip -r90 | \ - ${PBM_TESTPREFIX}pamflip -r90 | cksum -${PBM_TESTPREFIX}pamflip -r270 testimg.ppm | \ - ${PBM_TESTPREFIX}pamflip -r270 | \ - ${PBM_TESTPREFIX}pamflip -r270 | \ - ${PBM_TESTPREFIX}pamflip -r270 | cksum + alias pamflip="${PBM_TESTPREFIX}pamflip" + shopt -s expand_aliases -${PBM_TESTPREFIX}pamflip -lr testgrid.pbm | \ - ${PBM_TESTPREFIX}pamflip -lr | cksum -${PBM_TESTPREFIX}pamflip -tb testgrid.pbm | \ - ${PBM_TESTPREFIX}pamflip -tb | cksum -${PBM_TESTPREFIX}pamflip -r180 testgrid.pbm | \ - ${PBM_TESTPREFIX}pamflip -r180 | cksum -${PBM_TESTPREFIX}pamflip -xy testgrid.pbm | \ - ${PBM_TESTPREFIX}pamflip -xy | cksum -${PBM_TESTPREFIX}pamflip -r90 testgrid.pbm | \ - ${PBM_TESTPREFIX}pamflip -r90 | \ - ${PBM_TESTPREFIX}pamflip -r90 | \ - ${PBM_TESTPREFIX}pamflip -r90 | cksum -${PBM_TESTPREFIX}pamflip -r270 testgrid.pbm | \ - ${PBM_TESTPREFIX}pamflip -r270 | \ - ${PBM_TESTPREFIX}pamflip -r270 | \ - ${PBM_TESTPREFIX}pamflip -r270 | cksum +pamflip -lr testimg.ppm | pamflip -lr | cksum +pamflip -tb testimg.ppm | pamflip -tb | cksum +pamflip -r180 testimg.ppm | \ + pamflip -r180 | cksum +pamflip -xy testimg.ppm | pamflip -xy | cksum +pamflip -r90 testimg.ppm | \ + pamflip -r90 | \ + pamflip -r90 | \ + pamflip -r90 | cksum +pamflip -r270 testimg.ppm | \ + pamflip -r270 | \ + pamflip -r270 | \ + pamflip -r270 | cksum + +pamflip -lr testgrid.pbm | \ + pamflip -lr | cksum +pamflip -tb testgrid.pbm | \ + pamflip -tb | cksum +pamflip -r180 testgrid.pbm | \ + pamflip -r180 | cksum +pamflip -xy testgrid.pbm | \ + pamflip -xy | cksum +pamflip -r90 testgrid.pbm | \ + pamflip -r90 | \ + pamflip -r90 | \ + pamflip -r90 | cksum +pamflip -r270 testgrid.pbm | \ + pamflip -r270 | \ + pamflip -r270 | \ + pamflip -r270 | cksum diff --git a/test/pamflip.test b/test/pamflip.test index 59f8e639..4ea275bd 100755 --- a/test/pamflip.test +++ b/test/pamflip.test @@ -2,15 +2,18 @@ # This script tests: pamflip # Also requires: + alias pamflip="${PBM_TESTPREFIX}pamflip" + shopt -s expand_aliases + # Test 1. Should print 2116496681 101484 -${PBM_TESTPREFIX}pamflip -lr testimg.ppm | cksum +pamflip -lr testimg.ppm | cksum # Test 2. Should print 217037000 101484 -${PBM_TESTPREFIX}pamflip -cw testimg.ppm | cksum +pamflip -cw testimg.ppm | cksum # Test 3. Should print 2052917888 101484 -${PBM_TESTPREFIX}pamflip -tb testimg.ppm | cksum +pamflip -tb testimg.ppm | cksum # Test 4. Should print 3375384165 41 -${PBM_TESTPREFIX}pamflip -lr testgrid.pbm | cksum +pamflip -lr testgrid.pbm | cksum # Test 5. Should print 604323149 41 -${PBM_TESTPREFIX}pamflip -tb testgrid.pbm | cksum +pamflip -tb testgrid.pbm | cksum # Test 6. Should print 490797850 37 -${PBM_TESTPREFIX}pamflip -cw testgrid.pbm | cksum +pamflip -cw testgrid.pbm | cksum diff --git a/test/pamseq.test b/test/pamseq.test index 1c6ae44b..acc5d1b1 100755 --- a/test/pamseq.test +++ b/test/pamseq.test @@ -2,4 +2,7 @@ # This script tests: pamseq # Also requires: -${PBM_TESTPREFIX}pamseq 1 255 | cksum + alias pamseq="${PBM_TESTPREFIX}pamseq" + shopt -s expand_aliases + +pamseq 1 255 | cksum diff --git a/test/pamslice-roundtrip.ok b/test/pamslice-roundtrip.ok index f9fe0bb4..eae64745 100644 --- a/test/pamslice-roundtrip.ok +++ b/test/pamslice-roundtrip.ok @@ -1,2 +1,4 @@ 2425386270 41 -1926073387 101484 +914327477 4864 +914327477 4864 +914327477 4864 diff --git a/test/pamslice-roundtrip.test b/test/pamslice-roundtrip.test index d7ca657d..edec0d26 100755 --- a/test/pamslice-roundtrip.test +++ b/test/pamslice-roundtrip.test @@ -1,7 +1,15 @@ #! /bin/bash -# This script tests: pamslice -# Also requires: pnmtopnm pamtopnm +# This script tests: pamslice pamdeinterlace +# Also requires: pamcut pnmtopnm pamflip + alias pamslice="${PBM_TESTPREFIX}pamslice" + alias pamdeinterlace="${PBM_TESTPREFIX}pamdeinterlace" + alias pamcut="${PBM_BINPREFIX}pamcut" + alias pnmtopnm="${PBM_BINPREFIX}pnmtopnm" + alias pamflip="${PBM_BINPREFIX}pamflip" + shopt -s expand_aliases + +# Test 1. # Slice rows, one by one, out of testgrid.pbm. # Add header and reconstruct pbm image. # Note that in pamslice output 0 is white and 1 is black: opposite of PBM @@ -9,21 +17,56 @@ (echo "P1" echo "14 16" - seq 0 15 | while read i; + seq 0 15 | while read i; do - ${PBM_TESTPREFIX}pamslice -row=$i testgrid.pbm | \ - awk '{print $2}' | sed 'y/01/10/'; - done ) | ${PBM_BINPREFIX}pnmtopnm | cksum + pamslice -row=$i testgrid.pbm | \ + awk '{print $2}' | sed 'y/01/10/'; + done ) | pnmtopnm | cksum -# Slice rows, one by one, out of testimg.ppm. -# Add header and reconstruct pbm image. -# Should print 1926073387 101484 +# Test 2. +# Slice rows, one by one, out of ppm test image +# We take a part out of testimg.ppm with pamcut for processing the +# whole image takes much time. +# Add header and reconstruct ppm image. +# Should print 914327477 4864 + +pamcut 50 50 49 33 testimg.ppm > ${tmpdir}/test4933.ppm + +(echo "P3" + echo "49 33" + echo "255" + seq 0 32 | while read i; + do + pamslice -row=$i ${tmpdir}/test4933.ppm | awk '{print $2, $3, $4}'; + done ) | pnmtopnm | cksum + +# Same as above test 2, but take cols instead of rows. +# Should print 914327477 4864 (echo "P3" - echo "227 149" + echo "33 49" echo "255" - seq 0 148 | while read i; + seq 0 48 | while read i; do - ${PBM_TESTPREFIX}pamslice -row=$i testimg.ppm | awk '{print $2, $3, $4}'; - done ) | ${PBM_BINPREFIX}pnmtopnm | cksum + pamslice -col=$i ${tmpdir}/test4933.ppm | awk '{print $2, $3, $4}'; + done ) | pamflip -xy | cksum + +# Test 4. +# Divide input image into two with pamdeinterlace and recombine. + +pamdeinterlace -takeodd ${tmpdir}/test4933.ppm > ${tmpdir}/testodd.ppm +pamdeinterlace -takeeven ${tmpdir}/test4933.ppm > ${tmpdir}/testevn.ppm + +(echo "P3" + echo "49 33" + echo "255" + seq 0 15 | while read i; + do + pamslice -row=$i ${tmpdir}/testevn.ppm | awk '{print $2, $3, $4}'; + pamslice -row=$i ${tmpdir}/testodd.ppm | awk '{print $2, $3, $4}'; + done + pamslice -row=16 ${tmpdir}/testevn.ppm | awk '{print $2, $3, $4}'; + ) | pnmtopnm | tee /tmp/z | cksum + +rm ${tmpdir}/test4933.ppm ${tmpdir}/testodd.ppm ${tmpdir}/testevn.ppm diff --git a/test/pamsumm.test b/test/pamsumm.test index 9c5f1b84..9697a2b9 100755 --- a/test/pamsumm.test +++ b/test/pamsumm.test @@ -2,12 +2,15 @@ # This script tests: pamsumm # Also requires: + alias pamsumm="${PBM_TESTPREFIX}pamsumm" + shopt -s expand_aliases + for type in -sum -min -max -mean do - ${PBM_TESTPREFIX}pamsumm -brief $type testgrid.pbm + pamsumm -brief $type testgrid.pbm done for type in -sum -min -max -mean do - ${PBM_TESTPREFIX}pamsumm -brief $type testimg.ppm + pamsumm -brief $type testimg.ppm done diff --git a/test/pamtopam.test b/test/pamtopam.test index 1a4cdff6..e2ec5adf 100755 --- a/test/pamtopam.test +++ b/test/pamtopam.test @@ -2,8 +2,11 @@ # This script tests: pamtopam # Also requires: -${PBM_TESTPREFIX}pamtopam < testimg.ppm | sed '/ENDHDR/q' -${PBM_TESTPREFIX}pamtopam < testgrid.pbm | sed '/ENDHDR/q' + alias pamtopam="${PBM_TESTPREFIX}pamtopam" + shopt -s expand_aliases -${PBM_TESTPREFIX}pamtopam < testimg.ppm | cksum -${PBM_TESTPREFIX}pamtopam < testgrid.pbm | cksum +pamtopam < testimg.ppm | sed '/ENDHDR/q' +pamtopam < testgrid.pbm | sed '/ENDHDR/q' + +pamtopam < testimg.ppm | cksum +pamtopam < testgrid.pbm | cksum diff --git a/test/pbmclean.test b/test/pbmclean.test index 69081ff9..28242d30 100755 --- a/test/pbmclean.test +++ b/test/pbmclean.test @@ -2,15 +2,21 @@ # This script tests: pbmclean # Also requires: pbmmake pbmpage pnmmargin pnmpad -${PBM_BINPREFIX}pbmmake -g 3 3 | ${PBM_BINPREFIX}pnmmargin -black 2 \ + alias pbmclean="${PBM_TESTPREFIX}pbmclean" + alias pbmmake="${PBM_BINPREFIX}pbmmake" + alias pbmpage="${PBM_BINPREFIX}pbmpage" + alias pnmmargin="${PBM_BINPREFIX}pnmmargin" + shopt -s expand_aliases + +pbmmake -g 3 3 | pnmmargin -black 2 \ >${tmpdir}/test.pbm for n in 1 2 3 4 5 6 7 8 do -${PBM_TESTPREFIX}pbmclean -min=$n -black -plain ${tmpdir}/test.pbm +pbmclean -min=$n -black -plain ${tmpdir}/test.pbm done rm ${tmpdir}/test.pbm # Should print 760076056 4210813 -${PBM_BINPREFIX}pbmpage 1 | ${PBM_TESTPREFIX}pbmclean -black | cksum +pbmpage 1 | pbmclean -black | cksum diff --git a/test/pbmmake.test b/test/pbmmake.test index 82fdb941..eb4b472d 100755 --- a/test/pbmmake.test +++ b/test/pbmmake.test @@ -2,17 +2,20 @@ # This script tests: pbmmake # Also requires: + alias pbmmake="${PBM_TESTPREFIX}pbmmake" + shopt -s expand_aliases + for i in `seq 1 8` do for color in -w -b -g do -${PBM_TESTPREFIX}pbmmake -plain $color $i $i | tr -d '\n'; echo +pbmmake -plain $color $i $i | tr -d '\n'; echo done done for i in `seq 8 5 98` do - ( ${PBM_TESTPREFIX}pbmmake -w $i $i ; - ${PBM_TESTPREFIX}pbmmake -b $i $i ; - ${PBM_TESTPREFIX}pbmmake -g $i $i ) | cksum + ( pbmmake -w $i $i ; + pbmmake -b $i $i ; + pbmmake -g $i $i ) | cksum done diff --git a/test/pbmminkowski.test b/test/pbmminkowski.test index ccb882b1..120441f1 100755 --- a/test/pbmminkowski.test +++ b/test/pbmminkowski.test @@ -2,9 +2,14 @@ # This script tests: pbmminkowski # Also requires: pbmmake pnmmargin pnmpad -${PBM_BINPREFIX}pbmmake -w 1 1 | ${PBM_BINPREFIX}pnmmargin -b 1 | \ - ${PBM_TESTPREFIX}pbmminkowski + alias pbmminkowski="${PBM_TESTPREFIX}pbmminkowski" + alias pbmmake="${PBM_BINPREFIX}pbmmake" + alias pnmmargin="${PBM_BINPREFIX}pnmmargin" + shopt -s expand_aliases + +pbmmake -w 1 1 | pnmmargin -b 1 | \ + pbmminkowski echo -${PBM_BINPREFIX}pbmmake -g 3 3 | ${PBM_TESTPREFIX}pbmminkowski +pbmmake -g 3 3 | pbmminkowski echo -${PBM_TESTPREFIX}pbmminkowski testgrid.pbm \ No newline at end of file +pbmminkowski testgrid.pbm diff --git a/test/pbmpage.test b/test/pbmpage.test index dcf8e688..c03ee8d7 100755 --- a/test/pbmpage.test +++ b/test/pbmpage.test @@ -2,6 +2,9 @@ # This script tests: pbmpage # Also requires: -${PBM_TESTPREFIX}pbmpage 1 | cksum -${PBM_TESTPREFIX}pbmpage 2 | cksum -${PBM_TESTPREFIX}pbmpage 3 | cksum \ No newline at end of file + alias pbmpage="${PBM_TESTPREFIX}pbmpage" + shopt -s expand_aliases + +pbmpage 1 | cksum +pbmpage 2 | cksum +pbmpage 3 | cksum diff --git a/test/pbmpscale.test b/test/pbmpscale.test index e1125fc7..50ae470d 100755 --- a/test/pbmpscale.test +++ b/test/pbmpscale.test @@ -2,10 +2,15 @@ # This script tests: pbmpscale # Also requires: pamenlarge pbmtext -${PBM_BINPREFIX}pbmtext -nomargin "F" | ${PBM_TESTPREFIX}pbmpscale 3 -plain + alias pbmpscale="${PBM_TESTPREFIX}pbmpscale" + alias pamenlarge="${PBM_BINPREFIX}pamenlarge" + alias pbmtext="${PBM_BINPREFIX}pbmtext" + shopt -s expand_aliases + +pbmtext -nomargin "F" | pbmpscale 3 -plain for i in 2 3 4 do -${PBM_BINPREFIX}pamenlarge 2 testgrid.pbm | \ - ${PBM_TESTPREFIX}pbmpscale $i | cksum +pamenlarge 2 testgrid.pbm | \ + pbmpscale $i | cksum done diff --git a/test/pbmtext.test b/test/pbmtext.test index 69fa9b23..21020969 100755 --- a/test/pbmtext.test +++ b/test/pbmtext.test @@ -2,10 +2,13 @@ # This script tests: pbmtext # Also requires: + alias pbmtext="${PBM_TESTPREFIX}pbmtext" + shopt -s expand_aliases + for i in 0123456789 abcdefghijk lmnopqrst uzwxyz ABCDEFGHIJK LMNOPQRST UVWXYZ do for flags in "" "-nom" "-builtin fixed" do -echo $i | ${PBM_TESTPREFIX}pbmtext $flags | cksum +echo $i | pbmtext $flags | cksum done done diff --git a/test/pbmtog3.test b/test/pbmtog3.test index 09b5d784..74b901e3 100755 --- a/test/pbmtog3.test +++ b/test/pbmtog3.test @@ -2,27 +2,31 @@ # This script tests: pbmtog3 # Also requires: pbmmake + alias pbmtog3="${PBM_TESTPREFIX}pbmtog3" + alias pbmmake="${PBM_BINPREFIX}pbmmake" + shopt -s expand_aliases + # Test 1. Should print 3697098186 144 -${PBM_TESTPREFIX}pbmtog3 testgrid.pbm | cksum +pbmtog3 testgrid.pbm | cksum # Test 2. Should print 1248301383 122 -${PBM_TESTPREFIX}pbmtog3 -nofixedwidth testgrid.pbm | cksum +pbmtog3 -nofixedwidth testgrid.pbm | cksum # Test 3. Should print 686713716 144 -${PBM_TESTPREFIX}pbmtog3 -reverse testgrid.pbm | cksum +pbmtog3 -reverse testgrid.pbm | cksum # Test 4. Should print 215463240 122 -${PBM_TESTPREFIX}pbmtog3 -nofixedwidth -reverse testgrid.pbm | cksum +pbmtog3 -nofixedwidth -reverse testgrid.pbm | cksum # Test 5. Should print 28792587 47 -${PBM_BINPREFIX}pbmmake -w 10 10 | ${PBM_TESTPREFIX}pbmtog3 | cksum +pbmmake -w 10 10 | pbmtog3 | cksum # Test 6. Should print 277456854 32 -${PBM_BINPREFIX}pbmmake -w 10 10 | \ - ${PBM_TESTPREFIX}pbmtog3 -nofixedwidth | cksum +pbmmake -w 10 10 | \ + pbmtog3 -nofixedwidth | cksum # Test 7. Should print 28792587 47 -${PBM_BINPREFIX}pbmmake -w 10000 10 | ${PBM_TESTPREFIX}pbmtog3 | cksum +pbmmake -w 10000 10 | pbmtog3 | cksum # Test 8. Should print 871281767 162 -${PBM_BINPREFIX}pbmmake -w 10000 10 | \ - ${PBM_TESTPREFIX}pbmtog3 -nofixedwidth | cksum +pbmmake -w 10000 10 | \ + pbmtog3 -nofixedwidth | cksum # Test 9. Should print 3736247115 62 -${PBM_BINPREFIX}pbmmake -b 10 10 | ${PBM_TESTPREFIX}pbmtog3 | cksum +pbmmake -b 10 10 | pbmtog3 | cksum # Test 10. Should print 2820255307 2191856 -${PBM_BINPREFIX}pbmmake -g 1700 2286 | ${PBM_TESTPREFIX}pbmtog3 | cksum +pbmmake -g 1700 2286 | pbmtog3 | cksum # Test 11. Should print 4159089282 2226575 -${PBM_BINPREFIX}pbmmake -g 1800 2286 | ${PBM_TESTPREFIX}pbmtog3 | cksum +pbmmake -g 1800 2286 | pbmtog3 | cksum diff --git a/test/pbmupc.test b/test/pbmupc.test index 6fa772d7..39e4c10c 100755 --- a/test/pbmupc.test +++ b/test/pbmupc.test @@ -2,7 +2,10 @@ # This script tests: pbmupc # Also requires: + alias pbmupc="${PBM_TESTPREFIX}pbmupc" + shopt -s expand_aliases + for type in -s1 -s2 do -${PBM_TESTPREFIX}pbmupc $type 0 72890 00011 +pbmupc $type 0 72890 00011 done | cksum diff --git a/test/pfm-roundtrip.test b/test/pfm-roundtrip.test index 7cd2693c..650cc4d0 100755 --- a/test/pfm-roundtrip.test +++ b/test/pfm-roundtrip.test @@ -2,6 +2,11 @@ # This script tests: pamtopfm pfmtopam # Also requires: pamtopnm + alias pamtopfm="${PBM_TESTPREFIX}pamtopfm" + alias pfmtopam="${PBM_TESTPREFIX}pfmtopam" + alias pamtopnm="${PBM_BINPREFIX}pamtopnm" + shopt -s expand_aliases + # Should print 1926073387 101484, cksum of testimg.ppm -${PBM_TESTPREFIX}pamtopfm testimg.ppm | ${PBM_TESTPREFIX}pfmtopam | \ - ${PBM_BINPREFIX}pamtopnm | cksum +pamtopfm testimg.ppm | pfmtopam | \ + pamtopnm | cksum diff --git a/test/pgmcrater.test b/test/pgmcrater.test index e6942cee..ffba435f 100755 --- a/test/pgmcrater.test +++ b/test/pgmcrater.test @@ -1,6 +1,9 @@ #! /bin/bash # This script tests: pgmcrater + alias pgmcrater="${PBM_TESTPREFIX}pgmcrater" + shopt -s expand_aliases + # This test is sensitive to differences in floating point math. # With GCC slight results start to appear with -number 75 in # the following test. Compiler type (GCC, Clang, etc.), @@ -17,7 +20,7 @@ testrandom -q case $? in 81) # Should print: 3828822912 65551 - ${PBM_TESTPREFIX}pgmcrater -quiet -number 25 -randomseed 1 | cksum + pgmcrater -quiet -number 25 -randomseed 1 | cksum ;; 8[02-9] | 90) diff --git a/test/pgmhist.test b/test/pgmhist.test index b3361dc4..32b18189 100755 --- a/test/pgmhist.test +++ b/test/pgmhist.test @@ -2,10 +2,14 @@ # This script tests: pgmhist # Also requires: pgmramp + alias pgmhist="${PBM_TESTPREFIX}pgmhist" + alias pgmramp="${PBM_BINPREFIX}pgmramp" + shopt -s expand_aliases + # Ignore differences in spaces. -${PBM_BINPREFIX}pgmramp -maxval=8 -lr 8 2 | ${PBM_TESTPREFIX}pgmhist | \ +pgmramp -maxval=8 -lr 8 2 | pgmhist | \ sed -e 's/ */ /g' -e 's/ *$//' -${PBM_TESTPREFIX}pgmhist testgrid.pbm | \ - sed -e 's/ */ /g' -e 's/ *$//' \ No newline at end of file +pgmhist testgrid.pbm | \ + sed -e 's/ */ /g' -e 's/ *$//' diff --git a/test/pgmmake.test b/test/pgmmake.test index 0180b502..2c384e1b 100755 --- a/test/pgmmake.test +++ b/test/pgmmake.test @@ -2,9 +2,12 @@ # This script tests: pgmmake # Also requires: -${PBM_TESTPREFIX}pgmmake 1 50 50 | cksum -${PBM_TESTPREFIX}pgmmake .2 50 100 -maxval=5 | cksum + alias pgmmake="${PBM_TESTPREFIX}pgmmake" + shopt -s expand_aliases +pgmmake 1 50 50 | cksum +pgmmake .2 50 100 -maxval=5 | cksum - \ No newline at end of file + + diff --git a/test/pgmnoise.test b/test/pgmnoise.test index 60d06510..a5c1c380 100755 --- a/test/pgmnoise.test +++ b/test/pgmnoise.test @@ -2,6 +2,9 @@ # This script tests: pgmnoise # Also requires: + alias pgmnoise="${PBM_TESTPREFIX}pgmnoise" + shopt -s expand_aliases + # We first check whether random number generator is glibc rand(). # If not, this test is skipped. @@ -10,7 +13,7 @@ testrandom case $? in 81) # Should print: 1663614689 10015 - ${PBM_TESTPREFIX}pgmnoise --randomseed=0 100 100 | cksum ;; + pgmnoise --randomseed=0 100 100 | cksum ;; # Any additional tests go here. diff --git a/test/pgmramp.ok b/test/pgmramp.ok index 0971ccd7..989ef7d4 100644 --- a/test/pgmramp.ok +++ b/test/pgmramp.ok @@ -1,32 +1,40 @@ P2 4 4 -3 -0 1 2 3 -0 1 2 3 -0 1 2 3 -0 1 2 3 +6 +0 2 4 6 +0 2 4 6 +0 2 4 6 +0 2 4 6 P2 4 4 -3 +6 0 0 0 0 -1 1 1 1 2 2 2 2 -3 3 3 3 +4 4 4 4 +6 6 6 6 P2 4 4 -3 -0 0 1 0 -0 1 2 1 -1 2 3 2 -0 1 2 1 +6 +0 1 3 1 +1 3 4 3 +3 4 6 4 +1 3 4 3 P2 4 4 -3 +6 0 0 0 0 -0 1 2 1 -0 2 3 2 -0 1 2 1 +0 3 4 3 +0 4 6 4 +0 3 4 3 +P2 +4 4 +6 +0 1 2 3 +1 2 3 4 +2 3 4 5 +3 4 5 6 1777787286 65551 2046889993 65551 1975520432 65551 807973067 65551 +886972785 131087 diff --git a/test/pgmramp.test b/test/pgmramp.test index cf3d91d7..231b9311 100755 --- a/test/pgmramp.test +++ b/test/pgmramp.test @@ -2,11 +2,17 @@ # This script tests: pgmramp # Also requires: -for type in -lr -tb -rect -ell + alias pgmramp="${PBM_TESTPREFIX}pgmramp" + shopt -s expand_aliases + +for type in -lr -tb -rectangle -ellipse -diagonal do -${PBM_TESTPREFIX}pgmramp -maxval=3 $type 4 4 -plain +pgmramp -maxval=6 $type 4 4 -plain done -for type in -lr -tb -rect -ell -do ${PBM_TESTPREFIX}pgmramp $type 256 256 | cksum +for type in -lr -tb -rectangle -ellipse +do pgmramp $type 256 256 | cksum done + +pgmramp -diagonal -maxval=510 256 256 | cksum + \ No newline at end of file diff --git a/test/pgmtopgm.test b/test/pgmtopgm.test index 638cb68b..388cca93 100755 --- a/test/pgmtopgm.test +++ b/test/pgmtopgm.test @@ -2,4 +2,7 @@ # This script tests: pgmtopgm # Also requires: -${PBM_TESTPREFIX}pgmtopgm < testgrid.pbm | cksum + alias pgmtopgm="${PBM_TESTPREFIX}pgmtopgm" + shopt -s expand_aliases + +pgmtopgm < testgrid.pbm | cksum diff --git a/test/pgmtoppm.test b/test/pgmtoppm.test index b93d7867..cdd53623 100755 --- a/test/pgmtoppm.test +++ b/test/pgmtoppm.test @@ -2,16 +2,22 @@ # This script tests: pgmtoppm # Also requires: pamseq pamtopnm pgmramp -${PBM_BINPREFIX}pgmramp -maxval=5 -lr 256 1 >${tmpdir}/test.pgm -${PBM_BINPREFIX}pamseq 3 5 -tupletype=RGB | ${PBM_BINPREFIX}pamtopnm \ + alias pgmtoppm="${PBM_TESTPREFIX}pgmtoppm" + alias pamseq="${PBM_BINPREFIX}pamseq" + alias pamtopnm="${PBM_BINPREFIX}pamtopnm" + alias pgmramp="${PBM_BINPREFIX}pgmramp" + shopt -s expand_aliases + +pgmramp -maxval=5 -lr 256 1 >${tmpdir}/test.pgm +pamseq 3 5 -tupletype=RGB | pamtopnm \ >${tmpdir}/palette # Test 1. -${PBM_TESTPREFIX}pgmtoppm green ${tmpdir}/test.pgm | cksum +pgmtoppm green ${tmpdir}/test.pgm | cksum -${PBM_TESTPREFIX}pgmtoppm yellow-blue ${tmpdir}/test.pgm | cksum +pgmtoppm yellow-blue ${tmpdir}/test.pgm | cksum -${PBM_TESTPREFIX}pgmtoppm -map=${tmpdir}/palette ${tmpdir}/test.pgm | cksum +pgmtoppm -map=${tmpdir}/palette ${tmpdir}/test.pgm | cksum rm ${tmpdir}/test.pgm ${tmpdir}/palette diff --git a/test/png-roundtrip.ok b/test/png-roundtrip.ok index 67f7a1fe..28b8c057 100644 --- a/test/png-roundtrip.ok +++ b/test/png-roundtrip.ok @@ -1,2 +1,36 @@ 1926073387 101484 +1926073387 101484 +1926073387 101484 +1926073387 101484 +1926073387 101484 +1926073387 101484 +1926073387 101484 +1926073387 101484 +1926073387 101484 +1926073387 101484 +1926073387 101484 +1926073387 101484 +1926073387 101484 +1926073387 101484 +1926073387 101484 +1926073387 101484 +1926073387 101484 +1926073387 101484 +2425386270 41 +2425386270 41 +2425386270 41 +2425386270 41 +2425386270 41 +2425386270 41 +2425386270 41 +2425386270 41 +2425386270 41 +2425386270 41 +2425386270 41 +2425386270 41 +2425386270 41 +2425386270 41 +2425386270 41 +2425386270 41 +2425386270 41 2425386270 41 diff --git a/test/png-roundtrip.test b/test/png-roundtrip.test index 6f25d1c3..223103c8 100755 --- a/test/png-roundtrip.test +++ b/test/png-roundtrip.test @@ -2,6 +2,52 @@ # This script tests: pngtopnm pnmtopng # Also requires: -${PBM_TESTPREFIX}pnmtopng testimg.ppm | ${PBM_TESTPREFIX}pngtopnm | cksum -${PBM_TESTPREFIX}pnmtopng testgrid.pbm | ${PBM_TESTPREFIX}pngtopnm | cksum + alias pngtopnm="${PBM_TESTPREFIX}pngtopnm" + alias pnmtopng="${PBM_TESTPREFIX}pnmtopng" + shopt -s expand_aliases +## Fails because .ok not set yet. + +# Test 1. Should print 1926073387 101484 18 times +for flags in "" -interlace \ + -gamma=.45 \ + -hist \ + -nofilter \ + -sub \ + -up \ + -avg \ + -paeth \ + -compression=9 \ + "-compression=0 -comp_mem=1 -comp_window=8 -comp_buffer=512" \ + "-compression=9 -comp_mem=1 -comp_window=15 -comp_buffer=512" \ + "-compression=9 -comp_mem=1 -comp_window=8 -comp_buffer=512" \ + "-compression=0 -comp_mem=9 -comp_window=8 -comp_buffer=512" \ + "-compression=9 -comp_mem=9 -comp_window=15 -comp_buffer=8096" \ + -comp_strategy=huffman_only \ + -comp_strategy=filtered \ + -force + do +pnmtopng testimg.ppm $flags | pngtopnm | cksum +done + +# Test 2. Should print 2425386270 41 18 times +for flags in "" -interlace \ + -gamma=.45 \ + -hist \ + -nofilter \ + -sub \ + -up \ + -avg \ + -paeth \ + -compression=9 \ + "-compression=0 -comp_mem=1 -comp_window=8 -comp_buffer=512" \ + "-compression=9 -comp_mem=1 -comp_window=15 -comp_buffer=512" \ + "-compression=9 -comp_mem=1 -comp_window=8 -comp_buffer=512" \ + "-compression=0 -comp_mem=9 -comp_window=8 -comp_buffer=512" \ + "-compression=9 -comp_mem=9 -comp_window=15 -comp_buffer=8096" \ + -comp_strategy=huffman_only \ + -comp_strategy=filtered \ + -force + do + pnmtopng testgrid.pbm $flags | pngtopnm | cksum + done diff --git a/test/pnm-pam-roundtrip.test b/test/pnm-pam-roundtrip.test index 1aef986c..506d25aa 100755 --- a/test/pnm-pam-roundtrip.test +++ b/test/pnm-pam-roundtrip.test @@ -2,6 +2,10 @@ # This script tests: pamtopam pamtopnm # Also requires: -${PBM_TESTPREFIX}pamtopam < testimg.ppm | ${PBM_TESTPREFIX}pamtopnm | cksum -${PBM_TESTPREFIX}pamtopam < testgrid.pbm | ${PBM_TESTPREFIX}pamtopnm | cksum + alias pamtopam="${PBM_TESTPREFIX}pamtopam" + alias pamtopnm="${PBM_TESTPREFIX}pamtopnm" + shopt -s expand_aliases + +pamtopam < testimg.ppm | pamtopnm | cksum +pamtopam < testgrid.pbm | pamtopnm | cksum diff --git a/test/pnm-plain-roundtrip.test b/test/pnm-plain-roundtrip.test index 86dbb2fb..7d0293ee 100755 --- a/test/pnm-plain-roundtrip.test +++ b/test/pnm-plain-roundtrip.test @@ -2,8 +2,11 @@ # This script tests: pnmtopnm # Also requires: pamtopnm -${PBM_TESTPREFIX}pnmtopnm -plain testimg.ppm | \ - ${PBM_TESTPREFIX}pnmtopnm | cksum -${PBM_TESTPREFIX}pnmtopnm -plain testgrid.pbm | \ - ${PBM_TESTPREFIX}pnmtopnm | cksum + alias pnmtopnm="${PBM_TESTPREFIX}pnmtopnm" + shopt -s expand_aliases + +pnmtopnm -plain testimg.ppm | \ + pnmtopnm | cksum +pnmtopnm -plain testgrid.pbm | \ + pnmtopnm | cksum diff --git a/test/pnmcat.test b/test/pnmcat.test index 35efd515..b77c90fd 100755 --- a/test/pnmcat.test +++ b/test/pnmcat.test @@ -2,8 +2,11 @@ # This script tests: pnmcat # Also requires: -${PBM_TESTPREFIX}pnmcat -lr testgrid.pbm testgrid.pbm | cksum -${PBM_TESTPREFIX}pnmcat -tb testgrid.pbm testgrid.pbm | cksum + alias pnmcat="${PBM_TESTPREFIX}pnmcat" + shopt -s expand_aliases -${PBM_TESTPREFIX}pnmcat -lr testimg.ppm testimg.ppm | cksum -${PBM_TESTPREFIX}pnmcat -tb testimg.ppm testimg.ppm | cksum +pnmcat -lr testgrid.pbm testgrid.pbm | cksum +pnmcat -tb testgrid.pbm testgrid.pbm | cksum + +pnmcat -lr testimg.ppm testimg.ppm | cksum +pnmcat -tb testimg.ppm testimg.ppm | cksum diff --git a/test/pnminvert-roundtrip.test b/test/pnminvert-roundtrip.test index 8cdb6c25..eb3e2b35 100755 --- a/test/pnminvert-roundtrip.test +++ b/test/pnminvert-roundtrip.test @@ -2,5 +2,8 @@ # This script tests: pnminvert # Also requires: -${PBM_TESTPREFIX}pnminvert testimg.ppm | ${PBM_TESTPREFIX}pnminvert | cksum -${PBM_TESTPREFIX}pnminvert testgrid.pbm | ${PBM_TESTPREFIX}pnminvert | cksum + alias pnminvert="${PBM_TESTPREFIX}pnminvert" + shopt -s expand_aliases + +pnminvert testimg.ppm | pnminvert | cksum +pnminvert testgrid.pbm | pnminvert | cksum diff --git a/test/pnminvert.test b/test/pnminvert.test index 7fc8523c..eb25d2a0 100755 --- a/test/pnminvert.test +++ b/test/pnminvert.test @@ -2,19 +2,24 @@ # This script tests: pnminvert # Also requires: pbmmake ppmtopgm + alias pnminvert="${PBM_TESTPREFIX}pnminvert" + alias pbmmake="${PBM_BINPREFIX}pbmmake" + alias ppmtopgm="${PBM_BINPREFIX}ppmtopgm" + shopt -s expand_aliases + # Test 1. Should print 1240379484 41 -${PBM_TESTPREFIX}pnminvert testgrid.pbm | cksum +pnminvert testgrid.pbm | cksum # Test 2. Should print 1416115901 101484 -${PBM_TESTPREFIX}pnminvert testimg.ppm | cksum +pnminvert testimg.ppm | cksum # Test 3. Should print 2961441369 33838 # printed 4215652354 33838 with older ppmtopgm -${PBM_BINPREFIX}ppmtopgm testimg.ppm | ${PBM_TESTPREFIX}pnminvert | cksum +ppmtopgm testimg.ppm | pnminvert | cksum # Test 4. Should print 2595564405 14 -${PBM_BINPREFIX}pbmmake -w 7 7 | ${PBM_TESTPREFIX}pnminvert | cksum +pbmmake -w 7 7 | pnminvert | cksum # Test 5. Should print 2595564405 14 -${PBM_BINPREFIX}pbmmake -b 7 7 | cksum +pbmmake -b 7 7 | cksum # Test 6. Should print 2595564405 14 -${PBM_BINPREFIX}pbmmake -b 7 7 | ${PBM_TESTPREFIX}pnminvert | \ - ${PBM_TESTPREFIX}pnminvert | cksum +pbmmake -b 7 7 | pnminvert | \ + pnminvert | cksum # Test 7. Should print 2896726098 15 -${PBM_BINPREFIX}pbmmake -g 8 8 | ${PBM_TESTPREFIX}pnminvert | cksum +pbmmake -g 8 8 | pnminvert | cksum diff --git a/test/pnmpsnr.test b/test/pnmpsnr.test index d5aa07f3..da88d70d 100755 --- a/test/pnmpsnr.test +++ b/test/pnmpsnr.test @@ -2,10 +2,14 @@ # This script tests: pnmpsnr # Also requires: pbmmake -${PBM_BINPREFIX}pbmmake -w 10 10 > ${tmpdir}/w.pbm -${PBM_BINPREFIX}pbmmake -b 10 10 > ${tmpdir}/b.pbm -${PBM_TESTPREFIX}pnmpsnr ${tmpdir}/w.pbm ${tmpdir}/b.pbm 2>&1 | \ + alias pnmpsnr="${PBM_TESTPREFIX}pnmpsnr" + alias pbmmake="${PBM_BINPREFIX}pbmmake" + shopt -s expand_aliases + +pbmmake -w 10 10 > ${tmpdir}/w.pbm +pbmmake -b 10 10 > ${tmpdir}/b.pbm +pnmpsnr ${tmpdir}/w.pbm ${tmpdir}/b.pbm 2>&1 | \ awk '{print $(NF-1),$NF}' -${PBM_TESTPREFIX}pnmpsnr ${tmpdir}/w.pbm ${tmpdir}/w.pbm 2>&1 | \ +pnmpsnr ${tmpdir}/w.pbm ${tmpdir}/w.pbm 2>&1 | \ awk '{print $(NF-1),$NF}' rm ${tmpdir}/b.pbm ${tmpdir}/w.pbm diff --git a/test/pnmremap1.test b/test/pnmremap1.test index 1e68c8ad..208be2fb 100755 --- a/test/pnmremap1.test +++ b/test/pnmremap1.test @@ -2,9 +2,15 @@ # This script tests: pnmremap # Also requires: pamdepth pamseq pamtopnm -${PBM_BINPREFIX}pamseq 3 5 -tupletype=RGB | ${PBM_BINPREFIX}pamtopnm \ + alias pnmremap="${PBM_TESTPREFIX}pnmremap" + alias pamdepth="${PBM_BINPREFIX}pamdepth" + alias pamseq="${PBM_BINPREFIX}pamseq" + alias pamtopnm="${PBM_BINPREFIX}pamtopnm" + shopt -s expand_aliases + +pamseq 3 5 -tupletype=RGB | pamtopnm \ > ${tmpdir}/palette -${PBM_BINPREFIX}pamdepth 255 ${tmpdir}/palette > ${tmpdir}/palette255 +pamdepth 255 ${tmpdir}/palette > ${tmpdir}/palette255 # Test 1. Floyd-Steinberg # This fails with older versions of Netpbm and x86-64. @@ -13,7 +19,7 @@ ${PBM_BINPREFIX}pamdepth 255 ${tmpdir}/palette > ${tmpdir}/palette255 # x86-32: 2667816854 101482 # x86-64: 3602410851 101482 -${PBM_TESTPREFIX}pnmremap -mapfile=${tmpdir}/palette -floyd -norandom \ +pnmremap -mapfile=${tmpdir}/palette -floyd -norandom \ testimg.ppm | cksum rm ${tmpdir}/palette{,255} diff --git a/test/pnmremap2.test b/test/pnmremap2.test index f2fd92e0..3399dc39 100755 --- a/test/pnmremap2.test +++ b/test/pnmremap2.test @@ -2,20 +2,26 @@ # This script tests: pnmremap # Also requires: pamdepth pamseq pamtopnm -${PBM_BINPREFIX}pamseq 3 5 -tupletype=RGB | ${PBM_BINPREFIX}pamtopnm \ + alias pnmremap="${PBM_TESTPREFIX}pnmremap" + alias pamdepth="${PBM_BINPREFIX}pamdepth" + alias pamseq="${PBM_BINPREFIX}pamseq" + alias pamtopnm="${PBM_BINPREFIX}pamtopnm" + shopt -s expand_aliases + +pamseq 3 5 -tupletype=RGB | pamtopnm \ > ${tmpdir}/palette -${PBM_BINPREFIX}pamdepth 255 ${tmpdir}/palette > ${tmpdir}/palette255 +pamdepth 255 ${tmpdir}/palette > ${tmpdir}/palette255 # Test 2. Default (unmodified quantization) -${PBM_TESTPREFIX}pnmremap -mapfile=${tmpdir}/palette -nofloyd \ +pnmremap -mapfile=${tmpdir}/palette -nofloyd \ testimg.ppm | cksum # Test 3. Use first color in palette for missing colors -${PBM_TESTPREFIX}pnmremap -mapfile=${tmpdir}/palette255 -nofloyd \ +pnmremap -mapfile=${tmpdir}/palette255 -nofloyd \ -firstisdefault testimg.ppm | cksum # Test 4. Use black for missing colors -${PBM_TESTPREFIX}pnmremap -mapfile=${tmpdir}/palette255 -nofloyd \ +pnmremap -mapfile=${tmpdir}/palette255 -nofloyd \ -missingcolor=black testimg.ppm | cksum rm ${tmpdir}/palette{,255} diff --git a/test/pnmshear.ok b/test/pnmshear.ok index d701faaf..058ec042 100644 --- a/test/pnmshear.ok +++ b/test/pnmshear.ok @@ -1 +1 @@ -2080980136 22 +598644601 24 diff --git a/test/pnmshear.test b/test/pnmshear.test index 276e3e22..30ab45be 100644..100755 --- a/test/pnmshear.test +++ b/test/pnmshear.test @@ -1,19 +1,26 @@ #! /bin/bash # This script tests: pnmshear -# Also requires: pbmmake +# Also requires: pbmmake pnmpad -# Test. Should produce 2080980136 22 -${PBM_BINPREFIX}pbmmake -g 7 7 | \ - ${PBM_TESTPREFIX}pnmshear 45 -noantialias | cksum + alias pnmshear="${PBM_TESTPREFIX}pnmshear" + alias pbmmake="${PBM_BINPREFIX}pbmmake" + alias pnmpad="${PBM_BINPREFIX}pnmpad" + shopt -s expand_aliases + +# Test. Should produce 598644601 24 + +pbmmake -g 7 7 | pnmpad -white -top 1 | \ + pnmshear 45 -noantialias | cksum # Output of above, in pbm plain format # # P1 -# 14 7 -# 01010101111111 -# 10101011111111 -# 10101010111111 -# 11101010111111 -# 11101010101111 -# 11111010101111 -# 11111010101011 +# 15 8 +# 000000000000000 +# 010101000000000 +# 010101010000000 +# 000101010000000 +# 000101010100000 +# 000001010100000 +# 000001010101000 +# 000000010101000 diff --git a/test/pnmtile.test b/test/pnmtile.test index 0f9d91df..f74bdce3 100755 --- a/test/pnmtile.test +++ b/test/pnmtile.test @@ -2,11 +2,15 @@ # This script tests: pnmtile # Also requires: pnmcat -${PBM_TESTPREFIX}pnmtile 40 50 testgrid.pbm | cksum + alias pnmtile="${PBM_TESTPREFIX}pnmtile" + alias pnmcat="${PBM_BINPREFIX}pnmcat" + shopt -s expand_aliases -${PBM_TESTPREFIX}pnmtile 454 298 testimg.ppm > ${tmpdir}/testimg4.ppm && -${PBM_BINPREFIX}pnmcat -lr testimg.ppm testimg.ppm > ${tmpdir}/testimg2.ppm && -${PBM_BINPREFIX}pnmcat -tb ${tmpdir}/testimg2.ppm ${tmpdir}/testimg2.ppm | \ +pnmtile 40 50 testgrid.pbm | cksum + +pnmtile 454 298 testimg.ppm > ${tmpdir}/testimg4.ppm && +pnmcat -lr testimg.ppm testimg.ppm > ${tmpdir}/testimg2.ppm && +pnmcat -tb ${tmpdir}/testimg2.ppm ${tmpdir}/testimg2.ppm | \ cmp -s - ${tmpdir}/testimg4.ppm echo $? diff --git a/test/pnmtopnm-plain.test b/test/pnmtopnm-plain.test index ff211e40..f4e0749e 100755 --- a/test/pnmtopnm-plain.test +++ b/test/pnmtopnm-plain.test @@ -2,9 +2,14 @@ # This script tests: pnmtopnm # Also requires: pgmtopgm ppmtoppm pamtopnm -${PBM_TESTPREFIX}pnmtopnm -plain testgrid.pbm + alias pnmtopnm="${PBM_TESTPREFIX}pnmtopnm" + alias pgmtopgm="${PBM_BINPREFIX}pgmtopgm" + alias ppmtoppm="${PBM_BINPREFIX}ppmtoppm" + shopt -s expand_aliases -${PBM_BINPREFIX}pgmtopgm < testgrid.pbm | ${PBM_TESTPREFIX}pnmtopnm -plain +pnmtopnm -plain testgrid.pbm -${PBM_BINPREFIX}ppmtoppm < testgrid.pbm | ${PBM_TESTPREFIX}pnmtopnm -plain | \ +pgmtopgm < testgrid.pbm | pnmtopnm -plain + +ppmtoppm < testgrid.pbm | pnmtopnm -plain | \ head -n11 diff --git a/test/ppmbrighten.test b/test/ppmbrighten.test index 72bebff4..29cfeb2c 100755 --- a/test/ppmbrighten.test +++ b/test/ppmbrighten.test @@ -2,6 +2,9 @@ # This script tests: ppmbrighten # Also requires: -${PBM_TESTPREFIX}ppmbrighten -v 100 testimg.ppm | cksum -${PBM_TESTPREFIX}ppmbrighten -v 100 -normalize testimg.ppm | cksum -${PBM_TESTPREFIX}ppmbrighten -s 100 -v -50 testimg.ppm | cksum + alias ppmbrighten="${PBM_TESTPREFIX}ppmbrighten" + shopt -s expand_aliases + +ppmbrighten -v 100 testimg.ppm | cksum +ppmbrighten -v 100 -normalize testimg.ppm | cksum +ppmbrighten -s 100 -v -50 testimg.ppm | cksum diff --git a/test/ppmchange-roundtrip.test b/test/ppmchange-roundtrip.test index c303c11b..a357870e 100755 --- a/test/ppmchange-roundtrip.test +++ b/test/ppmchange-roundtrip.test @@ -2,10 +2,16 @@ # This script tests: ppmchange # Also requires: pgmtopbm pnminvert ppmtopgm -${PBM_TESTPREFIX}ppmchange black white white black testgrid.pbm | \ -${PBM_BINPREFIX}pnminvert | ${PBM_BINPREFIX}ppmtopgm | \ -${PBM_BINPREFIX}pgmtopbm -th -val=0.5 | cksum + alias ppmchange="${PBM_TESTPREFIX}ppmchange" + alias pgmtopbm="${PBM_BINPREFIX}pgmtopbm" + alias pnminvert="${PBM_BINPREFIX}pnminvert" + alias ppmtopgm="${PBM_BINPREFIX}ppmtopgm" + shopt -s expand_aliases -${PBM_TESTPREFIX}ppmchange black white white black testgrid.pbm | \ -${PBM_TESTPREFIX}ppmchange black white white black -plain | \ -${PBM_BINPREFIX}ppmtopgm | ${PBM_BINPREFIX}pgmtopbm -th -val=0.5 | cksum +ppmchange black white white black testgrid.pbm | \ +pnminvert | ppmtopgm | \ +pgmtopbm -th -val=0.5 | cksum + +ppmchange black white white black testgrid.pbm | \ +ppmchange black white white black -plain | \ +ppmtopgm | pgmtopbm -th -val=0.5 | cksum diff --git a/test/ppmcie.test b/test/ppmcie.test index 1e60c848..2584ece4 100755 --- a/test/ppmcie.test +++ b/test/ppmcie.test @@ -2,6 +2,11 @@ # This script tests: ppmcie # Also requires: pamsumm pamsharpness + alias ppmcie="${PBM_TESTPREFIX}ppmcie" + alias pamsharpness="${PBM_BINPREFIX}pamsharpness" + alias pamsumm="${PBM_BINPREFIX}pamsumm" + shopt -s expand_aliases + # Test 1. Should print 955840041 786447 # Without -nolabel -noaxes -nowpoint -noblack older versions of # Netpbm produce slightly different charts. @@ -9,7 +14,7 @@ # v. 10.35.86: 288356530 786447 # v. 10.59.2 : 2292601420 786447 -${PBM_TESTPREFIX}ppmcie -nolabel -noaxes -nowpoint -noblack \ +ppmcie -nolabel -noaxes -nowpoint -noblack \ > ${tmpdir}/ppmcie.ppm # There is a slight difference in the output depending on whether ppmcie @@ -26,7 +31,7 @@ ${PBM_TESTPREFIX}ppmcie -nolabel -noaxes -nowpoint -noblack \ # x86 32 bit: 38.660173 # x86 64 bit: 38.681432 -${PBM_BINPREFIX}pamsumm --mean --brief ${tmpdir}/ppmcie.ppm | \ +pamsumm --mean --brief ${tmpdir}/ppmcie.ppm | \ awk '{ if(38.65 < $1 && $1 <38.69) print "ok"; else print $1}' # Test 2. Measure image sharpness @@ -34,7 +39,7 @@ ${PBM_BINPREFIX}pamsumm --mean --brief ${tmpdir}/ppmcie.ppm | \ # x86 32 bit: 0.002476 # x86 64 bit: 0.002478 -${PBM_BINPREFIX}pamsharpness ${tmpdir}/ppmcie.ppm 2>&1 | \ +pamsharpness ${tmpdir}/ppmcie.ppm 2>&1 | \ awk 'NF==4 && $2=="Sharpness" \ {if (0.002475 < $4 && $4 < 0.002479) print "ok"; else print $4} NF>0 && NF!=4 {print "error"}' diff --git a/test/ppmdfont.test b/test/ppmdfont.test index 027b8f2c..30f74a9c 100755 --- a/test/ppmdfont.test +++ b/test/ppmdfont.test @@ -2,11 +2,16 @@ # This script tests: ppmdmkfont ppmddumpfont ppmdcfont # Also requires: + alias ppmdcfont="${PBM_TESTPREFIX}ppmdcfont" + alias ppmddumpfont="${PBM_TESTPREFIX}ppmddumpfont" + alias ppmdmkfont="${PBM_TESTPREFIX}ppmdmkfont" + shopt -s expand_aliases + # Test 1. Should produce: 2726488777 48129 -${PBM_TESTPREFIX}ppmdmkfont | ${PBM_TESTPREFIX}ppmddumpfont 2>&1 | cksum +ppmdmkfont | ppmddumpfont 2>&1 | cksum # Test 2. Should produce: 2845495212 75033 -${PBM_TESTPREFIX}ppmdmkfont | ${PBM_TESTPREFIX}ppmdcfont | cksum +ppmdmkfont | ppmdcfont | cksum # There is a strange glitch in output when ppmdcfont is compiled by clang: # 3171,3173c3171,3173 diff --git a/test/ppmdim.test b/test/ppmdim.test index e2a1b0df..e528c3ce 100755 --- a/test/ppmdim.test +++ b/test/ppmdim.test @@ -2,6 +2,12 @@ # This script tests: ppmdim # Also requires: pamfunc pnmarith pamarith pamsumm + alias ppmdim="${PBM_TESTPREFIX}ppmdim" + alias pamfunc="${PBM_BINPREFIX}pamfunc" + alias pamsumm="${PBM_BINPREFIX}pamsumm" + alias pnmarith="${PBM_BINPREFIX}pnmarith" + shopt -s expand_aliases + # Compare ppmdim and pamfunc with various dim factors # Due to the difference in rounding methods, pamfunc produces slightly # brighter images, by about 0.5 per pixel. @@ -10,10 +16,10 @@ for i in 0.125 0.25 0.5 0.75 0.1 0.0117 0.2 0.4 0.333 0.666 0.8 0.9 0.95 do - ${PBM_TESTPREFIX}ppmdim $i testimg.ppm > ${tmpdir}/dim1.ppm - ${PBM_BINPREFIX}pamfunc -mult=$i testimg.ppm > ${tmpdir}/dim2.ppm - ${PBM_BINPREFIX}pnmarith -diff ${tmpdir}/dim1.ppm ${tmpdir}/dim2.ppm | \ - ${PBM_BINPREFIX}pamsumm -mean -brief | \ + ppmdim $i testimg.ppm > ${tmpdir}/dim1.ppm + pamfunc -mult=$i testimg.ppm > ${tmpdir}/dim2.ppm + pnmarith -diff ${tmpdir}/dim1.ppm ${tmpdir}/dim2.ppm | \ + pamsumm -mean -brief | \ awk '{print $1<0.75 ? "ok" : "fail"}' done rm ${tmpdir}/dim[12].ppm diff --git a/test/ppmdither.test b/test/ppmdither.test index 5fea0bb4..a93a434a 100755 --- a/test/ppmdither.test +++ b/test/ppmdither.test @@ -2,6 +2,9 @@ # This script tests: ppmdither # Also requires: -${PBM_TESTPREFIX}ppmdither testimg.ppm | cksum -${PBM_TESTPREFIX}ppmdither -red 2 -green 2 -blue 2 testimg.ppm | cksum -${PBM_TESTPREFIX}ppmdither -dim 2 testimg.ppm | cksum + alias ppmdither="${PBM_TESTPREFIX}ppmdither" + shopt -s expand_aliases + +ppmdither testimg.ppm | cksum +ppmdither -red 2 -green 2 -blue 2 testimg.ppm | cksum +ppmdither -dim 2 testimg.ppm | cksum diff --git a/test/ppmforge.test b/test/ppmforge.test index 5ec37e9c..09a66916 100755 --- a/test/ppmforge.test +++ b/test/ppmforge.test @@ -1,6 +1,9 @@ #! /bin/bash # This script tests: ppmforge + alias ppmforge="${PBM_TESTPREFIX}ppmforge" + shopt -s expand_aliases + # Use small x y values to avoid floating point issues. @@ -8,7 +11,7 @@ testrandom -q case $? in 81) # Test 1: Should print: 3634219838 196623 - ${PBM_TESTPREFIX}ppmforge -night -seed 1 | cksum + ppmforge -night -seed 1 | cksum ;; 8[02-9] | 90) diff --git a/test/ppmgauss.test b/test/ppmgauss.test index a75d272c..9dfdd2f6 100755 --- a/test/ppmgauss.test +++ b/test/ppmgauss.test @@ -2,10 +2,13 @@ # This script tests: pamgauss # Also requires: + alias pamgauss="${PBM_TESTPREFIX}pamgauss" + shopt -s expand_aliases + for i in `seq 3 11` do for s in `seq 1 9` do -${PBM_TESTPREFIX}pamgauss $i $i -sigma=.$s | cksum +pamgauss $i $i -sigma=.$s | cksum done done diff --git a/test/ppmhist.test b/test/ppmhist.test index 95fcd2f7..6dcbc762 100755 --- a/test/ppmhist.test +++ b/test/ppmhist.test @@ -2,6 +2,10 @@ # This script tests: ppmhist # Also requires: pgmramp -${PBM_BINPREFIX}pgmramp -maxval=8 -lr 8 2 | ${PBM_TESTPREFIX}ppmhist -sort=rgb -${PBM_TESTPREFIX}ppmhist -map -sort=rgb testimg.ppm | cksum + alias ppmhist="${PBM_TESTPREFIX}ppmhist" + alias pgmramp="${PBM_BINPREFIX}pgmramp" + shopt -s expand_aliases + +pgmramp -maxval=8 -lr 8 2 | ppmhist -sort=rgb +ppmhist -map -sort=rgb testimg.ppm | cksum diff --git a/test/ppmmake.test b/test/ppmmake.test index da23095c..faba1ace 100755 --- a/test/ppmmake.test +++ b/test/ppmmake.test @@ -2,10 +2,13 @@ # This script tests: ppmmake # Also requires: -${PBM_TESTPREFIX}ppmmake rgb:ff/80/80 50 100 -maxval=5 | cksum -${PBM_TESTPREFIX}ppmmake red 50 50 | cksum + alias ppmmake="${PBM_TESTPREFIX}ppmmake" + shopt -s expand_aliases +ppmmake rgb:ff/80/80 50 100 -maxval=5 | cksum +ppmmake red 50 50 | cksum - \ No newline at end of file + + diff --git a/test/ppmmix.test b/test/ppmmix.test index 451aa8be..d24e589d 100755 --- a/test/ppmmix.test +++ b/test/ppmmix.test @@ -3,26 +3,36 @@ # Also requires: pamdepth pamenlarge pamsumm pbmmake # Also requires: pgmtopgm pnminvert ppmtopgm + alias ppmmix="${PBM_TESTPREFIX}ppmmix" + alias pamdepth="${PBM_BINPREFIX}pamdepth" + alias pamenlarge="${PBM_BINPREFIX}pamenlarge" + alias pamsumm="${PBM_BINPREFIX}pamsumm" + alias pbmmake="${PBM_BINPREFIX}pbmmake" + alias pgmtopgm="${PBM_BINPREFIX}pgmtopgm" + alias pnminvert="${PBM_BINPREFIX}pnminvert" + alias ppmtopgm="${PBM_BINPREFIX}ppmtopgm" + shopt -s expand_aliases + # Print a pretty checkerboard pattern -${PBM_BINPREFIX}pbmmake -g 8 8 | \ - ${PBM_BINPREFIX}pgmtopgm > ${tmpdir}/a1.pgm && -${PBM_BINPREFIX}pbmmake -g 2 2 | ${PBM_BINPREFIX}pamenlarge 4 | \ - ${PBM_BINPREFIX}pgmtopgm > ${tmpdir}/a2.pgm && -${PBM_TESTPREFIX}ppmmix 0.75 ${tmpdir}/a1.pgm ${tmpdir}/a2.pgm -plain | \ - ${PBM_BINPREFIX}ppmtopgm | ${PBM_BINPREFIX}pamdepth 3 -plain && +pbmmake -g 8 8 | \ + pgmtopgm > ${tmpdir}/a1.pgm && +pbmmake -g 2 2 | pamenlarge 4 | \ + pgmtopgm > ${tmpdir}/a2.pgm && +ppmmix 0.75 ${tmpdir}/a1.pgm ${tmpdir}/a2.pgm -plain | \ + ppmtopgm | pamdepth 3 -plain && rm ${tmpdir}/a1.pgm ${tmpdir}/a2.pgm # Mix image with itself. # Output should match input regardless of ratio. for i in 0 0.5 0.6 1 do -${PBM_TESTPREFIX}ppmmix $i testimg.ppm testimg.ppm | cksum +ppmmix $i testimg.ppm testimg.ppm | cksum done # Mix image with its own inverse. # Output should be a monotone gray sheet. -${PBM_BINPREFIX}pnminvert testimg.ppm | ${PBM_TESTPREFIX}ppmmix .5 \ +pnminvert testimg.ppm | ppmmix .5 \ testimg.ppm - | tee ${tmpdir}/a3.ppm | \ - ${PBM_BINPREFIX}pamsumm -brief -max && - ${PBM_BINPREFIX}pamsumm -brief -min ${tmpdir}/a3.ppm && + pamsumm -brief -max && + pamsumm -brief -min ${tmpdir}/a3.ppm && rm ${tmpdir}/a3.ppm diff --git a/test/ppmpat.test b/test/ppmpat.test index af0ce956..bf1e9316 100755 --- a/test/ppmpat.test +++ b/test/ppmpat.test @@ -1,6 +1,9 @@ #! /bin/bash # This script tests: ppmpat + alias ppmpat="${PBM_TESTPREFIX}ppmpat" + shopt -s expand_aliases + # TODO: Write tests for squig and poles. It appears that they are # sensitive to differences in floating point math. @@ -8,22 +11,22 @@ testrandom -q case $? in 81) # Test 1. Should print: 4008533639 781 - ${PBM_TESTPREFIX}ppmpat --randomseed=0 -g2 16 16 | cksum + ppmpat --randomseed=0 -g2 16 16 | cksum # Test 2. Should print: 2448908863 9613 - ${PBM_TESTPREFIX}ppmpat --randomseed=0 -g2 64 50 | cksum + ppmpat --randomseed=0 -g2 64 50 | cksum # Test 3. Should print: 2698433077 1549 - ${PBM_TESTPREFIX}ppmpat --randomseed=0 -madras 32 16 | cksum + ppmpat --randomseed=0 -madras 32 16 | cksum # Test 4. Should print: 3705929501 781 - ${PBM_TESTPREFIX}ppmpat --randomseed=0 -tartan 16 16 | cksum + ppmpat --randomseed=0 -tartan 16 16 | cksum # Test 5. Should print: 2219119109 36015 - ${PBM_TESTPREFIX}ppmpat --randomseed=0 -camo 100 120 | cksum + ppmpat --randomseed=0 -camo 100 120 | cksum # Test 6. Should print: 3436846137 16813 - ${PBM_TESTPREFIX}ppmpat --randomseed=0 -anticamo 80 70 | cksum + ppmpat --randomseed=0 -anticamo 80 70 | cksum ;; 8[02-9] | 90) diff --git a/test/ppmrelief.ok b/test/ppmrelief.ok new file mode 100644 index 00000000..3c236775 --- /dev/null +++ b/test/ppmrelief.ok @@ -0,0 +1,3 @@ +3637356697 688 +3979143778 780 +2954951371 780 diff --git a/test/ppmrelief.test b/test/ppmrelief.test new file mode 100755 index 00000000..378a22c9 --- /dev/null +++ b/test/ppmrelief.test @@ -0,0 +1,42 @@ +#! /bin/bash +# This script tests: ppmrelief +# Also requires: pbmmake pgmramp pamflip + + alias ppmrelief="${PBM_TESTPREFIX}ppmrelief" + alias pbmmake="${PBM_BINPREFIX}pbmmake" + alias pgmramp="${PBM_BINPREFIX}pgmramp" + alias pamflip="${PBM_BINPREFIX}pamflip" + shopt -s expand_aliases + +# Test 1. Should print 3637356697 688 +pbmmake -w 15 15 | ppmrelief | cksum + +# Test 2. Should print 3979143778 780 +pgmramp -diagonal -maxval=30 16 16 | ppmrelief | cksum + +# Test 3. Should print 2954951371 780 +pgmramp -diagonal -maxval=30 16 16 | pamflip -lr | ppmrelief | cksum + + +# pgmramp -diagonal -maxval=30 16 16 | ppmrelief | ppmtopgm -plain + +# P2 +# 16 16 +# 30 +# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +# 0 14 14 14 14 14 14 14 14 14 14 14 14 14 14 0 +# 0 14 14 14 14 14 14 14 14 14 14 14 14 14 14 0 +# 0 14 14 14 14 14 14 14 14 14 14 14 14 14 14 0 +# 0 14 14 14 14 14 14 14 14 14 14 14 14 14 14 0 +# 0 14 14 14 14 14 14 14 14 14 14 14 14 14 14 0 +# 0 14 14 14 14 14 14 14 14 14 14 14 14 14 14 0 +# 0 14 14 14 14 14 14 14 14 14 14 14 14 14 14 0 +# 0 14 14 14 14 14 14 14 14 14 14 14 14 14 14 0 +# 0 14 14 14 14 14 14 14 14 14 14 14 14 14 14 0 +# 0 14 14 14 14 14 14 14 14 14 14 14 14 14 14 0 +# 0 14 14 14 14 14 14 14 14 14 14 14 14 14 14 0 +# 0 14 14 14 14 14 14 14 14 14 14 14 14 14 14 0 +# 0 14 14 14 14 14 14 14 14 14 14 14 14 14 14 0 +# 0 14 14 14 14 14 14 14 14 14 14 14 14 14 14 0 +# 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + diff --git a/test/ppmrough.test b/test/ppmrough.test index 92cc02d7..dbe92c29 100755 --- a/test/ppmrough.test +++ b/test/ppmrough.test @@ -1,12 +1,15 @@ #! /bin/bash # This script tests: ppmrough + alias ppmrough="${PBM_TESTPREFIX}ppmrough" + shopt -s expand_aliases + testrandom -q case $? in 81) # Should print: 378403602 30015 - ${PBM_TESTPREFIX}ppmrough -randomseed 1 | cksum + ppmrough -randomseed 1 | cksum ;; 8[02-9] | 90) diff --git a/test/ppmtopgm.test b/test/ppmtopgm.test index 7ab481c6..94e0ae91 100755 --- a/test/ppmtopgm.test +++ b/test/ppmtopgm.test @@ -2,6 +2,9 @@ # This script tests: ppmtopgm # Also requires: + alias ppmtopgm="${PBM_TESTPREFIX}ppmtopgm" + shopt -s expand_aliases + # Test 1. Should produce 2871603838 33838 -${PBM_TESTPREFIX}ppmtopgm testimg.ppm | cksum +ppmtopgm testimg.ppm | cksum diff --git a/test/ppmtoppm.test b/test/ppmtoppm.test index c073ecff..2d84809a 100755 --- a/test/ppmtoppm.test +++ b/test/ppmtoppm.test @@ -2,4 +2,7 @@ # This script tests: ppmtoppm # Also requires: -${PBM_TESTPREFIX}ppmtoppm < testgrid.pbm | cksum \ No newline at end of file + alias ppmtoppm="${PBM_TESTPREFIX}ppmtoppm" + shopt -s expand_aliases + +ppmtoppm < testgrid.pbm | cksum diff --git a/test/ppmwheel.test b/test/ppmwheel.test index 4d786f26..89bab029 100755 --- a/test/ppmwheel.test +++ b/test/ppmwheel.test @@ -2,12 +2,15 @@ # This script tests: ppmwheel # Also requires: + alias ppmwheel="${PBM_TESTPREFIX}ppmwheel" + shopt -s expand_aliases + # For values 6 and above, x86(-32) and x86-64 produce different output. # SSE floating-point math is the probable cause. for i in 4 5 do -${PBM_TESTPREFIX}ppmwheel $i | cksum +ppmwheel $i | cksum done # i 32 bit 64 bit @@ -110,4 +113,4 @@ done - \ No newline at end of file + diff --git a/test/ps-alt-roundtrip.test b/test/ps-alt-roundtrip.test index 8ce1689d..8c4cfc2a 100755 --- a/test/ps-alt-roundtrip.test +++ b/test/ps-alt-roundtrip.test @@ -2,6 +2,14 @@ # This script tests: pbmtoepsi pbmtopsg3 pbmtolps psidtopgm pstopnm # Also requires: gs pnmtopnm pnmcrop + alias pbmtoepsi="${PBM_TESTPREFIX}pbmtoepsi" + alias pbmtolps="${PBM_TESTPREFIX}pbmtolps" + alias pbmtopsg3="${PBM_TESTPREFIX}pbmtopsg3" + alias psidtopgm="${PBM_TESTPREFIX}psidtopgm" + alias pstopnm="${PBM_TESTPREFIX}pstopnm" + alias pnmcrop="${PBM_BINPREFIX}pnmcrop" + shopt -s expand_aliases + # This script is for testing alternative (or minor) utilities that # read/write Postscript and encapsulated Postscript: # pbmtoepsi, pbmtopsg3, pbmtolps and psidtopgm. @@ -14,33 +22,35 @@ # If ps-roundtrip.test succeeds and this test fails, it is most likely # a problem with one of the minor utilities, and vice versa. +# pstopnm does not use libnetpbm functions for output. +# Output is filtered through pnmtopnm. # Test 1. Should print: 2425386270 41 -${PBM_TESTPREFIX}pbmtopsg3 -dpi=72 testgrid.pbm \ +pbmtopsg3 -dpi=72 testgrid.pbm \ > ${tmpdir}/testgrid1.ps && \ -${PBM_TESTPREFIX}pstopnm -xborder=0 -yborder=0 -llx=0 -lly=-16 -urx=14 \ +pstopnm -xborder=0 -yborder=0 -llx=0 -lly=-16 -urx=14 \ -dpi=72 -stdout -quiet -pbm ${tmpdir}/testgrid1.ps | \ - ${PBM_BINPREFIX}pnmcrop | cksum + pnmcrop | cksum # Test 2. Should print: 2425386270 41 -${PBM_TESTPREFIX}pbmtolps -dpi 72 testgrid.pbm \ +pbmtolps -dpi 72 testgrid.pbm \ > ${tmpdir}/testgrid2.ps && \ -${PBM_TESTPREFIX}pstopnm -xborder=0 -yborder=0 -dpi=72 -stdout \ +pstopnm -xborder=0 -yborder=0 -dpi=72 -stdout \ -quiet ${tmpdir}/testgrid2.ps -pbm | \ - ${PBM_BINPREFIX}pnmcrop | cksum + pnmcrop | cksum # Test 3. Should print: 2916080186 235 # Output is pgm maxval=1 with black and white inverted. # -${PBM_TESTPREFIX}pbmtoepsi testgrid.pbm > ${tmpdir}/testgrid.epsi && \ +pbmtoepsi testgrid.pbm > ${tmpdir}/testgrid.epsi && \ xysizebps=`awk '/BeginPreview/ {print $2,$3,$4}' \ ${tmpdir}/testgrid.epsi` && \ awk '/^%%BeginPreview:/ { p=1; next } /^%%EndImage/ { p=0; next } \ p==1 && /%[ \t0-9a-fA-F]+/ { print substr($0,2); next } \ p==1 {print "!"$0}' \ - ${tmpdir}/testgrid.epsi | ${PBM_TESTPREFIX}psidtopgm $xysizebps | cksum + ${tmpdir}/testgrid.epsi | psidtopgm $xysizebps | cksum rm ${tmpdir}/testgrid[12].ps ${tmpdir}/testgrid.epsi diff --git a/test/ps-roundtrip.test b/test/ps-roundtrip.test index 92925064..1877724d 100755 --- a/test/ps-roundtrip.test +++ b/test/ps-roundtrip.test @@ -2,41 +2,58 @@ # This script tests: pnmtops pstopnm # Also requires: pnmtopnm pamtopnm gs pbmmake pnmshear pnmpad pnmcat + alias pnmtops="${PBM_TESTPREFIX}pnmtops" + alias pstopnm="${PBM_TESTPREFIX}pstopnm" + alias pbmmake="${PBM_BINPREFIX}pbmmake" + alias pnmcat="${PBM_BINPREFIX}pnmcat" + alias pnmpad="${PBM_BINPREFIX}pnmpad" + alias pnmshear="${PBM_BINPREFIX}pnmshear" + alias pnmtopnm="${PBM_BINPREFIX}pnmtopnm" + shopt -s expand_aliases + +# Failure message +## This test fails when: +## (1) zlib was not linked. +## (2) ghostscript is not available. + +# pstopnm does not use libnetpbm functions for output. +# Output is filtered through pnmtopnm. + # Test 1. Should print: 1926073387 101484 five times # *NOTE* Fifth iteration fails if pnmtops was compiled without zlib # (flate compression) support. for flag in "" "-ps" "-rle" "-ps -ascii" "-ps -flate" do - ${PBM_TESTPREFIX}pnmtops -nocenter -equalpixels -dpi 72 -noturn \ + pnmtops -nocenter -equalpixels -dpi 72 -noturn \ ${flag} testimg.ppm \ > ${tmpdir}/testimg.ps xysize1=`awk '/BoundingBox/ {print "-xsize="$4,"-ysize="$5}' \ ${tmpdir}/testimg.ps` - ${PBM_TESTPREFIX}pstopnm -portrait -xborder=0 -yborder=0 $xysize1 -stdout \ + pstopnm -portrait -xborder=0 -yborder=0 $xysize1 -stdout \ -quiet ${tmpdir}/testimg.ps | \ - ${PBM_BINPREFIX}pnmtopnm | cksum + pnmtopnm | cksum done # Test 2. Should print: 2918318199 62 seven times # Test image designed to detect problems with run-length compression # -${PBM_BINPREFIX}pbmmake -g 2 2 > ${tmpdir}/g.pbm -${PBM_BINPREFIX}pbmmake -g 8 4 | \ - ${PBM_BINPREFIX}pnmshear 45 -noantialias -background=black | \ - ${PBM_BINPREFIX}pnmpad -right 60 | \ - ${PBM_BINPREFIX}pnmcat -tb -jright - ${tmpdir}/g.pbm > ${tmpdir}/t.pbm && +pbmmake -g 2 2 > ${tmpdir}/g.pbm +pbmmake -g 8 4 | \ + pnmshear 45 -noantialias -background=black | \ + pnmpad -right 60 | \ + pnmcat -tb -jright - ${tmpdir}/g.pbm > ${tmpdir}/t.pbm && for flag in "" "-rle" "-ps -rle -ascii" \ "-bitspersample=2 -rle" "-ps -bitspersample=4 -rle" \ "-bitspersample=8 -rle" "-ps -bitspersample=12 -rle -dict" do - ${PBM_TESTPREFIX}pnmtops -nocenter -equalpixels -dpi 72 -noturn \ + pnmtops -nocenter -equalpixels -dpi 72 -noturn \ ${flag} ${tmpdir}/t.pbm > ${tmpdir}/testgrid.ps && xysize2=`awk '/BoundingBox/ {print "-xsize="$4,"-ysize="$5}' \ ${tmpdir}/testgrid.ps` - ${PBM_TESTPREFIX}pstopnm -portrait -xborder=0 -yborder=0 $xysize2 -stdout \ + pstopnm -portrait -xborder=0 -yborder=0 $xysize2 -stdout \ -quiet ${tmpdir}/testgrid.ps -pbm | \ - ${PBM_BINPREFIX}pnmtopnm | cksum + pnmtopnm | cksum done @@ -56,13 +73,13 @@ for flag in "" "-ps" \ "-ps -bitspersample=12 -flate -rle -vmreclaim" do cat testimg.ppm testimg.ppm testimg.ppm testgrid.pbm testgrid.pbm | \ -${PBM_TESTPREFIX}pnmtops -nocenter -equalpixels -dpi 72 -noturn -setpage \ +pnmtops -nocenter -equalpixels -dpi 72 -noturn -setpage \ ${flag} > ${tmpdir}/testimg5.ps xysize3=`awk '/BoundingBox/ {print "-xsize="$4,"-ysize="$5 ; exit}' \ ${tmpdir}/testimg5.ps` -${PBM_TESTPREFIX}pstopnm -portrait -xborder=0 -yborder=0 $xysize3 \ +pstopnm -portrait -xborder=0 -yborder=0 $xysize3 \ -stdout ${tmpdir}/testimg5.ps | \ - ${PBM_BINPREFIX}pnmtopnm | cksum + pnmtopnm | cksum done diff --git a/test/rgb3-roundtrip.test b/test/rgb3-roundtrip.test index d3575b95..829feab4 100755 --- a/test/rgb3-roundtrip.test +++ b/test/rgb3-roundtrip.test @@ -2,13 +2,20 @@ # This script tests: ppmtorgb3 rgb3toppm # Also requires: pgmtopbm pgmtopgm ppmtopgm + alias ppmtorgb3="${PBM_TESTPREFIX}ppmtorgb3" + alias rgb3toppm="${PBM_TESTPREFIX}rgb3toppm" + alias pgmtopbm="${PBM_BINPREFIX}pgmtopbm" + alias pgmtopgm="${PBM_BINPREFIX}pgmtopgm" + alias ppmtopgm="${PBM_BINPREFIX}ppmtopgm" + shopt -s expand_aliases + # Break an image into three monochrome planes, reassemble the # image from them and check whether the resulting output is # identical to the original input. cp testimg.ppm ${tmpdir} && -${PBM_TESTPREFIX}ppmtorgb3 ${tmpdir}/testimg.ppm && -${PBM_TESTPREFIX}rgb3toppm ${tmpdir}/testimg.red ${tmpdir}/testimg.grn \ +ppmtorgb3 ${tmpdir}/testimg.ppm && +rgb3toppm ${tmpdir}/testimg.red ${tmpdir}/testimg.grn \ ${tmpdir}/testimg.blu | cksum cat ${tmpdir}/testimg.red ${tmpdir}/testimg.grn ${tmpdir}/testimg.blu | \ @@ -17,10 +24,10 @@ cat ${tmpdir}/testimg.red ${tmpdir}/testimg.grn ${tmpdir}/testimg.blu | \ rm ${tmpdir}/testimg.{ppm,red,grn,blu} cp testgrid.pbm ${tmpdir} && -${PBM_TESTPREFIX}ppmtorgb3 ${tmpdir}/testgrid.pbm && -${PBM_TESTPREFIX}rgb3toppm ${tmpdir}/testgrid.red ${tmpdir}/testgrid.grn \ +ppmtorgb3 ${tmpdir}/testgrid.pbm && +rgb3toppm ${tmpdir}/testgrid.red ${tmpdir}/testgrid.grn \ ${tmpdir}/testgrid.blu | \ - ${PBM_BINPREFIX}ppmtopgm | ${PBM_BINPREFIX}pgmtopbm -th -val=0.5 | cksum + ppmtopgm | pgmtopbm -th -val=0.5 | cksum # With PGM or PBM input, the three monochrome planes should be @@ -28,7 +35,7 @@ ${PBM_TESTPREFIX}rgb3toppm ${tmpdir}/testgrid.red ${tmpdir}/testgrid.grn \ cmp -s ${tmpdir}/testgrid.red ${tmpdir}/testgrid.grn ; echo $? cmp -s ${tmpdir}/testgrid.grn ${tmpdir}/testgrid.blu ; echo $? -${PBM_BINPREFIX}pgmtopgm < testgrid.pbm | cmp -s - ${tmpdir}/testgrid.red +pgmtopgm < testgrid.pbm | cmp -s - ${tmpdir}/testgrid.red echo $? rm ${tmpdir}/testgrid.{pbm,red,grn,blu} diff --git a/test/sunrast-roundtrip.test b/test/sunrast-roundtrip.test index ee5b25e3..78e4ae15 100755 --- a/test/sunrast-roundtrip.test +++ b/test/sunrast-roundtrip.test @@ -2,5 +2,9 @@ # This script tests: pnmtorast rasttopnm # Also requires: + alias pnmtorast="${PBM_TESTPREFIX}pnmtorast" + alias rasttopnm="${PBM_TESTPREFIX}rasttopnm" + shopt -s expand_aliases + # Should produce 1926073387 101484, cksum of testimg.ppm -${PBM_TESTPREFIX}pnmtorast testimg.ppm | ${PBM_TESTPREFIX}rasttopnm | cksum +pnmtorast testimg.ppm | rasttopnm | cksum diff --git a/test/symmetry.ok b/test/symmetry.ok new file mode 100644 index 00000000..23129684 --- /dev/null +++ b/test/symmetry.ok @@ -0,0 +1,12 @@ +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok +ok diff --git a/test/symmetry.test b/test/symmetry.test new file mode 100755 index 00000000..5fdb3918 --- /dev/null +++ b/test/symmetry.test @@ -0,0 +1,95 @@ +#! /bin/bash +# This script tests: pgmramp pamgauss pgmkernel pbmpscale +# Also requires: pamflip + + alias pgmramp="${PBM_TESTPREFIX}pgmramp" + alias pamgauss="${PBM_TESTPREFIX}pamgauss" + alias pgmkernel="${PBM_TESTPREFIX}pgmkernel" + alias pbmpscale="${PBM_TESTPREFIX}pbmpscale" + alias pamflip="${PBM_BINPREFIX}pamflip" + shopt -s expand_aliases + +# All tests print "ok" upon success, cksum results otherwise. +# The "$3>0" is a kludge for preventing false positives with empty files. + +# All test images are square and have the symmetries of the square (Dih4). +# The sole exception is ell.pgm which is a rectangle (Dih2, also called +# "Klein four-group".) + +# Example symmetric square PGM image: +# P2 +# 5 5 +# 6 +# 1 2 3 2 1 +# 2 4 5 4 2 +# 3 5 6 5 3 +# 2 4 5 4 2 +# 1 2 3 2 1 + +## Failure with this test indicates that a generator or editor which +## should produce symmetric output images isn't doing so. + +# Test 1. +pgmramp -rect 31 31 > ${tmpdir}/rect.pgm + +( for op in -null -tb -lr -r90 + do pamflip $op ${tmpdir}/rect.pgm | cksum + done ) | uniq -c | \ + awk '$1==4 && $3>0 { print "ok"; exit }; { print }' + +rm ${tmpdir}/rect.pgm + +# Test 2. +pgmramp -ell 63 63 > ${tmpdir}/circle.pgm + +( for op in -null -tb -lr -r90 + do pamflip $op ${tmpdir}/circle.pgm | cksum + done ) | uniq -c | \ + awk '$1==4 && $3>0 { print "ok"; exit }; { print }' + +rm ${tmpdir}/circle.pgm + +# Test 3. +pamgauss -sigma=0.1 -tupletype=GRAYSCALE 25 25 > ${tmpdir}/gauss.pam + +( for op in -null -tb -lr -r90 + do pamflip $op ${tmpdir}/gauss.pam | cksum + done ) | uniq -c | \ + awk '$1==4 && $3>0 { print "ok"; exit }; { print }' + +rm ${tmpdir}/gauss.pam + +# Test 4. +pgmkernel 15 15 > ${tmpdir}/kernel.pgm + +( for op in -null -tb -lr -r90 + do pamflip $op ${tmpdir}/kernel.pgm | cksum + done ) | uniq -c | \ + awk '$1==4 && $3>0 { print "ok"; exit }; { print }' + +rm ${tmpdir}/kernel.pgm + +# Test 5. +# Should print "ok" 7 times. +for size in `seq 1 7` +do +pbmmake -g 5 5 | pbmpscale $size > ${tmpdir}/pscale.pbm + +( for op in -null -tb -lr -r90 + do pamflip $op ${tmpdir}/pscale.pbm | cksum + done ) | uniq -c | \ + awk '$1==4 && $3>0 { print "ok"; exit }; { print }' + +rm ${tmpdir}/pscale.pbm +done + +# Test 6. +pgmramp -ell 101 33 > ${tmpdir}/ell.pgm + +( for op in -null -tb -lr + do pamflip $op ${tmpdir}/ell.pgm | cksum + done ) | uniq -c | \ + awk '$1==3 && $3>0 { print "ok"; exit }; { print }' + +rm ${tmpdir}/ell.pgm + diff --git a/test/targa-roundtrip.test b/test/targa-roundtrip.test index 3fac1630..4a99e0e0 100755 --- a/test/targa-roundtrip.test +++ b/test/targa-roundtrip.test @@ -2,20 +2,26 @@ # This script tests: pamtotga tgatoppm # Also requires: ppmtopgm pgmtopbm + alias pamtotga="${PBM_TESTPREFIX}pamtotga" + alias tgatoppm="${PBM_TESTPREFIX}tgatoppm" + alias pgmtopbm="${PBM_BINPREFIX}pgmtopbm" + alias ppmtopgm="${PBM_BINPREFIX}ppmtopgm" + shopt -s expand_aliases + #Test 1: Should print 2425386270 41, cksum of testgrid.pbm -${PBM_TESTPREFIX}pamtotga -mono testgrid.pbm | \ - ${PBM_TESTPREFIX}tgatoppm | ${PBM_BINPREFIX}ppmtopgm | \ - ${PBM_BINPREFIX}pgmtopbm -threshold -val 0.5 | cksum +pamtotga -mono testgrid.pbm | \ + tgatoppm | ppmtopgm | \ + pgmtopbm -threshold -val 0.5 | cksum #Test 2: Should print 2871603838 33838, cksum of testimg.pgm -${PBM_BINPREFIX}ppmtopgm testimg.ppm > ${tmpdir}/testimg.pgm -${PBM_TESTPREFIX}pamtotga -cmap ${tmpdir}/testimg.pgm | \ - ${PBM_TESTPREFIX}tgatoppm | ${PBM_BINPREFIX}ppmtopgm | cksum +ppmtopgm testimg.ppm > ${tmpdir}/testimg.pgm +pamtotga -cmap ${tmpdir}/testimg.pgm | \ + tgatoppm | ppmtopgm | cksum rm ${tmpdir}/testimg.pgm #Test 3: Should print 1926073387 101484, cksum of testimg.ppm -${PBM_TESTPREFIX}pamtotga -rgb testimg.ppm | ${PBM_TESTPREFIX}tgatoppm | cksum +pamtotga -rgb testimg.ppm | tgatoppm | cksum diff --git a/test/tiff-roundtrip.test b/test/tiff-roundtrip.test index e7f875cf..410148a5 100755 --- a/test/tiff-roundtrip.test +++ b/test/tiff-roundtrip.test @@ -2,19 +2,25 @@ # This script tests: pamtotiff tifftopnm # Also requires: -${PBM_TESTPREFIX}pamtotiff testimg.ppm 1<>${tmpdir}/test1.tiff && - ${PBM_TESTPREFIX}tifftopnm ${tmpdir}/test1.tiff | cksum + alias pamtotiff="${PBM_TESTPREFIX}pamtotiff" + alias tifftopnm="${PBM_TESTPREFIX}tifftopnm" + shopt -s expand_aliases + +# Failure message +## Second test fails if Netpbm was built without the flate library + +pamtotiff testimg.ppm 1<>${tmpdir}/test1.tiff && + tifftopnm ${tmpdir}/test1.tiff | cksum # test flate compression -# Will fail if Netpbm was built without the flate library -${PBM_TESTPREFIX}pamtotiff -flate testimg.ppm 1<>${tmpdir}/test2.tiff && - ${PBM_TESTPREFIX}tifftopnm ${tmpdir}/test2.tiff | cksum +pamtotiff -flate testimg.ppm 1<>${tmpdir}/test2.tiff && + tifftopnm ${tmpdir}/test2.tiff | cksum -${PBM_TESTPREFIX}pamtotiff testgrid.pbm 1<>${tmpdir}/test3.tiff && - ${PBM_TESTPREFIX}tifftopnm ${tmpdir}/test3.tiff | cksum +pamtotiff testgrid.pbm 1<>${tmpdir}/test3.tiff && + tifftopnm ${tmpdir}/test3.tiff | cksum # test G4 compression -${PBM_TESTPREFIX}pamtotiff -g4 testgrid.pbm 1<>${tmpdir}/test4.tiff && - ${PBM_TESTPREFIX}tifftopnm ${tmpdir}/test4.tiff | cksum +pamtotiff -g4 testgrid.pbm 1<>${tmpdir}/test4.tiff && + tifftopnm ${tmpdir}/test4.tiff | cksum rm ${tmpdir}/test[1234].tiff diff --git a/test/utahrle-roundtrip.test b/test/utahrle-roundtrip.test index 7113a2d5..83bc6c90 100755 --- a/test/utahrle-roundtrip.test +++ b/test/utahrle-roundtrip.test @@ -2,13 +2,18 @@ # This script tests: pnmtorle rletopnm # Also requires: ppmtopgm + alias pnmtorle="${PBM_TESTPREFIX}pnmtorle" + alias rletopnm="${PBM_TESTPREFIX}rletopnm" + alias ppmtopgm="${PBM_BINPREFIX}ppmtopgm" + shopt -s expand_aliases + #Test 1. Should print 2871603838 33838, cksum of testimg.pgm -${PBM_BINPREFIX}ppmtopgm testimg.ppm > ${tmpdir}/testimg.pgm -${PBM_TESTPREFIX}pnmtorle ${tmpdir}/testimg.pgm | \ - ${PBM_TESTPREFIX}rletopnm | cksum +ppmtopgm testimg.ppm > ${tmpdir}/testimg.pgm +pnmtorle ${tmpdir}/testimg.pgm | \ + rletopnm | cksum rm ${tmpdir}/testimg.pgm #Test 2. Should print 1926073387 101484, cksum of testimg.ppm -${PBM_TESTPREFIX}pnmtorle testimg.ppm | \ - ${PBM_TESTPREFIX}rletopnm | cksum +pnmtorle testimg.ppm | \ + rletopnm | cksum diff --git a/test/wbmp-roundtrip.test b/test/wbmp-roundtrip.test index bab2b6a5..40988635 100755 --- a/test/wbmp-roundtrip.test +++ b/test/wbmp-roundtrip.test @@ -2,5 +2,9 @@ # This script tests: pbmtowbmp wbmptopbm # Also requires: + alias pbmtowbmp="${PBM_TESTPREFIX}pbmtowbmp" + alias wbmptopbm="${PBM_TESTPREFIX}wbmptopbm" + shopt -s expand_aliases + # Should print 2425386270 41, cksum of testgrid.pbm -${PBM_TESTPREFIX}pbmtowbmp testgrid.pbm | ${PBM_TESTPREFIX}wbmptopbm | cksum +pbmtowbmp testgrid.pbm | wbmptopbm | cksum diff --git a/test/winicon-roundtrip.test b/test/winicon-roundtrip.test index f5f2926e..20b0a225 100755 --- a/test/winicon-roundtrip.test +++ b/test/winicon-roundtrip.test @@ -2,12 +2,21 @@ # This script tests: pamtowinicon winicontopam # Also requires: pnmcut pnmtile pamtopnm ppmtopgm pgmtopbm -${PBM_BINPREFIX}pnmcut --left=30 --width=48 --height=48 testimg.ppm | \ -${PBM_TESTPREFIX}pamtowinicon | ${PBM_TESTPREFIX}winicontopam | \ - ${PBM_BINPREFIX}pamtopnm | cksum - -${PBM_BINPREFIX}pnmtile 32 32 testgrid.pbm | \ -${PBM_TESTPREFIX}pamtowinicon | ${PBM_TESTPREFIX}winicontopam | \ - ${PBM_BINPREFIX}pamtopnm | ${PBM_BINPREFIX}ppmtopgm | \ - ${PBM_BINPREFIX}pgmtopbm -th -val=0.5 | cksum + alias pamtowinicon="${PBM_TESTPREFIX}pamtowinicon" + alias winicontopam="${PBM_TESTPREFIX}winicontopam" + alias pamtopnm="${PBM_BINPREFIX}pamtopnm" + alias pgmtopbm="${PBM_BINPREFIX}pgmtopbm" + alias pnmcut="${PBM_BINPREFIX}pnmcut" + alias pnmtile="${PBM_BINPREFIX}pnmtile" + alias ppmtopgm="${PBM_BINPREFIX}ppmtopgm" + shopt -s expand_aliases + +pnmcut --left=30 --width=48 --height=48 testimg.ppm | \ +pamtowinicon | winicontopam | \ + pamtopnm | cksum + +pnmtile 32 32 testgrid.pbm | \ +pamtowinicon | winicontopam | \ + pamtopnm | ppmtopgm | \ + pgmtopbm -th -val=0.5 | cksum diff --git a/test/xbm-roundtrip.test b/test/xbm-roundtrip.test index 2dcb5a13..4823adfd 100755 --- a/test/xbm-roundtrip.test +++ b/test/xbm-roundtrip.test @@ -2,5 +2,9 @@ # This script tests: pbmtoxbm xbmtopbm # Also requires: -${PBM_TESTPREFIX}pbmtoxbm testgrid.pbm | ${PBM_TESTPREFIX}xbmtopbm | cksum -${PBM_TESTPREFIX}pbmtoxbm -x10 testgrid.pbm | ${PBM_TESTPREFIX}xbmtopbm | cksum + alias pbmtoxbm="${PBM_TESTPREFIX}pbmtoxbm" + alias xbmtopbm="${PBM_TESTPREFIX}xbmtopbm" + shopt -s expand_aliases + +pbmtoxbm testgrid.pbm | xbmtopbm | cksum +pbmtoxbm -x10 testgrid.pbm | xbmtopbm | cksum diff --git a/test/xpm-roundtrip.test b/test/xpm-roundtrip.test index 310022cc..c3c9894d 100755 --- a/test/xpm-roundtrip.test +++ b/test/xpm-roundtrip.test @@ -2,7 +2,13 @@ # This script tests: ppmtoxpm xpmtoppm # Also requires: pgmtopbm ppmtopgm -#${PBM_TESTPREFIX}ppmtoxpm -hexonly testimg.ppm | \ -# ${PBM_TESTPREFIX}xpmtoppm | cksum -${PBM_TESTPREFIX}ppmtoxpm testgrid.pbm | ${PBM_TESTPREFIX}xpmtoppm | \ - ${PBM_BINPREFIX}ppmtopgm | ${PBM_BINPREFIX}pgmtopbm -th -value=0.5 | cksum + alias ppmtoxpm="${PBM_TESTPREFIX}ppmtoxpm" + alias xpmtoppm="${PBM_TESTPREFIX}xpmtoppm" + alias pgmtopbm="${PBM_BINPREFIX}pgmtopbm" + alias ppmtopgm="${PBM_BINPREFIX}ppmtopgm" + shopt -s expand_aliases + +#ppmtoxpm -hexonly testimg.ppm | \ +# xpmtoppm | cksum +ppmtoxpm testgrid.pbm | xpmtoppm | \ + ppmtopgm | pgmtopbm -th -value=0.5 | cksum diff --git a/test/xwd-roundtrip.test b/test/xwd-roundtrip.test index e24db7bc..b5614f01 100755 --- a/test/xwd-roundtrip.test +++ b/test/xwd-roundtrip.test @@ -2,13 +2,21 @@ # This script tests: pnmtoxwd xwdtopnm # Also requires: pamdepth ppmtopgm + alias pnmtoxwd="${PBM_TESTPREFIX}pnmtoxwd" + alias xwdtopnm="${PBM_TESTPREFIX}xwdtopnm" + alias pamdepth="${PBM_BINPREFIX}pamdepth" + alias ppmtopgm="${PBM_BINPREFIX}ppmtopgm" + shopt -s expand_aliases + # Test 1. Should produce 2871603838 33838 # which is the output of ppmtopgm testimg.ppm | cksum -${PBM_BINPREFIX}ppmtopgm testimg.ppm | ${PBM_TESTPREFIX}pnmtoxwd | \ - ${PBM_TESTPREFIX}xwdtopnm | ${PBM_BINPREFIX}pamdepth 255 | cksum +ppmtopgm testimg.ppm | pnmtoxwd | \ + xwdtopnm | pamdepth 255 | cksum -${PBM_TESTPREFIX}pnmtoxwd --quiet testimg.ppm | \ - ${PBM_TESTPREFIX}xwdtopnm --quiet | ${PBM_BINPREFIX}pamdepth 255 | cksum +# Test 2. Should produce 1926073387 101484 +pnmtoxwd --quiet testimg.ppm | \ + xwdtopnm --quiet | pamdepth 255 | cksum -${PBM_TESTPREFIX}pnmtoxwd --quiet testgrid.pbm | \ - ${PBM_TESTPREFIX}xwdtopnm | cksum +# Test 3. Should produce 2425386270 41 +pnmtoxwd --quiet testgrid.pbm | \ + xwdtopnm | cksum diff --git a/test/yuv-roundtrip.test b/test/yuv-roundtrip.test index 697d86aa..8e0d4f1a 100755 --- a/test/yuv-roundtrip.test +++ b/test/yuv-roundtrip.test @@ -2,8 +2,13 @@ # This script tests: ppmtoyuv yuvtoppm # Also requires: pamgradient + alias ppmtoyuv="${PBM_TESTPREFIX}ppmtoyuv" + alias yuvtoppm="${PBM_TESTPREFIX}yuvtoppm" + alias pamgradient="${PBM_BINPREFIX}pamgradient" + shopt -s expand_aliases + # Should produce 1904478375 253455 -${PBM_BINPREFIX}pamgradient rgb:00/ff/ff rgb:ff/ff/00 \ +pamgradient rgb:00/ff/ff rgb:ff/ff/00 \ rgb:ff/00/00 rgb:00/ff/00 352 240 | \ - ${PBM_TESTPREFIX}ppmtoyuv | ${PBM_TESTPREFIX}yuvtoppm 352 240 | cksum + ppmtoyuv | yuvtoppm 352 240 | cksum diff --git a/version.mk b/version.mk index 682d7f1f..da0a87f5 100644 --- a/version.mk +++ b/version.mk @@ -1,3 +1,3 @@ NETPBM_MAJOR_RELEASE = 10 -NETPBM_MINOR_RELEASE = 65 -NETPBM_POINT_RELEASE = 7 +NETPBM_MINOR_RELEASE = 66 +NETPBM_POINT_RELEASE = 0 |