This is pgmnorm.c in view mode; [Download] [Up]
/* pgmnorm.c - read a portable graymap and normalize the contrast ** ** Copyright (C) 1989, 1991 by Jef Poskanzer. ** ** Permission to use, copy, modify, and distribute this software and its ** documentation for any purpose and without fee is hereby granted, provided ** that the above copyright notice appear in all copies and that both that ** copyright notice and this permission notice appear in supporting ** documentation. This software is provided "as is" without express or ** implied warranty. */ #include "pgm.h" static int hist[PGM_MAXMAXVAL+1]; int main( argc, argv ) int argc; char* argv[]; { FILE* ifp; gray maxval; gray** grays; gray* grayrow; register gray* gP; int argn, rows, cols, format, row; register int col; int i, size, cutoff, count, val; float bpercent, wpercent; int bvalue, wvalue, range; int specbpercent, specbvalue, specwpercent, specwvalue; char* usage = "[-bpercent N | -bvalue N] [-wpercent N | -wvalue N] [pgmfile]"; pgm_init( &argc, argv ); argn = 1; bpercent = 2.0; wpercent = 1.0; specbpercent = specbvalue = specwpercent = specwvalue = 0; while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) { if ( pm_keymatch( argv[argn], "-bpercent", 3 ) ) { if ( specbvalue ) pm_error( "only one of -bpercent and -bvalue may be specified" ); ++argn; if ( argn == argc || sscanf( argv[argn], "%f", &bpercent ) != 1 ) pm_usage( usage ); if ( bpercent < 0.0 || bpercent > 100.0 ) pm_error( "black percentage must between 0 and 100" ); specbpercent = 1; } else if ( pm_keymatch( argv[argn], "-bvalue", 3 ) ) { if ( specbpercent ) pm_error( "only one of -bpercent and -bvalue may be specified" ); ++argn; if ( argn == argc || sscanf( argv[argn], "%d", &bvalue ) != 1 ) pm_usage( usage ); if ( bvalue < 0 ) pm_error( "black value must be >= 0" ); specbvalue = 1; } else if ( pm_keymatch( argv[argn], "-wpercent", 3 ) ) { if ( specwvalue ) pm_error( "only one of -wpercent and -wvalue may be specified" ); ++argn; if ( argn == argc || sscanf( argv[argn], "%f", &wpercent ) != 1 ) pm_usage( usage ); if ( wpercent < 0.0 || wpercent > 100.0 ) pm_error( "white percentage must be between 0 and 100" ); specwpercent = 1; } else if ( pm_keymatch( argv[argn], "-wvalue", 3 ) ) { if ( specwpercent ) pm_error( "only one of -wpercent and -wvalue may be specified" ); ++argn; if ( argn == argc || sscanf( argv[argn], "%d", &wvalue ) != 1 ) pm_usage( usage ); if ( wvalue < 0 ) pm_error( "white value must be >= 0" ); specwvalue = 1; } else pm_usage( usage ); ++argn; } if ( argn < argc ) { ifp = pm_openr( argv[argn] ); ++argn; } else ifp = stdin; if ( argn != argc ) pm_usage( usage ); if ( specbvalue && specwvalue ) { /* Rescale so that bvalue maps to 0, wvalue maps to maxval. */ pgm_readpgminit( ifp, &cols, &rows, &maxval, &format ); grayrow = pgm_allocrow( cols ); pgm_writepgminit( stdout, cols, rows, maxval, 0 ); for ( i = 0; i <= bvalue; ++i ) hist[i] = 0; for ( i = wvalue; i <= maxval; ++i ) hist[i] = maxval; range = wvalue - bvalue; for ( i = bvalue+1, val = maxval; i < wvalue; ++i, val += maxval ) hist[i] = val / range; for ( row = 0; row < rows; ++row ) { pgm_readpgmrow( ifp, grayrow, cols, maxval, format ); for ( col = 0, gP = grayrow; col < cols; ++col, ++gP ) *gP = hist[*gP]; pgm_writepgmrow( stdout, grayrow, cols, maxval, 0 ); } pm_close( ifp ); } else { grays = pgm_readpgm( ifp, &cols, &rows, &maxval ); pm_close( ifp ); /* Build histogram. */ for ( i = 0; i <= maxval; ++i ) hist[i] = 0; for ( row = 0; row < rows; ++row ) for ( col = 0, gP = grays[row]; col < cols; ++col, ++gP ) ++hist[*gP]; size = rows * cols; if ( ! specbvalue ) { /* Compute bvalue from bpercent. */ cutoff = size * bpercent / 100.0; count = 0; for ( bvalue = 0; bvalue <= maxval; ++bvalue ) { count += hist[bvalue]; if ( count > cutoff ) break; } } if ( ! specwvalue ) { /* Compute wvalue from wpercent. */ cutoff = size * wpercent / 100.0; count = 0; for ( wvalue = maxval; wvalue >= 0; wvalue-- ) { count += hist[wvalue]; if ( count > cutoff ) break; } } /* Now rescale so that bvalue maps to 0, wvalue maps to maxval. */ pm_message( "remapping %d..%d to %d..%d", bvalue, wvalue, 0, maxval, 0 ); pgm_writepgminit( stdout, cols, rows, maxval, 0 ); for ( i = 0; i <= bvalue; ++i ) hist[i] = 0; for ( i = wvalue; i <= maxval; ++i ) hist[i] = maxval; range = wvalue - bvalue; for ( i = bvalue + 1, val = maxval; i < wvalue; ++i, val += maxval ) hist[i] = val / range; for ( row = 0; row < rows; ++row ) { for ( col = 0, gP = grays[row]; col < cols; ++col, ++gP ) *gP = hist[*gP]; pgm_writepgmrow( stdout, grays[row], cols, maxval, 0 ); } } pm_close( stdout ); exit( 0 ); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.