diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2016-03-27 01:38:28 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2016-03-27 01:38:28 +0000 |
commit | 367c9cb514c9da766488b9bdb218a18e31cb7624 (patch) | |
tree | f9e343be94161a4837f0f1c1d072a35538ae0f63 /analyzer | |
parent | 6e88e3326cb0c7f7975b56189278cab3f84ba1bd (diff) | |
download | netpbm-mirror-367c9cb514c9da766488b9bdb218a18e31cb7624.tar.gz netpbm-mirror-367c9cb514c9da766488b9bdb218a18e31cb7624.tar.xz netpbm-mirror-367c9cb514c9da766488b9bdb218a18e31cb7624.zip |
Promote Stable (10.47) to Super Stable
git-svn-id: http://svn.code.sf.net/p/netpbm/code/super_stable@2691 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'analyzer')
-rw-r--r-- | analyzer/Makefile | 10 | ||||
-rw-r--r-- | analyzer/pamfile.c | 1 | ||||
-rw-r--r-- | analyzer/pamsharpmap.c | 1 | ||||
-rw-r--r-- | analyzer/pamsharpness.c | 1 | ||||
-rw-r--r-- | analyzer/pamslice.c | 1 | ||||
-rw-r--r-- | analyzer/pamsumm.c | 1 | ||||
-rw-r--r-- | analyzer/pamtilt.c | 1 | ||||
-rw-r--r-- | analyzer/pbmminkowski.c | 199 | ||||
-rw-r--r-- | analyzer/pgmhist.c | 225 | ||||
-rw-r--r-- | analyzer/pnmhistmap.c | 85 | ||||
-rw-r--r-- | analyzer/pnmpsnr.c | 81 | ||||
-rw-r--r-- | analyzer/ppmhist.c | 33 |
12 files changed, 389 insertions, 250 deletions
diff --git a/analyzer/Makefile b/analyzer/Makefile index 6a447ea7..ed180917 100644 --- a/analyzer/Makefile +++ b/analyzer/Makefile @@ -5,7 +5,7 @@ endif SUBDIR = analyzer VPATH=.:$(SRCDIR)/$(SUBDIR) -include $(BUILDDIR)/Makefile.config +include $(BUILDDIR)/config.mk # We tend to separate out the build targets so that we don't have # any more dependencies for a given target than it really needs. @@ -15,7 +15,7 @@ include $(BUILDDIR)/Makefile.config # build. PORTBINARIES = pamfile pamslice pamsumm pamtilt \ - pgmhist pnmhistmap ppmhist pgmminkowski + pbmminkowski pgmhist pnmhistmap ppmhist pgmminkowski MATHBINARIES = pamsharpmap pamsharpness pgmtexture pnmpsnr BINARIES = $(PORTBINARIES) $(MATHBINARIES) @@ -33,16 +33,16 @@ MERGE_OBJECTS = $(MERGEBINARIES:%=%.o2) .PHONY: all all: $(BINARIES) -include $(SRCDIR)/Makefile.common +include $(SRCDIR)/common.mk install.bin: install.bin.local .PHONY: install.bin.local install.bin.local: $(PKGDIR)/bin # Remember that $(SYMLINK) might just be a copy command. cd $(PKGDIR)/bin ; \ - $(SYMLINK) pamslice$(EXE) pgmslice + $(SYMLINK) pamslice$(EXE) pgmslice$(EXE) cd $(PKGDIR)/bin ; \ - $(SYMLINK) pamfile$(EXE) pnmfile + $(SYMLINK) pamfile$(EXE) pnmfile$(EXE) FORCE: diff --git a/analyzer/pamfile.c b/analyzer/pamfile.c index efb2cbee..4fa81330 100644 --- a/analyzer/pamfile.c +++ b/analyzer/pamfile.c @@ -10,6 +10,7 @@ ** implied warranty. */ +#include "pm_c_util.h" #include "mallocvar.h" #include "nstring.h" #include "shhopt.h" diff --git a/analyzer/pamsharpmap.c b/analyzer/pamsharpmap.c index 8a08f981..ddeefe14 100644 --- a/analyzer/pamsharpmap.c +++ b/analyzer/pamsharpmap.c @@ -20,6 +20,7 @@ #include <stdio.h> #include <math.h> +#include "pm_c_util.h" #include "pam.h" #include "shhopt.h" #include "mallocvar.h" diff --git a/analyzer/pamsharpness.c b/analyzer/pamsharpness.c index 3850aa3a..8e2d9a3f 100644 --- a/analyzer/pamsharpness.c +++ b/analyzer/pamsharpness.c @@ -20,6 +20,7 @@ #include <stdio.h> #include <math.h> +#include "pm_c_util.h" #include "pam.h" #include "shhopt.h" diff --git a/analyzer/pamslice.c b/analyzer/pamslice.c index fc63a2cc..ab372c8a 100644 --- a/analyzer/pamslice.c +++ b/analyzer/pamslice.c @@ -22,6 +22,7 @@ enum orientation {ROW, COLUMN}; +#include "pm_c_util.h" #include "pam.h" #include "shhopt.h" diff --git a/analyzer/pamsumm.c b/analyzer/pamsumm.c index 390b8ebb..c9b8a7bf 100644 --- a/analyzer/pamsumm.c +++ b/analyzer/pamsumm.c @@ -10,6 +10,7 @@ ******************************************************************************/ +#include "pm_c_util.h" #include "pam.h" #include "shhopt.h" #include "mallocvar.h" diff --git a/analyzer/pamtilt.c b/analyzer/pamtilt.c index cc135ab6..d70f491b 100644 --- a/analyzer/pamtilt.c +++ b/analyzer/pamtilt.c @@ -15,6 +15,7 @@ #include <assert.h> #include <math.h> +#include "pm_c_util.h" #include "pam.h" #include "mallocvar.h" #include "shhopt.h" diff --git a/analyzer/pbmminkowski.c b/analyzer/pbmminkowski.c index 5edce506..0f7b47a9 100644 --- a/analyzer/pbmminkowski.c +++ b/analyzer/pbmminkowski.c @@ -15,154 +15,171 @@ #include "pbm.h" -#define ISWHITE(x) ( (x) == PBM_WHITE ) +#define ISWHITE(x) ((x) == PBM_WHITE) -int main( int argc, char** argv ){ +int main(int argc, const char ** argv) { - FILE* ifp; + FILE * ifP; - bit* prevrow; - bit* thisrow; - bit* tmprow; + bit * prevrow; + bit * thisrow; + bit * tmprow; - int row; - int col; + int row; + int col; - int countTile=0; - int countEdgeX=0; - int countEdgeY=0; - int countVertex=0; + int countTile; + int countEdgeX; + int countEdgeY; + int countVertex; - int rows; - int cols; - int format; + int rows; + int cols; + int format; - int area, perimeter, eulerchi; + int area, perimeter, eulerchi; - /* - * parse arg and initialize - */ - - pbm_init( &argc, argv ); + pm_proginit(&argc, argv); - if ( argc > 2 ) - pm_usage( "[pbmfile]" ); + if (argc > 2) + pm_usage("[pbmfile]"); - if ( argc == 2 ) - ifp = pm_openr( argv[1] ); - else - ifp = stdin; + if (argc == 2) + ifP = pm_openr(argv[1]); + else + ifP = stdin; - pbm_readpbminit( ifp, &cols, &rows, &format ); + pbm_readpbminit(ifP, &cols, &rows, &format); + + prevrow = pbm_allocrow(cols); + thisrow = pbm_allocrow(cols); - prevrow = pbm_allocrow( cols ); - thisrow = pbm_allocrow( cols ); + /* first row */ - /* first row */ + pbm_readpbmrow(ifP, thisrow, cols, format); - pbm_readpbmrow( ifp, thisrow, cols, format ); + countTile = 0; + countEdgeX = 0; + countEdgeY = 0; + countVertex = 0; - /* tiles */ + /* tiles */ - for ( col = 0; col < cols; ++col ) - if( ISWHITE(thisrow[col]) ) ++countTile; + for (col = 0; col < cols; ++col) + if (ISWHITE(thisrow[col])) + ++countTile; - /* shortcut: for the first row, edgeY == countTile */ - countEdgeY = countTile; + /* shortcut: for the first row, edgeY == countTile */ + countEdgeY = countTile; - /* x-edges */ + /* x-edges */ - if( ISWHITE(thisrow[0]) ) ++countEdgeX; + if (ISWHITE(thisrow[0])) + ++countEdgeX; - for ( col = 0; col < cols-1; ++col ) - if( ISWHITE(thisrow[col]) || ISWHITE(thisrow[col+1]) ) ++countEdgeX; + for (col = 0; col < cols-1; ++col) + if (ISWHITE(thisrow[col]) || ISWHITE(thisrow[col+1])) + ++countEdgeX; - if( ISWHITE(thisrow[cols-1]) ) ++countEdgeX; + if (ISWHITE(thisrow[cols-1])) + ++countEdgeX; - /* shortcut: for the first row, countVertex == countEdgeX */ + /* shortcut: for the first row, countVertex == countEdgeX */ - countVertex = countEdgeX; + countVertex = countEdgeX; - for ( row = 1; row < rows; ++row ){ + for (row = 1; row < rows; ++row) { - tmprow = prevrow; - prevrow = thisrow; - thisrow = tmprow; + tmprow = prevrow; + prevrow = thisrow; + thisrow = tmprow; - pbm_readpbmrow( ifp, thisrow, cols, format ); + pbm_readpbmrow(ifP, thisrow, cols, format); - /* tiles */ + /* tiles */ - for ( col = 0; col < cols; ++col ) - if( ISWHITE(thisrow[col]) ) ++countTile; + for (col = 0; col < cols; ++col) + if (ISWHITE(thisrow[col])) + ++countTile; - /* y-edges */ + /* y-edges */ - for ( col = 0; col < cols; ++col ) - if( ISWHITE(thisrow[col]) || ISWHITE( prevrow[col] )) ++countEdgeY; + for (col = 0; col < cols; ++col) + if (ISWHITE(thisrow[col]) || ISWHITE(prevrow[col])) + ++countEdgeY; - /* x-edges */ + /* x-edges */ - if( ISWHITE(thisrow[0]) ) ++countEdgeX; + if (ISWHITE(thisrow[0])) + ++countEdgeX; - for ( col = 0; col < cols-1; ++col ) - if( ISWHITE(thisrow[col]) || ISWHITE(thisrow[col+1]) ) ++countEdgeX; + for (col = 0; col < cols-1; ++col) + if (ISWHITE(thisrow[col]) || ISWHITE(thisrow[col+1])) + ++countEdgeX; - if( ISWHITE(thisrow[cols-1]) ) ++countEdgeX; + if (ISWHITE(thisrow[cols-1])) + ++countEdgeX; - /* vertices */ + /* vertices */ - if( ISWHITE(thisrow[0]) || ISWHITE(prevrow[0]) ) ++countVertex; + if (ISWHITE(thisrow[0]) || ISWHITE(prevrow[0])) + ++countVertex; - for ( col = 0; col < cols-1; ++col ) - if( ISWHITE(thisrow[col]) || ISWHITE(thisrow[col+1]) - || ISWHITE(prevrow[col]) || ISWHITE(prevrow[col+1]) ) ++countVertex; + for (col = 0; col < cols-1; ++col) + if (ISWHITE(thisrow[col]) || ISWHITE(thisrow[col+1]) + || ISWHITE(prevrow[col]) || ISWHITE(prevrow[col+1])) + ++countVertex; - if( ISWHITE(thisrow[cols-1]) || ISWHITE(prevrow[cols-1]) ) ++countVertex; + if (ISWHITE(thisrow[cols-1]) || ISWHITE(prevrow[cols-1])) + ++countVertex; - } /* for row */ + } /* for row */ - /* now thisrow contains the top row*/ - /* tiles and x-edges have been counted, now y-edges and top vertices remain */ + /* now thisrow contains the top row*/ + /* tiles and x-edges have been counted, now y-edges and top + vertices remain + */ - /* y-edges */ + /* y-edges */ - for ( col = 0; col < cols; ++col ) - if( ISWHITE(thisrow[col]) ) ++countEdgeY; + for (col = 0; col < cols; ++col) + if (ISWHITE(thisrow[col])) + ++countEdgeY; - /* vertices */ + /* vertices */ - if( ISWHITE(thisrow[0]) ) ++countVertex; - - for ( col = 0; col < cols-1; ++col ) - if( ISWHITE(thisrow[col]) || ISWHITE(thisrow[col+1]) ) ++countVertex; + if (ISWHITE(thisrow[0])) + ++countVertex; - if( ISWHITE(thisrow[cols-1]) ) ++countVertex; + for (col = 0; col < cols-1; ++col) + if (ISWHITE(thisrow[col]) || ISWHITE(thisrow[col+1])) + ++countVertex; + if (ISWHITE(thisrow[cols-1])) + ++countVertex; - /* cleanup */ + /* cleanup */ - pm_close( ifp ); + pm_close(ifP); - /* print results */ + /* print results */ - printf( " tiles:\t%d\n x-edges:\t%d\n y-edges:\t%d\nvertices:\t%d\n", - countTile, countEdgeX, countEdgeY,countVertex ); + printf(" tiles:\t%d\n x-edges:\t%d\n y-edges:\t%d\nvertices:\t%d\n", + countTile, countEdgeX, countEdgeY,countVertex); - area = countTile; - perimeter = 2*countEdgeX + 2*countEdgeY - 4*countTile; - eulerchi = countTile - countEdgeX - countEdgeY + countVertex; + area = countTile; + perimeter = 2*countEdgeX + 2*countEdgeY - 4*countTile; + eulerchi = countTile - countEdgeX - countEdgeY + countVertex; - printf( " area:\t%d\nperimeter:\t%d\n eulerchi:\t%d\n", - area, perimeter, eulerchi ); + printf(" area:\t%d\nperimeter:\t%d\n eulerchi:\t%d\n", + area, perimeter, eulerchi ); - exit( 0 ); - -} /* main */ + return 0; +} diff --git a/analyzer/pgmhist.c b/analyzer/pgmhist.c index 126fe693..4790ecba 100644 --- a/analyzer/pgmhist.c +++ b/analyzer/pgmhist.c @@ -1,4 +1,4 @@ -/* pgmhist.c - print a histogram of the values in a portable graymap +/* pgmhist.c - print a histogram of the values in a PGM image ** ** Copyright (C) 1989 by Jef Poskanzer. ** @@ -10,86 +10,189 @@ ** implied warranty. */ +#include <assert.h> #include <limits.h> -#include "pgm.h" +#include "pm_c_util.h" #include "mallocvar.h" +#include "shhopt.h" +#include "pgm.h" -int -main( argc, argv ) - int argc; - char *argv[]; -{ - FILE *ifp; - gray maxval, *grayrow; - register gray *gP; - int argn, rows, cols, format, row; - int i, *hist, *rcount, count, size; - register int col; - const char * const usage = "[pgmfile]"; - - pgm_init( &argc, argv ); - - argn = 1; - - if ( argn < argc ) - { - ifp = pm_openr( argv[argn] ); - argn++; - } + + +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; /* Filename of input files */ +}; + + + +static void +parseCommandLine(int argc, const char ** argv, + struct cmdline_info * const cmdlineP) { +/*---------------------------------------------------------------------------- + Note that the file spec array we return is stored in the storage that + was passed to us as the argv array. +-----------------------------------------------------------------------------*/ + 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 */ + + OPTENTINIT; + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ + opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + + optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + + 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 - ifp = stdin; + cmdlineP->inputFileName = argv[1]; +} - if ( argn != argc ) - pm_usage( usage ); - pgm_readpgminit( ifp, &cols, &rows, &maxval, &format ); + +static void +buildHistogram(FILE * const ifP, + unsigned int ** const histP, + gray * const maxvalP) { + + 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); - grayrow = pgm_allocrow( cols ); + grayrow = pgm_allocrow(cols); - /* Build histogram. */ MALLOCARRAY(hist, maxval + 1); - MALLOCARRAY(rcount, maxval + 1); - if ( hist == NULL || rcount == NULL ) - pm_error( "out of memory" ); - for ( i = 0; i <= maxval; i++ ) + if (hist == NULL) + pm_error("out of memory"); + + for (i = 0; i <= maxval; ++i) hist[i] = 0; - for ( row = 0; row < rows; row++ ) - { - pgm_readpgmrow( ifp, grayrow, cols, maxval, format ); - for ( col = 0, gP = grayrow; col < cols; col++, gP++ ) - hist[(int) *gP]++; - } - pm_close( ifp ); + for (row = 0; row < rows; ++row) { + unsigned int col; + + pgm_readpgmrow(ifP, grayrow, cols, maxval, format); + + for (col = 0; col < cols; ++col) { + /* Because total pixels in image is limited: */ + assert (hist[grayrow[col]] < INT_MAX); + + ++hist[grayrow[col]]; + } + } + pgm_freerow(grayrow); + + *histP = hist; + *maxvalP = maxval; +} + + + +static void +countCumulative(unsigned int const hist[], + gray const maxval, + unsigned int ** const rcountP) { + + unsigned int * rcount; + unsigned int cumCount; + int i; + + MALLOCARRAY(rcount, maxval + 1); + if (rcount == NULL) + pm_error("out of memory"); + + for (i = maxval, cumCount = 0; i >= 0; --i) { + /* Because total pixels in image is limited: */ + assert(UINT_MAX - hist[i] >= cumCount); + + cumCount += hist[i]; + rcount[i] = cumCount; + } + + *rcountP = rcount; +} + + + +static void +report(unsigned int const hist[], + unsigned int const rcount[], + gray const maxval) { + + unsigned int const totalPixels = rcount[0]; + unsigned int count; + unsigned int i; + + printf("value count b%% w%% \n"); + printf("----- ----- ------ ------\n"); - /* Compute count-down */ - count = 0; - for ( i = maxval; i >= 0; i-- ) - { - count += hist[i]; - rcount[i] = count; - } - - /* And print it. */ - printf( "value\tcount\tb%%\tw%%\n" ); - printf( "-----\t-----\t--\t--\n" ); count = 0; - size = rows * cols; - for ( i = 0; i <= maxval; i++ ) - if ( hist[i] > 0 ) - { + + for (i = 0; i <= maxval; ++i) { + if (hist[i] > 0) { count += hist[i]; printf( - "%d\t%d\t%5.3g%%\t%5.3g%%\n", i, hist[i], - (float) count * 100.0 / size, - (float) rcount[i] * 100.0 / size ); - } + "%5d %5d %5.3g%% %5.3g%%\n", i, hist[i], + (float) count * 100.0 / totalPixels, + (float) rcount[i] * 100.0 / totalPixels); + } + } +} + - exit( 0 ); + +int +main(int argc, const char ** argv) { + + struct cmdline_info cmdline; + FILE * ifP; + gray maxval; + unsigned int * rcount; /* malloc'ed array */ + unsigned int * hist; /* malloc'ed array */ + + pm_proginit(&argc, argv); + + parseCommandLine(argc, argv, &cmdline); + + ifP = pm_openr(cmdline.inputFileName); + + buildHistogram(ifP, &hist, &maxval); + + countCumulative(hist, maxval, &rcount); + + report(hist, rcount, maxval); + + free(rcount); + free(hist); + pm_close(ifP); + + return 0; } + + + diff --git a/analyzer/pnmhistmap.c b/analyzer/pnmhistmap.c index 0e5cf302..7e504734 100644 --- a/analyzer/pnmhistmap.c +++ b/analyzer/pnmhistmap.c @@ -19,6 +19,7 @@ #include <string.h> +#include "pm_c_util.h" #include "pnm.h" #include "shhopt.h" #include "mallocvar.h" @@ -152,16 +153,16 @@ clipHistogram(unsigned int * const hist, unsigned int const hist_width, unsigned int const hmax) { - unsigned int i; + unsigned int i; - for (i = 0; i < hist_width; ++i) - hist[i] = MIN(hmax, hist[i]); + for (i = 0; i < hist_width; ++i) + hist[i] = MIN(hmax, hist[i]); } static void -pgm_hist(FILE * const fp, +pgm_hist(FILE * const ifP, int const cols, int const rows, xelval const maxval, @@ -186,41 +187,44 @@ pgm_hist(FILE * const fp, unsigned int * ghist; double vscale; unsigned int hmax; - - if ((ghist = calloc(hist_width, sizeof(int))) == NULL) - pm_error ("Not enough memory for histogram array (%d bytes)", + + MALLOCARRAY(ghist, hist_width); + if (ghist == NULL) + pm_error("Not enough memory for histogram array (%d bytes)", hist_width * sizeof(int)); - if ((bits = pbm_allocarray (hist_width, hist_height)) == NULL) - pm_error ("no space for output array (%d bits)", - hist_width * hist_height); - memset (ghist, 0, sizeof (ghist)); + bits = pbm_allocarray(hist_width, hist_height); + if (bits == NULL) + pm_error("no space for output array (%d bits)", + hist_width * hist_height); + memset(ghist, 0, hist_width * sizeof(ghist[0])); /* read the pixel values into the histogram arrays */ - grayrow = pgm_allocrow (cols); - /*XX error-check! */ - if (verbose) pm_message ("making histogram..."); + grayrow = pgm_allocrow(cols); + + if (verbose) + pm_message("making histogram..."); + for (i = rows; i > 0; --i) { - pgm_readpgmrow (fp, grayrow, cols, maxval, format); + pgm_readpgmrow (ifP, grayrow, cols, maxval, format); for (j = cols-1; j >= 0; --j) { - int value; + int const value = grayrow[j]; - if ((value = grayrow[j]) >= startval && value <= endval) - ghist[SCALE_H(value-startval)]++; + if (value >= startval && value <= endval) + ++ghist[SCALE_H(value-startval)]; } } - pgm_freerow (grayrow); - fclose (fp); + pgm_freerow(grayrow); /* find the highest-valued slot and set the vertical scale value */ if (verbose) - pm_message ("finding max. slot height..."); + pm_message("finding max. slot height..."); if (clipSpec) hmax = clipCount; else hmax = maxSlotCount(ghist, hist_width, no_white, no_black); if (verbose) - pm_message ("Done: height = %u", hmax); + pm_message("Done: height = %u", hmax); clipHistogram(ghist, hist_width, hmax); @@ -236,7 +240,7 @@ pgm_hist(FILE * const fp, bits[j][i] = dots ? PBM_BLACK : PBM_WHITE; } - pbm_writepbm (stdout, bits, hist_width, hist_height, 0); + pbm_writepbm(stdout, bits, hist_width, hist_height, 0); } @@ -309,7 +313,7 @@ clipHistogramAll(unsigned int * const hist[3], static void -ppm_hist(FILE * const fp, +ppm_hist(FILE * const ifP, int const cols, int const rows, xelval const maxval, @@ -329,8 +333,8 @@ ppm_hist(FILE * const fp, bool const hscale_unity = hscale - 1 < epsilon; - pixel *pixrow; - pixel **pixels; + pixel * pixrow; + pixel ** pixels; int i, j; unsigned int * hist[3]; /* Subscript is enum wantedColor */ double vscale; @@ -339,17 +343,19 @@ ppm_hist(FILE * const fp, createHist(colorWanted, hist_width, &hist); if ((pixels = ppm_allocarray (hist_width, hist_height)) == NULL) - pm_error ("no space for output array (%d pixels)", - hist_width * hist_height); + pm_error("no space for output array (%d pixels)", + hist_width * hist_height); for (i = 0; i < hist_height; ++i) - memset (pixels[i], 0, hist_width * sizeof (pixel)); + memset(pixels[i], 0, hist_width * sizeof(pixels[i][0])); /* read the pixel values into the histogram arrays */ - pixrow = ppm_allocrow (cols); - /*XX error-check! */ - if (verbose) pm_message ("making histogram..."); + pixrow = ppm_allocrow(cols); + + if (verbose) + pm_message("making histogram..."); + for (i = rows; i > 0; --i) { - ppm_readppmrow (fp, pixrow, cols, maxval, format); + ppm_readppmrow(ifP, pixrow, cols, maxval, format); for (j = cols-1; j >= 0; --j) { int value; @@ -367,12 +373,11 @@ ppm_hist(FILE * const fp, hist[WANT_BLU][SCALE_H(value-startval)]++; } } - ppm_freerow (pixrow); - fclose (fp); + ppm_freerow(pixrow); /* find the highest-valued slot and set the vertical scale value */ if (verbose) - pm_message ("finding max. slot height..."); + pm_message("finding max. slot height..."); if (clipSpec) hmax = clipCount; else @@ -420,16 +425,16 @@ ppm_hist(FILE * const fp, } } } - ppm_writeppm (stdout, pixels, hist_width, hist_height, maxval, 0); + ppm_writeppm(stdout, pixels, hist_width, hist_height, maxval, 0); } int -main (int argc, char ** argv) { +main(int argc, char ** argv) { struct cmdlineInfo cmdline; - FILE* ifP; + FILE * ifP; int cols, rows; xelval maxval; int format; @@ -479,5 +484,7 @@ main (int argc, char ** argv) { pm_error("Cannot do a histogram of a a PBM file"); break; } + pm_close(ifP); + return 0; } diff --git a/analyzer/pnmpsnr.c b/analyzer/pnmpsnr.c index a7331d27..1160fff6 100644 --- a/analyzer/pnmpsnr.c +++ b/analyzer/pnmpsnr.c @@ -13,6 +13,7 @@ #include <math.h> #include "pm_c_util.h" +#include "nstring.h" #include "pam.h" #define MAXFILES 16 @@ -47,7 +48,7 @@ validate_input(const struct pam pam1, const struct pam pam2) { pm_error("images do not have the same maxval. This programs works " "only on like maxvals. " "The first image has maxval %u, " - "while the second has %u. Use Pnmdepth to change the " + "while the second has %u. Use Pamdepth to change the " "maxval of one of them.", (unsigned int) pam1.maxval, (unsigned int) pam2.maxval); @@ -66,16 +67,18 @@ validate_input(const struct pam pam1, const struct pam pam2) { static void -psnr_color(tuple const tuple1, tuple const tuple2, +psnr_color(tuple const tuple1, + tuple const tuple2, double * const ySqDiffP, - double * const cbSqDiffP, double * const crSqDiffP) { + double * const cbSqDiffP, + double * const crSqDiffP) { double y1, y2, cb1, cb2, cr1, cr2; pnm_YCbCrtuple(tuple1, &y1, &cb1, &cr1); pnm_YCbCrtuple(tuple2, &y2, &cb2, &cr2); - *ySqDiffP = square(y1 - y2); + *ySqDiffP = square(y1 - y2); *cbSqDiffP = square(cb1 - cb2); *crSqDiffP = square(cr1 - cr2); } @@ -83,45 +86,49 @@ psnr_color(tuple const tuple1, tuple const tuple2, static void -reportPsnr(struct pam const pam1, struct pam const pam2, - double const ySumSqDiff, - double const crSumSqDiff, double const cbSumSqDiff, - const char filespec1[], const char filespec2[]) { +reportPsnr(struct pam const pam, + double const ySumSqDiff, + double const crSumSqDiff, + double const cbSumSqDiff, + char const filespec1[], + char const filespec2[]) { - bool const color = (strcmp(pam1.tuple_type, PAM_PPM_TUPLETYPE) == 0); + bool const color = streq(pam.tuple_type, PAM_PPM_TUPLETYPE); - /* The PSNR is the mean of the sum of squares of the differences, - normalized to the range 0..1 + /* The PSNR is the ratio of the maximum possible mean square difference + to the actual mean square difference. + */ + double const yPsnr = + square(pam.maxval) / (ySumSqDiff / (pam.width * pam.height)); + + /* Note that in the important special case that the images are + identical, the sum square differences are identically 0.0. No + precision error; no rounding error. */ - double const yPsnr = ySumSqDiff - / (pam1.width * pam1.height) - / square(pam1.maxval); if (color) { - double const cbPsnr = cbSumSqDiff - / (pam1.width * pam1.height) - / square(pam1.maxval); - double const crPsnr = crSumSqDiff - / (pam1.width * pam1.height) - / (pam1.maxval * pam2.maxval); + double const cbPsnr = + square(pam.maxval) / (cbSumSqDiff / (pam.width * pam.height)); + double const crPsnr = + square(pam.maxval) / (crSumSqDiff / (pam.width * pam.height)); pm_message("PSNR between %s and %s:", filespec1, filespec2); - if (yPsnr > 1e-9) - pm_message("Y color component: %.2f dB", 10 * log10(1/yPsnr)); + if (ySumSqDiff > 0) + pm_message("Y color component: %.2f dB", 10 * log10(yPsnr)); else pm_message("Y color component does not differ."); - if (cbPsnr > 1e-9) - pm_message("Cb color component: %.2f dB", 10 * log10(1/cbPsnr)); + if (cbSumSqDiff > 0) + pm_message("Cb color component: %.2f dB", 10 * log10(cbPsnr)); else - pm_message("Cb color component does not differ."); - if (crPsnr > 1e-9) - pm_message("Cr color component: %.2f dB", 10 * log10(1/crPsnr)); + pm_message("Cb color component does not differ."); + if (crSumSqDiff > 0) + pm_message("Cr color component: %.2f dB", 10 * log10(crPsnr)); else pm_message("Cr color component does not differ."); } else { - if (yPsnr > 1e-9) + if (ySumSqDiff > 0) pm_message("PSNR between %s and %s: %.2f dB", - filespec1, filespec2, 10 * log10(1/yPsnr)); + filespec1, filespec2, 10 * log10(yPsnr)); else pm_message("Images %s and %s don't differ.", filespec1, filespec2); @@ -166,7 +173,7 @@ main (int argc, char **argv) { tuplerow1 = pnm_allocpamrow(&pam1); tuplerow2 = pnm_allocpamrow(&pam2); - ySumSqDiff = 0.0; + ySumSqDiff = 0.0; cbSumSqDiff = 0.0; crSumSqDiff = 0.0; @@ -181,19 +188,19 @@ main (int argc, char **argv) { double ySqDiff, cbSqDiff, crSqDiff; psnr_color(tuplerow1[col], tuplerow2[col], &ySqDiff, &cbSqDiff, &crSqDiff); - ySumSqDiff += ySqDiff; + ySumSqDiff += ySqDiff; cbSumSqDiff += cbSqDiff; crSumSqDiff += crSqDiff; } else { - unsigned int yDiffSq; - yDiffSq = square(udiff(tuplerow1[col][0], tuplerow2[col][0])); + unsigned int const yDiffSq = + square(udiff(tuplerow1[col][0], tuplerow2[col][0])); ySumSqDiff += yDiffSq; } } } - reportPsnr(pam1, pam2, ySumSqDiff, crSumSqDiff, cbSumSqDiff, + reportPsnr(pam1, ySumSqDiff, crSumSqDiff, cbSumSqDiff, filespec1, filespec2); pnm_freepamrow(tuplerow1); @@ -201,9 +208,3 @@ main (int argc, char **argv) { return 0; } - - - - - - diff --git a/analyzer/ppmhist.c b/analyzer/ppmhist.c index 4c4d3c55..673c8175 100644 --- a/analyzer/ppmhist.c +++ b/analyzer/ppmhist.c @@ -12,9 +12,11 @@ #include <assert.h> -#include "ppm.h" -#include "shhopt.h" +#include "pm_c_util.h" +#include "mallocvar.h" #include "nstring.h" +#include "shhopt.h" +#include "ppm.h" enum sort {SORT_BY_FREQUENCY, SORT_BY_RGB}; @@ -24,7 +26,7 @@ struct cmdline_info { /* All the information the user supplied in the command line, in a form easy for the program to use. */ - const char *input_filespec; /* Filespecs of input files */ + const char * inputFileName; /* Name of input file */ unsigned int noheader; /* -noheader option */ enum colorFmt colorFmt; unsigned int colorname; /* -colorname option */ @@ -34,19 +36,21 @@ struct cmdline_info { static void -parse_command_line(int argc, char ** argv, - struct cmdline_info * const cmdlineP) { +parseCommandLine(int argc, const char ** argv, + struct cmdline_info * const cmdlineP) { /*---------------------------------------------------------------------------- Note that the file spec array we return is stored in the storage that was passed to us as the argv array. -----------------------------------------------------------------------------*/ optStruct3 opt; /* set by OPTENT3 */ - optEntry *option_def = malloc(100*sizeof(optEntry)); + optEntry * option_def; unsigned int option_def_index; unsigned int hexcolorOpt, floatOpt, mapOpt, nomapOpt; const char * sort_type; + MALLOCARRAY(option_def, 100); + option_def_index = 0; /* incremented by OPTENTRY */ OPTENT3(0, "map", OPT_FLAG, NULL, &mapOpt, 0); OPTENT3(0, "nomap", OPT_FLAG, NULL, &nomapOpt, 0); @@ -63,16 +67,16 @@ parse_command_line(int argc, char ** argv, /* Set defaults */ sort_type = "frequency"; - optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (argc-1 == 0) - cmdlineP->input_filespec = "-"; + cmdlineP->inputFileName = "-"; else if (argc-1 != 1) pm_error("Program takes zero or one argument (filename). You " "specified %d", argc-1); else - cmdlineP->input_filespec = argv[1]; + cmdlineP->inputFileName = argv[1]; if (hexcolorOpt + floatOpt + mapOpt > 1) pm_error("You can specify only one of -hexcolor, -float, and -map"); @@ -218,9 +222,10 @@ printColors(colorhist_vector const chv, int -main(int argc, char *argv[] ) { +main(int argc, const char *argv[]) { + struct cmdline_info cmdline; - FILE* ifP; + FILE * ifP; colorhist_vector chv; int rows, cols; pixval maxval; @@ -234,11 +239,11 @@ main(int argc, char *argv[] ) { const char ** dictColornames; pixel * dictColors; - ppm_init( &argc, argv ); + pm_proginit(&argc, argv); - parse_command_line(argc, argv, &cmdline); + parseCommandLine(argc, argv, &cmdline); - ifP = pm_openr(cmdline.input_filespec); + ifP = pm_openr(cmdline.inputFileName); ppm_readppminit(ifP, &cols, &rows, &maxval, &format); |