diff options
author | tron <tron@pkgsrc.org> | 1998-07-15 19:52:55 +0000 |
---|---|---|
committer | tron <tron@pkgsrc.org> | 1998-07-15 19:52:55 +0000 |
commit | 90af7c496c515dc43eb6565e99ee02bb34fef324 (patch) | |
tree | a9a0c2b126b7164ff33a46687d38de3f6d6d3809 /graphics/netpbm | |
parent | 0eeef44b77aa07f4e2fcbf3c79cae558502dd2c9 (diff) | |
download | pkgsrc-90af7c496c515dc43eb6565e99ee02bb34fef324.tar.gz |
Add well known fixes for "netpbm-1mar1994" supplied by John F. Woods
in PR pkg/5723.
Diffstat (limited to 'graphics/netpbm')
27 files changed, 3554 insertions, 1 deletions
diff --git a/graphics/netpbm/patches/patch-ba b/graphics/netpbm/patches/patch-ba new file mode 100644 index 00000000000..997750d9aba --- /dev/null +++ b/graphics/netpbm/patches/patch-ba @@ -0,0 +1,50 @@ +--- ./pnm/anytopnm.orig Mon Oct 4 05:11:29 1993 ++++ ./pnm/anytopnm Sat Jul 20 22:19:05 1996 +@@ -53,7 +53,7 @@ + ;; + + *GIF* ) +- giftoppm "$file" ++ giftopnm "$file" + break + ;; + +@@ -82,6 +82,15 @@ + break + ;; + ++ *JPEG* | *JFIF* ) ++ djpeg "$file" ++ ;; ++ ++ *PNG* ) ++ pngtopnm "$file" ++ break ++ ;; ++ + * ) + # Can't figure out the file type from the magic number, + # try the extension. +@@ -130,7 +139,7 @@ + fitstopgm "$file" + ;; + *.gif | *.gif.* ) +- giftoppm "$file" ++ giftopnm "$file" + ;; + *.iff | *.iff.* | *.ilbm | *.ilbm.* ) + ilbmtoppm "$file" +@@ -168,6 +177,13 @@ + *.ybm | *.ybm.* | *.face | *.face.* ) + ybmtopbm "$file" + ;; ++ *.JPEG | *.jpeg | *.jpg | *.JPG ) ++ djpeg "$file" ++ ;; ++ *.png | *.PNG ) ++ pngtopnm "$file" ++ break ++ ;; + * ) + echo "$0: unknown file type" 1>&2 + exit 1 diff --git a/graphics/netpbm/patches/patch-bb b/graphics/netpbm/patches/patch-bb new file mode 100644 index 00000000000..59910e104f3 --- /dev/null +++ b/graphics/netpbm/patches/patch-bb @@ -0,0 +1,11 @@ +--- ./pbm/libpbm1.c.orig Mon Jan 10 12:37:22 1994 ++++ ./pbm/libpbm1.c Sun Aug 13 00:03:56 1995 +@@ -132,7 +132,7 @@ + if ( isupper( c1 ) ) + c1 = tolower( c1 ); + if ( isupper( c2 ) ) +- c1 = tolower( c2 ); ++ c2 = tolower( c2 ); + if ( c1 != c2 ) + return 0; + } diff --git a/graphics/netpbm/patches/patch-bc b/graphics/netpbm/patches/patch-bc new file mode 100644 index 00000000000..fde93cf1ea7 --- /dev/null +++ b/graphics/netpbm/patches/patch-bc @@ -0,0 +1,13 @@ +--- ./pbm/pbmmerge.c.orig Wed Nov 3 04:28:55 1993 ++++ ./pbm/pbmmerge.c Sat Aug 12 23:51:57 1995 +@@ -29,6 +29,10 @@ + { + ++argv; + --argc; ++ if(!*argv) { ++ fprintf(stderr, "Usage: pbmmerge pbm_program_name [args ...]\n"); ++ exit(1); ++ } + goto again; + } + diff --git a/graphics/netpbm/patches/patch-bd b/graphics/netpbm/patches/patch-bd new file mode 100644 index 00000000000..4f2d17fb84a --- /dev/null +++ b/graphics/netpbm/patches/patch-bd @@ -0,0 +1,16 @@ +--- ./pbm/pbmtext.c.orig Wed Oct 27 03:27:04 1993 ++++ ./pbm/pbmtext.c Sat Jul 20 21:48:12 1996 +@@ -105,10 +105,12 @@ + else + { /* Read text from stdin. */ + lines = 0; +- while ( gets( buf ) != NULL ) ++ while ( fgets( buf, sizeof(buf), stdin ) != NULL ) + { + int l; ++ char *nl = strchr(buf, '\n'); + ++ if (nl) *nl = 0; + fix_control_chars( buf ); + l = strlen( buf ); + if ( lines >= maxlines ) diff --git a/graphics/netpbm/patches/patch-be b/graphics/netpbm/patches/patch-be new file mode 100644 index 00000000000..7aa02036b6f --- /dev/null +++ b/graphics/netpbm/patches/patch-be @@ -0,0 +1,137 @@ +--- ./pbm/pbmto10x.c.orig Mon Oct 4 05:10:42 1993 ++++ ./pbm/pbmto10x.c Sat Aug 12 23:36:40 1995 +@@ -1,6 +1,6 @@ + /* pbmto10x.c - read a portable bitmap and produce a Gemini 10X printer file + ** +-** Copyright (C) 1990 by Ken Yap ++** Copyright (C) 1990, 1994 by Ken Yap + ** + ** Permission to use, copy, modify, and distribute this software and its + ** documentation for any purpose and without fee is hereby granted, provided +@@ -8,6 +8,8 @@ + ** copyright notice and this permission notice appear in supporting + ** documentation. This software is provided "as is" without express or + ** implied warranty. ++** ++** Modified to shorten stripes and eliminate blank stripes. Dec 1994. + */ + + #include "pbm.h" +@@ -52,15 +54,40 @@ + } + + static void ++outstripe(stripe, sP, reschar) ++ register char *stripe, *sP; ++ register int reschar; ++{ ++ register int ncols; ++ ++ /* scan backwards, removing empty columns */ ++ while (sP != stripe) ++ if (*--sP != 0) ++ { ++ ++sP; ++ break; ++ } ++ ncols = sP - stripe; ++ if (ncols > 0) ++ { ++ printf("\033%c%c%c", reschar, ncols % 256, ncols / 256); ++ fwrite(stripe, sizeof(char), ncols, stdout); ++ } ++ putchar('\n'); /* flush buffer */ ++} ++ ++static void + res_60x72() + { + register int i, item, npins, row, col; + bit *bitrows[LOW_RES_ROWS], *bP[LOW_RES_ROWS]; ++ char *stripe, *sP; + ++ stripe = malloc(cols); + for (i = 0; i < LOW_RES_ROWS; ++i) + bitrows[i] = pbm_allocrow(cols); + printf("\033A\010"); /* '\n' = 8/72 */ +- for (row = 0; row < rows; row += LOW_RES_ROWS) ++ for (row = 0, sP = stripe; row < rows; row += LOW_RES_ROWS, sP = stripe) + { + if (row + LOW_RES_ROWS <= rows) + npins = LOW_RES_ROWS; +@@ -68,17 +95,18 @@ + npins = rows - row; + for (i = 0; i < npins; ++i) + pbm_readpbmrow(ifp, bP[i] = bitrows[i], cols, format); +- printf("\033K%c%c", cols % 256, cols / 256); + for (col = 0; col < cols; ++col) + { + item = 0; + for (i = 0; i < npins; ++i) + if (*(bP[i]++) == PBM_BLACK) + item |= 1 << (7 - i); +- putchar(item); ++ *sP++ = item; + } +- putchar('\n'); ++ outstripe(stripe, sP, 'K'); + } ++ printf("\033@"); ++ free(stripe); + } + + static void +@@ -86,11 +114,13 @@ + { + register int i, pin, item, npins, row, col; + bit *bitrows[HIGH_RES_ROWS], *bP[HIGH_RES_ROWS]; ++ char *stripe, *sP; + ++ stripe = malloc(cols); + for (i = 0; i < HIGH_RES_ROWS; ++i) + bitrows[i] = pbm_allocrow(cols); +- putchar('\033'); putchar('3'); putchar('\0'); +- for (row = 0; row < rows; row += HIGH_RES_ROWS) ++ printf("\0333\001"); /* \n = 1/144" */ ++ for (row = 0, sP = stripe; row < rows; row += HIGH_RES_ROWS, sP = stripe) + { + if (row + HIGH_RES_ROWS <= rows) + npins = HIGH_RES_ROWS; +@@ -98,7 +128,6 @@ + npins = rows - row; + for (i = 0; i < npins; ++i) + pbm_readpbmrow(ifp, bP[i] = bitrows[i], cols, format); +- printf("\033L%c%c", cols % 256, cols / 256); + for (col = 0; col < cols; ++col) + { + item = 0; +@@ -106,11 +135,10 @@ + for (pin = i = 0; i < npins; i += 2, ++pin) + if (*(bP[i]++) == PBM_BLACK) + item |= 1 << (7 - pin); +- putchar(item); ++ *sP++ = item; + } +- putchar('\n'); /* flush buffer */ +- printf("\033J\001"); /* 1/144 down */ +- printf("\033L%c%c", cols % 256, cols / 256); ++ outstripe(stripe, sP, 'L'); ++ sP = stripe; + for (col = 0; col < cols; ++col) + { + item = 0; +@@ -118,9 +146,11 @@ + for (i = 1, pin = 0; i < npins; i += 2, ++pin) + if (*(bP[i]++) == PBM_BLACK) + item |= 1 << (7 - pin); +- putchar(item); ++ *sP++ = item; + } +- putchar('\n'); /* flush buffer */ +- printf("\033J\017"); /* 15/144 down */ ++ outstripe(stripe, sP, 'L'); ++ printf("\033J\016"); /* 14/144 down, \n did 1/144 */ + } ++ printf("\033@"); ++ free(stripe); + } diff --git a/graphics/netpbm/patches/patch-bf b/graphics/netpbm/patches/patch-bf new file mode 100644 index 00000000000..2cf57738469 --- /dev/null +++ b/graphics/netpbm/patches/patch-bf @@ -0,0 +1,13 @@ +--- ./pgm/pgmmerge.c.orig Fri Jan 28 05:17:38 1994 ++++ ./pgm/pgmmerge.c Sat Aug 12 23:51:14 1995 +@@ -29,6 +29,10 @@ + { + ++argv; + --argc; ++ if(!*argv) { ++ fprintf(stderr, "Usage: pgmmerge pgm_program_name [args ...]\n"); ++ exit(1); ++ } + goto again; + } + diff --git a/graphics/netpbm/patches/patch-bg b/graphics/netpbm/patches/patch-bg new file mode 100644 index 00000000000..78db9a658e1 --- /dev/null +++ b/graphics/netpbm/patches/patch-bg @@ -0,0 +1,36 @@ +--- ./pnm/Makefile.orig Tue Jul 7 22:02:33 1998 ++++ ./pnm/Makefile Wed Jul 8 07:43:20 1998 +@@ -61,19 +61,21 @@ + pnminvert pnmnoraw pnmpad pnmpaste \ + pnmtile pnmtoddif pnmtofits pnmtops pnmtorast \ + pnmtorle pnmtosgi pnmtosir pnmtoxwd \ +- rasttopnm rletopnm sgitopnm sirtopnm xwdtopnm zeisstopnm ++ rasttopnm rletopnm sgitopnm sirtopnm xwdtopnm zeisstopnm \ ++ pnmsmooth pnmhisteq + MATHBINARIES = pnmgamma pnmnlfilt pnmrotate pnmscale pnmshear + PNGBINARIES = pngtopnm pnmtopng + BINARIES = $(PORTBINARIES) $(MATHBINARIES) $(PNGBINARIES) $(TIFFBINARIES) +-SCRIPTS = anytopnm pnmindex pnmmargin pnmsmooth pstopnm ++SCRIPTS = anytopnm pnmindex pnmmargin pstopnm + + PORTOBJECTS = fitstopnm.o giftopnm.o \ + pnmalias.o pnmarith.o pnmcat.o pnmcomp.o pnmconvol.o pnmcrop.o \ + pnmcut.o pnmdepth.o pnmenlarge.o pnmfile.o pnmflip.o pnmhistmap.o \ +- pnminvert.o pnmnoraw.o pnmpad.o pnmpaste.o \ ++ pnmhisteq.o pnminvert.o pnmnoraw.o pnmpad.o pnmpaste.o\ + pnmtile.o pnmtoddif.o pnmtofits.o pnmtops.o pnmtorast.o \ + pnmtosgi.o pnmtosir.o pnmtoxwd.o \ + rasttopnm.o sgitopnm.o sirtopnm.o xwdtopnm.o zeisstopnm.o \ ++ pnmsmooth.o pnmhisteq.o \ + pnmgamma.o pnmnlfilt.o pnmrotate.o pnmscale.o pnmshear.o + OBJECTS = $(PORTOBJECTS) + +@@ -209,6 +211,8 @@ + tifftopnm tifftopnm.o: tifftopnm.c + xwdtopnm xwdtopnm.o: xwdtopnm.c x10wd.h x11wd.h + zeisstopnm zeisstopnm.o: zeisstopnm.c ++pnmhisteq pnmhisteq.o: pnmhisteq.c ++pnmsmooth pnmsmooth.o: pnmsmooth.c + + clean: + -rm -f *.o *.a *.cat *~ core $(BINARIES) pnmmerge diff --git a/graphics/netpbm/patches/patch-bh b/graphics/netpbm/patches/patch-bh new file mode 100644 index 00000000000..2454151e908 --- /dev/null +++ b/graphics/netpbm/patches/patch-bh @@ -0,0 +1,11 @@ +--- ./pnm/pnmarith.1.orig Sun Aug 13 00:08:22 1995 ++++ ./pnm/pnmarith.1 Sun Aug 13 00:08:46 1995 +@@ -4,7 +4,7 @@ + pnmarith - perform arithmetic on two portable anymaps + .SH SYNOPSIS + .B pnmarith +-.BR -add | -subtract | -multiply | -difference ++.BR -add | -subtract | -multiply | -difference | -minimum | -maximum. + .I pnmfile1 pnmfile2 + .SH DESCRIPTION + Reads two portable anymaps as input. diff --git a/graphics/netpbm/patches/patch-bi b/graphics/netpbm/patches/patch-bi new file mode 100644 index 00000000000..0c09a5ec15f --- /dev/null +++ b/graphics/netpbm/patches/patch-bi @@ -0,0 +1,66 @@ +--- ./pnm/pnmarith.c.orig Sun Aug 13 00:04:38 1995 ++++ ./pnm/pnmarith.c Sun Aug 13 00:08:04 1995 +@@ -29,7 +29,8 @@ + xelval maxval1, maxval2, maxval3; + int argn, rows1, cols1, format1, rows2, cols2, format2, format3, row, col; + char function; +- char* usage = "-add|-subtract|-multiply|-difference pnmfile1 pnmfile2"; ++ char* usage = ++"-add|-subtract|-multiply|-difference|-minimum|-maximum pnmfile1 pnmfile2"; + + + pnm_init( &argc, argv ); +@@ -48,6 +49,10 @@ + function = '*'; + else if ( pm_keymatch( argv[argn], "-difference", 2 ) ) + function = 'D'; ++ else if ( pm_keymatch( argv[argn], "-minimum", 2 ) ) ++ function = 'N'; ++ else if ( pm_keymatch( argv[argn], "-maximum", 2 ) ) ++ function = 'X'; + else + pm_usage( usage ); + ++argn; +@@ -112,7 +117,7 @@ + pnm_promoteformatrow( + xelrow2, cols1, maxval2, format2, maxval3, format3 ); + +- for ( col = 0, x1P = xelrow1, x2P = xelrow2; ++ for ( col = 0, x1P = xelrow1, x2P = xelrow2; + col < cols1; ++col, ++x1P, ++x2P ) + { + switch ( PNM_FORMAT_TYPE(format3) ) +@@ -153,6 +158,18 @@ + b1 = (b1>b2)?(b1-b2):(b2-b1); + break; + ++ case 'N': ++ r1 = (r1>r2)?(r2):(r1); ++ g1 = (g1>g2)?(g2):(g1); ++ b1 = (b1>b2)?(b2):(b1); ++ break; ++ ++ case 'X': ++ r1 = (r1>r2)?(r1):(r2); ++ g1 = (g1>g2)?(g1):(g2); ++ b1 = (b1>b2)?(b1):(b2); ++ break; ++ + default: + pm_error( "can't happen" ); + } +@@ -188,6 +205,14 @@ + + case 'D': + g1 = (g1>g2)?(g1-g2):(g2-g1); ++ break; ++ ++ case 'N': ++ g1 = (g1>g2)?(g2):(g1); ++ break; ++ ++ case 'X': ++ g1 = (g1>g2)?(g1):(g2); + break; + + default: diff --git a/graphics/netpbm/patches/patch-bj b/graphics/netpbm/patches/patch-bj new file mode 100644 index 00000000000..f067c9beabc --- /dev/null +++ b/graphics/netpbm/patches/patch-bj @@ -0,0 +1,1872 @@ +--- ./pnm/pnmconvol.c.orig Mon Oct 4 05:11:36 1993 ++++ ./pnm/pnmconvol.c Wed Jul 8 07:48:07 1998 +@@ -1,5 +1,10 @@ + /* pnmconvol.c - general MxN convolution on a portable anymap + ** ++** Version 2.0.1 January 30, 1995 ++** ++** Major rewriting by Mike Burns ++** Copyright (C) 1994, 1995 by Mike Burns (burns@chem.psu.edu) ++** + ** Copyright (C) 1989, 1991 by Jef Poskanzer. + ** + ** Permission to use, copy, modify, and distribute this software and its +@@ -10,31 +15,109 @@ + ** implied warranty. + */ + ++/* Version 2.0.1 Changes ++** --------------------- ++** Fixed four lines that were improperly allocated as sizeof( float ) when they ++** should have been sizeof( long ). ++** ++** Version 2.0 Changes ++** ------------------- ++** Reduce run time by general optimizations and handling special cases of ++** convolution matrices. Program automatically determines if convolution ++** matrix is one of the types it can make use of so no extra command line ++** arguments are necessary. ++** ++** Examples of convolution matrices for the special cases are ++** ++** Mean Horizontal Vertical ++** x x x x x x x y z ++** x x x y y y x y z ++** x x x z z z x y z ++** ++** I don't know if the horizontal and vertical ones are of much use, but ++** after working on the mean convolution, it gave me ideas for the other two. ++** ++** Some other compiler dependent optimizations ++** ------------------------------------------- ++** Created separate functions as code was getting too large to put keep both ++** PGM and PPM cases in same function and also because SWITCH statement in ++** inner loop can take progressively more time the larger the size of the ++** convolution matrix. GCC is affected this way. ++** ++** Removed use of MOD (%) operator from innermost loop by modifying manner in ++** which the current xelbuf[] is chosen. ++** ++*/ ++ + #include "pnm.h" + ++/* Macros to verify that r,g,b values are within proper range */ ++ ++#define CHECK_GRAY \ ++ if ( tempgsum < 0L ) g = 0; \ ++ else if ( tempgsum > maxval ) g = maxval; \ ++ else g = tempgsum; ++ ++#define CHECK_RED \ ++ if ( temprsum < 0L ) r = 0; \ ++ else if ( temprsum > maxval ) r = maxval; \ ++ else r = temprsum; ++ ++#define CHECK_GREEN \ ++ if ( tempgsum < 0L ) g = 0; \ ++ else if ( tempgsum > maxval ) g = maxval; \ ++ else g = tempgsum; ++ ++#define CHECK_BLUE \ ++ if ( tempbsum < 0L ) b = 0; \ ++ else if ( tempbsum > maxval ) b = maxval; \ ++ else b = tempbsum; ++ ++ ++static int check_convolve_type ARGS((xel **cxels)); ++static void pgm_general_convolve ARGS((void)); ++static void ppm_general_convolve ARGS((void)); ++static void pgm_mean_convolve ARGS((void)); ++static void ppm_mean_convolve ARGS((void)); ++static void pgm_vertical_convolve ARGS((void)); ++static void ppm_vertical_convolve ARGS((void)); ++static void pgm_horizontal_convolve ARGS((void)); ++static void ppm_horizontal_convolve ARGS((void)); ++ ++#define TRUE 1 ++#define FALSE 0 ++ ++#define GENERAL_CONVOLVE 0 ++#define MEAN_CONVOLVE 1 ++#define HORIZONTAL_CONVOLVE 2 ++#define VERTICAL_CONVOLVE 3 ++ ++static FILE* ifp; ++static float** rweights; ++static float** gweights; ++static float** bweights; ++static int crows, ccols, ccolso2, crowso2; ++static int cols, rows; ++static xelval maxval; ++static int format, newformat; ++static float rmeanweight, gmeanweight, bmeanweight; ++ + int + main( argc, argv ) + int argc; + char* argv[]; + { + FILE* cifp; +- FILE* ifp; + xel** cxels; +- xel** xelbuf; +- xel* outputrow; +- xel x; +- int argn, crows, ccols, cformat, ccolso2, crowso2; +- int rows, cols, format, newformat, crow, row; ++ int argn, cformat; ++ int crow, row; + register int ccol, col; +- xelval cmaxval, maxval; ++ xelval cmaxval; + xelval g; +- float** gweights; + float gsum; +- xelval r, b; +- float** rweights; +- float** bweights; + float rsum, bsum; + char* usage = "<convolutionfile> [pnmfile]"; ++ int convolve_type; + + pnm_init( &argc, argv ); + +@@ -90,6 +173,7 @@ + } + } + ++ + /* Set up the normalized weights. */ + rweights = (float**) pm_allocarray( ccols, crows, sizeof(float) ); + gweights = (float**) pm_allocarray( ccols, crows, sizeof(float) ); +@@ -115,6 +199,14 @@ + break; + } + } ++ ++ /* For mean_convolve routines. All weights of a single color are the same ++ ** so just grab any one of them. ++ */ ++ rmeanweight = rweights[0][0]; ++ gmeanweight = gweights[0][0]; ++ bmeanweight = bweights[0][0]; ++ + switch ( PNM_FORMAT_TYPE(format) ) + { + case PPM_TYPE: +@@ -131,11 +223,199 @@ + break; + } + ++ /* Handle certain special cases when runtime can be improved. */ ++ ++ convolve_type = check_convolve_type(cxels); ++ ++ switch ( PNM_FORMAT_TYPE(format) ) ++ { ++ case PPM_TYPE: ++ switch (convolve_type) ++ { ++ case MEAN_CONVOLVE: ++ ppm_mean_convolve(); ++ break; ++ ++ case HORIZONTAL_CONVOLVE: ++ ppm_horizontal_convolve(); ++ break; ++ ++ case VERTICAL_CONVOLVE: ++ ppm_vertical_convolve(); ++ break; ++ ++ default: /* GENERAL_CONVOLVE */ ++ ppm_general_convolve(); ++ break; ++ } ++ break; ++ ++ default: ++ switch (convolve_type) ++ { ++ case MEAN_CONVOLVE: ++ pgm_mean_convolve(); ++ break; ++ ++ case HORIZONTAL_CONVOLVE: ++ pgm_horizontal_convolve(); ++ break; ++ ++ case VERTICAL_CONVOLVE: ++ pgm_vertical_convolve(); ++ break; ++ ++ default: /* GENERAL_CONVOLVE */ ++ pgm_general_convolve(); ++ break; ++ } ++ break; ++ } /* PNM_TYPE */ ++ ++ pm_close( ifp ); ++ exit( 0 ); ++ } ++ ++ ++ ++/* check_convolve_type ++** ++** Determine if the convolution matrix is one of the special cases that ++** can be processed faster than the general form. ++** ++** Does not check for the case where one of the PPM colors can have differing ++** types. Only handles cases where all PPM's are of the same special case. ++*/ ++ ++static int ++check_convolve_type (cxels) ++ xel **cxels; ++ { ++ int convolve_type; ++ int horizontal, vertical; ++ int tempcxel, rtempcxel, gtempcxel, btempcxel; ++ int crow, ccol; ++ ++ switch ( PNM_FORMAT_TYPE(format) ) ++ { ++ case PPM_TYPE: ++ horizontal = TRUE; ++ crow = 0; ++ while ( horizontal && (crow < crows) ) ++ { ++ ccol = 1; ++ rtempcxel = PPM_GETR(cxels[crow][0]); ++ gtempcxel = PPM_GETG(cxels[crow][0]); ++ btempcxel = PPM_GETB(cxels[crow][0]); ++ while ( horizontal && (ccol < ccols) ) ++ { ++ if (( PPM_GETR(cxels[crow][ccol]) != rtempcxel ) | ++ ( PPM_GETG(cxels[crow][ccol]) != gtempcxel ) | ++ ( PPM_GETB(cxels[crow][ccol]) != btempcxel )) ++ horizontal = FALSE; ++ ++ccol; ++ } ++ ++crow; ++ } ++ ++ vertical = TRUE; ++ ccol = 0; ++ while ( vertical && (ccol < ccols) ) ++ { ++ crow = 1; ++ rtempcxel = PPM_GETR(cxels[0][ccol]); ++ gtempcxel = PPM_GETG(cxels[0][ccol]); ++ btempcxel = PPM_GETB(cxels[0][ccol]); ++ while ( vertical && (crow < crows) ) ++ { ++ if (( PPM_GETR(cxels[crow][ccol]) != rtempcxel ) | ++ ( PPM_GETG(cxels[crow][ccol]) != gtempcxel ) | ++ ( PPM_GETB(cxels[crow][ccol]) != btempcxel )) ++ vertical = FALSE; ++ ++crow; ++ } ++ ++ccol; ++ } ++ break; ++ ++ default: ++ horizontal = TRUE; ++ crow = 0; ++ while ( horizontal && (crow < crows) ) ++ { ++ ccol = 1; ++ tempcxel = PNM_GET1(cxels[crow][0]); ++ while ( horizontal && (ccol < ccols) ) ++ { ++ if ( PNM_GET1(cxels[crow][ccol]) != tempcxel ) ++ horizontal = FALSE; ++ ++ccol; ++ } ++ ++crow; ++ } ++ ++ vertical = TRUE; ++ ccol = 0; ++ while ( vertical && (ccol < ccols) ) ++ { ++ crow = 1; ++ tempcxel = PNM_GET1(cxels[0][ccol]); ++ while ( vertical && (crow < crows) ) ++ { ++ if ( PNM_GET1(cxels[crow][ccol]) != tempcxel ) ++ vertical = FALSE; ++ ++crow; ++ } ++ ++ccol; ++ } ++ break; ++ } ++ ++ /* Which type do we have? */ ++ if ( horizontal && vertical ) ++ convolve_type = MEAN_CONVOLVE; ++ else if ( horizontal ) ++ convolve_type = HORIZONTAL_CONVOLVE; ++ else if ( vertical ) ++ convolve_type = VERTICAL_CONVOLVE; ++ else ++ convolve_type = GENERAL_CONVOLVE; ++ ++ return (convolve_type); ++ } ++ ++ ++ ++ ++/* General PGM Convolution ++** ++** No useful redundancy in convolution matrix. ++*/ ++ ++static void ++pgm_general_convolve() ++ { ++ register int ccol, col; ++ xel** xelbuf; ++ xel* outputrow; ++ xel x, y; ++ xelval g; ++ int row, crow; ++ float gsum; ++ xel **rowptr, *temprptr; ++ int toprow, temprow; ++ int i, irow; ++ int leftcol; ++ long tempgsum; ++ + /* Allocate space for one convolution-matrix's worth of rows, plus + ** a row output buffer. */ + xelbuf = pnm_allocarray( cols, crows ); + outputrow = pnm_allocrow( cols ); + ++ /* Allocate array of pointers to xelbuf */ ++ rowptr = (xel **) pnm_allocarray( 1, crows ); ++ + pnm_writepnminit( stdout, cols, rows, maxval, newformat, 0 ); + + /* Read in one convolution-matrix's worth of image, less one row. */ +@@ -155,65 +435,1470 @@ + */ + for ( ; row < rows; ++row ) + { +- pnm_readpnmrow( ifp, xelbuf[row % crows], cols, maxval, format ); ++ toprow = row + 1; ++ temprow = row % crows; ++ pnm_readpnmrow( ifp, xelbuf[temprow], cols, maxval, format ); + if ( PNM_FORMAT_TYPE(format) != newformat ) + pnm_promoteformatrow( +- xelbuf[row % crows], cols, maxval, format, maxval, newformat ); ++ xelbuf[temprow], cols, maxval, format, maxval, newformat ); ++ ++ /* Arrange rowptr to eliminate the use of mod function to determine ++ ** which row of xelbuf is 0...crows. Mod function can be very costly. ++ */ ++ temprow = toprow % crows; ++ i = 0; ++ for (irow = temprow; irow < crows; ++i, ++irow) ++ rowptr[i] = xelbuf[irow]; ++ for (irow = 0; irow < temprow; ++irow, ++i) ++ rowptr[i] = xelbuf[irow]; + + for ( col = 0; col < cols; ++col ) ++ { + if ( col < ccolso2 || col >= cols - ccolso2 ) +- outputrow[col] = xelbuf[(row - crowso2) % crows][col]; ++ outputrow[col] = rowptr[crowso2][col]; + else + { +- switch ( PNM_FORMAT_TYPE(format) ) +- { +- case PPM_TYPE: +- rsum = gsum = bsum = 0.0; +- for ( crow = 0; crow < crows; ++crow ) +- for ( ccol = 0; ccol < ccols; ++ccol ) +- { +- x = xelbuf[(row+1+crow) % crows][col-ccolso2+ccol]; +- rsum += PPM_GETR( x ) * rweights[crow][ccol]; +- gsum += PPM_GETG( x ) * gweights[crow][ccol]; +- bsum += PPM_GETB( x ) * bweights[crow][ccol]; +- } +- if ( rsum < 0.0 ) r = 0; +- else if ( rsum > maxval ) r = maxval; +- else r = rsum + 0.5; +- if ( gsum < 0.0 ) g = 0; +- else if ( gsum > maxval ) g = maxval; +- else g = gsum + 0.5; +- if ( bsum < 0.0 ) b = 0; +- else if ( bsum > maxval ) b = maxval; +- else b = bsum + 0.5; +- PPM_ASSIGN( outputrow[col], r, g, b ); +- break; +- +- default: +- gsum = 0.0; +- for ( crow = 0; crow < crows; ++crow ) +- for ( ccol = 0; ccol < ccols; ++ccol ) +- { +- x = xelbuf[(row+1+crow) % crows][col-ccolso2+ccol]; +- gsum += PNM_GET1( x ) * gweights[crow][ccol]; +- } +- if ( gsum < 0.0 ) g = 0; +- else if ( gsum > maxval ) g = maxval; +- else g = gsum + 0.5; ++ leftcol = col - ccolso2; ++ gsum = 0.0; ++ for ( crow = 0; crow < crows; ++crow ) ++ { ++ temprptr = rowptr[crow] + leftcol; ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ gsum += PNM_GET1( *(temprptr + ccol) ) ++ * gweights[crow][ccol]; ++ } ++ tempgsum = gsum + 0.5; ++ CHECK_GRAY; + PNM_ASSIGN1( outputrow[col], g ); +- break; +- } + } ++ } ++ pnm_writepnmrow( stdout, outputrow, cols, maxval, newformat, 0 ); ++ } ++ ++ /* Now write out the remaining unconvolved rows in xelbuf. */ ++ for ( irow = crowso2 + 1; irow < crows; ++irow ) ++ pnm_writepnmrow( ++ stdout, rowptr[irow], cols, maxval, newformat, 0 ); ++ ++ pm_close( stdout ); ++ } ++ ++ ++/* PGM Mean Convolution ++** ++** This is the common case where you just want the target pixel replaced with ++** the average value of its neighbors. This can work much faster than the ++** general case because you can reduce the number of floating point operations ++** that are required since all the weights are the same. You will only need ++** to multiply by the weight once, not for every pixel in the convolution ++** matrix. ++** ++** This algorithm works by creating sums for each column of crows height for ++** the whole width of the image. Then add ccols column sums together to obtain ++** the total sum of the neighbors and multiply that sum by the weight. As you ++** move right to left to calculate the next pixel, take the total sum you just ++** generated, add in the value of the next column and subtract the value of the ++** leftmost column. Multiply that by the weight and that's it. As you move ++** down a row, calculate new column sums by using previous sum for that column ++** and adding in pixel on current row and subtracting pixel in top row. ++** ++*/ ++ ++ ++static void ++pgm_mean_convolve() ++ { ++ register int ccol, col; ++ xel** xelbuf; ++ xel* outputrow; ++ xelval g; ++ int row, crow; ++ xel **rowptr, *temprptr; ++ int leftcol; ++ int i, irow; ++ int toprow, temprow; ++ int subrow, addrow; ++ int subcol, addcol; ++ long gisum; ++ int tempcol, crowsp1; ++ long tempgsum; ++ long *gcolumnsum; ++ ++ /* Allocate space for one convolution-matrix's worth of rows, plus ++ ** a row output buffer. MEAN uses an extra row. */ ++ xelbuf = pnm_allocarray( cols, crows + 1 ); ++ outputrow = pnm_allocrow( cols ); ++ ++ /* Allocate array of pointers to xelbuf. MEAN uses an extra row. */ ++ rowptr = (xel **) pnm_allocarray( 1, crows + 1); ++ ++ /* Allocate space for intermediate column sums */ ++ gcolumnsum = (long *) pm_allocrow( cols, sizeof(long) ); ++ for ( col = 0; col < cols; ++col ) ++ gcolumnsum[col] = 0L; ++ ++ pnm_writepnminit( stdout, cols, rows, maxval, newformat, 0 ); ++ ++ /* Read in one convolution-matrix's worth of image, less one row. */ ++ for ( row = 0; row < crows - 1; ++row ) ++ { ++ pnm_readpnmrow( ifp, xelbuf[row], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[row], cols, maxval, format, maxval, newformat ); ++ /* Write out just the part we're not going to convolve. */ ++ if ( row < crowso2 ) ++ pnm_writepnmrow( stdout, xelbuf[row], cols, maxval, newformat, 0 ); ++ } ++ ++ /* Do first real row only */ ++ subrow = crows; ++ addrow = crows - 1; ++ toprow = row + 1; ++ temprow = row % crows; ++ pnm_readpnmrow( ifp, xelbuf[temprow], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[temprow], cols, maxval, format, maxval, newformat ); ++ ++ temprow = toprow % crows; ++ i = 0; ++ for (irow = temprow; irow < crows; ++i, ++irow) ++ rowptr[i] = xelbuf[irow]; ++ for (irow = 0; irow < temprow; ++irow, ++i) ++ rowptr[i] = xelbuf[irow]; ++ ++ gisum = 0L; ++ for ( col = 0; col < cols; ++col ) ++ { ++ if ( col < ccolso2 || col >= cols - ccolso2 ) ++ outputrow[col] = rowptr[crowso2][col]; ++ else if ( col == ccolso2 ) ++ { ++ leftcol = col - ccolso2; ++ for ( crow = 0; crow < crows; ++crow ) ++ { ++ temprptr = rowptr[crow] + leftcol; ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ gcolumnsum[leftcol + ccol] += ++ PNM_GET1( *(temprptr + ccol) ); ++ } ++ for ( ccol = 0; ccol < ccols; ++ccol) ++ gisum += gcolumnsum[leftcol + ccol]; ++ tempgsum = (float) gisum * gmeanweight + 0.5; ++ CHECK_GRAY; ++ PNM_ASSIGN1( outputrow[col], g ); ++ } ++ else ++ { ++ /* Column numbers to subtract or add to isum */ ++ subcol = col - ccolso2 - 1; ++ addcol = col + ccolso2; ++ for ( crow = 0; crow < crows; ++crow ) ++ gcolumnsum[addcol] += PNM_GET1( rowptr[crow][addcol] ); ++ gisum = gisum - gcolumnsum[subcol] + gcolumnsum[addcol]; ++ tempgsum = (float) gisum * gmeanweight + 0.5; ++ CHECK_GRAY; ++ PNM_ASSIGN1( outputrow[col], g ); ++ } ++ } ++ pnm_writepnmrow( stdout, outputrow, cols, maxval, newformat, 0 ); + ++ ++row; ++ /* For all subsequent rows do it this way as the columnsums have been ++ ** generated. Now we can use them to reduce further calculations. ++ */ ++ crowsp1 = crows + 1; ++ for ( ; row < rows; ++row ) ++ { ++ toprow = row + 1; ++ temprow = row % (crows + 1); ++ pnm_readpnmrow( ifp, xelbuf[temprow], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[temprow], cols, maxval, format, maxval, newformat ); ++ ++ /* This rearrangement using crows+1 rowptrs and xelbufs will cause ++ ** rowptr[0..crows-1] to always hold active xelbufs and for ++ ** rowptr[crows] to always hold the oldest (top most) xelbuf. ++ */ ++ temprow = (toprow + 1) % crowsp1; ++ i = 0; ++ for (irow = temprow; irow < crowsp1; ++i, ++irow) ++ rowptr[i] = xelbuf[irow]; ++ for (irow = 0; irow < temprow; ++irow, ++i) ++ rowptr[i] = xelbuf[irow]; ++ ++ gisum = 0L; ++ for ( col = 0; col < cols; ++col ) ++ { ++ if ( col < ccolso2 || col >= cols - ccolso2 ) ++ outputrow[col] = rowptr[crowso2][col]; ++ else if ( col == ccolso2 ) ++ { ++ leftcol = col - ccolso2; ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ { ++ tempcol = leftcol + ccol; ++ gcolumnsum[tempcol] = gcolumnsum[tempcol] ++ - PNM_GET1( rowptr[subrow][ccol] ) ++ + PNM_GET1( rowptr[addrow][ccol] ); ++ gisum += gcolumnsum[tempcol]; ++ } ++ tempgsum = (float) gisum * gmeanweight + 0.5; ++ CHECK_GRAY; ++ PNM_ASSIGN1( outputrow[col], g ); ++ } ++ else ++ { ++ /* Column numbers to subtract or add to isum */ ++ subcol = col - ccolso2 - 1; ++ addcol = col + ccolso2; ++ gcolumnsum[addcol] = gcolumnsum[addcol] ++ - PNM_GET1( rowptr[subrow][addcol] ) ++ + PNM_GET1( rowptr[addrow][addcol] ); ++ gisum = gisum - gcolumnsum[subcol] + gcolumnsum[addcol]; ++ tempgsum = (float) gisum * gmeanweight + 0.5; ++ CHECK_GRAY; ++ PNM_ASSIGN1( outputrow[col], g ); ++ } ++ } + pnm_writepnmrow( stdout, outputrow, cols, maxval, newformat, 0 ); + } +- pm_close( ifp ); + + /* Now write out the remaining unconvolved rows in xelbuf. */ +- for ( ; row < rows + crowso2; ++row ) ++ for ( irow = crowso2 + 1; irow < crows; ++irow ) + pnm_writepnmrow( +- stdout, xelbuf[(row-crowso2) % crows], cols, maxval, newformat, 0 ); ++ stdout, rowptr[irow], cols, maxval, newformat, 0 ); ++ ++ pm_close( stdout ); ++ } ++ ++ ++/* PGM Horizontal Convolution ++** ++** Similar idea to using columnsums of the Mean and Vertical convolution, ++** but uses temporary sums of row values. Need to multiply by weights crows ++** number of times. Each time a new line is started, must recalculate the ++** initials rowsums for the newest row only. Uses queue to still access ++** previous row sums. ++** ++*/ ++ ++static void ++pgm_horizontal_convolve() ++ { ++ register int ccol, col; ++ xel** xelbuf; ++ xel* outputrow; ++ xel x; ++ xelval g; ++ int row, crow; ++ xel **rowptr, *temprptr; ++ int leftcol; ++ int i, irow; ++ int temprow; ++ int subcol, addcol; ++ float gsum; ++ int addrow, subrow; ++ long **growsum, **growsumptr; ++ int crowsp1; ++ long tempgsum; ++ ++ /* Allocate space for one convolution-matrix's worth of rows, plus ++ ** a row output buffer. */ ++ xelbuf = pnm_allocarray( cols, crows + 1 ); ++ outputrow = pnm_allocrow( cols ); ++ ++ /* Allocate array of pointers to xelbuf */ ++ rowptr = (xel **) pnm_allocarray( 1, crows + 1); ++ ++ /* Allocate intermediate row sums. HORIZONTAL uses an extra row. */ ++ /* crows current rows and 1 extra for newest added row. */ ++ growsum = (long **) pm_allocarray( cols, crows + 1, sizeof(long) ); ++ growsumptr = (long **) pnm_allocarray( 1, crows + 1); ++ ++ pnm_writepnminit( stdout, cols, rows, maxval, newformat, 0 ); ++ ++ /* Read in one convolution-matrix's worth of image, less one row. */ ++ for ( row = 0; row < crows - 1; ++row ) ++ { ++ pnm_readpnmrow( ifp, xelbuf[row], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[row], cols, maxval, format, maxval, newformat ); ++ /* Write out just the part we're not going to convolve. */ ++ if ( row < crowso2 ) ++ pnm_writepnmrow( stdout, xelbuf[row], cols, maxval, newformat, 0 ); ++ } ++ ++ /* First row only */ ++ temprow = row % crows; ++ pnm_readpnmrow( ifp, xelbuf[temprow], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[temprow], cols, maxval, format, maxval, newformat ); ++ ++ temprow = (row + 1) % crows; ++ i = 0; ++ for (irow = temprow; irow < crows; ++i, ++irow) ++ rowptr[i] = xelbuf[irow]; ++ for (irow = 0; irow < temprow; ++irow, ++i) ++ rowptr[i] = xelbuf[irow]; ++ ++ for ( crow = 0; crow < crows; ++crow ) ++ growsumptr[crow] = growsum[crow]; ++ ++ for ( col = 0; col < cols; ++col ) ++ { ++ if ( col < ccolso2 || col >= cols - ccolso2 ) ++ outputrow[col] = rowptr[crowso2][col]; ++ else if ( col == ccolso2 ) ++ { ++ leftcol = col - ccolso2; ++ gsum = 0.0; ++ for ( crow = 0; crow < crows; ++crow ) ++ { ++ temprptr = rowptr[crow] + leftcol; ++ growsumptr[crow][leftcol] = 0L; ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ growsumptr[crow][leftcol] += ++ PNM_GET1( *(temprptr + ccol) ); ++ gsum += growsumptr[crow][leftcol] * gweights[crow][0]; ++ } ++ tempgsum = gsum + 0.5; ++ CHECK_GRAY; ++ PNM_ASSIGN1( outputrow[col], g ); ++ } ++ else ++ { ++ gsum = 0.0; ++ leftcol = col - ccolso2; ++ subcol = col - ccolso2 - 1; ++ addcol = col + ccolso2; ++ for ( crow = 0; crow < crows; ++crow ) ++ { ++ growsumptr[crow][leftcol] = growsumptr[crow][subcol] ++ - PNM_GET1( rowptr[crow][subcol] ) ++ + PNM_GET1( rowptr[crow][addcol] ); ++ gsum += growsumptr[crow][leftcol] * gweights[crow][0]; ++ } ++ tempgsum = gsum + 0.5; ++ CHECK_GRAY; ++ PNM_ASSIGN1( outputrow[col], g ); ++ } ++ } ++ pnm_writepnmrow( stdout, outputrow, cols, maxval, newformat, 0 ); ++ ++ ++ /* For all subsequent rows */ ++ ++ subrow = crows; ++ addrow = crows - 1; ++ crowsp1 = crows + 1; ++ ++row; ++ for ( ; row < rows; ++row ) ++ { ++ temprow = row % crowsp1; ++ pnm_readpnmrow( ifp, xelbuf[temprow], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[temprow], cols, maxval, format, maxval, newformat ); ++ ++ temprow = (row + 2) % crowsp1; ++ i = 0; ++ for (irow = temprow; irow < crowsp1; ++i, ++irow) ++ { ++ rowptr[i] = xelbuf[irow]; ++ growsumptr[i] = growsum[irow]; ++ } ++ for (irow = 0; irow < temprow; ++irow, ++i) ++ { ++ rowptr[i] = xelbuf[irow]; ++ growsumptr[i] = growsum[irow]; ++ } ++ ++ for ( col = 0; col < cols; ++col ) ++ { ++ if ( col < ccolso2 || col >= cols - ccolso2 ) ++ outputrow[col] = rowptr[crowso2][col]; ++ else if ( col == ccolso2 ) ++ { ++ gsum = 0.0; ++ leftcol = col - ccolso2; ++ growsumptr[addrow][leftcol] = 0L; ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ growsumptr[addrow][leftcol] += ++ PNM_GET1( rowptr[addrow][leftcol + ccol] ); ++ for ( crow = 0; crow < crows; ++crow ) ++ gsum += growsumptr[crow][leftcol] * gweights[crow][0]; ++ tempgsum = gsum + 0.5; ++ CHECK_GRAY; ++ PNM_ASSIGN1( outputrow[col], g ); ++ } ++ else ++ { ++ gsum = 0.0; ++ leftcol = col - ccolso2; ++ subcol = col - ccolso2 - 1; ++ addcol = col + ccolso2; ++ growsumptr[addrow][leftcol] = growsumptr[addrow][subcol] ++ - PNM_GET1( rowptr[addrow][subcol] ) ++ + PNM_GET1( rowptr[addrow][addcol] ); ++ for ( crow = 0; crow < crows; ++crow ) ++ gsum += growsumptr[crow][leftcol] * gweights[crow][0]; ++ tempgsum = gsum + 0.5; ++ CHECK_GRAY; ++ PNM_ASSIGN1( outputrow[col], g ); ++ } ++ } ++ pnm_writepnmrow( stdout, outputrow, cols, maxval, newformat, 0 ); ++ } ++ ++ /* Now write out the remaining unconvolved rows in xelbuf. */ ++ for ( irow = crowso2 + 1; irow < crows; ++irow ) ++ pnm_writepnmrow( ++ stdout, rowptr[irow], cols, maxval, newformat, 0 ); ++ ++ pm_close( stdout ); ++ } ++ ++ ++/* PGM Vertical Convolution ++** ++** Uses column sums as in Mean Convolution. ++** ++*/ ++ ++ ++static void ++pgm_vertical_convolve() ++ { ++ register int ccol, col; ++ xel** xelbuf; ++ xel* outputrow; ++ xelval g; ++ int row, crow; ++ xel **rowptr, *temprptr; ++ int leftcol; ++ int i, irow; ++ int toprow, temprow; ++ int subrow, addrow; ++ int tempcol; ++ float gsum; ++ long *gcolumnsum; ++ int crowsp1; ++ int addcol; ++ long tempgsum; ++ ++ /* Allocate space for one convolution-matrix's worth of rows, plus ++ ** a row output buffer. VERTICAL uses an extra row. */ ++ xelbuf = pnm_allocarray( cols, crows + 1 ); ++ outputrow = pnm_allocrow( cols ); ++ ++ /* Allocate array of pointers to xelbuf */ ++ rowptr = (xel **) pnm_allocarray( 1, crows + 1 ); ++ ++ /* Allocate space for intermediate column sums */ ++ gcolumnsum = (long *) pm_allocrow( cols, sizeof(long) ); ++ for ( col = 0; col < cols; ++col ) ++ gcolumnsum[col] = 0L; ++ ++ pnm_writepnminit( stdout, cols, rows, maxval, newformat, 0 ); ++ ++ /* Read in one convolution-matrix's worth of image, less one row. */ ++ for ( row = 0; row < crows - 1; ++row ) ++ { ++ pnm_readpnmrow( ifp, xelbuf[row], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[row], cols, maxval, format, maxval, newformat ); ++ /* Write out just the part we're not going to convolve. */ ++ if ( row < crowso2 ) ++ pnm_writepnmrow( stdout, xelbuf[row], cols, maxval, newformat, 0 ); ++ } ++ ++ /* Now the rest of the image - read in the row at the end of ++ ** xelbuf, and convolve and write out the row in the middle. ++ */ ++ /* For first row only */ ++ ++ toprow = row + 1; ++ temprow = row % crows; ++ pnm_readpnmrow( ifp, xelbuf[temprow], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[temprow], cols, maxval, format, maxval, newformat ); ++ ++ /* Arrange rowptr to eliminate the use of mod function to determine ++ ** which row of xelbuf is 0...crows. Mod function can be very costly. ++ */ ++ temprow = toprow % crows; ++ i = 0; ++ for (irow = temprow; irow < crows; ++i, ++irow) ++ rowptr[i] = xelbuf[irow]; ++ for (irow = 0; irow < temprow; ++irow, ++i) ++ rowptr[i] = xelbuf[irow]; ++ ++ for ( col = 0; col < cols; ++col ) ++ { ++ if ( col < ccolso2 || col >= cols - ccolso2 ) ++ outputrow[col] = rowptr[crowso2][col]; ++ else if ( col == ccolso2 ) ++ { ++ gsum = 0.0; ++ leftcol = col - ccolso2; ++ for ( crow = 0; crow < crows; ++crow ) ++ { ++ temprptr = rowptr[crow] + leftcol; ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ gcolumnsum[leftcol + ccol] += ++ PNM_GET1( *(temprptr + ccol) ); ++ } ++ for ( ccol = 0; ccol < ccols; ++ccol) ++ gsum += gcolumnsum[leftcol + ccol] * gweights[0][ccol]; ++ tempgsum = gsum + 0.5; ++ CHECK_GRAY; ++ PNM_ASSIGN1( outputrow[col], g ); ++ } ++ else ++ { ++ gsum = 0.0; ++ leftcol = col - ccolso2; ++ addcol = col + ccolso2; ++ for ( crow = 0; crow < crows; ++crow ) ++ gcolumnsum[addcol] += PNM_GET1( rowptr[crow][addcol] ); ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ gsum += gcolumnsum[leftcol + ccol] * gweights[0][ccol]; ++ tempgsum = gsum + 0.5; ++ CHECK_GRAY; ++ PNM_ASSIGN1( outputrow[col], g ); ++ } ++ } ++ pnm_writepnmrow( stdout, outputrow, cols, maxval, newformat, 0 ); ++ ++ /* For all subsequent rows */ ++ subrow = crows; ++ addrow = crows - 1; ++ crowsp1 = crows + 1; ++ ++row; ++ for ( ; row < rows; ++row ) ++ { ++ toprow = row + 1; ++ temprow = row % (crows +1); ++ pnm_readpnmrow( ifp, xelbuf[temprow], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[temprow], cols, maxval, format, maxval, newformat ); ++ ++ /* Arrange rowptr to eliminate the use of mod function to determine ++ ** which row of xelbuf is 0...crows. Mod function can be very costly. ++ */ ++ temprow = (toprow + 1) % crowsp1; ++ i = 0; ++ for (irow = temprow; irow < crowsp1; ++i, ++irow) ++ rowptr[i] = xelbuf[irow]; ++ for (irow = 0; irow < temprow; ++irow, ++i) ++ rowptr[i] = xelbuf[irow]; ++ ++ for ( col = 0; col < cols; ++col ) ++ { ++ if ( col < ccolso2 || col >= cols - ccolso2 ) ++ outputrow[col] = rowptr[crowso2][col]; ++ else if ( col == ccolso2 ) ++ { ++ gsum = 0.0; ++ leftcol = col - ccolso2; ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ { ++ tempcol = leftcol + ccol; ++ gcolumnsum[tempcol] = gcolumnsum[tempcol] ++ - PNM_GET1( rowptr[subrow][ccol] ) ++ + PNM_GET1( rowptr[addrow][ccol] ); ++ gsum = gsum + gcolumnsum[tempcol] * gweights[0][ccol]; ++ } ++ tempgsum = gsum + 0.5; ++ CHECK_GRAY; ++ PNM_ASSIGN1( outputrow[col], g ); ++ } ++ else ++ { ++ gsum = 0.0; ++ leftcol = col - ccolso2; ++ addcol = col + ccolso2; ++ gcolumnsum[addcol] = gcolumnsum[addcol] ++ - PNM_GET1( rowptr[subrow][addcol] ) ++ + PNM_GET1( rowptr[addrow][addcol] ); ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ gsum += gcolumnsum[leftcol + ccol] * gweights[0][ccol]; ++ tempgsum = gsum + 0.5; ++ CHECK_GRAY; ++ PNM_ASSIGN1( outputrow[col], g ); ++ } ++ } ++ pnm_writepnmrow( stdout, outputrow, cols, maxval, newformat, 0 ); ++ } ++ ++ /* Now write out the remaining unconvolved rows in xelbuf. */ ++ for ( irow = crowso2 + 1; irow < crows; ++irow ) ++ pnm_writepnmrow( ++ stdout, rowptr[irow], cols, maxval, newformat, 0 ); ++ ++ pm_close( stdout ); ++ } ++ ++ ++ ++ ++/* PPM General Convolution Algorithm ++** ++** No redundancy in convolution matrix. Just use brute force. ++** See pgm_general_convolve() for more details. ++*/ ++ ++static void ++ppm_general_convolve() ++ { ++ register int ccol, col; ++ xel** xelbuf; ++ xel* outputrow; ++ xel x, y; ++ xelval r, g, b; ++ int row, crow; ++ float rsum, gsum, bsum; ++ xel **rowptr, *temprptr; ++ int toprow, temprow; ++ int i, irow; ++ int leftcol; ++ long temprsum, tempgsum, tempbsum; ++ ++ /* Allocate space for one convolution-matrix's worth of rows, plus ++ ** a row output buffer. */ ++ xelbuf = pnm_allocarray( cols, crows ); ++ outputrow = pnm_allocrow( cols ); ++ ++ /* Allocate array of pointers to xelbuf */ ++ rowptr = (xel **) pnm_allocarray( 1, crows ); ++ ++ pnm_writepnminit( stdout, cols, rows, maxval, newformat, 0 ); ++ ++ /* Read in one convolution-matrix's worth of image, less one row. */ ++ for ( row = 0; row < crows - 1; ++row ) ++ { ++ pnm_readpnmrow( ifp, xelbuf[row], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[row], cols, maxval, format, maxval, newformat ); ++ /* Write out just the part we're not going to convolve. */ ++ if ( row < crowso2 ) ++ pnm_writepnmrow( stdout, xelbuf[row], cols, maxval, newformat, 0 ); ++ } ++ ++ /* Now the rest of the image - read in the row at the end of ++ ** xelbuf, and convolve and write out the row in the middle. ++ */ ++ for ( ; row < rows; ++row ) ++ { ++ toprow = row + 1; ++ temprow = row % crows; ++ pnm_readpnmrow( ifp, xelbuf[temprow], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[temprow], cols, maxval, format, maxval, newformat ); ++ ++ /* Arrange rowptr to eliminate the use of mod function to determine ++ ** which row of xelbuf is 0...crows. Mod function can be very costly. ++ */ ++ temprow = toprow % crows; ++ i = 0; ++ for (irow = temprow; irow < crows; ++i, ++irow) ++ rowptr[i] = xelbuf[irow]; ++ for (irow = 0; irow < temprow; ++irow, ++i) ++ rowptr[i] = xelbuf[irow]; ++ ++ for ( col = 0; col < cols; ++col ) ++ { ++ if ( col < ccolso2 || col >= cols - ccolso2 ) ++ outputrow[col] = rowptr[crowso2][col]; ++ else ++ { ++ leftcol = col - ccolso2; ++ rsum = gsum = bsum = 0.0; ++ for ( crow = 0; crow < crows; ++crow ) ++ { ++ temprptr = rowptr[crow] + leftcol; ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ { ++ rsum += PPM_GETR( *(temprptr + ccol) ) ++ * rweights[crow][ccol]; ++ gsum += PPM_GETG( *(temprptr + ccol) ) ++ * gweights[crow][ccol]; ++ bsum += PPM_GETB( *(temprptr + ccol) ) ++ * bweights[crow][ccol]; ++ } ++ } ++ temprsum = rsum + 0.5; ++ tempgsum = gsum + 0.5; ++ tempbsum = bsum + 0.5; ++ CHECK_RED; ++ CHECK_GREEN; ++ CHECK_BLUE; ++ PPM_ASSIGN( outputrow[col], r, g, b ); ++ } ++ } ++ pnm_writepnmrow( stdout, outputrow, cols, maxval, newformat, 0 ); ++ } ++ ++ /* Now write out the remaining unconvolved rows in xelbuf. */ ++ for ( irow = crowso2 + 1; irow < crows; ++irow ) ++ pnm_writepnmrow( ++ stdout, rowptr[irow], cols, maxval, newformat, 0 ); ++ ++ pm_close( stdout ); ++ } ++ ++ ++/* PPM Mean Convolution ++** ++** Same as pgm_mean_convolve() but for PPM. ++** ++*/ ++ ++static void ++ppm_mean_convolve() ++ { ++ register int ccol, col; ++ xel** xelbuf; ++ xel* outputrow; ++ xelval r, g, b; ++ int row, crow; ++ xel **rowptr, *temprptr; ++ int leftcol; ++ int i, irow; ++ int toprow, temprow; ++ int subrow, addrow; ++ int subcol, addcol; ++ long risum, gisum, bisum; ++ float rsum, gsum, bsum; ++ long temprsum, tempgsum, tempbsum; ++ int tempcol, crowsp1; ++ long *rcolumnsum, *gcolumnsum, *bcolumnsum; ++ ++ /* Allocate space for one convolution-matrix's worth of rows, plus ++ ** a row output buffer. MEAN uses an extra row. */ ++ xelbuf = pnm_allocarray( cols, crows + 1 ); ++ outputrow = pnm_allocrow( cols ); ++ ++ /* Allocate array of pointers to xelbuf. MEAN uses an extra row. */ ++ rowptr = (xel **) pnm_allocarray( 1, crows + 1); ++ ++ /* Allocate space for intermediate column sums */ ++ rcolumnsum = (long *) pm_allocrow( cols, sizeof(long) ); ++ gcolumnsum = (long *) pm_allocrow( cols, sizeof(long) ); ++ bcolumnsum = (long *) pm_allocrow( cols, sizeof(long) ); ++ for ( col = 0; col < cols; ++col ) ++ { ++ rcolumnsum[col] = 0L; ++ gcolumnsum[col] = 0L; ++ bcolumnsum[col] = 0L; ++ } ++ ++ pnm_writepnminit( stdout, cols, rows, maxval, newformat, 0 ); ++ ++ /* Read in one convolution-matrix's worth of image, less one row. */ ++ for ( row = 0; row < crows - 1; ++row ) ++ { ++ pnm_readpnmrow( ifp, xelbuf[row], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[row], cols, maxval, format, maxval, newformat ); ++ /* Write out just the part we're not going to convolve. */ ++ if ( row < crowso2 ) ++ pnm_writepnmrow( stdout, xelbuf[row], cols, maxval, newformat, 0 ); ++ } ++ ++ /* Do first real row only */ ++ subrow = crows; ++ addrow = crows - 1; ++ toprow = row + 1; ++ temprow = row % crows; ++ pnm_readpnmrow( ifp, xelbuf[temprow], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[temprow], cols, maxval, format, maxval, newformat ); ++ ++ temprow = toprow % crows; ++ i = 0; ++ for (irow = temprow; irow < crows; ++i, ++irow) ++ rowptr[i] = xelbuf[irow]; ++ for (irow = 0; irow < temprow; ++irow, ++i) ++ rowptr[i] = xelbuf[irow]; ++ ++ risum = 0L; ++ gisum = 0L; ++ bisum = 0L; ++ for ( col = 0; col < cols; ++col ) ++ { ++ if ( col < ccolso2 || col >= cols - ccolso2 ) ++ outputrow[col] = rowptr[crowso2][col]; ++ else if ( col == ccolso2 ) ++ { ++ leftcol = col - ccolso2; ++ for ( crow = 0; crow < crows; ++crow ) ++ { ++ temprptr = rowptr[crow] + leftcol; ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ { ++ rcolumnsum[leftcol + ccol] += ++ PPM_GETR( *(temprptr + ccol) ); ++ gcolumnsum[leftcol + ccol] += ++ PPM_GETG( *(temprptr + ccol) ); ++ bcolumnsum[leftcol + ccol] += ++ PPM_GETB( *(temprptr + ccol) ); ++ } ++ } ++ for ( ccol = 0; ccol < ccols; ++ccol) ++ { ++ risum += rcolumnsum[leftcol + ccol]; ++ gisum += gcolumnsum[leftcol + ccol]; ++ bisum += bcolumnsum[leftcol + ccol]; ++ } ++ temprsum = (float) risum * rmeanweight + 0.5; ++ tempgsum = (float) gisum * gmeanweight + 0.5; ++ tempbsum = (float) bisum * bmeanweight + 0.5; ++ CHECK_RED; ++ CHECK_GREEN; ++ CHECK_BLUE; ++ PPM_ASSIGN( outputrow[col], r, g, b ); ++ } ++ else ++ { ++ /* Column numbers to subtract or add to isum */ ++ subcol = col - ccolso2 - 1; ++ addcol = col + ccolso2; ++ for ( crow = 0; crow < crows; ++crow ) ++ { ++ rcolumnsum[addcol] += PPM_GETR( rowptr[crow][addcol] ); ++ gcolumnsum[addcol] += PPM_GETG( rowptr[crow][addcol] ); ++ bcolumnsum[addcol] += PPM_GETB( rowptr[crow][addcol] ); ++ } ++ risum = risum - rcolumnsum[subcol] + rcolumnsum[addcol]; ++ gisum = gisum - gcolumnsum[subcol] + gcolumnsum[addcol]; ++ bisum = bisum - bcolumnsum[subcol] + bcolumnsum[addcol]; ++ temprsum = (float) risum * rmeanweight + 0.5; ++ tempgsum = (float) gisum * gmeanweight + 0.5; ++ tempbsum = (float) bisum * bmeanweight + 0.5; ++ CHECK_RED; ++ CHECK_GREEN; ++ CHECK_BLUE; ++ PPM_ASSIGN( outputrow[col], r, g, b ); ++ } ++ } ++ pnm_writepnmrow( stdout, outputrow, cols, maxval, newformat, 0 ); ++ ++ ++row; ++ /* For all subsequent rows do it this way as the columnsums have been ++ ** generated. Now we can use them to reduce further calculations. ++ */ ++ crowsp1 = crows + 1; ++ for ( ; row < rows; ++row ) ++ { ++ toprow = row + 1; ++ temprow = row % (crows + 1); ++ pnm_readpnmrow( ifp, xelbuf[temprow], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[temprow], cols, maxval, format, maxval, newformat ); ++ ++ /* This rearrangement using crows+1 rowptrs and xelbufs will cause ++ ** rowptr[0..crows-1] to always hold active xelbufs and for ++ ** rowptr[crows] to always hold the oldest (top most) xelbuf. ++ */ ++ temprow = (toprow + 1) % crowsp1; ++ i = 0; ++ for (irow = temprow; irow < crowsp1; ++i, ++irow) ++ rowptr[i] = xelbuf[irow]; ++ for (irow = 0; irow < temprow; ++irow, ++i) ++ rowptr[i] = xelbuf[irow]; ++ ++ risum = 0L; ++ gisum = 0L; ++ bisum = 0L; ++ for ( col = 0; col < cols; ++col ) ++ { ++ if ( col < ccolso2 || col >= cols - ccolso2 ) ++ outputrow[col] = rowptr[crowso2][col]; ++ else if ( col == ccolso2 ) ++ { ++ leftcol = col - ccolso2; ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ { ++ tempcol = leftcol + ccol; ++ rcolumnsum[tempcol] = rcolumnsum[tempcol] ++ - PPM_GETR( rowptr[subrow][ccol] ) ++ + PPM_GETR( rowptr[addrow][ccol] ); ++ risum += rcolumnsum[tempcol]; ++ gcolumnsum[tempcol] = gcolumnsum[tempcol] ++ - PPM_GETG( rowptr[subrow][ccol] ) ++ + PPM_GETG( rowptr[addrow][ccol] ); ++ gisum += gcolumnsum[tempcol]; ++ bcolumnsum[tempcol] = bcolumnsum[tempcol] ++ - PPM_GETB( rowptr[subrow][ccol] ) ++ + PPM_GETB( rowptr[addrow][ccol] ); ++ bisum += bcolumnsum[tempcol]; ++ } ++ temprsum = (float) risum * rmeanweight + 0.5; ++ tempgsum = (float) gisum * gmeanweight + 0.5; ++ tempbsum = (float) bisum * bmeanweight + 0.5; ++ CHECK_RED; ++ CHECK_GREEN; ++ CHECK_BLUE; ++ PPM_ASSIGN( outputrow[col], r, g, b ); ++ } ++ else ++ { ++ /* Column numbers to subtract or add to isum */ ++ subcol = col - ccolso2 - 1; ++ addcol = col + ccolso2; ++ rcolumnsum[addcol] = rcolumnsum[addcol] ++ - PPM_GETR( rowptr[subrow][addcol] ) ++ + PPM_GETR( rowptr[addrow][addcol] ); ++ risum = risum - rcolumnsum[subcol] + rcolumnsum[addcol]; ++ gcolumnsum[addcol] = gcolumnsum[addcol] ++ - PPM_GETG( rowptr[subrow][addcol] ) ++ + PPM_GETG( rowptr[addrow][addcol] ); ++ gisum = gisum - gcolumnsum[subcol] + gcolumnsum[addcol]; ++ bcolumnsum[addcol] = bcolumnsum[addcol] ++ - PPM_GETB( rowptr[subrow][addcol] ) ++ + PPM_GETB( rowptr[addrow][addcol] ); ++ bisum = bisum - bcolumnsum[subcol] + bcolumnsum[addcol]; ++ temprsum = (float) risum * rmeanweight + 0.5; ++ tempgsum = (float) gisum * gmeanweight + 0.5; ++ tempbsum = (float) bisum * bmeanweight + 0.5; ++ CHECK_RED; ++ CHECK_GREEN; ++ CHECK_BLUE; ++ PPM_ASSIGN( outputrow[col], r, g, b ); ++ } ++ } ++ pnm_writepnmrow( stdout, outputrow, cols, maxval, newformat, 0 ); ++ } ++ ++ /* Now write out the remaining unconvolved rows in xelbuf. */ ++ for ( irow = crowso2 + 1; irow < crows; ++irow ) ++ pnm_writepnmrow( ++ stdout, rowptr[irow], cols, maxval, newformat, 0 ); ++ ++ pm_close( stdout ); ++ } ++ ++ ++/* PPM Horizontal Convolution ++** ++** Same as pgm_horizontal_convolve() ++** ++**/ ++ ++static void ++ppm_horizontal_convolve() ++ { ++ register int ccol, col; ++ xel** xelbuf; ++ xel* outputrow; ++ xel x; ++ xelval r, g, b; ++ int row, crow; ++ xel **rowptr, *temprptr; ++ int leftcol; ++ int i, irow; ++ int temprow; ++ int subcol, addcol; ++ float rsum, gsum, bsum; ++ int addrow, subrow; ++ long **rrowsum, **rrowsumptr; ++ long **growsum, **growsumptr; ++ long **browsum, **browsumptr; ++ int crowsp1; ++ long temprsum, tempgsum, tempbsum; ++ ++ /* Allocate space for one convolution-matrix's worth of rows, plus ++ ** a row output buffer. */ ++ xelbuf = pnm_allocarray( cols, crows + 1 ); ++ outputrow = pnm_allocrow( cols ); ++ ++ /* Allocate array of pointers to xelbuf */ ++ rowptr = (xel **) pnm_allocarray( 1, crows + 1); ++ ++ /* Allocate intermediate row sums. HORIZONTAL uses an extra row */ ++ rrowsum = (long **) pm_allocarray( cols, crows + 1, sizeof(long) ); ++ rrowsumptr = (long **) pnm_allocarray( 1, crows + 1); ++ growsum = (long **) pm_allocarray( cols, crows + 1, sizeof(long) ); ++ growsumptr = (long **) pnm_allocarray( 1, crows + 1); ++ browsum = (long **) pm_allocarray( cols, crows + 1, sizeof(long) ); ++ browsumptr = (long **) pnm_allocarray( 1, crows + 1); ++ ++ pnm_writepnminit( stdout, cols, rows, maxval, newformat, 0 ); ++ ++ /* Read in one convolution-matrix's worth of image, less one row. */ ++ for ( row = 0; row < crows - 1; ++row ) ++ { ++ pnm_readpnmrow( ifp, xelbuf[row], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[row], cols, maxval, format, maxval, newformat ); ++ /* Write out just the part we're not going to convolve. */ ++ if ( row < crowso2 ) ++ pnm_writepnmrow( stdout, xelbuf[row], cols, maxval, newformat, 0 ); ++ } ++ ++ /* First row only */ ++ temprow = row % crows; ++ pnm_readpnmrow( ifp, xelbuf[temprow], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[temprow], cols, maxval, format, maxval, newformat ); ++ ++ temprow = (row + 1) % crows; ++ i = 0; ++ for (irow = temprow; irow < crows; ++i, ++irow) ++ rowptr[i] = xelbuf[irow]; ++ for (irow = 0; irow < temprow; ++irow, ++i) ++ rowptr[i] = xelbuf[irow]; ++ ++ for ( crow = 0; crow < crows; ++crow ) ++ { ++ rrowsumptr[crow] = rrowsum[crow]; ++ growsumptr[crow] = growsum[crow]; ++ browsumptr[crow] = browsum[crow]; ++ } ++ ++ for ( col = 0; col < cols; ++col ) ++ { ++ if ( col < ccolso2 || col >= cols - ccolso2 ) ++ outputrow[col] = rowptr[crowso2][col]; ++ else if ( col == ccolso2 ) ++ { ++ leftcol = col - ccolso2; ++ rsum = 0.0; ++ gsum = 0.0; ++ bsum = 0.0; ++ for ( crow = 0; crow < crows; ++crow ) ++ { ++ temprptr = rowptr[crow] + leftcol; ++ rrowsumptr[crow][leftcol] = 0L; ++ growsumptr[crow][leftcol] = 0L; ++ browsumptr[crow][leftcol] = 0L; ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ { ++ rrowsumptr[crow][leftcol] += ++ PPM_GETR( *(temprptr + ccol) ); ++ growsumptr[crow][leftcol] += ++ PPM_GETG( *(temprptr + ccol) ); ++ browsumptr[crow][leftcol] += ++ PPM_GETB( *(temprptr + ccol) ); ++ } ++ rsum += rrowsumptr[crow][leftcol] * rweights[crow][0]; ++ gsum += growsumptr[crow][leftcol] * gweights[crow][0]; ++ bsum += browsumptr[crow][leftcol] * bweights[crow][0]; ++ } ++ temprsum = rsum + 0.5; ++ tempgsum = gsum + 0.5; ++ tempbsum = bsum + 0.5; ++ CHECK_RED; ++ CHECK_GREEN; ++ CHECK_BLUE; ++ PPM_ASSIGN( outputrow[col], r, g, b ); ++ } ++ else ++ { ++ rsum = 0.0; ++ gsum = 0.0; ++ bsum = 0.0; ++ leftcol = col - ccolso2; ++ subcol = col - ccolso2 - 1; ++ addcol = col + ccolso2; ++ for ( crow = 0; crow < crows; ++crow ) ++ { ++ rrowsumptr[crow][leftcol] = rrowsumptr[crow][subcol] ++ - PPM_GETR( rowptr[crow][subcol] ) ++ + PPM_GETR( rowptr[crow][addcol] ); ++ rsum += rrowsumptr[crow][leftcol] * rweights[crow][0]; ++ growsumptr[crow][leftcol] = growsumptr[crow][subcol] ++ - PPM_GETG( rowptr[crow][subcol] ) ++ + PPM_GETG( rowptr[crow][addcol] ); ++ gsum += growsumptr[crow][leftcol] * gweights[crow][0]; ++ browsumptr[crow][leftcol] = browsumptr[crow][subcol] ++ - PPM_GETB( rowptr[crow][subcol] ) ++ + PPM_GETB( rowptr[crow][addcol] ); ++ bsum += browsumptr[crow][leftcol] * bweights[crow][0]; ++ } ++ temprsum = rsum + 0.5; ++ tempgsum = gsum + 0.5; ++ tempbsum = bsum + 0.5; ++ CHECK_RED; ++ CHECK_GREEN; ++ CHECK_BLUE; ++ PPM_ASSIGN( outputrow[col], r, g, b ); ++ } ++ } ++ pnm_writepnmrow( stdout, outputrow, cols, maxval, newformat, 0 ); ++ ++ ++ /* For all subsequent rows */ ++ ++ subrow = crows; ++ addrow = crows - 1; ++ crowsp1 = crows + 1; ++ ++row; ++ for ( ; row < rows; ++row ) ++ { ++ temprow = row % crowsp1; ++ pnm_readpnmrow( ifp, xelbuf[temprow], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[temprow], cols, maxval, format, maxval, newformat ); ++ ++ temprow = (row + 2) % crowsp1; ++ i = 0; ++ for (irow = temprow; irow < crowsp1; ++i, ++irow) ++ { ++ rowptr[i] = xelbuf[irow]; ++ rrowsumptr[i] = rrowsum[irow]; ++ growsumptr[i] = growsum[irow]; ++ browsumptr[i] = browsum[irow]; ++ } ++ for (irow = 0; irow < temprow; ++irow, ++i) ++ { ++ rowptr[i] = xelbuf[irow]; ++ rrowsumptr[i] = rrowsum[irow]; ++ growsumptr[i] = growsum[irow]; ++ browsumptr[i] = browsum[irow]; ++ } ++ ++ for ( col = 0; col < cols; ++col ) ++ { ++ if ( col < ccolso2 || col >= cols - ccolso2 ) ++ outputrow[col] = rowptr[crowso2][col]; ++ else if ( col == ccolso2 ) ++ { ++ rsum = 0.0; ++ gsum = 0.0; ++ bsum = 0.0; ++ leftcol = col - ccolso2; ++ rrowsumptr[addrow][leftcol] = 0L; ++ growsumptr[addrow][leftcol] = 0L; ++ browsumptr[addrow][leftcol] = 0L; ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ { ++ rrowsumptr[addrow][leftcol] += ++ PPM_GETR( rowptr[addrow][leftcol + ccol] ); ++ growsumptr[addrow][leftcol] += ++ PPM_GETG( rowptr[addrow][leftcol + ccol] ); ++ browsumptr[addrow][leftcol] += ++ PPM_GETB( rowptr[addrow][leftcol + ccol] ); ++ } ++ for ( crow = 0; crow < crows; ++crow ) ++ { ++ rsum += rrowsumptr[crow][leftcol] * rweights[crow][0]; ++ gsum += growsumptr[crow][leftcol] * gweights[crow][0]; ++ bsum += browsumptr[crow][leftcol] * bweights[crow][0]; ++ } ++ temprsum = rsum + 0.5; ++ tempgsum = gsum + 0.5; ++ tempbsum = bsum + 0.5; ++ CHECK_RED; ++ CHECK_GREEN; ++ CHECK_BLUE; ++ PPM_ASSIGN( outputrow[col], r, g, b ); ++ } ++ else ++ { ++ rsum = 0.0; ++ gsum = 0.0; ++ bsum = 0.0; ++ leftcol = col - ccolso2; ++ subcol = col - ccolso2 - 1; ++ addcol = col + ccolso2; ++ rrowsumptr[addrow][leftcol] = rrowsumptr[addrow][subcol] ++ - PPM_GETR( rowptr[addrow][subcol] ) ++ + PPM_GETR( rowptr[addrow][addcol] ); ++ growsumptr[addrow][leftcol] = growsumptr[addrow][subcol] ++ - PPM_GETG( rowptr[addrow][subcol] ) ++ + PPM_GETG( rowptr[addrow][addcol] ); ++ browsumptr[addrow][leftcol] = browsumptr[addrow][subcol] ++ - PPM_GETB( rowptr[addrow][subcol] ) ++ + PPM_GETB( rowptr[addrow][addcol] ); ++ for ( crow = 0; crow < crows; ++crow ) ++ { ++ rsum += rrowsumptr[crow][leftcol] * rweights[crow][0]; ++ gsum += growsumptr[crow][leftcol] * gweights[crow][0]; ++ bsum += browsumptr[crow][leftcol] * bweights[crow][0]; ++ } ++ temprsum = rsum + 0.5; ++ tempgsum = gsum + 0.5; ++ tempbsum = bsum + 0.5; ++ CHECK_RED; ++ CHECK_GREEN; ++ CHECK_BLUE; ++ PPM_ASSIGN( outputrow[col], r, g, b ); ++ } ++ } ++ pnm_writepnmrow( stdout, outputrow, cols, maxval, newformat, 0 ); ++ } ++ ++ /* Now write out the remaining unconvolved rows in xelbuf. */ ++ for ( irow = crowso2 + 1; irow < crows; ++irow ) ++ pnm_writepnmrow( ++ stdout, rowptr[irow], cols, maxval, newformat, 0 ); ++ ++ pm_close( stdout ); ++ } ++ ++ ++/* PPM Vertical Convolution ++** ++** Same as pgm_vertical_convolve() ++** ++*/ ++ ++static void ++ppm_vertical_convolve() ++ { ++ register int ccol, col; ++ xel** xelbuf; ++ xel* outputrow; ++ xelval r, g, b; ++ int row, crow; ++ xel **rowptr, *temprptr; ++ int leftcol; ++ int i, irow; ++ int toprow, temprow; ++ int subrow, addrow; ++ int tempcol; ++ float rsum, gsum, bsum; ++ long *rcolumnsum, *gcolumnsum, *bcolumnsum; ++ int crowsp1; ++ int addcol; ++ long temprsum, tempgsum, tempbsum; ++ ++ /* Allocate space for one convolution-matrix's worth of rows, plus ++ ** a row output buffer. VERTICAL uses an extra row. */ ++ xelbuf = pnm_allocarray( cols, crows + 1 ); ++ outputrow = pnm_allocrow( cols ); ++ ++ /* Allocate array of pointers to xelbuf */ ++ rowptr = (xel **) pnm_allocarray( 1, crows + 1 ); ++ ++ /* Allocate space for intermediate column sums */ ++ rcolumnsum = (long *) pm_allocrow( cols, sizeof(long) ); ++ gcolumnsum = (long *) pm_allocrow( cols, sizeof(long) ); ++ bcolumnsum = (long *) pm_allocrow( cols, sizeof(long) ); ++ for ( col = 0; col < cols; ++col ) ++ { ++ rcolumnsum[col] = 0L; ++ gcolumnsum[col] = 0L; ++ bcolumnsum[col] = 0L; ++ } ++ ++ pnm_writepnminit( stdout, cols, rows, maxval, newformat, 0 ); ++ ++ /* Read in one convolution-matrix's worth of image, less one row. */ ++ for ( row = 0; row < crows - 1; ++row ) ++ { ++ pnm_readpnmrow( ifp, xelbuf[row], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[row], cols, maxval, format, maxval, newformat ); ++ /* Write out just the part we're not going to convolve. */ ++ if ( row < crowso2 ) ++ pnm_writepnmrow( stdout, xelbuf[row], cols, maxval, newformat, 0 ); ++ } ++ ++ /* Now the rest of the image - read in the row at the end of ++ ** xelbuf, and convolve and write out the row in the middle. ++ */ ++ /* For first row only */ ++ ++ toprow = row + 1; ++ temprow = row % crows; ++ pnm_readpnmrow( ifp, xelbuf[temprow], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[temprow], cols, maxval, format, maxval, newformat ); ++ ++ /* Arrange rowptr to eliminate the use of mod function to determine ++ ** which row of xelbuf is 0...crows. Mod function can be very costly. ++ */ ++ temprow = toprow % crows; ++ i = 0; ++ for (irow = temprow; irow < crows; ++i, ++irow) ++ rowptr[i] = xelbuf[irow]; ++ for (irow = 0; irow < temprow; ++irow, ++i) ++ rowptr[i] = xelbuf[irow]; ++ ++ for ( col = 0; col < cols; ++col ) ++ { ++ if ( col < ccolso2 || col >= cols - ccolso2 ) ++ outputrow[col] = rowptr[crowso2][col]; ++ else if ( col == ccolso2 ) ++ { ++ rsum = 0.0; ++ gsum = 0.0; ++ bsum = 0.0; ++ leftcol = col - ccolso2; ++ for ( crow = 0; crow < crows; ++crow ) ++ { ++ temprptr = rowptr[crow] + leftcol; ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ { ++ rcolumnsum[leftcol + ccol] += ++ PPM_GETR( *(temprptr + ccol) ); ++ gcolumnsum[leftcol + ccol] += ++ PPM_GETG( *(temprptr + ccol) ); ++ bcolumnsum[leftcol + ccol] += ++ PPM_GETB( *(temprptr + ccol) ); ++ } ++ } ++ for ( ccol = 0; ccol < ccols; ++ccol) ++ { ++ rsum += rcolumnsum[leftcol + ccol] * rweights[0][ccol]; ++ gsum += gcolumnsum[leftcol + ccol] * gweights[0][ccol]; ++ bsum += bcolumnsum[leftcol + ccol] * bweights[0][ccol]; ++ } ++ temprsum = rsum + 0.5; ++ tempgsum = gsum + 0.5; ++ tempbsum = bsum + 0.5; ++ CHECK_RED; ++ CHECK_GREEN; ++ CHECK_BLUE; ++ PPM_ASSIGN( outputrow[col], r, g, b ); ++ } ++ else ++ { ++ rsum = 0.0; ++ gsum = 0.0; ++ bsum = 0.0; ++ leftcol = col - ccolso2; ++ addcol = col + ccolso2; ++ for ( crow = 0; crow < crows; ++crow ) ++ { ++ rcolumnsum[addcol] += PPM_GETR( rowptr[crow][addcol] ); ++ gcolumnsum[addcol] += PPM_GETG( rowptr[crow][addcol] ); ++ bcolumnsum[addcol] += PPM_GETB( rowptr[crow][addcol] ); ++ } ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ { ++ rsum += rcolumnsum[leftcol + ccol] * rweights[0][ccol]; ++ gsum += gcolumnsum[leftcol + ccol] * gweights[0][ccol]; ++ bsum += bcolumnsum[leftcol + ccol] * bweights[0][ccol]; ++ } ++ temprsum = rsum + 0.5; ++ tempgsum = gsum + 0.5; ++ tempbsum = bsum + 0.5; ++ CHECK_RED; ++ CHECK_GREEN; ++ CHECK_BLUE; ++ PPM_ASSIGN( outputrow[col], r, g, b ); ++ } ++ } ++ pnm_writepnmrow( stdout, outputrow, cols, maxval, newformat, 0 ); ++ ++ /* For all subsequent rows */ ++ subrow = crows; ++ addrow = crows - 1; ++ crowsp1 = crows + 1; ++ ++row; ++ for ( ; row < rows; ++row ) ++ { ++ toprow = row + 1; ++ temprow = row % (crows +1); ++ pnm_readpnmrow( ifp, xelbuf[temprow], cols, maxval, format ); ++ if ( PNM_FORMAT_TYPE(format) != newformat ) ++ pnm_promoteformatrow( ++ xelbuf[temprow], cols, maxval, format, maxval, newformat ); ++ ++ /* Arrange rowptr to eliminate the use of mod function to determine ++ ** which row of xelbuf is 0...crows. Mod function can be very costly. ++ */ ++ temprow = (toprow + 1) % crowsp1; ++ i = 0; ++ for (irow = temprow; irow < crowsp1; ++i, ++irow) ++ rowptr[i] = xelbuf[irow]; ++ for (irow = 0; irow < temprow; ++irow, ++i) ++ rowptr[i] = xelbuf[irow]; ++ ++ for ( col = 0; col < cols; ++col ) ++ { ++ if ( col < ccolso2 || col >= cols - ccolso2 ) ++ outputrow[col] = rowptr[crowso2][col]; ++ else if ( col == ccolso2 ) ++ { ++ rsum = 0.0; ++ gsum = 0.0; ++ bsum = 0.0; ++ leftcol = col - ccolso2; ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ { ++ tempcol = leftcol + ccol; ++ rcolumnsum[tempcol] = rcolumnsum[tempcol] ++ - PPM_GETR( rowptr[subrow][ccol] ) ++ + PPM_GETR( rowptr[addrow][ccol] ); ++ rsum = rsum + rcolumnsum[tempcol] * rweights[0][ccol]; ++ gcolumnsum[tempcol] = gcolumnsum[tempcol] ++ - PPM_GETG( rowptr[subrow][ccol] ) ++ + PPM_GETG( rowptr[addrow][ccol] ); ++ gsum = gsum + gcolumnsum[tempcol] * gweights[0][ccol]; ++ bcolumnsum[tempcol] = bcolumnsum[tempcol] ++ - PPM_GETB( rowptr[subrow][ccol] ) ++ + PPM_GETB( rowptr[addrow][ccol] ); ++ bsum = bsum + bcolumnsum[tempcol] * bweights[0][ccol]; ++ } ++ temprsum = rsum + 0.5; ++ tempgsum = gsum + 0.5; ++ tempbsum = bsum + 0.5; ++ CHECK_RED; ++ CHECK_GREEN; ++ CHECK_BLUE; ++ PPM_ASSIGN( outputrow[col], r, g, b ); ++ } ++ else ++ { ++ rsum = 0.0; ++ gsum = 0.0; ++ bsum = 0.0; ++ leftcol = col - ccolso2; ++ addcol = col + ccolso2; ++ rcolumnsum[addcol] = rcolumnsum[addcol] ++ - PPM_GETR( rowptr[subrow][addcol] ) ++ + PPM_GETR( rowptr[addrow][addcol] ); ++ gcolumnsum[addcol] = gcolumnsum[addcol] ++ - PPM_GETG( rowptr[subrow][addcol] ) ++ + PPM_GETG( rowptr[addrow][addcol] ); ++ bcolumnsum[addcol] = bcolumnsum[addcol] ++ - PPM_GETB( rowptr[subrow][addcol] ) ++ + PPM_GETB( rowptr[addrow][addcol] ); ++ for ( ccol = 0; ccol < ccols; ++ccol ) ++ { ++ rsum += rcolumnsum[leftcol + ccol] * rweights[0][ccol]; ++ gsum += gcolumnsum[leftcol + ccol] * gweights[0][ccol]; ++ bsum += bcolumnsum[leftcol + ccol] * bweights[0][ccol]; ++ } ++ temprsum = rsum + 0.5; ++ tempgsum = gsum + 0.5; ++ tempbsum = bsum + 0.5; ++ CHECK_RED; ++ CHECK_GREEN; ++ CHECK_BLUE; ++ PPM_ASSIGN( outputrow[col], r, g, b ); ++ } ++ } ++ pnm_writepnmrow( stdout, outputrow, cols, maxval, newformat, 0 ); ++ } ++ ++ /* Now write out the remaining unconvolved rows in xelbuf. */ ++ for ( irow = crowso2 + 1; irow < crows; ++irow ) ++ pnm_writepnmrow( ++ stdout, rowptr[irow], cols, maxval, newformat, 0 ); + + pm_close( stdout ); +- exit( 0 ); + } diff --git a/graphics/netpbm/patches/patch-bk b/graphics/netpbm/patches/patch-bk new file mode 100644 index 00000000000..95d928e25c8 --- /dev/null +++ b/graphics/netpbm/patches/patch-bk @@ -0,0 +1,164 @@ +--- /dev/null Thu Oct 16 09:27:24 1997 ++++ ./pnm/pnmhisteq.1 Sun Aug 13 00:13:48 1995 +@@ -0,0 +1,161 @@ ++.TH pnmhisteq 1 "19 March 1995" ++.IX "pnmhisteq command" ++.IX histogram ++.SH NAME ++pnmhisteq \- histogram equalise a portable anymap ++.SH SYNOPSIS ++.na ++.B pnmhisteq ++'ti 15 ++.RB [ \-gray ] ++.RB [ \-rmap ++.IR pgmfile ] ++.RB [ \-wmap ++.IR pgmfile ] ++.RB [ \-verbose ] ++.RI [ pnmfile ] ++.ad ++.SH DESCRIPTION ++.B pnmhisteq ++increases the contrast of a portable graymap or pixmap through the ++technique of ++.IR "histogram equalisation" [1]. ++A histogram of the luminance of pixels in the map is computed, from ++which a transfer function is calculated which spreads out intensity levels ++around histogram peaks and compresses them at troughs. This has the ++effect of using the available levels of intensity more efficiently and ++thereby increases the detail visible in the image. ++.PP ++Mathematically, if ++.I N[i] ++is the number of pixels of luminosity ++.I i ++in the image and ++.I T ++is the total number of pixels, luminosity ++.I j ++is replaced by: ++.PP ++.NF ++.vs 9p ++ j ++ --- ++ \\ ++ \> N[i] / T ++ \/ ++ --- ++ i=0 ++.vs ++.FI ++.PP ++If you're processing a related set of images, for example frames of an ++animation, it's generally best to apply the same intensity map to ++every frame, since otherwise you'll get distracting frame-to-frame ++changes in the brightness of objects. ++.BR pnmhisteq 's ++.B \-wmap ++option ++allows you to save, as a portable graymap, the luminosity map computed ++from an image (usually a composite of the images you intend ++to process created with ++.BR pnmcat ). ++Then, you can subsequently process each of the individual images using ++the luminosity map saved in the file, supplied with the ++.B \-rmap ++option. ++.SH OPTIONS ++.TP 10 ++.B \-gray ++When processing a pixmap, only gray pixels (those with identical red, ++green, and blue values) are included in the histogram and modified ++in the output image. This is a special purpose option intended ++for images where the actual data are gray scale, with ++colour annotations you don't want modified. Weather ++satellite images that show continent outlines in colour are best ++processed using this option. The option has no effect when the input ++is a graymap. ++.TP ++.BI \-rmap " mapfile" ++Process the image using the luminosity map specified by the portable ++graymap ++.I mapfile. ++The graymap, usually created by an earlier run of ++.B pnmhisteq ++with the ++.B \-wmap ++option, contains a single row with number of columns equal to ++the ++.I maxval ++(greatest intensity) of the image. Each pixel in the image is ++transformed by looking up its luminosity in the corresponding ++column in the map file and changing it to the value ++given by that column. ++.TP ++.BI \-wmap " mapfile" ++Creates a portable graymap, ++.I mapfile, ++containing the luminosity map computed from the histogram of the ++input image. This map file can be read on subsequent runs of ++.B pnmhisteq ++with the ++.B \-rmap ++option, allowing a group of images to be processed with ++an identical map. ++.TP ++.B \-verbose ++Prints the histogram and luminosity map on standard error. ++.PP ++All flags can be abbreviated to their shortest unique prefix. ++.SH BUGS ++Histogram equalisation is effective for increasing the visible detail ++in scientific imagery and in some continuous-tone pictures. It is ++often too drastic, however, for scanned halftone images, where it ++does an excellent job of making halftone artifacts apparent. You ++might want to experiment with ++.BR pgnnorm , ++.BR ppmnorm , ++and ++.B pnmgamma ++for more subtle contrast enhancement. ++.PP ++The luminosity map file supplied by the ++.B \-rmap ++option must have the same ++.I maxval ++as the input image. This is always the case when the ++map file was created by the ++.B \-wmap ++option of ++.BR pnmhisteq . ++If this restriction causes a problem, simply adjust the ++.I maxval ++of the map with ++.B pnmdepth ++to agree with the input image. ++.PP ++If the input is a PBM file (on which histogram equalisation is an ++identity operation), the only effect of passing the file through ++.B pnmhisteq ++will be the passage of time. ++.SH "SEE ALSO" ++.PD ++.BR pgmnorm (1), ++.BR pnm (5), ++.BR pnmcat (1), ++.BR pnmdepth (1), ++.BR pnmgamma (1), ++.BR pnmnorm (1) ++.TP 5 ++[1] ++Russ, John C. The Image Processing Handbook. ++Boca Raton: CRC Press, 1992. Pages 105-110. ++.ne 10 ++.SH AUTHOR ++.ce 2 ++Copyright (C) 1995 by John Walker (kelvin@fourmilab.ch). ++WWW home page: http://www.fourmilab.ch/ ++.PP ++Permission to use, copy, modify, and distribute this software and its ++documentation for any purpose and without fee is hereby granted, ++without any conditions or restrictions. This software is provided ``as ++is'' without express or implied warranty. diff --git a/graphics/netpbm/patches/patch-bl b/graphics/netpbm/patches/patch-bl new file mode 100644 index 00000000000..0dbab9b0f1e --- /dev/null +++ b/graphics/netpbm/patches/patch-bl @@ -0,0 +1,374 @@ +--- /dev/null Thu Oct 16 09:27:24 1997 ++++ ./pnm/pnmhisteq.c Sun Aug 13 00:13:48 1995 +@@ -0,0 +1,371 @@ ++/* ++ pnmhisteq.c ++ ++ Equalise histogram for a PGM or PPM file ++ ++ Options: -gray: modify gray pixels only; leave colours unchanged ++ -rmap fn: read luminosity map from PGM file fn ++ -wmap wn: write luminosity map to PGM file fn ++ -verbose: print histogram and luminosity map ++ ++ Accepts PGM and PPM as input. PBM input is allowed, but histogram ++ equalisation does not modify a PBM file. ++ ++ by John Walker (kelvin@fourmilab.ch) -- March MVM. ++ WWW home page: http://www.fourmilab.ch/ ++ ++ Copyright (C) 1995 by John Walker ++ ++ Permission to use, copy, modify, and distribute this software and ++ its documentation for any purpose and without fee is hereby ++ granted, without any conditions or restrictions. This software is ++ provided "as is" without express or implied warranty. ++ ++*/ ++ ++#include "pnm.h" ++ ++/* Prototypes */ ++ ++static void hsv_rgb ARGS((double h, double s, double v, ++ double *r, double *g, double *b)); ++static void rgb_hsv ARGS((double r, double g, double b, ++ double *h, double *s, double *v)); ++ ++/* HSV_RGB -- Convert HSV colour specification to RGB intensities. ++ Hue is specified as a real value from 0 to 360, ++ Saturation and Intensity as reals from 0 to 1. The ++ RGB components are returned as reals from 0 to 1. */ ++ ++static void hsv_rgb(h, s, v, r, g, b) ++ double h, s, v; ++ double *r, *g, *b; ++{ ++ int i; ++ double f, p, q, t; ++ ++ if (s == 0) { ++ *r = *g = *b = v; ++ } else { ++ if (h == 360.0) { ++ h = 0; ++ } ++ h /= 60.0; ++ ++ i = h; ++ f = h - i; ++ p = v * (1.0 - s); ++ q = v * (1.0 - (s * f)); ++ t = v * (1.0 - (s * (1.0 - f))); ++ switch (i) { ++ ++ case 0: ++ *r = v; ++ *g = t; ++ *b = p; ++ break; ++ ++ case 1: ++ *r = q; ++ *g = v; ++ *b = p; ++ break; ++ ++ case 2: ++ *r = p; ++ *g = v; ++ *b = t; ++ break; ++ ++ case 3: ++ *r = p; ++ *g = q; ++ *b = v; ++ break; ++ ++ case 4: ++ *r = t; ++ *g = p; ++ *b = v; ++ break; ++ ++ case 5: ++ *r = v; ++ *g = p; ++ *b = q; ++ break; ++ } ++ } ++} ++ ++/* RGB_HSV -- Map R, G, B intensities in the range from 0 to 1 into ++ Hue, Saturation, and Value: Hue from 0 to 360, ++ Saturation from 0 to 1, and Value from 0 to 1. ++ Special case: if Saturation is 0 (it's a grey scale ++ tone), Hue is undefined and is returned as -1. ++ ++ This follows Foley & van Dam, section 17.4.4. */ ++ ++static void rgb_hsv(r, g, b, h, s, v) ++ double r, g, b; ++ double *h, *s, *v; ++{ ++ double imax = max(r, max(g, b)), ++ imin = min(r, min(g, b)), ++ rc, gc, bc; ++ ++ *v = imax; ++ if (imax != 0) { ++ *s = (imax - imin) / imax; ++ } else { ++ *s = 0; ++ } ++ ++ if (*s == 0) { ++ *h = -1; ++ } else { ++ rc = (imax - r) / (imax - imin); ++ gc = (imax - g) / (imax - imin); ++ bc = (imax - b) / (imax - imin); ++ if (r == imax) { ++ *h = bc - gc; ++ } else if (g == imax) { ++ *h = 2.0 + rc - bc; ++ } else { ++ *h = 4.0 + gc - rc; ++ } ++ *h *= 60.0; ++ if (*h < 0.0) { ++ *h += 360.0; ++ } ++ } ++} ++ ++int main(argc, argv) ++ int argc; ++ char *argv[]; ++{ ++ FILE *ifp; ++ int argn = 1, i, j, verbose = 0, mono_only = 0; ++ gray lmin, lmax; ++ gray **lumamap; /* Luminosity map */ ++ long *lumahist; /* Histogram of luminosity values */ ++ int rows, hist_cols; /* Rows, columns of input image */ ++ xelval maxval; /* Maxval of input image */ ++ int format; /* Format indicator (PBM/PGM/PPM) */ ++ xel** xels; /* Pixel array */ ++ unsigned long pixels = 0, pixsum = 0, maxluma = 0; ++ double lscale; ++ xel *grayrow; ++ pixel *pixrow; ++ FILE *rmap = NULL, *wmap = NULL; ++ char *usage = "[-gray] [-verbose] [-rmap pgmfile] [-wmap pgmfile] [pnmfile]"; ++ ++ pnm_init(&argc, argv); ++ ++ /* Check for flags. */ ++ ++ while (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0') { ++ if (pm_keymatch(argv[argn], "-gray", 1)) { ++ mono_only = 1; ++ } else if (pm_keymatch(argv[argn], "-verbose", 1)) { ++ verbose = 1; ++ } else if (pm_keymatch(argv[argn], "-rmap", 1)) { ++ if (rmap != NULL) { ++ pm_error("already specified an input map"); ++ } ++ argn++; ++ if (argn == argc || strcmp(argv[argn], "-") == 0) { ++ pm_usage(usage); ++ } ++ rmap = pm_openr(argv[argn]); ++ } else if (pm_keymatch(argv[argn], "-wmap", 1)) { ++ if (wmap != NULL) { ++ pm_error("already specified an output map"); ++ } ++ argn++; ++ if (argn == argc) { ++ pm_usage(usage); ++ } ++ wmap = pm_openw(argv[argn]); ++ } else { ++ pm_usage(usage); ++ } ++ argn++; ++ } ++ ++ if (--argc > argn) { ++ pm_usage(usage); ++ } else if (argc == argn) { ++ ifp = pm_openr(argv[argn]); ++ } else { ++ ifp = stdin; ++ } ++ ++ xels = pnm_readpnm(ifp, &hist_cols, &rows, &maxval, &format); ++ pm_close(ifp); ++ ++ /* Allocate histogram and luminosity map arrays. If the ++ user has specified an input map file, read it in at ++ this point. */ ++ ++ lumahist = (long *) pm_allocrow(maxval + 1, sizeof(long)); ++ bzero((char *) lumahist, (maxval + 1) * sizeof(long)); ++ ++ if (rmap == NULL) { ++ lumamap = pgm_allocarray(maxval + 1, 1); ++ } else { ++ int rmcols, rmrows; ++ gray rmmaxv; ++ ++ lumamap = pgm_readpgm(rmap, &rmcols, &rmrows, &rmmaxv); ++ if (rmmaxv != maxval) { ++ pm_error("maxval in map file (%d) different from input (%d)", ++ rmmaxv, maxval); ++ } ++ if (rmrows != 1 || rmcols != rmmaxv) { ++ pm_error("map size (%d by %d) wrong; must be (%d by 1)", ++ rmcols, rmrows, maxval); ++ } ++ } ++ ++ /* Scan the image and build the luminosity histogram. If ++ the input is a PPM, we calculate the luminosity of each ++ pixel from its RGB components. */ ++ ++ lmin = maxval; ++ lmax = 0; ++ if (PNM_FORMAT_TYPE(format) == PGM_TYPE || ++ PNM_FORMAT_TYPE(format) == PBM_TYPE) { ++ ++ /* Compute intensity histogram */ ++ ++ pixels = ((unsigned long) rows) * ((unsigned long) hist_cols); ++ for (i = 0; i < rows; i++) { ++ xel *grayrow = xels[i]; ++ for (j = 0; j < hist_cols; j++) { ++ gray l = PNM_GET1(grayrow[j]); ++ lmin = min(lmin, l); ++ lmax = max(lmax, l); ++ lumahist[l]++; ++ } ++ } ++ } else if (PNM_FORMAT_TYPE(format) == PPM_TYPE) { ++ for (i = 0; i < rows; i++) { ++ pixel *pixrow = (pixel *) xels[i]; ++ ++ for (j = 0; j < hist_cols; j++) { ++ if (!mono_only || ++ ((PPM_GETR(pixrow[j]) == PPM_GETG(pixrow[j])) && ++ (PPM_GETR(pixrow[j]) == PPM_GETB(pixrow[j])))) { ++ gray l = (gray) PPM_LUMIN(pixrow[j]); ++ lmin = min(lmin, l); ++ lmax = max(lmax, l); ++ lumahist[l]++; ++ pixels++; ++ } ++ } ++ } ++ } else { ++ pm_error("unknown input format"); ++ } ++ ++ /* The PGM and PPM branches rejoin here to calculate the ++ luminosity mapping table which gives the histogram-equalised ++ luminosity for each original luminosity. */ ++ ++ /* Calculate initial histogram equalisation curve. */ ++ ++ for (i = 0; i <= (int) maxval; i++) { ++ ++ /* Yick. If PGM_BIGGRAYS is defined (I thought they were little ++ guys, about four foot, with funny eyes...) the following ++ calculation can overflow a 32 bit long. So, we do it in ++ floating point. Since this happens only maxval times, the ++ inefficiency is trivial compared to the every-pixel code above ++ and below. */ ++ ++ lumamap[0][i] = (gray) (((((double) pixsum * maxval)) / pixels) + 0.5); ++ if (lumahist[i] > 0) { ++ maxluma = i; ++ } ++ pixsum += lumahist[i]; ++ } ++ ++ /* Normalise so that the brightest pixels are set to ++ maxval. */ ++ ++ lscale = ((double) maxval) / ((lumahist[maxluma] > 0) ? ++ ((double) lumamap[0][maxluma]) : ((double) maxval)); ++ for (i = 0; i <= (int) maxval; i++) { ++ lumamap[0][i] = (gray) ++ min(((long) maxval), ((long) (lumamap[0][i] * lscale + 0.5))); ++ } ++ ++ /* If requested, print the luminosity map and original histogram. */ ++ ++ if (verbose) { ++ fprintf(stderr, ++ " Luminosity map Number of\n Original New Pixels\n"); ++ for (i = 0; i <= (int) maxval; i++) { ++ if (lumahist[i] > 0) { ++ fprintf(stderr,"%6d -> %6d %8d\n", i, ++ lumamap[0][i], lumahist[i]); ++ } ++ } ++ } ++ ++ switch (PNM_FORMAT_TYPE(format)) { ++ case PBM_TYPE: ++ case PPM_TYPE: ++ for (i = 0; i < rows; i++) { ++ pixrow = (pixel *) xels[i]; ++ for (j = 0; j < hist_cols; j++) { ++ if (!mono_only || ++ ((PPM_GETR(pixrow[j]) == PPM_GETG(pixrow[j])) && ++ (PPM_GETR(pixrow[j]) == PPM_GETB(pixrow[j])))) { ++ double r, g, b, h, s, v; ++ int iv; ++ ++ r = (double) PPM_GETR(pixrow[j]) / ((double) maxval); ++ g = (double) PPM_GETG(pixrow[j]) / ((double) maxval); ++ b = (double) PPM_GETB(pixrow[j]) / ((double) maxval); ++ rgb_hsv(r, g, b, &h, &s, &v); ++ iv = (int) ((v * maxval) + 0.5); ++ ++ if (iv > ((int) maxval)) { ++ iv = maxval; ++ } ++ v = ((double) lumamap[0][iv]) / ((double) maxval); ++ if (v > 1.0) { ++ v = 1.0; ++ } ++ hsv_rgb(h, s, v, &r, &g, &b); ++ PPM_ASSIGN(pixrow[j], (int) (r * maxval), ++ (int) (g * maxval), (int) (b * maxval)); ++ } ++ } ++ } ++ break; ++ ++ case PGM_TYPE: ++ for (i = 0; i < rows; i++) { ++ grayrow = xels[i]; ++ for (j = 0; j < hist_cols; j++) { ++ PNM_ASSIGN1(grayrow[j], lumamap[0][PNM_GET1(grayrow[j])]); ++ } ++ } ++ break; ++ } ++ ++ pnm_writepnm(stdout, xels, hist_cols, rows, maxval, format, 0); ++ ++ /* If requested, save the map as a PGM file. */ ++ ++ if (wmap != NULL) { ++ pgm_writepgm(wmap, lumamap, maxval, 1, maxval, 0); ++ fclose(wmap); ++ } ++ ++ return 0; ++} diff --git a/graphics/netpbm/patches/patch-bm b/graphics/netpbm/patches/patch-bm new file mode 100644 index 00000000000..3cbd8d55541 --- /dev/null +++ b/graphics/netpbm/patches/patch-bm @@ -0,0 +1,29 @@ +--- ./pnm/pnmmerge.c.orig Mon Jan 31 06:31:47 1994 ++++ ./pnm/pnmmerge.c Thu Oct 16 11:08:33 1997 +@@ -30,6 +30,10 @@ + { + ++argv; + --argc; ++ if(!*argv) { ++ fprintf(stderr, "Usage: pnmmerge pnm_program_name [args ...]\n"); ++ exit(1); ++ } + goto again; + } + +@@ -51,6 +55,7 @@ + TRY("pnmgamma", pnmgamma_main); + TRY("pnminvert", pnminvert_main); + TRY("pnmhistmap", pnmhistmap_main); ++ TRY("pnmhisteq", pnmhisteq_main); + TRY("pnmnlfilt", pnmnlfilt_main); + TRY("pnmnoraw", pnmnoraw_main); + TRY("pnmpaste", pnmpaste_main); +@@ -76,6 +81,7 @@ + #endif /*LIBTIFF*/ + TRY("xwdtopnm", xwdtopnm_main); + TRY("zeisstopnm", zeisstopnm_main); ++ TRY("pnmsmooth", pnmsmooth_main); + + (void) fprintf( + stderr, "pnmmerge: \"%s\" is an unknown PNM program!\n", cp ); diff --git a/graphics/netpbm/patches/patch-bn b/graphics/netpbm/patches/patch-bn new file mode 100644 index 00000000000..141ab4f26b9 --- /dev/null +++ b/graphics/netpbm/patches/patch-bn @@ -0,0 +1,52 @@ +--- ./pnm/pnmsmooth.1.orig Mon Oct 4 05:11:56 1993 ++++ ./pnm/pnmsmooth.1 Sun Aug 13 00:21:28 1995 +@@ -1,25 +1,42 @@ +-.TH pnmsmooth 1 "13 January 1991" ++.TH pnmsmooth 1 "4 December 1994" + .IX pnmsmooth + .SH NAME + pnmsmooth - smooth out an image + .SH SYNOPSIS + .B pnmsmooth ++.RB [ -size ++.IR width ++.IR height ] ++.RB [ -dump ++.IR dumpfile ] + .RI [ pnmfile ] + .SH DESCRIPTION + Smooths out an image by replacing each pixel with the +-average of its nine immediate neighbors. ++average of its width X height neighbors. + .IX smoothing + .IX anti-aliasing +-It is implemented as a simple script using ++It is implemented as a C progam that generates a PGM convolution matrix ++and then invokes + .IR pnmconvol . + .IX pnmconvol ++.SH OPTIONS ++.TP ++.B -size width height ++Specifies the size of the convolution matrix. ++Default size is a 3x3 matrix. ++Width and height sizes must be odd. ++Maximum size of convolution matrix is limited by the maximum value for a ++pixel such that (width * height * 2) must not exceed the maximum pixel value. ++.TP ++.B -dump dumpfile ++Generates and saves the convolution file only. ++Use of this option does not invoke pnmconvol. + .SH "SEE ALSO" + pnmconvol(1), pnm(5) +-.SH BUGS +-It's a script. +-Scripts are not portable to non-Unix environments. +-.SH AUTHOR ++.SH AUTHORS + Copyright (C) 1989, 1991 by Jef Poskanzer. ++.br ++Converted from script to C program December 1994 by Mike Burns (burns@chem.psu.edu). + .\" Permission to use, copy, modify, and distribute this software and its + .\" documentation for any purpose and without fee is hereby granted, provided + .\" that the above copyright notice appear in all copies and that both that diff --git a/graphics/netpbm/patches/patch-bo b/graphics/netpbm/patches/patch-bo new file mode 100644 index 00000000000..b016f05254f --- /dev/null +++ b/graphics/netpbm/patches/patch-bo @@ -0,0 +1,24 @@ +--- /dev/null Thu Oct 16 09:27:24 1997 ++++ ./pnm/pnmsmooth.README Sun Aug 13 00:21:28 1995 +@@ -0,0 +1,21 @@ ++README for pnmsmooth.c 2.0 ++ ++This is a replacement for the pnmsmooth script that is distributed with ++pbmplus/netpbm. This version of pnmsmooth is written as a C program rather ++than a shell script. It accepts command line arguments to specify a size ++other than 3x3 for the convolution matrix and an argument for dumping the ++resultant convolution matrix as a PGM file. By default it uses the same 3x3 ++matrix size as the pnmsmooth script and can be used as a direct replacement. ++ ++Also included are an updated man page and a patch file to update the Imakefile ++in the pnm directory. You may want to apply the patches by hand if you have ++already modified the Imakefile to add other new programs. You will then ++have to remake the Makefiles and then type 'make all' in the pnm directory. ++ ++- Mike ++ ++---------------------------------------------------------------------------- ++Mike Burns System Administrator ++burns@chem.psu.edu Department of Chemistry ++(814) 863-2123 The Pennsylvania State University ++ diff --git a/graphics/netpbm/patches/patch-bp b/graphics/netpbm/patches/patch-bp new file mode 100644 index 00000000000..4d68010221b --- /dev/null +++ b/graphics/netpbm/patches/patch-bp @@ -0,0 +1,174 @@ +--- /dev/null Thu Oct 16 09:27:24 1997 ++++ ./pnm/pnmsmooth.c Sun Aug 13 00:21:29 1995 +@@ -0,0 +1,171 @@ ++/* pnmsmooth.c - smooth out an image by replacing each pixel with the ++** average of its width x height neighbors. ++** ++** Version 2.0 December 5, 1994 ++** ++** Copyright (C) 1994 by Mike Burns (burns@chem.psu.edu) ++** ++** Permission to use, copy, modify, and distribute this software and its ++** documentation for any purpose and without fee is hereby granted, provided ++** that the above copyright notice appear in all copies and that both that ++** copyright notice and this permission notice appear in supporting ++** documentation. This software is provided "as is" without express or ++** implied warranty. ++*/ ++ ++/* Version 2.0 - December 5, 1994 ++** ------------------------------ ++** Rewrote as a C program that accepts a few options instead of a shell ++** script with no options. ++** ++*/ ++ ++#include "pnm.h" ++#include <sys/wait.h> ++ ++#define TRUE 1 ++#define FALSE 0 ++ ++int ++main( argc, argv ) ++ int argc; ++ char* argv[]; ++ { ++ FILE *cofp; ++ char *tempfn; ++ char *pnmfn; ++ int argn; ++ int col, row; ++ int format, forceplain; ++ int cols, rows; ++ int newmaxval; /* normally xelval, but want int here */ ++ xelval g; ++ xel *outputrow; ++ int pid, status; ++ int DUMPFLAG = FALSE; ++ char *usage = "[-size width height] [-dump dumpfile] [pnmfile]"; ++ ++ pnm_init( &argc, argv ); ++ ++ /* set up defaults */ ++ cols = 3; ++ rows = 3; ++ format = PGM_FORMAT; ++ forceplain = 1; ++ pnmfn = (char *) 0; /* initialize to NULL just in case */ ++ ++ argn = 1; ++ while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) ++ { ++ if ( pm_keymatch( argv[argn], "-size", 2 ) ) ++ { ++ ++argn; ++ if ( argn+1 >= argc ) ++ { ++ pm_message( "incorrect number of arguments for -size option" ); ++ pm_usage( usage ); ++ } ++ else if ( argv[argn][0] == '-' || argv[argn+1][0] == '-' ) ++ { ++ pm_message( "invalid arguments to -size option: %s %s", ++ argv[argn], argv[argn+1] ); ++ pm_usage( usage ); ++ } ++ if ( (cols = atoi(argv[argn])) == 0 ) ++ pm_error( "invalid width size specification: %s", argv[argn] ); ++ ++argn; ++ if ( (rows = atoi(argv[argn])) == 0 ) ++ pm_error( "invalid height size specification: %s",argv[argn] ); ++ if ( cols % 2 != 1 || rows % 2 != 1 ) ++ pm_error( "the convolution matrix must have an odd number of rows and columns" ); ++ } ++ else if ( pm_keymatch( argv[argn], "-dump", 2 ) ) ++ { ++ ++argn; ++ if ( argn >= argc ) ++ { ++ pm_message( "missing argument to -dump option" ); ++ pm_usage( usage ); ++ } ++ else if ( argv[argn][0] == '-' ) ++ { ++ pm_message( "invalid argument to -dump option: %s", ++ argv[argn] ); ++ pm_usage( usage ); ++ } ++ cofp = pm_openw( argv[argn] ); ++ DUMPFLAG = TRUE; ++ } ++ else ++ pm_usage( usage ); ++ ++argn; ++ } ++ ++ /* Only get file name if given on command line to pass through to ++ ** pnmconvol. If filename is coming from stdin, pnmconvol will read it. ++ */ ++ if ( argn < argc ) ++ { ++ pnmfn = argv[argn]; ++ ++argn; ++ } ++ ++ if ( argn != argc ) ++ pm_usage( usage ); ++ ++ ++ if ( !DUMPFLAG ) ++ { ++ if ( (tempfn = tmpnam((char *) 0)) == NULL ) ++ pm_error( "could not create temporary file name" ); ++ if ( (cofp = pm_openw(tempfn)) == NULL ) ++ pm_error( "could not create temporary convolution file" ); ++ } ++ ++ /* Generate mean value for all pixels in convolution matrix. */ ++ g = rows * cols + 1; ++ ++ /* Make sure newmaxval is not larger than PNM_MAXMAXVAL or else ++ ** newmaxval will overrun its defined data size and become garbage. ++ */ ++ newmaxval = ( rows * cols ) * 2; ++ if ( newmaxval > PNM_MAXMAXVAL ) ++ pm_error( "generated maxval is too large: %d", newmaxval ); ++ ++ pnm_writepnminit( cofp, cols, rows, newmaxval, format, forceplain ); ++ outputrow = pnm_allocrow( cols ); ++ ++ for ( row = 0; row < rows; ++ row ) ++ { ++ for ( col = 0; col < cols; ++col ) ++ PNM_ASSIGN1( outputrow[col], g ); ++ pnm_writepnmrow( cofp, outputrow, cols, newmaxval, format, forceplain ); ++ } ++ pm_close( cofp ); ++ pnm_freerow( outputrow ); ++ ++ /* If we're only going to dump the file, now is the time to stop. */ ++ if ( DUMPFLAG ) ++ exit( 0 ); ++ ++ /* fork a child process */ ++ if ( (pid = fork()) < 0 ) ++ pm_error( "fork" ); ++ ++ /* child process executes following code */ ++ if ( pid == 0 ) ++ { ++ /* If pnmfile name is not given on command line, then pnmfn will be ++ ** (char *) 0 and the arglist will terminate there. ++ */ ++ execlp( "pnmconvol", "pnmconvol", tempfn, pnmfn, (char *) 0 ); ++ pm_error( "error executing pnmconvol command" ); ++ } ++ ++ /* wait for child to finish */ ++ while ( wait(&status) != pid ) ++ ; ++ ++ unlink( tempfn ); ++ exit( 0 ); ++ } diff --git a/graphics/netpbm/patches/patch-bq b/graphics/netpbm/patches/patch-bq new file mode 100644 index 00000000000..3a3481091de --- /dev/null +++ b/graphics/netpbm/patches/patch-bq @@ -0,0 +1,23 @@ +--- /dev/null Thu Oct 16 09:27:24 1997 ++++ ./pnm/pnmsmooth.orig Mon Oct 4 05:11:56 1993 +@@ -0,0 +1,20 @@ ++#!/bin/sh ++# ++# pnmsmooth - smooth out an image by replacing each xel with the ++# average of its nine immediate neighbors ++ ++tmp=/tmp/psm.$$ ++rm -f $tmp ++ ++cat > $tmp << MOO ++P2 ++3 3 ++18 ++10 10 10 ++10 10 10 ++10 10 10 ++MOO ++ ++pnmconvol $tmp ${1+"$@"} ++ ++rm -f $tmp diff --git a/graphics/netpbm/patches/patch-br b/graphics/netpbm/patches/patch-br new file mode 100644 index 00000000000..4274fcb0aff --- /dev/null +++ b/graphics/netpbm/patches/patch-br @@ -0,0 +1,38 @@ +--- ./pnm/pnmtotiff.c.orig Sun Aug 13 00:32:57 1995 ++++ ./pnm/pnmtotiff.c Sun Aug 13 00:34:21 1995 +@@ -196,6 +196,7 @@ + samplesperpixel = 1; + bitspersample = pm_maxvaltobits( maxval ); + photometric = PHOTOMETRIC_MINISBLACK; ++ i = 8 / bitspersample; + bytesperrow = ( cols + i - 1 ) / i; + } + else +@@ -276,20 +277,20 @@ + for ( col = 0, xP = xels[row], tP = buf; + col < cols; ++col, ++xP ) + { +- register unsigned char s; ++ register xelval s; + + s = PPM_GETR( *xP ); + if ( maxval != 255 ) +- s = (long) s * 255 / maxval; +- *tP++ = s; ++ s = s * 255 / maxval; ++ *tP++ = (unsigned char)s; + s = PPM_GETG( *xP ); + if ( maxval != 255 ) +- s = (long) s * 255 / maxval; +- *tP++ = s; ++ s = s * 255 / maxval; ++ *tP++ = (unsigned char)s; + s = PPM_GETB( *xP ); + if ( maxval != 255 ) +- s = (long) s * 255 / maxval; +- *tP++ = s; ++ s = s * 255 / maxval; ++ *tP++ = (unsigned char)s; + } + } + else diff --git a/graphics/netpbm/patches/patch-bs b/graphics/netpbm/patches/patch-bs new file mode 100644 index 00000000000..62e93c308d8 --- /dev/null +++ b/graphics/netpbm/patches/patch-bs @@ -0,0 +1,11 @@ +--- ./ppm/ppm.5.orig Mon Oct 4 05:12:19 1993 ++++ ./ppm/ppm.5 Sat Jul 20 21:53:06 1996 +@@ -73,7 +73,7 @@ + it will automatically fall back on the slower but more general plain + format. + .SH "SEE ALSO" +-giftoppm(1), gouldtoppm(1), ilbmtoppm(1), imgtoppm(1), mtvtoppm(1), ++giftopnm(1), gouldtoppm(1), ilbmtoppm(1), imgtoppm(1), mtvtoppm(1), + pcxtoppm(1), pgmtoppm(1), pi1toppm(1), picttoppm(1), pjtoppm(1), qrttoppm(1), + rawtoppm(1), rgb3toppm(1), sldtoppm(1), spctoppm(1), sputoppm(1), tgatoppm(1), + ximtoppm(1), xpmtoppm(1), yuvtoppm(1), diff --git a/graphics/netpbm/patches/patch-bt b/graphics/netpbm/patches/patch-bt new file mode 100644 index 00000000000..12abf41a78c --- /dev/null +++ b/graphics/netpbm/patches/patch-bt @@ -0,0 +1,13 @@ +--- ./ppm/ppmmerge.c.orig Mon Jan 31 11:44:31 1994 ++++ ./ppm/ppmmerge.c Sat Aug 12 23:51:35 1995 +@@ -29,6 +29,10 @@ + { + ++argv; + --argc; ++ if(!*argv) { ++ fprintf(stderr, "Usage: ppmmerge ppm_program_name [args ...]\n"); ++ exit(1); ++ } + goto again; + } + diff --git a/graphics/netpbm/patches/patch-bu b/graphics/netpbm/patches/patch-bu new file mode 100644 index 00000000000..e95b5e6d187 --- /dev/null +++ b/graphics/netpbm/patches/patch-bu @@ -0,0 +1,11 @@ +--- ./ppm/ppmtogif.1.orig Fri Nov 12 04:18:30 1993 ++++ ./ppm/ppmtogif.1 Sat Jul 20 21:54:02 1996 +@@ -54,7 +54,7 @@ + .PP + All flags can be abbreviated to their shortest unique prefix. + .SH "SEE ALSO" +-giftoppm(1), ppmquant(1), ppm(5) ++giftopnm(1), ppmquant(1), ppm(5) + .SH AUTHOR + Based on GIFENCOD by David Rowley <mgardi@watdcsu.waterloo.edu>. + Lempel-Ziv compression based on "compress". diff --git a/graphics/netpbm/patches/patch-bv b/graphics/netpbm/patches/patch-bv new file mode 100644 index 00000000000..412e7dc1d30 --- /dev/null +++ b/graphics/netpbm/patches/patch-bv @@ -0,0 +1,11 @@ +--- ./ppm/ppmtoicr.1.orig Mon Oct 4 05:12:38 1993 ++++ ./ppm/ppmtoicr.1 Sat Jul 20 21:54:58 1996 +@@ -83,7 +83,7 @@ + the displayed image by a factor of 2, and + run-length encode the data: + .nf +- giftoppm giffile | ppmtoicr -w giffile -r -e 2 ++ giftopnm giffile | ppmtoicr -w giffile -r -e 2 + .fi + .SH BUGS + .PP diff --git a/graphics/netpbm/patches/patch-bw b/graphics/netpbm/patches/patch-bw new file mode 100644 index 00000000000..ab51edaeb59 --- /dev/null +++ b/graphics/netpbm/patches/patch-bw @@ -0,0 +1,27 @@ +--- ./ppm/ppmtoxpm.1.orig Mon Jan 31 06:49:48 1994 ++++ ./ppm/ppmtoxpm.1 Fri Aug 18 05:30:35 1995 +@@ -8,20 +8,20 @@ + Produces X11 pixmap (version 3) as output which + can be loaded directly by the XPM library. + .PP +-The \fB-name\fP option allows one to specify the prefix string which is printed ++The \fB-name\f option allows one to specify the prefix string which is printed + in the resulting XPM output. If not specified, will default to the + filename (without extension) of the <ppmfile> argument. +-If \fB-name\fP is not specified and <ppmfile> ++If \fB-name\f is not specified and <ppmfile> + is not specified (i.e. piped input), the prefix string will default to + the string "noname". + .PP +-The \fB-rgb\fP option allows one to specify an X11 rgb text file for the ++The \fB-rgb\f option allows one to specify an X11 rgb text file for the + lookup of color name mnemonics. This rgb text file is typically the + /usr/lib/X11/rgb.txt of the MIT X11 distribution, but any file using the + same format may be used. When specified and + a RGB value from the ppm input matches a RGB value from the <rgb-textfile>, + then the corresponding color name mnemonic is printed in the XPM's colormap. +-If \fB-rgb\fP is not specified, or if the RGB values don't match, then the color ++If \fB-rgb\f is not specified, or if the RGB values don't match, then the color + will be printed with the #RGB, #RRGGBB, #RRRGGGBBB, or #RRRRGGGGBBBB + hexadecimal format. + .PP diff --git a/graphics/netpbm/patches/patch-bx b/graphics/netpbm/patches/patch-bx new file mode 100644 index 00000000000..2a83b1f6268 --- /dev/null +++ b/graphics/netpbm/patches/patch-bx @@ -0,0 +1,211 @@ +--- ./ppm/ppmtoxpm.c.orig Mon Jan 31 02:44:41 1994 ++++ ./ppm/ppmtoxpm.c Fri Aug 18 05:30:36 1995 +@@ -27,11 +27,25 @@ + ** + ** - lowercase conversion of RGB names def'ed out, + ** considered harmful. ++** ++** Michael Pall (pall@rz.uni-karlsruhe.de) - 29 Nov 93: ++** - Use the algorithm from xpm-lib for pixel encoding ++** (base 93 not base 28 -> saves a lot of space for colorful xpms) + */ + ++#include <stdio.h> ++#include <ctype.h> + #include "ppm.h" + #include "ppmcmap.h" + ++#if defined(SYSV) || defined(SVR4) ++#include <string.h> ++#ifndef index ++#define index strchr ++#endif ++#else /* SYSV */ ++#include <strings.h> ++#endif /* SYSV */ + + /* Max number of colors allowed in ppm input. */ + #define MAXCOLORS 256 +@@ -39,15 +53,19 @@ + /* Max number of rgb mnemonics allowed in rgb text file. */ + #define MAX_RGBNAMES 1024 + +-/* Lower bound and upper bound of character-pixels printed in XPM output. +- Be careful, don't want the character '"' in this range. */ +-/*#define LOW_CHAR '#' <-- minimum ascii character allowed */ +-/*#define HIGH_CHAR '~' <-- maximum ascii character allowed */ +-#define LOW_CHAR '`' +-#define HIGH_CHAR 'z' ++#define MAXPRINTABLE 92 /* number of printable ascii chars ++ * minus \ and " for string compat ++ * and ? to avoid ANSI trigraphs. */ ++ ++static char *printable = ++" .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\ ++ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|"; ++ + + #define max(a,b) ((a) > (b) ? (a) : (b)) + ++void read_rgb_names(); /* forward reference */ ++void gen_cmap(); /* forward reference */ + + typedef struct { /* rgb values and ascii names (from + * rgb text file) */ +@@ -62,17 +80,8 @@ + * mnemonic or #rgb value */ + } cixel_map; + +- +-/* prototypes/forward reference */ +-static void read_rgb_names ARGS((char *, rgb_names *, int *)); +-static char * gen_numstr ARGS((int, int, int)); +-static void gen_cmap ARGS((colorhist_vector, int, pixval, int, rgb_names *, int, cixel_map *, int *)); +- +- + pixel **pixels; + +- +-int + main(argc, argv) + int argc; + char *argv[]; +@@ -88,11 +97,11 @@ + + /* Used for rgb value -> rgb mnemonic mapping */ + int map_rgb_names = 0; +- rgb_names *rgbn; /* rgb_names rgbn[MAX_RGBNAMES]; */ ++ rgb_names rgbn[MAX_RGBNAMES]; + int rgbn_max; + + /* Used for rgb value -> character-pixel string mapping */ +- cixel_map *cmap; /* cixel_map cmap[MAXCOLORS]; */ ++ cixel_map cmap[MAXCOLORS]; + int charspp; /* chars per pixel */ + + char out_name[100], rgb_fname[100], *cp; +@@ -188,17 +197,9 @@ + * If a rgb text file was specified, read in the rgb mnemonics. Does not + * return if fatal error occurs. + */ +- rgbn = (rgb_names *) malloc(MAX_RGBNAMES * sizeof(rgb_names)); +- if (rgbn == (rgb_names *) NULL) +- pm_error("out of memory"); +- + if (map_rgb_names) + read_rgb_names(rgb_fname, rgbn, &rgbn_max); + +- cmap = (cixel_map *)malloc(ncolors * sizeof(cixel_map)); +- if (cmap == (cixel_map *) NULL) +- pm_error("out of memory"); +- + /* Now generate the character-pixel colormap table. */ + gen_cmap(chv, ncolors, maxval, map_rgb_names, rgbn, rgbn_max, + cmap, &charspp); +@@ -231,12 +232,12 @@ + /* This routine reads a rgb text file. It stores the rgb values (0->65535) + and the rgb mnemonics (malloc'ed) into the "rgbn" array. Returns the + number of entries stored in "rgbn_max". */ +-static + void + read_rgb_names(rgb_fname, rgbn, rgbn_max) + char *rgb_fname; +- rgb_names *rgbn; +- int *rgbn_max; ++ rgb_names rgbn[MAX_RGBNAMES]; ++int *rgbn_max; ++ + { + FILE *rgbf; + int i, items, red, green, blue; +@@ -303,16 +304,16 @@ + } /* read_rgb_names */ + + /*---------------------------------------------------------------------------*/ +-/* Given a number and a base, (base == HIGH_CHAR-LOW_CHAR+1), this routine ++/* Given a number and a base (MAXPRINTABLE), this routine + prints the number into a malloc'ed string and returns it. The length of + the string is specified by "digits". The ascii characters of the printed +- number range from LOW_CHAR to HIGH_CHAR. The string is LOW_CHAR filled, +- (e.g. if LOW_CHAR==0, HIGH_CHAR==1, digits==5, i=3, routine would return +- the malloc'ed string "00011"). */ +-static ++ number range from printable[0] to printable[MAXPRINTABLE]. The string is ++ printable[0] filled, (e.g. if printable[0]==0, printable[1]==1, ++ MAXPRINTABLE==2, digits==5, i=3, routine would return the malloc'ed ++ string "00011"). */ + char * +-gen_numstr(i, base, digits) +- int i, base, digits; ++gen_numstr(i, digits) ++ int i, digits; + { + char *str, *p; + int d; +@@ -325,9 +326,9 @@ + p = str + digits; + *p-- = '\0'; /* nul terminate string */ + while (p >= str) { +- d = i % base; +- i /= base; +- *p-- = (char) ((int) LOW_CHAR + d); ++ d = i % MAXPRINTABLE; ++ i /= MAXPRINTABLE; ++ *p-- = printable[d]; + } + + return str; +@@ -336,7 +337,6 @@ + + /*---------------------------------------------------------------------------*/ + /* This routine generates the character-pixel colormap table. */ +-static + void + gen_cmap(chv, ncolors, maxval, map_rgb_names, rgbn, rgbn_max, + cmap, charspp) +@@ -348,16 +348,16 @@ + * == unsigned short) */ + int map_rgb_names; /* == 1 if mapping rgb values to rgb + * mnemonics */ +- rgb_names *rgbn; /* rgb mnemonics from rgb text file */ ++ rgb_names rgbn[MAX_RGBNAMES]; /* rgb mnemonics from rgb text file */ + int rgbn_max; /* number of rgb mnemonics in table */ + + /* output: */ +-cixel_map *cmap; /* pixel strings and ascii rgb ++cixel_map cmap[MAXCOLORS]; /* pixel strings and ascii rgb + * colors */ + int *charspp; /* characters per pixel */ + + { +- int i, j, base, cpp, mval, red, green, blue, r, g, b, matched; ++ int i, j, cpp, mval, red, green, blue, r, g, b, matched; + char *str; + + /* +@@ -365,9 +365,8 @@ + * to be forced to link with libm.a, so using a division loop rather + * than a log function. + */ +- base = (int) HIGH_CHAR - (int) LOW_CHAR + 1; + for (cpp = 0, j = ncolors; j; cpp++) +- j /= base; ++ j /= MAXPRINTABLE; + *charspp = cpp; + + /* +@@ -392,10 +391,11 @@ + + /* + * The character-pixel string is simply a printed number in base +- * "base" where the digits of the number range from LOW_CHAR to +- * HIGH_CHAR and the printed length of the number is "cpp". ++ * MAXPRINTABLE where the digits of the number range from ++ * printable[0] .. printable[MAXPRINTABLE-1] and the printed length ++ * of the number is "cpp". + */ +- cmap[i].cixel = gen_numstr(i, base, cpp); ++ cmap[i].cixel = gen_numstr(i, cpp); + + /* Fetch the rgb value of the current colormap entry. */ + red = PPM_GETR(chv[i].color); diff --git a/graphics/netpbm/patches/patch-by b/graphics/netpbm/patches/patch-by new file mode 100644 index 00000000000..02c652f2a9e --- /dev/null +++ b/graphics/netpbm/patches/patch-by @@ -0,0 +1,113 @@ +--- ./pnm/tifftopnm.c.orig Mon Oct 4 05:12:01 1993 ++++ ./pnm/tifftopnm.c Sun Aug 13 00:35:55 1995 +@@ -54,7 +54,7 @@ + int headerdump; + register u_char sample; + register int bitsleft; +- unsigned short bps, spp, photomet; ++ unsigned short bps, spp, photomet, planarconfig; + unsigned short* redcolormap; + unsigned short* greencolormap; + unsigned short* bluecolormap; +@@ -101,6 +101,13 @@ + spp = 1; + if ( ! TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photomet ) ) + pm_error( "error getting photometric" ); ++ if( spp > 1 ){ ++ if ( ! TIFFGetField( tif, TIFFTAG_PLANARCONFIG, &planarconfig ) ) ++ pm_error( "error getting planarconfig" ); ++ }else{ ++ planarconfig = PLANARCONFIG_CONTIG; ++ } ++ + + switch ( spp ) + { +@@ -114,6 +121,18 @@ + "can only handle 1-channel gray scale or 1- or 3-channel color" ); + } + ++ switch( planarconfig ) ++ { ++ case PLANARCONFIG_CONTIG: ++ break; ++ case PLANARCONFIG_SEPARATE: ++ if( photomet != PHOTOMETRIC_RGB ) ++ pm_error( "can only handle separate planes with RGB data" ); ++ break; ++ default: ++ pm_error("Unrecongnized PLANARCONFIG tag!\n"); ++ } ++ + (void) TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &cols ); + (void) TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &rows ); + +@@ -259,20 +278,54 @@ + break; + + case PHOTOMETRIC_RGB: +- for ( col = 0; col < cols; ++col, ++xP ) +- { +- register xelval r, g, b; +- +- NEXTSAMPLE +- r = sample; +- NEXTSAMPLE +- g = sample; +- NEXTSAMPLE +- b = sample; +- if ( spp == 4 ) +- NEXTSAMPLE /* skip alpha channel */ +- PPM_ASSIGN( *xP, r, g, b ); +- } ++ if( planarconfig == PLANARCONFIG_CONTIG ){ ++ for ( col = 0; col < cols; ++col, ++xP ) ++ { ++ register xelval r, g, b; ++ ++ NEXTSAMPLE ++ r = sample; ++ NEXTSAMPLE ++ g = sample; ++ NEXTSAMPLE ++ b = sample; ++ if ( spp == 4 ) ++ NEXTSAMPLE /* skip alpha channel */ ++ PPM_ASSIGN( *xP, r, g, b ); ++ } ++ }else{ ++ /* First clear the value and assign the reds */ ++ for ( col = 0; col < cols; ++col, ++xP ) ++ { ++ NEXTSAMPLE ++ PPM_ASSIGN( *xP, 0, 0, 0 ); ++ PPM_PUTR( *xP, sample ); ++ } ++ ++ /* Next the greens */ ++ if ( TIFFReadScanline( tif, buf, row, 1 ) < 0 ) ++ pm_error( "bad data read on green line %d", row ); ++ xP = xelrow; ++ inP = buf; ++ bitsleft = 8; ++ for ( col = 0; col < cols; ++col, ++xP ) ++ { ++ NEXTSAMPLE ++ PPM_PUTG( *xP, sample ); ++ } ++ ++ /* And finally the blues */ ++ if ( TIFFReadScanline( tif, buf, row, 2 ) < 0 ) ++ pm_error( "bad data read on green line %d", row ); ++ xP = xelrow; ++ inP = buf; ++ bitsleft = 8; ++ for ( col = 0; col < cols; ++col, ++xP ) ++ { ++ NEXTSAMPLE ++ PPM_PUTB( *xP, sample ); ++ } ++ } + break; + + default: diff --git a/graphics/netpbm/patches/patch-bz b/graphics/netpbm/patches/patch-bz new file mode 100644 index 00000000000..d95829211b6 --- /dev/null +++ b/graphics/netpbm/patches/patch-bz @@ -0,0 +1,51 @@ +--- ./ppm/xpmtoppm.c.orig Mon Jan 31 02:42:05 1994 ++++ ./ppm/xpmtoppm.c Fri Aug 18 05:30:36 1995 +@@ -30,9 +30,8 @@ + + #include "ppm.h" + +-static void ReadXPMFile ARGS((FILE *stream, int *widthP, int *heightP, +- int *ncolorsP, int *chars_per_pixelP, pixel **colorsP, int **dataP)); +-static void getline ARGS((char *line, int size, FILE *stream)); ++void ReadXPMFile(); ++static void getline(); + + /* number of xpmColorKeys */ + #define NKEYS 5 +@@ -46,7 +45,27 @@ + "c", /* key #5: color visual */ + }; + +-int ++#ifdef NEED_STRSTR ++/* for systems which do not provide it */ ++static char * ++strstr(s1, s2) ++ char *s1, *s2; ++{ ++ int ls2 = strlen(s2); ++ ++ if (ls2 == 0) ++ return (s1); ++ while (strlen(s1) >= ls2) { ++ if (strncmp(s1, s2, ls2) == 0) ++ return (s1); ++ s1++; ++ } ++ return (0); ++} ++ ++#endif ++ ++void + main(argc, argv) + int argc; + char *argv[]; +@@ -89,7 +108,6 @@ + + #define MAX_LINE 2048 + +-static + void + ReadXPMFile(stream, widthP, heightP, ncolorsP, + chars_per_pixelP, colorsP, dataP) diff --git a/graphics/netpbm/pkg/PLIST b/graphics/netpbm/pkg/PLIST index 1327dd88426..935265ecc83 100644 --- a/graphics/netpbm/pkg/PLIST +++ b/graphics/netpbm/pkg/PLIST @@ -1,4 +1,4 @@ -@comment $NetBSD: PLIST,v 1.3 1997/12/31 03:34:57 hubertf Exp $ +@comment $NetBSD: PLIST,v 1.4 1998/07/15 19:52:58 tron Exp $ bin/anytopnm bin/asciitopgm bin/atktopbm @@ -89,6 +89,7 @@ bin/pnmenlarge bin/pnmfile bin/pnmflip bin/pnmgamma +bin/pnmhisteq bin/pnmhistmap bin/pnmindex bin/pnminvert @@ -268,6 +269,7 @@ man/man1/pnmenlarge.1 man/man1/pnmfile.1 man/man1/pnmflip.1 man/man1/pnmgamma.1 +man/man1/pnmhisteq.1 man/man1/pnmhistmap.1 man/man1/pnmindex.1 man/man1/pnminvert.1 |