diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2013-12-22 19:10:25 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2013-12-22 19:10:25 +0000 |
commit | 00b5c554ee6d2ec2f1f8b29ebd7b4bbaa8581cb9 (patch) | |
tree | d8f29fe03a11046ccdf0a33246e31d2d41ca9172 | |
parent | 8796566268e8f7469f8dc6ccc41cf03d135c4d74 (diff) | |
download | netpbm-mirror-00b5c554ee6d2ec2f1f8b29ebd7b4bbaa8581cb9.tar.gz netpbm-mirror-00b5c554ee6d2ec2f1f8b29ebd7b4bbaa8581cb9.tar.xz netpbm-mirror-00b5c554ee6d2ec2f1f8b29ebd7b4bbaa8581cb9.zip |
Add -changemaxval
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@2075 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r-- | doc/HISTORY | 2 | ||||
-rw-r--r-- | editor/pamfunc.c | 79 |
2 files changed, 72 insertions, 9 deletions
diff --git a/doc/HISTORY b/doc/HISTORY index 27e58d86..5c4067df 100644 --- a/doc/HISTORY +++ b/doc/HISTORY @@ -6,6 +6,8 @@ CHANGE HISTORY not yet BJH Release 10.65.00 + pamfunc: add -changemaxval. + pgmkernel: add -maxval. Recognize SIGPWR on systems that have it in messages diff --git a/editor/pamfunc.c b/editor/pamfunc.c index bcec22f3..5945b82d 100644 --- a/editor/pamfunc.c +++ b/editor/pamfunc.c @@ -13,8 +13,8 @@ multiply/divide where possible. Especially when multiplying by an integer. - 2) For multiply/divide, give option of simply changing the maxval and - leaving the raster alone. + 2) speed up by not transforming the raster in the idempotent cases + (e.g. multiply by one). ******************************************************************************/ @@ -58,6 +58,7 @@ struct CmdlineInfo { unsigned int mask; unsigned int shiftCount; } u; + unsigned int changemaxval; unsigned int verbose; }; @@ -126,7 +127,10 @@ parseCommandLine(int argc, const char ** const argv, &shiftleftSpec, 0); OPTENT3(0, "shiftright", OPT_UINT, &cmdlineP->u.shiftCount, &shiftrightSpec, 0); - OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); + OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, + 0); + OPTENT3(0, "changemaxval", OPT_FLAG, NULL, &cmdlineP->changemaxval, + 0); opt.opt_table = option_def; opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ @@ -260,6 +264,57 @@ validateFunction(struct CmdlineInfo const cmdline, static void +planTransform(struct CmdlineInfo const cmdline, + sample const inputMaxval, + sample * const outputMaxvalP, + bool * const mustChangeRasterP) { +/*---------------------------------------------------------------------------- + Plan the transform described by 'cmdline', given the maxval of the input + image is 'inputMaxval. + + The plan just consists of whether to change the maxval or the raster. + Some multiplications and divisions can be achieved just by changing the + maxval and leaving the samples in the raster alone. +-----------------------------------------------------------------------------*/ + if (cmdline.changemaxval) { + /* User allows us to change the maxval, if that makes it easier */ + if (cmdline.function == FN_MULTIPLY || cmdline.function == FN_DIVIDE) { + float const multiplier = + cmdline.function == FN_MULTIPLY ? cmdline.u.multiplier : + (1/cmdline.u.divisor); + + float const neededMaxval = inputMaxval / multiplier; + + if (neededMaxval + 0.5 < inputMaxval) { + /* Lowering the maxval might make some of the sample values + higher than the maxval, so we'd have to modify the raster + to clip them. + */ + *outputMaxvalP = inputMaxval; + *mustChangeRasterP = true; + } else if (neededMaxval > PAM_OVERALL_MAXVAL) { + *outputMaxvalP = inputMaxval; + *mustChangeRasterP = true; + } else { + *outputMaxvalP = ROUNDU(neededMaxval); + *mustChangeRasterP = false; + } + } else { + *outputMaxvalP = inputMaxval; + *mustChangeRasterP = true; + } + } else { + *outputMaxvalP = inputMaxval; + *mustChangeRasterP = true; + } + if (*outputMaxvalP != inputMaxval) + pm_message("Changing maxval to %u because of -changemaxval", + (unsigned)*outputMaxvalP); +} + + + +static void applyFunction(struct CmdlineInfo const cmdline, struct pam const inpam, struct pam const outpam, @@ -276,10 +331,10 @@ applyFunction(struct CmdlineInfo const cmdline, divide, both cmdline.u.divisor and oneOverDivisor are meaningless. */ - int col; + unsigned int col; for (col = 0; col < inpam.width; ++col) { - int plane; + unsigned int plane; for (plane = 0; plane < inpam.depth; ++plane) { sample const inSample = inputRow[col][plane]; sample outSample; /* Could be > maxval */ @@ -336,10 +391,11 @@ main(int argc, const char *argv[]) { FILE * ifP; tuple * inputRow; /* Row from input image */ tuple * outputRow; /* Row of output image */ - int row; + unsigned int row; struct CmdlineInfo cmdline; struct pam inpam; /* Input PAM image */ struct pam outpam; /* Output PAM image */ + bool mustChangeRaster; pm_proginit(&argc, argv); @@ -356,16 +412,21 @@ main(int argc, const char *argv[]) { outpam = inpam; /* Initial value -- most fields should be same */ outpam.file = stdout; + planTransform(cmdline, inpam.maxval, &outpam.maxval, &mustChangeRaster); + pnm_writepaminit(&outpam); outputRow = pnm_allocpamrow(&outpam); - for (row = 0; row < inpam.height; row++) { + for (row = 0; row < inpam.height; ++row) { pnm_readpamrow(&inpam, inputRow); - applyFunction(cmdline, inpam, outpam, inputRow, outputRow); + if (mustChangeRaster) { + applyFunction(cmdline, inpam, outpam, inputRow, outputRow); - pnm_writepamrow(&outpam, outputRow); + pnm_writepamrow(&outpam, outputRow); + } else + pnm_writepamrow(&outpam, inputRow); } pnm_freepamrow(outputRow); pnm_freepamrow(inputRow); |