From 2723e0371c97959bd79eab9999667b5c279739fc Mon Sep 17 00:00:00 2001 From: giraffedata Date: Mon, 14 Dec 2020 00:04:30 +0000 Subject: Convert to shhopt git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@4006 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- editor/pamaddnoise.c | 408 ++++++++++++++++++++++----------------------------- 1 file changed, 177 insertions(+), 231 deletions(-) (limited to 'editor') diff --git a/editor/pamaddnoise.c b/editor/pamaddnoise.c index 8035b197..20c68d99 100644 --- a/editor/pamaddnoise.c +++ b/editor/pamaddnoise.c @@ -28,9 +28,12 @@ #define _XOPEN_SOURCE 500 /* get M_PI in math.h */ +#include #include #include "pm_c_util.h" +#include "mallocvar.h" +#include "shhopt.h" #include "pm_gamma.h" #include "pam.h" @@ -46,17 +49,167 @@ rand1() { -enum noiseType { - GAUSSIAN, - IMPULSE, /* aka salt and pepper noise */ - LAPLACIAN, - MULTIPLICATIVE_GAUSSIAN, - POISSON, - MAX_NOISE_TYPES +enum NoiseType { + NOISETYPE_GAUSSIAN, + NOISETYPE_IMPULSE, /* aka salt and pepper noise */ + NOISETYPE_LAPLACIAN, + NOISETYPE_MULTIPLICATIVE_GAUSSIAN, + NOISETYPE_POISSON }; +struct CmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char * inputFileName; + + enum NoiseType noiseType; + + unsigned int seed; + + float lambda; + float lsigma; + float mgsigma; + float sigma1; + float sigma2; + float tolerance; +}; + + + +static enum NoiseType +typeFmName(const char * const name) { + + enum NoiseType retval; + + if (false) + assert(false); + else if (pm_keymatch(name, "gaussian", 1)) + retval = NOISETYPE_GAUSSIAN; + else if (pm_keymatch(name, "impulse", 1)) + retval = NOISETYPE_IMPULSE; + else if (pm_keymatch(name, "laplacian", 1)) + retval = NOISETYPE_LAPLACIAN; + else if (pm_keymatch(name, "multiplicative_gaussian", 1)) + retval = NOISETYPE_MULTIPLICATIVE_GAUSSIAN; + else if (pm_keymatch(name, "poisson", 1)) + retval = NOISETYPE_POISSON; + else + pm_error("Unrecognized -type value '%s'. " + "We recognize 'gaussian', 'impulse', 'laplacian', " + "'multiplicative_gaussian', and 'poisson'", name); + + return retval; +} + + + +static void +parseCommandLine(int argc, const char ** const argv, + struct CmdlineInfo * const cmdlineP) { +/*---------------------------------------------------------------------------- + Note that the file spec array we return is stored in the storage that + was passed to us as the argv array. +-----------------------------------------------------------------------------*/ + optEntry * option_def; + /* Instructions to OptParseOptions3 on how to parse our options. */ + optStruct3 opt; + + unsigned int option_def_index; + + unsigned int typeSpec, seedSpec, lambdaSpec, lsigmaSpec, mgsigmaSpec, + sigma1Spec, sigma2Spec, toleranceSpec; + + const char * type; + + MALLOCARRAY(option_def, 100); + + option_def_index = 0; /* incremented by OPTENT3 */ + OPTENT3(0, "type", OPT_STRING, &type, + &typeSpec, 0); + OPTENT3(0, "seed", OPT_UINT, &cmdlineP->seed, + &seedSpec, 0); + OPTENT3(0, "lambda", OPT_FLOAT, &cmdlineP->lambda, + &lambdaSpec, 0); + OPTENT3(0, "lsigma", OPT_FLOAT, &cmdlineP->lsigma, + &lsigmaSpec, 0); + OPTENT3(0, "mgsigma", OPT_FLOAT, &cmdlineP->mgsigma, + &mgsigmaSpec, 0); + OPTENT3(0, "sigma1", OPT_FLOAT, &cmdlineP->sigma1, + &sigma1Spec, 0); + OPTENT3(0, "sigma2", OPT_FLOAT, &cmdlineP->sigma2, + &sigma2Spec, 0); + OPTENT3(0, "tolerance", OPT_FLOAT, &cmdlineP->tolerance, + &toleranceSpec, 0); + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ + opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ + + pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + + if (!typeSpec) + cmdlineP->noiseType = NOISETYPE_GAUSSIAN; + else + cmdlineP->noiseType = typeFmName(type); + + if (sigma1Spec && cmdlineP->noiseType != NOISETYPE_GAUSSIAN) + pm_error("-sigma1 is valid only with -type=gaussian"); + + if (sigma2Spec && cmdlineP->noiseType != NOISETYPE_GAUSSIAN) + pm_error("-sigma2 is valid only with -type=gaussian"); + + if (mgsigmaSpec && + cmdlineP->noiseType != NOISETYPE_MULTIPLICATIVE_GAUSSIAN) + pm_error("-mgsigma is valid only with -type=multiplicative_guassian"); + + if (toleranceSpec && cmdlineP->noiseType != NOISETYPE_IMPULSE) + pm_error("-tolerance is valid only with -type=impulse"); + + if (lsigmaSpec && cmdlineP->noiseType != NOISETYPE_LAPLACIAN) + pm_error("-lsigma is valid only with -type=laplacian"); + + if (lambdaSpec && cmdlineP->noiseType != NOISETYPE_POISSON) + pm_error("-lambda is valid only with -type=poisson"); + + if (!lambdaSpec) + cmdlineP->lambda = 12.0; + + if (!lsigmaSpec) + cmdlineP->lsigma = 10.0; + + if (!mgsigmaSpec) + cmdlineP->mgsigma = 0.5; + + if (!sigma1Spec) + cmdlineP->sigma1 = 4.0; + + if (!sigma2Spec) + cmdlineP->sigma2 = 20.0; + + if (!toleranceSpec) + cmdlineP->tolerance = 0.10; + + if (!seedSpec) + cmdlineP->seed = pm_randseed(); + + if (argc-1 > 1) + pm_error("Too many arguments (%u). File spec is the only argument.", + argc-1); + + if (argc-1 < 1) + cmdlineP->inputFileName = "-"; + else + cmdlineP->inputFileName = argv[1]; + + free(option_def); +} + + + static void addGaussianNoise(sample const maxval, sample const origSample, @@ -253,9 +406,10 @@ addPoissonNoise(struct pam * const pamP, int -main(int argc, char * argv[]) { +main(int argc, const char ** argv) { FILE * ifP; + struct CmdlineInfo cmdline; struct pam inpam; struct pam outpam; tuple * tuplerow; @@ -263,221 +417,13 @@ main(int argc, char * argv[]) { unsigned int row; double infinity; - int argn; - const char * inputFilename; - int noise_type; - unsigned int seed; - int i; - const char * const usage = "[-type noise_type] [-lsigma x] [-mgsigma x] " - "[-sigma1 x] [-sigma2 x] [-lambda x] [-seed n] " - "[-tolerance ratio] [pgmfile]"; - - const char * const noise_name[] = { - "gaussian", - "impulse", - "laplacian", - "multiplicative_gaussian", - "poisson" - }; - int const noise_id[] = { - GAUSSIAN, - IMPULSE, - LAPLACIAN, - MULTIPLICATIVE_GAUSSIAN, - POISSON - }; - /* minimum number of characters to match noise name for pm_keymatch() */ - int const noise_compare[] = { - 1, - 1, - 1, - 1, - 1 - }; - - /* define default values for configurable options */ - float lambda = 12.0; - float lsigma = 10.0; - float mgsigma = 0.5; - float sigma1 = 4.0; - float sigma2 = 20.0; - float tolerance = 0.10; - - pnm_init(&argc, argv); - - seed = pm_randseed(); - noise_type = GAUSSIAN; - - argn = 1; - while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' ) - { - if ( pm_keymatch( argv[argn], "-lambda", 3 ) ) - { - ++argn; - if ( argn >= argc ) - { - pm_message( - "incorrect number of arguments for -lambda option" ); - pm_usage( usage ); - } - else if ( argv[argn][0] == '-' ) - { - pm_message( "invalid argument to -lambda option: %s", - argv[argn] ); - pm_usage( usage ); - } - lambda = atof( argv[argn] ); - } - else if ( pm_keymatch( argv[argn], "-lsigma", 3 ) ) - { - ++argn; - if ( argn >= argc ) - { - pm_message( - "incorrect number of arguments for -lsigma option" ); - pm_usage( usage ); - } - else if ( argv[argn][0] == '-' ) - { - pm_message( "invalid argument to -lsigma option: %s", - argv[argn] ); - pm_usage( usage ); - } - lsigma = atof( argv[argn] ); - } - else if ( pm_keymatch( argv[argn], "-mgsigma", 2 ) ) - { - ++argn; - if ( argn >= argc ) - { - pm_message( - "incorrect number of arguments for -mgsigma option" ); - pm_usage( usage ); - } - else if ( argv[argn][0] == '-' ) - { - pm_message( "invalid argument to -mgsigma option: %s", - argv[argn] ); - pm_usage( usage ); - } - mgsigma = atof( argv[argn] ); - } - else if ( pm_keymatch( argv[argn], "-seed", 3 ) ) - { - ++argn; - if ( argn >= argc ) - { - pm_message( "incorrect number of arguments for -seed option" ); - pm_usage( usage ); - } - else if ( argv[argn][0] == '-' ) - { - pm_message( "invalid argument to -seed option: %s", - argv[argn] ); - pm_usage( usage ); - } - seed = atoi(argv[argn]); - } - else if ( pm_keymatch( argv[argn], "-sigma1", 7 ) || - pm_keymatch( argv[argn], "-s1", 3 ) ) - { - ++argn; - if ( argn >= argc ) - { - pm_message( - "incorrect number of arguments for -sigma1 option" ); - pm_usage( usage ); - } - else if ( argv[argn][0] == '-' ) - { - pm_message( "invalid argument to -sigma1 option: %s", - argv[argn] ); - pm_usage( usage ); - } - sigma1 = atof( argv[argn] ); - } - else if ( pm_keymatch( argv[argn], "-sigma2", 7 ) || - pm_keymatch( argv[argn], "-s2", 3 ) ) - { - ++argn; - if ( argn >= argc ) - { - pm_message( - "incorrect number of arguments for -sigma2 option" ); - pm_usage( usage ); - } - else if ( argv[argn][0] == '-' ) - { - pm_message( "invalid argument to -sigma2 option: %s", - argv[argn] ); - pm_usage( usage ); - } - sigma2 = atof( argv[argn] ); - } - else if ( pm_keymatch( argv[argn], "-tolerance", 3 ) ) - { - ++argn; - if ( argn >= argc ) - { - pm_message( - "incorrect number of arguments for -tolerance option" ); - pm_usage( usage ); - } - else if ( argv[argn][0] == '-' ) - { - pm_message( "invalid argument to -tolerance option: %s", - argv[argn] ); - pm_usage( usage ); - } - tolerance = atof( argv[argn] ); - } - else if ( pm_keymatch( argv[argn], "-type", 3 ) ) - { - ++argn; - if ( argn >= argc ) - { - pm_message( "incorrect number of arguments for -type option" ); - pm_usage( usage ); - } - else if ( argv[argn][0] == '-' ) - { - pm_message( "invalid argument to -type option: %s", - argv[argn] ); - pm_usage( usage ); - } - /* search through list of valid noise types and compare */ - i = 0; - while ( ( i < MAX_NOISE_TYPES ) && - !pm_keymatch( argv[argn], - noise_name[i], noise_compare[i] ) ) - ++i; - if ( i >= MAX_NOISE_TYPES ) - { - pm_message( "invalid argument to -type option: %s", - argv[argn] ); - pm_usage( usage ); - } - noise_type = noise_id[i]; - } - else - pm_usage( usage ); - ++argn; - } - - if ( argn < argc ) - { - inputFilename = argv[argn]; - argn++; - } - else - inputFilename = "-"; + pm_proginit(&argc, argv); - if ( argn != argc ) - pm_usage( usage ); + parseCommandLine(argc, argv, &cmdline); - srand(seed); + srand(cmdline.seed); - ifP = pm_openr(inputFilename); + ifP = pm_openr(cmdline.inputFileName); pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); @@ -497,40 +443,40 @@ main(int argc, char * argv[]) { for (col = 0; col < inpam.width; ++col) { unsigned int plane; for (plane = 0; plane < inpam.depth; ++plane) { - switch (noise_type) { - case GAUSSIAN: + switch (cmdline.noiseType) { + case NOISETYPE_GAUSSIAN: addGaussianNoise(inpam.maxval, tuplerow[col][plane], &newtuplerow[col][plane], - sigma1, sigma2); + cmdline.sigma1, cmdline.sigma2); break; - case IMPULSE: + case NOISETYPE_IMPULSE: addImpulseNoise(inpam.maxval, tuplerow[col][plane], &newtuplerow[col][plane], - tolerance); + cmdline.tolerance); break; - case LAPLACIAN: + case NOISETYPE_LAPLACIAN: addLaplacianNoise(inpam.maxval, infinity, tuplerow[col][plane], &newtuplerow[col][plane], - lsigma); + cmdline.lsigma); break; - case MULTIPLICATIVE_GAUSSIAN: + case NOISETYPE_MULTIPLICATIVE_GAUSSIAN: addMultiplicativeGaussianNoise(inpam.maxval, infinity, tuplerow[col][plane], &newtuplerow[col][plane], - mgsigma); + cmdline.mgsigma); break; - case POISSON: + case NOISETYPE_POISSON: addPoissonNoise(&inpam, tuplerow[col][plane], &newtuplerow[col][plane], - lambda); + cmdline.lambda); break; } -- cgit 1.4.1