diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2015-07-26 00:38:01 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2015-07-26 00:38:01 +0000 |
commit | a507d475a249a41fe3452279c21fa5d595f39289 (patch) | |
tree | 9f7f58ebc540d2e0994c3686de96bd6f6b769eb7 /other | |
parent | 3a64dd90c11ae9dbd712f3df1708d635503d5f72 (diff) | |
download | netpbm-mirror-a507d475a249a41fe3452279c21fa5d595f39289.tar.gz netpbm-mirror-a507d475a249a41fe3452279c21fa5d595f39289.tar.xz netpbm-mirror-a507d475a249a41fe3452279c21fa5d595f39289.zip |
Add -byplane
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@2610 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'other')
-rw-r--r-- | other/pamlookup.c | 182 |
1 files changed, 142 insertions, 40 deletions
diff --git a/other/pamlookup.c b/other/pamlookup.c index d5f046a5..83f8a68c 100644 --- a/other/pamlookup.c +++ b/other/pamlookup.c @@ -13,32 +13,36 @@ ============================================================================*/ +#include <assert.h> + #include "pm_c_util.h" -#include "pam.h" +#include "mallocvar.h" #include "shhopt.h" #include "pm_system.h" #include "nstring.h" +#include "pam.h" -struct cmdlineInfo { +struct CmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. */ - const char *indexFilespec; - char *lookupFilespec; - char *missingcolor; /* -missingcolor value. null if not specified */ - unsigned int fit; /* -fit option */ + const char * indexFilespec; + char * lookupFilespec; + char * missingcolor; /* null if not specified */ + unsigned int fit; + unsigned int byplane; }; static void -parseCommandLine(int argc, char ** const argv, - struct cmdlineInfo * const cmdlineP) { +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 = malloc(100*sizeof(optEntry)); + optEntry * option_def; /* Instructions to OptParseOptions2 on how to parse our options. */ optStruct3 opt; @@ -47,6 +51,8 @@ parseCommandLine(int argc, char ** const argv, unsigned int lookupfileSpec, missingcolorSpec; + MALLOCARRAY_NOFAIL(option_def, 100); + option_def_index = 0; /* incremented by OPTENTRY */ OPTENT3(0, "lookupfile", OPT_STRING, &cmdlineP->lookupFilespec, &lookupfileSpec, 0); @@ -54,12 +60,14 @@ parseCommandLine(int argc, char ** const argv, &cmdlineP->missingcolor, &missingcolorSpec, 0); OPTENT3(0, "fit", OPT_FLAG, NULL, &cmdlineP->fit, 0); + OPTENT3(0, "byplane", OPT_FLAG, + NULL, &cmdlineP->byplane, 0); opt.opt_table = option_def; opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We may have parms that are negative numbers */ - pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (!lookupfileSpec) @@ -68,10 +76,15 @@ parseCommandLine(int argc, char ** const argv, if (!missingcolorSpec) cmdlineP->missingcolor = NULL; + if (cmdlineP->byplane && cmdlineP->missingcolor) + pm_error("You cannot specify -missingcolor with -byplane"); + if (argc-1 < 1) cmdlineP->indexFilespec = "-"; else cmdlineP->indexFilespec = argv[1]; + + free(option_def); } @@ -111,19 +124,32 @@ fitLookup(tuple ** const inputLookup, static void -getLookup(const char * const lookupFilespec, +getLookup(const char * const lookupFileName, unsigned int const indexDegree, unsigned int const indexMaxval, tuple *** const lookupP, struct pam * const lookuppamP, bool const fit) { +/*---------------------------------------------------------------------------- + Get the lookup image (the one that maps integers to tuples, e.g. a + color index / color map / palette) from the file named + 'lookupFileName'. - FILE* lookupfileP; + Interpret the lookup image for use with indices that are ntuples of size + 'indexDegree' (normally 1, could be 2) whose elements range from 0 through + 'indexMaxval' + + Iff 'fit' is true, stretch or compress the image in the file to fit + exactly the range identified by 'indexMaxval'. + + Return the image as *lookupP and *lookuppamP. +-----------------------------------------------------------------------------*/ + FILE * lookupfileP; struct pam inputLookuppam; - tuple** inputLookup; + tuple ** inputLookup; - lookupfileP = pm_openr(lookupFilespec); + lookupfileP = pm_openr(lookupFileName); inputLookup = pnm_readpam(lookupfileP, &inputLookuppam, PAM_STRUCT_SIZE(tuple_type)); @@ -153,14 +179,14 @@ getLookup(const char * const lookupFilespec, if (indexDegree == 2 && lookuppamP->height - 1 > indexMaxval) pm_message("Warning: your lookup table image is taller than " "the maxval of " - "your index message, so the bottom end of the lookup " + "your index image, so the bottom end of the lookup " "table image has no effect on the output."); } static void -computeDefaultTuple(struct cmdlineInfo const cmdline, +computeDefaultTuple(struct CmdlineInfo const cmdline, tuple ** const lookup, struct pam * const lookuppamP, tuple * const defaultTupleP) { @@ -203,20 +229,94 @@ computeDefaultTuple(struct cmdlineInfo const cmdline, static void -doLookup(struct pam const indexpam, - struct pam const outpamarg, - tuple const defaultTuple, - tuple ** const lookup, - struct pam const lookuppam) { +doLookupByPlane(struct pam const indexpam, + tuple ** const lookup, + struct pam const lookuppam, + FILE * const ofP) { +/*---------------------------------------------------------------------------- + Write an output image to *ofP derived from the input image read per + 'indexpam' (now positioned to its raster). + Base each tuple of the output on the tuple in the same place in the input. + Look up each sample of the input tuple in the lookupt image given by + 'lookup' and 'lookuppam' to get the corresponding sample of the output + image. + + Our output image has the same width, height, depth, image type, and tuple + type as the input image and the same maxval as the lookup image. + + We ignore any plane or row after the first in the lookup image. We expect + its width to match the maxval of the input image. +-----------------------------------------------------------------------------*/ struct pam outpam; unsigned int row; tuple* tuplerowIndex; tuple* tuplerowOut; - outpam = outpamarg; + outpam = indexpam; /* initial value */ + outpam.maxval = lookuppam.maxval; + outpam.file = ofP; + + tuplerowIndex = pnm_allocpamrow(&indexpam); + tuplerowOut = pnm_allocpamrow(&outpam); + + pnm_writepaminit(&outpam); + + assert(lookuppam.width == indexpam.maxval + 1); + /* Calling condition */ + + for (row = 0; row < indexpam.height; ++row) { + unsigned int col; + pnm_readpamrow(&indexpam, tuplerowIndex); + + for (col = 0; col < indexpam.width; ++col) { + unsigned int plane; + + for (plane = 0; plane < indexpam.depth; ++plane) { + unsigned int const index = tuplerowIndex[col][plane]; + + if (index > lookuppam.maxval) + pm_error("Sample value %u in the lookup image exceeds " + "the lookup image's maxval (%u)", + index, lookuppam.maxval); + + tuplerowOut[col][plane] = lookup[0][index][0]; + } + } + pnm_writepamrow(&outpam, tuplerowOut); + } + pnm_freepamrow(tuplerowIndex); + pnm_freepamrow(tuplerowOut); +} + + + +static void +doLookupWholeTuple(struct pam const indexpam, + tuple const defaultTuple, + tuple ** const lookup, + struct pam const lookuppam, + FILE * const ofP) { +/*---------------------------------------------------------------------------- + Write an output image to *ofP derived from the input image read per + 'indexpam' (now positioned to its raster). + + For each tuple of the output, use the corresponding tuple of the input as + an index into the lookup image given by 'lookup' and 'lookuppam'. If that + index is not present in the lookup image, put 'defaultTuple' in the output. +-----------------------------------------------------------------------------*/ + struct pam outpam; + unsigned int row; + + tuple* tuplerowIndex; + tuple* tuplerowOut; + outpam = lookuppam; /* initial value */ + outpam.height = indexpam.height; + outpam.width = indexpam.width; + outpam.file = ofP; + tuplerowIndex = pnm_allocpamrow(&indexpam); tuplerowOut = pnm_allocpamrow(&outpam); @@ -254,18 +354,18 @@ doLookup(struct pam const indexpam, int -main(int argc, char *argv[]) { +main(int argc, const char ** const argv) { - struct cmdlineInfo cmdline; + struct CmdlineInfo cmdline; struct pam indexpam; - struct pam outpam; - FILE* ifP; + FILE * ifP; + unsigned int indexDegree; struct pam lookuppam; - tuple** lookup; + tuple ** lookup; tuple defaultTuple; - pnm_init(&argc, argv); + pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); @@ -273,28 +373,30 @@ main(int argc, char *argv[]) { pnm_readpaminit(ifP, &indexpam, PAM_STRUCT_SIZE(tuple_type)); - if (indexpam.depth != 1 && indexpam.depth != 2) - pm_error("The input (index) file must have depth 1 or 2. " - "Yours has depth %d", + if (!cmdline.byplane && (indexpam.depth != 1 && indexpam.depth != 2)) + pm_error("Unless you specify -byplane, " + "the input (index) file must have depth 1 or 2. " + "Yours has depth %u", indexpam.depth); - getLookup(cmdline.lookupFilespec, indexpam.depth, indexpam.maxval, - &lookup, &lookuppam, cmdline.fit); + indexDegree = cmdline.byplane ? 1 : indexpam.depth; + + getLookup(cmdline.lookupFilespec, indexDegree, indexpam.maxval, + &lookup, &lookuppam, cmdline.fit || cmdline.byplane); computeDefaultTuple(cmdline, lookup, &lookuppam, &defaultTuple); - outpam = lookuppam; - outpam.height = indexpam.height; - outpam.width = indexpam.width; - outpam.file = stdout; - - doLookup(indexpam, outpam, defaultTuple, lookup, lookuppam); + if (cmdline.byplane) + doLookupByPlane(indexpam, lookup, lookuppam, stdout); + else + doLookupWholeTuple(indexpam, defaultTuple, lookup, lookuppam, stdout); pm_close(ifP); pnm_freepamtuple(defaultTuple); pnm_freepamarray(lookup, &lookuppam); - exit(0); + return 0; } + |