brianm@sco.COM (Brian Moffet) (11/29/90)
This needs the pbm libraries and header files to compile. ------------ cut here ------------ #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # ppmbrighten.1 # ppmbrighten.c # This archive created: Wed Nov 28 13:03:06 1990 export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'ppmbrighten.1' then echo shar: "will not over-write existing file 'ppmbrighten.1'" else cat << \SHAR_EOF > 'ppmbrighten.1' .TH ppmbrighten 1 "20 Nov 1990" .SH NAME ppmbrighten - change an images Saturation and Value from an HSV map .SH SYNOPSIS ppmbrighten [-n] [-s <+- saturation>] [-v <+- value>] <ppmfile> .SH DESCRIPTION Reads a portable pixmap as input. Converts the image from RGB space to HSV space and changes the Value by <+- value> as a percentage. Likewise with the Saturation. Doubling the Value would involve .sp ppmbrighten -v 100 .sp to add 100 percent to the Value. .PP The 'n' option normalizes the Value to exist between 0 and 1 (normalized). .SH "SEE ALSO" pgmnorm(1), ppm(5) .SH AUTHOR Copyright (C) 1990 by Brian Moffet Copyright (C) 1989 by Jef Poskanzer. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. This software is provided "as is" without express or implied warranty. .SH NOTES This program does not change the number of colors. SHAR_EOF fi if test -f 'ppmbrighten.c' then echo shar: "will not over-write existing file 'ppmbrighten.c'" else cat << \SHAR_EOF > 'ppmbrighten.c' /* ppmbrighten.c - allow user control over Value and Saturation of PPM file ** ** Copyright (C) 1989 by Jef Poskanzer. ** Copyright (C) 1990 by Brian Moffet. ** ** Permission to use, copy, modify, and distribute this software and its ** documentation for any purpose and without fee is hereby granted, provided ** that the above copyright notice appear in all copies and that both that ** copyright notice and this permission notice appear in supporting ** documentation. This software is provided "as is" without express or ** implied warranty. */ #include <stdio.h> #include "ppm.h" #define MULTI 1000 #define FIND_MINMAX 1 #define SET_VALUE 2 #define SET_SATUR 4 main( argc, argv ) int argc; char *argv[]; { FILE *fp = stdin; extern char *optarg; extern int optind; int value = 100, saturation = 100, c, error = 0; int min_value, max_value; int flags = 0; pixel *pixelP; pixval maxval; int rows, cols, format, index; while ((c = getopt( argc, argv, "s:v:n" )) != -1) switch (c) { case 's': flags |= SET_SATUR; saturation = 100 + atoi( optarg ); break; case 'v': flags |= SET_SATUR; value = 100 + atoi( optarg ); break; case 'n': flags |= FIND_MINMAX; break; default: error = 1; break; } if (error) { fprintf( stderr, "Usage: %s [-s <+- saturation>] [-v <+- value>] <ppmfile>\n", argv[0] ); exit( 1 ); } if (value < 0) value = 0; if (saturation < 0) saturation = 0; if (optind != argc) if ((fp = fopen( argv[optind], "r" )) == NULL ) { fprintf( stderr, "Coundn't open %s for reading\n", argv[optind] ); exit( 1 ); } if (flags & FIND_MINMAX) { ppm_readppminit( fp, &cols, &rows, &maxval, &format ); pixelP = ppm_allocrow( cols ); max_value = 0; min_value = MULTI; for (index = 0; index < rows; index++) { int i; ppm_readppmrow( fp, pixelP, cols, maxval, format ); for (i = 0; i < cols; i++) { int r, g, b; long R, G, B, H, S, V; r = PPM_GETR( pixelP[i] ); g = PPM_GETG( pixelP[i] ); b = PPM_GETB( pixelP[i] ); R = (MULTI * r + maxval - 1) / maxval; G = (MULTI * g + maxval - 1) / maxval; B = (MULTI * b + maxval - 1) / maxval; GetHSV( R, G, B, &H, &S, &V ); if ( V > max_value) max_value = V; if ( V < min_value) min_value = V; } } ppm_freerow( pixelP ); fprintf( stderr, "Min is %4d\tMax = %4d\n", min_value, max_value ); rewind( fp ); } ppm_readppminit( fp, &cols, &rows, &maxval, &format ); ppm_writeppminit( stdout, cols, rows, maxval ); pixelP = ppm_allocrow( cols ); if (pixelP == NULL) { fprintf( stderr, "Error allocating Pixel row\n" ); exit( 3 ); } for (index = 0; index < rows; index++) { int i; ppm_readppmrow( fp, pixelP, cols, maxval, format ); for (i = 0; i < cols; i++) { int r, g, b; long R, G, B, H, S, V; r = PPM_GETR( pixelP[i] ); g = PPM_GETG( pixelP[i] ); b = PPM_GETB( pixelP[i] ); R = (MULTI * r + maxval - 1) / maxval; G = (MULTI * g + maxval - 1) / maxval; B = (MULTI * b + maxval - 1) / maxval; GetHSV( R, G, B, &H, &S, &V ); if (flags & FIND_MINMAX) { V -= min_value; V = (V * MULTI) / (MULTI - (min_value+MULTI-max_value)); } S = ( S * saturation ) / 100; V = ( V * value ) / 100; if (V > MULTI) V = MULTI; if (S > MULTI) S = MULTI; GetRGB( H, S, V, &R, &G, &B ); r = (R * maxval) / MULTI; g = (G * maxval) / MULTI; b = (B * maxval) / MULTI; PPM_ASSIGN( pixelP[i], r, g, b ); } ppm_writeppmrow( stdout, pixelP, cols, maxval ); } ppm_freerow( pixelP ); if (fp != stdin) fclose( fp ); } #define min(x,y) ((x < y) ? x : y) #define max(x,y) ((x > y) ? x : y) static int GetHSV( r, g, b, h, s, v ) long r, g, b; long *h, *s, *v; { long t; *v = max( r, max( g, b ) ); t = min( r, min( g, b ) ); if ( *v == 0 ) *s = 0; else *s = ( (*v - t)*MULTI ) / *v; if ( *s == 0 ) *h = 0; else { long cr, cg, cb; cr = (MULTI * ( *v - r ))/( *v - t ); cg = (MULTI * ( *v - g ))/( *v - t ); cb = (MULTI * ( *v - b ))/( *v - t ); if ( r == *v ) *h = cb - cg; if ( g == *v ) *h = (2*MULTI) + cr - cb; if ( b == *v ) *h = (4*MULTI) + cg - cr; *h = *h * 60; if ( *h < 0 ) *h += (360 * MULTI); } } static int GetRGB( h, s, v, r, g, b ) long h, s, v; long *r, *g, *b; { if ( s == 0 ) { *r = v; *g = v; *b = v; } else { long f, m, n, k; long i; if (h == (360 * MULTI)) h = 0; h = h / 60; i = (h - (h % MULTI)); f = h - i; m = (v * (MULTI - s)) / MULTI; n = (v * (MULTI - (s * f)/MULTI)) / MULTI; k = (v * (MULTI - (s * (MULTI - f))/MULTI)) / MULTI; switch (i) { case 0: *r = v; *g = k; *b = m; break; case MULTI: *r = n; *g = v; *b = m; break; case (2*MULTI): *r = m; *g = v; *b = k; break; case (3*MULTI): *r = m; *g = n; *b = v; break; case (4*MULTI): *r = k; *g = m; *b = v; break; case (5*MULTI): *r = v; *g = m; *b = n; break; } } } SHAR_EOF fi exit 0 # End of shell archive -- Brian Moffet ext 6567 brianm@sco.com -or- ...!uunet!sco!brianm "Processed American Cheese Food.... Dog Food, Cat Food, Cheese Food?" -- Dan St. Paul