From 3be2255ecea7aa9442db31457e13bd0149ce606d Mon Sep 17 00:00:00 2001 From: giraffedata Date: Fri, 15 Mar 2019 15:09:54 +0000 Subject: Add pamfind git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@3572 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- analyzer/pamfind.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 analyzer/pamfind.c (limited to 'analyzer/pamfind.c') diff --git a/analyzer/pamfind.c b/analyzer/pamfind.c new file mode 100644 index 00000000..aa3070e7 --- /dev/null +++ b/analyzer/pamfind.c @@ -0,0 +1,222 @@ +#include +#include + +#include "pm_c_util.h" +#include "shhopt.h" +#include "mallocvar.h" + + +typedef struct { + unsigned int * target; + unsigned int targetDepth; + const char * color; /* NULL means not specified */ + const char * inputFileName; +} CmdLineInfo; + + +static CmdLineInfo +parsedCommandLine(int argc, + const char ** const argv) { + + optEntry * option_def; + /* Instructions to OptParseOptions3 on how to parse our options. + */ + optStruct3 opt; + + unsigned int option_def_index; + + CmdLineInfo cmdLine; + + unsigned int targetSpec, colorSpec; + const char ** target; + + MALLOCARRAY_NOFAIL(option_def, 100); + + option_def_index = 0; /* incremented by OPTENT3 */ + OPTENT3(0, "target", OPT_STRINGLIST, &target, &targetSpec, 0); + OPTENT3(0, "color", OPT_STRING, &cmdLine.color, &colorSpec, 0); + OPTENT3(0, 0, OPT_END, NULL, NULL, 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); + + if (targetSpec) { + if (colorSpec) + pm_error("You cannot specify both -target and -color"); + else { + unsigned int i; + + cmdLine.color = NULL; + + cmdLine.target = NULL; /* initial value */ + + for (i = 0, cmdLine.targetDepth = 0; target[i]; ++i) { + unsigned int sampleVal; + const char * error; + + pm_string_to_uint(target[i], &sampleVal, &error); + if (error) { + pm_error("Invalid sample value in -target option: '%s'. " + "%s", target[i], error); + } + + REALLOCARRAY(cmdLine.target, i+1); + + cmdLine.target[cmdLine.targetDepth++] = sampleVal; + } + + free(target); + } + } else if (!colorSpec) + pm_error("You must specify either -target or -color"); + + if (argc-1 < 1) + cmdLine.inputFileName = "-"; + else { + cmdLine.inputFileName = argv[1]; + + if (argc-1 > 1) + pm_error("Too many arguments: %u. " + "The only possible argument is the input file name", + argc-1); + } + free(option_def); + + return cmdLine; +} + + + +static void +freeCmdLine(CmdLineInfo const cmdLine) { + + if (!cmdLine.color) + pnm_freepamtuple(cmdLine.target); +} + + + +static tuple +targetValue(CmdLineInfo const cmdLine, + struct pam * const inpamP) { +/*---------------------------------------------------------------------------- + The tuple value user wants us to find in the image, per 'cmdLine'. + + The return value is to be interpreted per *inpamP. +-----------------------------------------------------------------------------*/ + tuple retval; + + if (cmdLine.color) { + if (inpamP->depth != 3) + pm_error("You specified -color, but the input image has " + "depth %u, not 3", inpamP->depth); + else + retval = pnm_parsecolor(cmdLine.color, inpamP->maxval); + } else { + if (cmdLine.targetDepth != inpamP->depth) + pm_error("You specified a %u-tuple for -target, " + "but the input image of of depth %u", + cmdLine.targetDepth, inpamP->depth); + else { + unsigned int i; + + retval = pnm_allocpamtuple(inpamP); + + for (i = 0; i < inpamP->depth; ++i) + retval[i] = cmdLine.target[i]; + } + } + + return retval; +} + + + +static void +printHeader(FILE * const ofP, + struct pam * const inpamP, + tuple const target) { + + unsigned int plane; + + fprintf(ofP, "Locations containing tuple "); + + fprintf(ofP, "("); + + for (plane = 0; plane < inpamP->depth; ++plane) { + fprintf(ofP, "%u", (unsigned)target[plane]); + if (plane + 1 < inpamP->depth) + fprintf(ofP, "/"); + } + + fprintf(ofP, ")"); + + fprintf(ofP, "/%u", inpamP->maxval); + + fprintf(ofP, ":\n"); +} + + + +static void +pamfind(FILE * const ifP, + struct pam * const inpamP, + CmdLineInfo const cmdLine, + FILE * const ofP) { + + pnm_readpaminit(ifP, inpamP, PAM_STRUCT_SIZE(tuple_type)); + + { + tuple * const inputRow = pnm_allocpamrow(inpamP); + tuple const target = targetValue(cmdLine, inpamP); + + unsigned int row; + + printHeader(ofP, inpamP, target); + + for (row = 0; row < inpamP->height; ++row) { + unsigned int col; + + pnm_readpamrow(inpamP, inputRow); + + for (col = 0; col < inpamP->width; ++col) { + + if (pnm_tupleequal(inpamP, target, inputRow[col])) { + fprintf(ofP, "(%u, %u)\n", row, col); + } + } + } + pnm_freepamtuple(target); + pnm_freepamrow(inputRow); + } +} + + + +int +main(int argc, const char *argv[]) { + + FILE * ifP; + CmdLineInfo cmdLine; + struct pam inpam; + + pm_proginit(&argc, argv); + + cmdLine = parsedCommandLine(argc, argv); + + ifP = pm_openr(cmdLine.inputFileName); + + pamfind(ifP, &inpam, cmdLine, stdout); + + freeCmdLine(cmdLine); + + pm_close(inpam.file); + + return 0; +} + + + -- cgit 1.4.1