aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2020-12-14 00:04:30 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2020-12-14 00:04:30 +0000
commit2723e0371c97959bd79eab9999667b5c279739fc (patch)
treed3e1340052e17549e327174e54afcd1d195f0db7
parent160db7518867b15be982cd2ac54bb827f76bcc86 (diff)
downloadnetpbm-mirror-2723e0371c97959bd79eab9999667b5c279739fc.tar.gz
netpbm-mirror-2723e0371c97959bd79eab9999667b5c279739fc.tar.xz
netpbm-mirror-2723e0371c97959bd79eab9999667b5c279739fc.zip
Convert to shhopt
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@4006 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r--editor/pamaddnoise.c408
1 files changed, 177 insertions, 231 deletions
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 <assert.h>
#include <math.h>
#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;
}