diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2011-02-27 23:56:20 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2011-02-27 23:56:20 +0000 |
commit | 32d9619be4a39d09db6721c24e6216d503466351 (patch) | |
tree | 415c02a9fa357d5586cf8c6c0b633a207cb86a89 /editor | |
parent | 93867b8c2f86de0cb99847d10c33112fb0fafc93 (diff) | |
download | netpbm-mirror-32d9619be4a39d09db6721c24e6216d503466351.tar.gz netpbm-mirror-32d9619be4a39d09db6721c24e6216d503466351.tar.xz netpbm-mirror-32d9619be4a39d09db6721c24e6216d503466351.zip |
Add pamwipeout
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1408 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'editor')
-rw-r--r-- | editor/Makefile | 1 | ||||
-rw-r--r-- | editor/pamwipeout.c | 229 |
2 files changed, 230 insertions, 0 deletions
diff --git a/editor/Makefile b/editor/Makefile index cac12657..e5983ac7 100644 --- a/editor/Makefile +++ b/editor/Makefile @@ -22,6 +22,7 @@ PORTBINARIES = pamaddnoise pambackground pamcomp pamcut \ pamfunc pammasksharpen \ pamperspective pamrecolor \ pamscale pamsistoaglyph pamstretch pamthreshold pamundice \ + pamwipeout \ pbmclean pbmmask pbmpscale pbmreduce \ pgmdeshadow pgmenhance \ pgmmedian \ diff --git a/editor/pamwipeout.c b/editor/pamwipeout.c new file mode 100644 index 00000000..0fff3fca --- /dev/null +++ b/editor/pamwipeout.c @@ -0,0 +1,229 @@ +/* pamwipeout.c - read a bitmap and replace it with a gradient between two +** edges +** +** Copyright (C) 2011 by Willem van Schaik (willem@schaik.com) +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <math.h> +#include "pm_c_util.h" +#include "mallocvar.h" +#include "shhopt.h" +#include "pam.h" + + +enum Direction {DIR_LR, DIR_TB}; + +struct cmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char *inputFileName; /* '-' if stdin */ + enum Direction direction; /* top-bottom or left-right */ +}; + + + +static void +parseCommandLine(int argc, + const char ** argv, + struct cmdlineInfo * const cmdlineP ) { +/*---------------------------------------------------------------------------- + Parse program command line described in Unix standard form by argc + and argv. Return the information in the options as *cmdlineP. + + If command line is internally inconsistent (invalid options, etc.), + issue error message to stderr and abort program. + + Note that the strings we return are stored in the storage that + was passed to us as the argv array. We also trash *argv. +-----------------------------------------------------------------------------*/ + optEntry *option_def; + /* Instructions to pm_optParseOptions3 on how to parse our options. + */ + optStruct3 opt; + + unsigned int option_def_index; + + unsigned int lr, tb; + + MALLOCARRAY_NOFAIL(option_def, 100); + + option_def_index = 0; /* incremented by OPTENT3 */ + OPTENT3(0, "lr", OPT_FLAG, NULL, + &lr, 0); + OPTENT3(0, "tb", OPT_FLAG, NULL, + &tb, 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 (!lr && !tb) + pm_error("You must specify either -lr or -tb"); + else if (lr && tb) + pm_error("You may not specify both -lr and -tb"); + else + cmdlineP->direction = lr ? DIR_LR : DIR_TB; + + + if (argc-1 < 1) + cmdlineP->inputFileName = "-"; + else { + cmdlineP->inputFileName = argv[1]; + if (argc-1 > 1) + pm_error("Too many arguments: %u. " + "The only possible argument is the " + "optional input file name", argc-1); + } +} + + + + +static void +wipeImgByRow (struct pam const inpam, + tuple ** const tuples) { + + double const h = (double) inpam.height; + + unsigned int row; + unsigned int col; + + for (row = 0; row < inpam.height; ++row) { + double const y = (double) row; + for (col = 0; col < inpam.width; ++col) { + unsigned int i; + for (i = 0; i < inpam.depth; ++i) { + sample const top = tuples[0][col][i]; + sample const bot = tuples[inpam.height - 1][col][i]; + tuples[row][col][i] = (int) + floor(((h - y) / h) + * (double) top + (y / h) + * (double) bot); + } + } + } +} + + + +static void +wipeRowByCol(struct pam const inpam, + tuple ** const tuples, + tuple * const tuplerow) { + + double const w = (double) inpam.width; + + unsigned int col; + + for (col = 0; col < inpam.width; ++col) { + double const x = (double) col; + unsigned int i; + for (i = 0; i < inpam.depth; ++i) { + sample const lft = tuplerow[0][i]; + sample const rgt = tuplerow[inpam.width - 1][i]; + tuplerow[col][i] = (int) + floor( ((w - x) / w) + * (double) lft + (x / w) + * (double) rgt ); + } + } +} + + + +static void +wipeoutTb(FILE * const ifP, + FILE * const ofP) { + + /* top-bottom we have to read the full image */ + + struct pam inpam, outpam; + tuple ** tuples; + + tuples = pnm_readpam(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); + + outpam = inpam; + outpam.file = ofP; + + wipeImgByRow(inpam, tuples); + + pnm_writepam(&outpam, tuples); + + pnm_freepamarray(tuples, &inpam); +} + + + +static void +wipeoutLr(FILE * const ifP, + FILE * const ofP) { + + /* left-right we can read row-by-row */ + + struct pam inpam, outpam; + tuple ** tuples; + tuple * tuplerow; + unsigned int row; + + pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); + + outpam = inpam; + outpam.file = ofP; + + pnm_writepaminit(&outpam); + + tuplerow = pnm_allocpamrow(&inpam); + + for (row = 0; row < inpam.height; ++row) { + pnm_readpamrow(&inpam, tuplerow); + + wipeRowByCol(inpam, tuples, tuplerow); + + pnm_writepamrow(&outpam, tuplerow); + } + + pnm_freepamrow(tuplerow); +} + + + +int +main(int argc, const char *argv[]) { + + struct cmdlineInfo cmdline; + FILE * ifP; + + pm_proginit(&argc, argv); + + parseCommandLine(argc, argv, &cmdline); + + ifP = pm_openr(cmdline.inputFileName); + + switch (cmdline.direction) { + case DIR_TB: + wipeoutTb(ifP, stdout); + break; + case DIR_LR: + wipeoutLr(ifP, stdout); + break; + } + + pm_close(ifP); + pm_close(stdout); + + return 0; +} |