diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2016-03-27 01:46:26 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2016-03-27 01:46:26 +0000 |
commit | dff6b9fdfeb78fe21a66aa459ddc1d5f7e362dfa (patch) | |
tree | b147568ccffc4cdba9e2a98de1452450ba8e55c3 /other | |
parent | 4ce684c4978610d1ea42be1b00f7332f3f5f337a (diff) | |
download | netpbm-mirror-dff6b9fdfeb78fe21a66aa459ddc1d5f7e362dfa.tar.gz netpbm-mirror-dff6b9fdfeb78fe21a66aa459ddc1d5f7e362dfa.tar.xz netpbm-mirror-dff6b9fdfeb78fe21a66aa459ddc1d5f7e362dfa.zip |
Promote Advanced (10.73) to Stable
git-svn-id: http://svn.code.sf.net/p/netpbm/code/stable@2692 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'other')
-rw-r--r-- | other/Makefile | 17 | ||||
-rw-r--r-- | other/pamarith.c | 97 | ||||
-rw-r--r-- | other/pambayer.c | 90 | ||||
-rw-r--r-- | other/pamchannel.c | 25 | ||||
-rw-r--r-- | other/pamdepth.c | 13 | ||||
-rw-r--r-- | other/pamexec.c | 192 | ||||
-rw-r--r-- | other/pamfix.c | 291 | ||||
-rwxr-xr-x | other/pamfixtrunc | 50 | ||||
-rw-r--r-- | other/pamfixtrunc.c | 176 | ||||
-rw-r--r-- | other/pamlookup.c | 186 | ||||
-rw-r--r-- | other/pampick.c | 10 | ||||
-rw-r--r-- | other/pamsplit.c | 23 | ||||
-rw-r--r-- | other/pamstack.c | 11 | ||||
-rw-r--r-- | other/pamsummcol.c | 2 | ||||
-rw-r--r-- | other/pamunlookup.c | 250 | ||||
-rw-r--r-- | other/pamvalidate.c | 86 | ||||
-rw-r--r-- | other/pamx/Makefile | 48 | ||||
-rw-r--r-- | other/pamx/pamx.c | 7 | ||||
-rw-r--r-- | other/pamx/send.c | 6 | ||||
-rw-r--r-- | other/pamx/window.c | 27 | ||||
-rw-r--r-- | other/pnmcolormap.c | 8 | ||||
-rw-r--r-- | other/ppmdcfont.c | 20 | ||||
-rw-r--r-- | other/ppmsvgalib.c | 16 |
23 files changed, 1269 insertions, 382 deletions
diff --git a/other/Makefile b/other/Makefile index f7333c64..bd2c9dc2 100644 --- a/other/Makefile +++ b/other/Makefile @@ -24,17 +24,17 @@ endif # build. PORTBINARIES = pamarith pambayer pamchannel pamdepth \ - pamendian pamfixtrunc pamlookup pampick pamsplit \ - pamstack pamsummcol pnmcolormap \ + pamendian pamexec pamfix pamlookup pampick pamsplit \ + pamstack pamsummcol pamunlookup pamvalidate pnmcolormap \ ppmdcfont ppmddumpfont ppmdmkfont -BINARIES = $(PORTBINARIES) - ifneq ($(LINUXSVGALIB),NONE) - BINARIES += ppmsvgalib + PORTBINARIES += ppmsvgalib endif -SCRIPTS = ppmtomap +BINARIES = $(PORTBINARIES) + +SCRIPTS = ppmtomap pamfixtrunc OBJECTS = $(BINARIES:%=%.o) @@ -50,10 +50,7 @@ all: $(BINARIES) $(SUBDIRS:%=%/all) include $(SRCDIR)/common.mk -ppmsvgalib: %: %.o $(NETPBMLIB) $(LIBOPT) - $(LD) -o $@ $< \ - $(shell $(LIBOPT) $(NETPBMLIB) $(LINUXSVGALIB)) \ - $(MATHLIB) $(LDFLAGS) $(LDLIBS) $(LADD) +ppmsvgalib: LDFLAGS_TARGET = $(shell $(LIBOPT) $(LINUXSVGALIB)) install.bin: install.bin.local .PHONY: install.bin.local diff --git a/other/pamarith.c b/other/pamarith.c index 4374ee1c..b64f69fb 100644 --- a/other/pamarith.c +++ b/other/pamarith.c @@ -47,7 +47,7 @@ isDyadic(enum function const function) { -struct cmdlineInfo { +struct CmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. */ @@ -60,7 +60,7 @@ struct cmdlineInfo { static void parseCommandLine(int argc, const char ** const argv, - struct cmdlineInfo * const cmdlineP) { + 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. @@ -102,7 +102,7 @@ parseCommandLine(int argc, const char ** const argv, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ - optParseOptions3(&argc, (char **)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 (addSpec + subtractSpec + multiplySpec + divideSpec + differenceSpec + @@ -400,48 +400,66 @@ doNormalizedArith(struct pam * const inpam1P, struct pam * const outpamP, enum function const function) { + /* Some of the logic in this subroutine is designed for future + expansion into non-dyadic computations. But for now, all + computations have exactly two operands. + */ unsigned int const operandCt = 2; - tuplen * tuplerown1; - tuplen * tuplerown2; + tuplen ** tuplerown; + /* tuplerown[0] is the current row in the first operand image */ + tuplen * tuplerownOut; unsigned int row; samplen * operands; + /* operand[0] is the first operand in the current one-sample + computation + */ + unsigned int * plane; + /* plane[0] is the plane number in the first operand image for + the current one-sample computation. plane[1] is the plane number + in the second operand image, etc. + */ MALLOCARRAY_NOFAIL(operands, operandCt); + MALLOCARRAY_NOFAIL(plane, operandCt); + MALLOCARRAY_NOFAIL(tuplerown, operandCt); - tuplerown1 = pnm_allocpamrown(inpam1P); - tuplerown2 = pnm_allocpamrown(inpam2P); + tuplerown[0] = pnm_allocpamrown(inpam1P); + tuplerown[1] = pnm_allocpamrown(inpam2P); tuplerownOut = pnm_allocpamrown(outpamP); for (row = 0; row < outpamP->height; ++row) { unsigned int col; - pnm_readpamrown(inpam1P, tuplerown1); - pnm_readpamrown(inpam2P, tuplerown2); + pnm_readpamrown(inpam1P, tuplerown[0]); + pnm_readpamrown(inpam2P, tuplerown[1]); for (col = 0; col < outpamP->width; ++col) { unsigned int outplane; for (outplane = 0; outplane < outpamP->depth; ++outplane) { - unsigned int const plane1 = MIN(outplane, inpam1P->depth-1); - unsigned int const plane2 = MIN(outplane, inpam2P->depth-1); + unsigned int op; - operands[0] = tuplerown1[col][plane1]; - operands[1] = tuplerown2[col][plane2]; + plane[0] = MIN(outplane, inpam1P->depth-1); + plane[1] = MIN(outplane, inpam2P->depth-1); + + for (op = 0; op < operandCt; ++op) + operands[op] = tuplerown[op][col][plane[op]]; tuplerownOut[col][outplane] = applyNormalizedFunction(function, operands, operandCt); assert(tuplerownOut[col][outplane] >= 0.); assert(tuplerownOut[col][outplane] <= 1.); - } } pnm_writepamrown(outpamP, tuplerownOut); } - pnm_freepamrown(tuplerown1); - pnm_freepamrown(tuplerown2); + pnm_freepamrown(tuplerown[0]); + pnm_freepamrown(tuplerown[1]); + free(tuplerown); pnm_freepamrown(tuplerownOut); + free(plane); free(operands); } @@ -701,14 +719,28 @@ doUnNormalizedArith(struct pam * const inpam1P, maxval to do the computation without time-consuming normalization of sample values. -----------------------------------------------------------------------------*/ + /* Some of the logic in this subroutine is designed for future + expansion into non-dyadic computations. But for now, all + computations have exactly two operands. + */ unsigned int const operandCt = 2; + sample const maxval = outpamP->maxval; - tuple * tuplerow1; - tuple * tuplerow2; + tuple ** tuplerow; + /* tuplerow[0] is the current row in the first operand image */ + tuple * tuplerowOut; unsigned int row; sample * operands; + /* operand[0] is the first operand in the current one-sample + computation + */ + unsigned int * plane; + /* plane[0] is the plane number in the first operand image for + the current one-sample computation. plane[1] is the plane number + in the second operand image, etc. + */ /* Input conditions: */ assert(inpam1P->maxval == maxval); @@ -716,25 +748,29 @@ doUnNormalizedArith(struct pam * const inpam1P, assert(outpamP->maxval == maxval); MALLOCARRAY_NOFAIL(operands, operandCt); + MALLOCARRAY_NOFAIL(plane, operandCt); + MALLOCARRAY_NOFAIL(tuplerow, operandCt); - tuplerow1 = pnm_allocpamrow(inpam1P); - tuplerow2 = pnm_allocpamrow(inpam2P); + tuplerow[0] = pnm_allocpamrow(inpam1P); + tuplerow[1] = pnm_allocpamrow(inpam2P); tuplerowOut = pnm_allocpamrow(outpamP); for (row = 0; row < outpamP->height; ++row) { unsigned int col; - pnm_readpamrow(inpam1P, tuplerow1); - pnm_readpamrow(inpam2P, tuplerow2); + pnm_readpamrow(inpam1P, tuplerow[0]); + pnm_readpamrow(inpam2P, tuplerow[1]); for (col = 0; col < outpamP->width; ++col) { unsigned int outplane; for (outplane = 0; outplane < outpamP->depth; ++outplane) { - unsigned int const plane1 = MIN(outplane, inpam1P->depth-1); - unsigned int const plane2 = MIN(outplane, inpam2P->depth-1); + unsigned int op; + + plane[0] = MIN(outplane, inpam1P->depth-1); + plane[1] = MIN(outplane, inpam2P->depth-1); - operands[0] = tuplerow1[col][plane1]; - operands[1] = tuplerow2[col][plane2]; + for (op = 0; op < operandCt; ++op) + operands[op] = tuplerow[op][col][plane[op]]; tuplerowOut[col][outplane] = applyUnNormalizedFunction(function, operands, operandCt, @@ -747,10 +783,11 @@ doUnNormalizedArith(struct pam * const inpam1P, pnm_writepamrow(outpamP, tuplerowOut); } - pnm_freepamrow(tuplerow1); - pnm_freepamrow(tuplerow2); + pnm_freepamrow(tuplerow[0]); + pnm_freepamrow(tuplerow[1]); + free(tuplerow); pnm_freepamrow(tuplerowOut); - + free(plane); free(operands); } @@ -759,7 +796,7 @@ doUnNormalizedArith(struct pam * const inpam1P, int main(int argc, const char *argv[]) { - struct cmdlineInfo cmdline; + struct CmdlineInfo cmdline; struct pam inpam1; struct pam inpam2; struct pam outpam; diff --git a/other/pambayer.c b/other/pambayer.c index f8ce0db8..7fc1f809 100644 --- a/other/pambayer.c +++ b/other/pambayer.c @@ -42,19 +42,20 @@ enum bayerType { struct cmdlineInfo { const char * inputFilespec; enum bayerType bayerType; + unsigned int nointerpolate; }; static void -parseCommandLine(int argc, char ** argv, +parseCommandLine(int argc, const char ** 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. + optEntry * option_def; + /* Instructions to pm_optParseOptions3 on how to parse our options. */ optStruct3 opt; @@ -67,12 +68,14 @@ parseCommandLine(int argc, char ** argv, option_def_index = 0; /* incremented by OPTENT3 */ OPTENT3(0, "type", OPT_UINT, &type, &typeSpec, 0); + OPTENT3(0, "nointerpolate", OPT_FLAG, NULL, + &cmdlineP->nointerpolate, 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 */ - 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 (argc-1 < 1) @@ -102,28 +105,47 @@ calc_4(const struct pam * const pamP, tuple ** const intuples, tuple ** const outtuples, unsigned int const plane, + bool const noInterpolation, unsigned int const xoffset, unsigned int const yoffset) { /*---------------------------------------------------------------------------- X . X . . . X . X + + For the Plane 'plane' sample values, an even pixel of outtuples[] gets the + same value as intuples[][]. An odd pixel of outtuples[] gets the mean of + the four surrounding even pixels, north, south, east, and west. But zero if + Caller says 'noInterpolation'. + + (even/odd is with respect to ('xoffset', 'yoffset')). -----------------------------------------------------------------------------*/ - unsigned int y; + unsigned int row; - for (y = yoffset; y < pamP->height; y += 2) { - unsigned int x; - for (x = xoffset; x + 2 < pamP->width; x += 2) { - outtuples[y][x][plane] = intuples[y][x][0]; - outtuples[y][x + 1][plane] = - (intuples[y][x][0] + intuples[y][x + 2][0]) / 2; + /* Do the even rows -- the even column pixels get copied from the input, + while the odd column pixels get the mean of adjacent even ones + */ + for (row = yoffset; row < pamP->height; row += 2) { + unsigned int col; + for (col = xoffset; col + 2 < pamP->width; col += 2) { + outtuples[row][col][plane] = intuples[row][col][0]; + outtuples[row][col + 1][plane] = + noInterpolation ? + 0 : + (intuples[row][col][0] + intuples[row][col + 2][0]) / 2; } } - for (y = yoffset; y + 2 < pamP->height; y += 2) { - unsigned int x; - for (x = xoffset; x < pamP->width; ++x) - outtuples[y + 1][x][plane] = - (outtuples[y][x][plane] + outtuples[y + 2][x][plane]) / 2; + + /* Do the odd rows -- every pixel is the mean of the one above and below */ + for (row = yoffset; row + 2 < pamP->height; row += 2) { + unsigned int col; + for (col = xoffset; col < pamP->width; ++col) { + outtuples[row + 1][col][plane] = + noInterpolation ? + 0 : + (outtuples[row][col][plane] + + outtuples[row + 2][col][plane]) / 2; + } } } @@ -134,25 +156,37 @@ calc_5(const struct pam * const pamP, tuple ** const intuples, tuple ** const outtuples, unsigned int const plane, + bool const noInterpolation, unsigned int const xoffset, unsigned int const yoffset) { /*---------------------------------------------------------------------------- . X . X . X . X . + + For the Plane 'plane' sample values, an pixel on an even diagonal of + outtuples[] gets the same value as intuples[][]. An pixel on an odd + diagonal gets the mean of the four surrounding even pixels, north, + south, east, and west. But zero if Caller says 'noInterpolation'. + + (even/odd is with respect to ('xoffset', 'yoffset')). -----------------------------------------------------------------------------*/ - unsigned int y; + unsigned int row; unsigned int j; j = 0; /* initial value */ - for (y = yoffset; y + 2 < pamP->height; ++y) { - unsigned int x; - for (x = xoffset + j; x + 2 < pamP->width; x += 2) { - outtuples[y][x + 1][plane] = intuples[y][x + 1][0]; - outtuples[y + 1][x + 1][plane] = - (intuples[y][x + 1][0] + intuples[y + 1][x][0] + - intuples[y + 2][x + 1][0] + intuples[y + 1][x + 2][0]) / 4; + for (row = yoffset; row + 2 < pamP->height; ++row) { + unsigned int col; + for (col = xoffset + j; col + 2 < pamP->width; col += 2) { + outtuples[row][col + 1][plane] = intuples[row][col + 1][0]; + outtuples[row + 1][col + 1][plane] = + noInterpolation ? + 0 : + (intuples[row][col + 1][0] + + intuples[row + 1][col][0] + + intuples[row + 2][col + 1][0] + + intuples[row + 1][col + 2][0]) / 4; } j = 1 - j; } @@ -167,6 +201,7 @@ struct compAction { tuple ** const intuples, tuple ** const outtuples, unsigned int const plane, + bool const noInterpolation, unsigned int const xoffset, unsigned int const yoffset); }; @@ -260,7 +295,7 @@ actionTableForType(enum bayerType const bayerType) { int -main(int argc, char **argv) { +main(int argc, const char **argv) { struct cmdlineInfo cmdline; FILE * ifP; @@ -271,8 +306,8 @@ main(int argc, char **argv) { const struct compAction * compActionTable; unsigned int plane; - pnm_init(&argc, argv); - + pm_proginit(&argc, argv); + parseCommandLine(argc, argv, &cmdline); ifP = pm_openr(cmdline.inputFilespec); @@ -289,6 +324,7 @@ main(int argc, char **argv) { struct compAction const compAction = compActionTable[plane]; compAction.calc(&inpam, intuples, outtuples, plane, + cmdline.nointerpolate, compAction.xoffset, compAction.yoffset); } pnm_writepam(&outpam, outtuples); diff --git a/other/pamchannel.c b/other/pamchannel.c index 64ab728b..e89a979b 100644 --- a/other/pamchannel.c +++ b/other/pamchannel.c @@ -14,14 +14,14 @@ #include <string.h> #include "pm_c_util.h" -#include "pam.h" -#include "shhopt.h" #include "mallocvar.h" +#include "shhopt.h" +#include "pam.h" #define MAX_CHANNELS 16 /* The most channels we allow user to specify */ -struct cmdlineInfo { +struct CmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. */ @@ -36,14 +36,14 @@ struct cmdlineInfo { static void -parseCommandLine(int argc, char ** argv, - struct cmdlineInfo * const cmdlineP) { +parseCommandLine(int argc, const char ** 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. + /* Instructions to pm_optParseOptions3 on how to parse our options. */ optStruct3 opt; extern struct pam pam; /* Just so we can look at field sizes */ @@ -63,7 +63,7 @@ parseCommandLine(int argc, char ** argv, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ - 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 (!infileSpec) @@ -74,7 +74,8 @@ parseCommandLine(int argc, char ** argv, else if (strlen(cmdlineP->tupletype)+1 > sizeof(pam.tuple_type)) pm_error("Tuple type name specified is too long. Maximum of " - "%u characters allowed.", sizeof(pam.tuple_type)); + "%u characters allowed.", + (unsigned)sizeof(pam.tuple_type)); cmdlineP->n_channel = 0; /* initial value */ { @@ -173,13 +174,13 @@ doOneImage(FILE * const ifP, int -main(int argc, char *argv[]) { +main(int argc, const char *argv[]) { - struct cmdlineInfo cmdline; + struct CmdlineInfo cmdline; FILE * ifP; - bool eof; + int eof; - pnm_init(&argc, argv); + pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); diff --git a/other/pamdepth.c b/other/pamdepth.c index ee59a408..71dae9d8 100644 --- a/other/pamdepth.c +++ b/other/pamdepth.c @@ -28,14 +28,14 @@ struct cmdlineInfo { static void -parseCommandLine(int argc, char ** argv, +parseCommandLine(int argc, const char ** argv, struct cmdlineInfo *cmdlineP) { /*---------------------------------------------------------------------------- Note that the file spec strings we return are 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. + /* Instructions to pm_optParseOptions3 on how to parse our options. */ optStruct3 opt; @@ -51,7 +51,7 @@ parseCommandLine(int argc, char ** argv, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We may have parms that are negative numbers */ - 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 (argc-1 < 1) @@ -133,16 +133,15 @@ transformRaster(struct pam * const inpamP, int -main(int argc, - char * argv[]) { +main(int argc, const char * argv[]) { struct cmdlineInfo cmdline; FILE * ifP; struct pam inpam; struct pam outpam; - bool eof; + int eof; - pnm_init(&argc, argv); + pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); diff --git a/other/pamexec.c b/other/pamexec.c new file mode 100644 index 00000000..d14d8752 --- /dev/null +++ b/other/pamexec.c @@ -0,0 +1,192 @@ +/****************************************************************************** + pamexec +******************************************************************************* + Split a Netpbm format input file into multiple Netpbm format output streams + with one image per output stream and pipe this into the specified command. + + By Bryan Henderson, Olympia WA; June 2000 + and Michael Pot, New Zealand, August 2011 + + Contributed to the public domain by its authors. + +******************************************************************************/ + +#define _BSD_SOURCE 1 /* Make sure strdup() is in string.h */ +#define _XOPEN_SOURCE 500 /* Make sure strdup() is in string.h */ + +#include <string.h> +#include <stdio.h> +#include <errno.h> + +#include "pm_c_util.h" +#include "shhopt.h" +#include "nstring.h" +#include "mallocvar.h" +#include "pam.h" + +struct cmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char * command; + const char * inputFileName; + unsigned int debug; + unsigned int check; +}; + + + + +static void +parseCommandLine(int argc, const char ** argv, + struct cmdlineInfo * const cmdlineP) { +/*---------------------------------------------------------------------------- + Note that the pointers we place into *cmdlineP are sometimes to storage + in the argv array. +-----------------------------------------------------------------------------*/ + optEntry *option_def; + /* Instructions to OptParseOptions3 on how to parse our options. + */ + optStruct3 opt; + + unsigned int option_def_index; + + MALLOCARRAY_NOFAIL(option_def, 100); + + option_def_index = 0; /* incremented by OPTENT3 */ + OPTENT3(0, "debug", OPT_FLAG, NULL, &cmdlineP->debug, 0); + OPTENT3(0, "check", OPT_FLAG, NULL, &cmdlineP->check, 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 (argc-1 < 1) + pm_error("You must specify at least one argument: the shell command " + "to execute"); + else { + cmdlineP->command = argv[1]; + + if (argc-1 < 2) + cmdlineP->inputFileName = "-"; + else { + cmdlineP->inputFileName = argv[2]; + + if (argc-1 > 2) + pm_error("Too many arguments. There are at most two: " + "command and input file name"); + } + } +} + + + +static void +pipeOneImage(FILE * const infileP, + FILE * const outfileP) { + + struct pam inpam; + struct pam outpam; + enum pm_check_code checkRetval; + + unsigned int row; + tuple * tuplerow; + + pnm_readpaminit(infileP, &inpam, PAM_STRUCT_SIZE(tuple_type)); + + pnm_checkpam(&inpam, PM_CHECK_BASIC, &checkRetval); + + outpam = inpam; + outpam.file = outfileP; + + pnm_writepaminit(&outpam); + + tuplerow = pnm_allocpamrow(&inpam); + + for (row = 0; row < inpam.height; ++row) { + pnm_readpamrow(&inpam, tuplerow); + pnm_writepamrow(&outpam, tuplerow); + } + + pnm_freepamrow(tuplerow); +} + + + +static void +doOneImage(FILE * const ifP, + const char * const command, + bool const check, + const char ** const errorP) { +/*---------------------------------------------------------------------------- + Run command 'command' on the next image in stream *ifP. + + Return as *errorP a text explanation of how we failed, or NULL if we + didn't. +-----------------------------------------------------------------------------*/ + FILE * ofP; + + ofP = popen(command, "w"); + + if (ofP == NULL) + pm_asprintf(errorP, + "Failed to start shell to run command '%s'. " + "errno = %d (%s)", + command, errno, strerror(errno)); + else { + int rc; + + pipeOneImage(ifP, ofP); + + rc = pclose(ofP); + + if (check && rc != 0) + pm_asprintf(errorP, "Command '%s' terminated abnormally " + "or with nonzero exit status", command); + else + *errorP = NULL; + } +} + + + +int +main(int argc, const char *argv[]) { + + struct cmdlineInfo cmdline; + + FILE * ifP; /* Input file pointer */ + int eof; /* No more images in input */ + unsigned int imageSeq; + /* Sequence number of current image in input file. First = 0. + (Useful for tracking down problems). + */ + + pm_proginit(&argc, argv); + + parseCommandLine(argc, argv, &cmdline); + + ifP = pm_openr(cmdline.inputFileName); + + for (eof = FALSE, imageSeq = 0; !eof; ++imageSeq) { + const char * error; + + doOneImage(ifP, cmdline.command, cmdline.check, &error); + + if (error) { + pm_error("Failed on image %u: %s", imageSeq, error); + pm_strfree(error); + } + + pnm_nextimage(ifP, &eof); + } + pm_close(ifP); + + return 0; +} + + + diff --git a/other/pamfix.c b/other/pamfix.c new file mode 100644 index 00000000..8db67e08 --- /dev/null +++ b/other/pamfix.c @@ -0,0 +1,291 @@ +/*============================================================================ + pamfix +============================================================================== + Salvage a Netpbm image that is corrupted in certain ways. + + By Bryan Henderson, January 2007. + + Contributed to the public domain by its author. +============================================================================*/ + +#include <setjmp.h> + +#include "pm_c_util.h" +#include "pam.h" +#include "shhopt.h" +#include "mallocvar.h" + +struct cmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char * inputFileName; /* File name of input file */ + unsigned int verbose; + unsigned int truncate; + unsigned int changemaxval; + unsigned int clip; +}; + + + +static void +parseCommandLine(int argc, 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; + + optStruct3 opt; + + unsigned int option_def_index; + + MALLOCARRAY(option_def, 100); + + option_def_index = 0; /* incremented by OPTENTRY */ + + OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); + OPTENT3(0, "truncate", OPT_FLAG, NULL, &cmdlineP->truncate, 0); + OPTENT3(0, "changemaxval", OPT_FLAG, NULL, &cmdlineP->changemaxval, 0); + OPTENT3(0, "clip", OPT_FLAG, NULL, &cmdlineP->clip, 0); + + opt.opt_table = option_def; + opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ + opt.allowNegNum = FALSE; /* We don't parms that are negative numbers */ + + pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + free(option_def); + + if (argc-1 == 0) + cmdlineP->inputFileName = "-"; + else if (argc-1 != 1) + pm_error("Program takes zero or one argument (filename). You " + "specified %d", argc-1); + else + cmdlineP->inputFileName = argv[1]; + + if (cmdlineP->changemaxval && cmdlineP->clip) + pm_error("You cannot specify both -changemaxval and -clip"); +} + + + +static unsigned int readErrRow; +static bool readErrVerbose; + +static pm_usererrormsgfn handleRowErrMsg; + +static void +handleRowErrMsg(const char * const msg) { + if (readErrVerbose) + pm_message("Error reading row %u: %s", readErrRow, msg); +} + + +static sample +highestSampleInRow(const struct pam * const pamP, + tuple * const tuplerow) { + + unsigned int col; + sample highestSoFar; + + for (col = 0, highestSoFar = 0; col < pamP->width; ++col) { + unsigned int plane; + for (plane = 0; plane < pamP->depth; ++plane) + highestSoFar = MAX(highestSoFar, tuplerow[col][plane]); + } + return highestSoFar; +} + + + +static void +analyzeRaster(const struct pam * const pamP, + unsigned int * const goodRowCountP, + sample * const highestSampleP, + bool const mustAbortOnReadError, + bool const verbose) { +/*---------------------------------------------------------------------------- + Go through the raster at which the stream described by *tweakedPamP is + presently positioned and count how many rows can be successfully read + (including validating the samples against pamP->maxval) and determine the + highest sample value in those rows. + + Leave the stream positioned arbitrarily. +-----------------------------------------------------------------------------*/ + tuple * tuplerow; + unsigned int row; + jmp_buf jmpbuf; + int rc; + + tuplerow = pnm_allocpamrow(pamP); + + pm_setusererrormsgfn(handleRowErrMsg); + + rc = setjmp(jmpbuf); + if (rc == 0) { + pm_setjmpbuf(&jmpbuf); + + readErrVerbose = mustAbortOnReadError || verbose; + *goodRowCountP = 0; /* initial value */ + *highestSampleP = 0; /* initial value */ + + for (row = 0; row < pamP->height; ++row) { + readErrRow = row; + pnm_readpamrow(pamP, tuplerow); + /* The above does not return if it can't read the next row from + the file. Instead, it longjmps out of this loop. + + Update return stats now in case the next iteration longjmps out. + */ + *highestSampleP = + MAX(*highestSampleP, + highestSampleInRow(pamP, tuplerow)); + ++*goodRowCountP; + } + } else { + /* pnm_readpamrow() encountered an error and longjmped */ + if (mustAbortOnReadError) { + /* handleRowErrMsg() has issued the error message */ + exit(1); + } + } + pm_setjmpbuf(NULL); + + pm_setusererrormsgfn(NULL); + + pnm_freepamrow(tuplerow); +} + + + +static void +clipPamRow(const struct pam * const pamP, + tuple * const tuplerow, + unsigned int const row, + bool const verbose) { +/*---------------------------------------------------------------------------- + Clip every sample value in tuplerow[] to the maxval. + + If 'verbose' is true, issue messages about every clipping, indicating it + is in row 'row'. +-----------------------------------------------------------------------------*/ + unsigned int col; + + for (col = 0; col < pamP->width; ++col) { + unsigned int plane; + for (plane = 0; plane < pamP->depth; ++plane) { + if (tuplerow[col][plane] > pamP->maxval) { + if (verbose) + pm_message("Clipping: Row %u Col %u Plane %u. " + "Sample value %lu exceeds the " + "image maxval of %lu", + row, col, plane, tuplerow[col][plane], + pamP->maxval); + tuplerow[col][plane] = pamP->maxval; + } + } + } +} + + + +static void +copyGoodRows(const struct pam * const inpamP, + const struct pam * const outpamP, + bool const verbose) { +/*---------------------------------------------------------------------------- + Copy the raster of the input stream described by *inpamP to the output + stream described by *outpamP. Copy only as many rows as *outpamP allows; + assume *outpamP specifies at most the number of rows of input. +-----------------------------------------------------------------------------*/ + tuple * tuplerow; + unsigned int row; + + tuplerow = pnm_allocpamrow(inpamP); + + for (row = 0; row < outpamP->height; ++row) { + pnm_readpamrow(inpamP, tuplerow); + clipPamRow(outpamP, tuplerow, row, verbose); + pnm_writepamrow(outpamP, tuplerow); + } + + pnm_freepamrow(tuplerow); +} + + + +int +main(int argc, char * argv[]) { + struct cmdlineInfo cmdline; + struct pam inpam; + struct pam outpam; + struct pam tweakedPam; + FILE * ifP; + pm_filepos rasterPos; + unsigned int goodRowCount; + sample highestSample; + + pnm_init(&argc, argv); + + parseCommandLine(argc, argv, &cmdline); + + ifP = pm_openr_seekable(cmdline.inputFileName); + + pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); + + pm_tell2(ifP, &rasterPos, sizeof(rasterPos)); + + /* Tweak maxval to circumvent out-of-bounds sample value check + in libpam. See function validatePamRow() in libpamread.c . + + Ideally we would like to set tweaked-maxval higher for the + plain (text) formats. We make a compromise to keep things + simple. + */ + + tweakedPam = inpam; /* initial value */ + + if ((cmdline.clip || cmdline.changemaxval) + && PNM_FORMAT_TYPE(inpam.format) != PBM_TYPE) + tweakedPam.maxval = + (((sample) 1) << tweakedPam.bytes_per_sample * 8) - 1; + + analyzeRaster(&tweakedPam, &goodRowCount, &highestSample, + !cmdline.truncate, cmdline.verbose); + + if (goodRowCount == 0) + pm_error("Cannot read a single row from the image%s", + cmdline.verbose ? "" : ". Use -verbose to find out why"); + + if (goodRowCount < inpam.height) + pm_message("Copying %u good rows; %u bottom rows missing%s", + goodRowCount, inpam.height - goodRowCount, + cmdline.verbose ? "" : ". Use -verbose to find out why"); + + pm_seek2(ifP, &rasterPos, sizeof(rasterPos)); + + outpam = inpam; /* initial value */ + + outpam.file = stdout; + outpam.height = goodRowCount; + if (cmdline.changemaxval && highestSample > outpam.maxval) { + pm_message("Raising maxval from %lu to %lu to legitimize " + "all sample values", + outpam.maxval, highestSample); + outpam.maxval = highestSample; + } + + pnm_writepaminit(&outpam); + + copyGoodRows(&tweakedPam, &outpam, cmdline.verbose); + + pm_close(inpam.file); + + return 0; +} + + + diff --git a/other/pamfixtrunc b/other/pamfixtrunc new file mode 100755 index 00000000..1aa3ff94 --- /dev/null +++ b/other/pamfixtrunc @@ -0,0 +1,50 @@ +#!/bin/sh + +############################################################################## +# This is essentially a Perl program. We exec the Perl interpreter specifying +# this same file as the Perl program and use the -x option to cause the Perl +# interpreter to skip down to the Perl code. The reason we do this instead of +# just making /usr/bin/perl the script interpreter (instead of /bin/sh) is +# that the user may have multiple Perl interpreters and the one he wants to +# use is properly located in the PATH. The user's choice of Perl interpreter +# may be crucial, such as when the user also has a PERL5LIB environment +# variable and it selects modules that work with only a certain main +# interpreter program. +# +# An alternative some people use is to have /usr/bin/env as the script +# interpreter. We don't do that because we think the existence and +# compatibility of /bin/sh is more reliable. +# +# Note that we aren't concerned about efficiency because the user who needs +# high efficiency can use directly the programs that this program invokes. +# +############################################################################## + +exec perl -w -x -S -- "$0" "$@" + +#!/usr/bin/perl +############################################################################## +# This is nothing but a compatibility interface for Pamfixtrunc. +# An old program coded to call Pamfixtrunc will continue working because +# this interface exists. All new (or newly modified) programs should +# call Pamfix instead. +############################################################################## + +use strict; +use File::Basename; +use Cwd 'abs_path'; + +my @pamFixOptions; + +@pamFixOptions = @ARGV; # initial value + +push(@pamFixOptions, '-truncate'); + +# We want to get Pamfix from the same directory we came from if +# it's there. Frequently, the directory containing Netpbm programs is +# not in the PATH and we were invoked by absolute path. + +my $my_directory = abs_path(dirname($0)); +$ENV{"PATH"} = $my_directory . ":" . $ENV{"PATH"}; + +exit(system('pamfix', @pamFixOptions)>>8); diff --git a/other/pamfixtrunc.c b/other/pamfixtrunc.c deleted file mode 100644 index 6d71406f..00000000 --- a/other/pamfixtrunc.c +++ /dev/null @@ -1,176 +0,0 @@ -/*============================================================================ - pamfixtrunc -============================================================================== - Fix a Netpbm image that has been truncated, e.g. by I/O error. - - By Bryan Henderson, January 2007. - - Contributed to the public domain by its author. - -============================================================================*/ - -#include <setjmp.h> - -#include "pm_c_util.h" -#include "pam.h" -#include "shhopt.h" -#include "mallocvar.h" - -struct cmdlineInfo { - /* All the information the user supplied in the command line, - in a form easy for the program to use. - */ - const char * inputFilespec; /* Filespec of input file */ - unsigned int verbose; -}; - - - -static void -parseCommandLine(int argc, 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; - - optStruct3 opt; - - unsigned int option_def_index; - - MALLOCARRAY(option_def, 100); - - option_def_index = 0; /* incremented by OPTENTRY */ - - OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); - - opt.opt_table = option_def; - opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ - opt.allowNegNum = FALSE; /* We don't parms that are negative numbers */ - - optParseOptions3(&argc, argv, opt, sizeof(opt), 0); - /* Uses and sets argc, argv, and some of *cmdlineP and others. */ - - if (argc-1 == 0) - cmdlineP->inputFilespec = "-"; - else if (argc-1 != 1) - pm_error("Program takes zero or one argument (filename). You " - "specified %d", argc-1); - else - cmdlineP->inputFilespec = argv[1]; -} - - - -static unsigned int readErrRow; -static bool readErrVerbose; - -static pm_usererrormsgfn discardMsg; - -static void -discardMsg(const char * const msg) { - if (readErrVerbose) - pm_message("Error reading row %u: %s", readErrRow, msg); -} - - - -static void -countRows(const struct pam * const inpamP, - bool const verbose, - unsigned int * const goodRowCountP) { - - tuple * tuplerow; - unsigned int row; - jmp_buf jmpbuf; - int rc; - unsigned int goodRowCount; - - tuplerow = pnm_allocpamrow(inpamP); - - pm_setusererrormsgfn(discardMsg); - - rc = setjmp(jmpbuf); - if (rc == 0) { - pm_setjmpbuf(&jmpbuf); - - readErrVerbose = verbose; - goodRowCount = 0; /* initial value */ - for (row = 0; row < inpamP->height; ++row) { - readErrRow = row; - pnm_readpamrow(inpamP, tuplerow); - /* The above does not return if it can't read the next row from - the file. Instead, it longjmps out of this loop. - */ - ++goodRowCount; - } - } - *goodRowCountP = goodRowCount; - - pnm_freepamrow(tuplerow); -} - - - -static void -copyGoodRows(const struct pam * const inpamP, - FILE * const ofP, - unsigned int const goodRowCount) { - - struct pam outpam; - tuple * tuplerow; - unsigned int row; - - outpam = *inpamP; /* initial value */ - - outpam.file = ofP; - outpam.height = goodRowCount; - - tuplerow = pnm_allocpamrow(inpamP); - - pnm_writepaminit(&outpam); - - for (row = 0; row < outpam.height; ++row) { - pnm_readpamrow(inpamP, tuplerow); - pnm_writepamrow(&outpam, tuplerow); - } - - pnm_freepamrow(tuplerow); -} - - - -int -main(int argc, char * argv[]) { - struct cmdlineInfo cmdline; - struct pam inpam; - FILE * ifP; - pm_filepos rasterPos; - unsigned int goodRowCount; - - pnm_init(&argc, argv); - - parseCommandLine(argc, argv, &cmdline); - - ifP = pm_openr_seekable(cmdline.inputFilespec); - - pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); - - pm_tell2(ifP, &rasterPos, sizeof(rasterPos)); - - countRows(&inpam, cmdline.verbose, &goodRowCount); - - pm_message("Copying %u good rows; %u bottom rows missing", - goodRowCount, inpam.height - goodRowCount); - - pm_seek2(ifP, &rasterPos, sizeof(rasterPos)); - - copyGoodRows(&inpam, stdout, goodRowCount); - - pm_close(inpam.file); - - return 0; -} - - diff --git a/other/pamlookup.c b/other/pamlookup.c index 3b7a7f59..4ceb047f 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 */ - 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); } @@ -94,7 +107,7 @@ fitLookup(tuple ** const inputLookup, fitLookuppamP->width = cols; fitLookuppamP->height = rows; - asprintfN(&pamscaleCommand, "pamscale -width=%u -height=%u", cols, rows); + pm_asprintf(&pamscaleCommand, "pamscale -width=%u -height=%u", cols, rows); inPamtuples.pamP = (struct pam *) &inputLookuppam; inPamtuples.tuplesP = (tuple ***) &inputLookup; @@ -105,25 +118,38 @@ fitLookup(tuple ** const inputLookup, &pm_accept_to_pamtuples, &outPamtuples, pamscaleCommand); - strfree(pamscaleCommand); + pm_strfree(pamscaleCommand); } 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, (unsigned)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; } + diff --git a/other/pampick.c b/other/pampick.c index 63f32968..61941f06 100644 --- a/other/pampick.c +++ b/other/pampick.c @@ -92,7 +92,7 @@ struct cmdlineInfo { static void -parseCommandLine(int argc, char ** argv, +parseCommandLine(int argc, const char ** argv, struct cmdlineInfo * const cmdlineP) { /*---------------------------------------------------------------------------- Note that the pointers we place into *cmdlineP are sometimes to storage @@ -119,7 +119,7 @@ parseCommandLine(int argc, char ** argv, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ - 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. */ initUintSet(&cmdlineP->imageSeqList, argc-1); @@ -217,15 +217,15 @@ failIfUnpickedImages(const struct uintSet * const uintSetP, int -main(int argc, char *argv[]) { +main(int argc, const char *argv[]) { struct cmdlineInfo cmdline; - bool eof; /* No more images in input */ + int eof; /* No more images in input */ unsigned int imageSeq; /* Sequence of current image in input file. First = 0 */ - pnm_init(&argc, argv); + pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); diff --git a/other/pamsplit.c b/other/pamsplit.c index a03353d7..26eb0d59 100644 --- a/other/pamsplit.c +++ b/other/pamsplit.c @@ -16,10 +16,10 @@ #include <stdio.h> #include "pm_c_util.h" -#include "pam.h" #include "shhopt.h" #include "nstring.h" #include "mallocvar.h" +#include "pam.h" struct cmdlineInfo { /* All the information the user supplied in the command line, @@ -34,7 +34,7 @@ struct cmdlineInfo { static void -parseCommandLine(int argc, char ** argv, +parseCommandLine(int argc, const char ** argv, struct cmdlineInfo * const cmdlineP) { /*---------------------------------------------------------------------------- Note that the pointers we place into *cmdlineP are sometimes to storage @@ -59,7 +59,7 @@ parseCommandLine(int argc, char ** argv, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ - 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 (!padnameSpec) @@ -138,11 +138,11 @@ computeOutputName(char const outputFilePattern[], afterSub = strstr(outputFilePattern, "%d") + 2; /* Make filenameFormat something like "%s%04u%s" */ - asprintfN(&filenameFormat, "%%s%%0%ud%%s", padCount); + pm_asprintf(&filenameFormat, "%%s%%0%ud%%s", padCount); - asprintfN(outputNameP, filenameFormat, beforeSub, imageSeq, afterSub); + pm_asprintf(outputNameP, filenameFormat, beforeSub, imageSeq, afterSub); - strfree(filenameFormat); + pm_strfree(filenameFormat); free(beforeSub); } @@ -150,16 +150,16 @@ computeOutputName(char const outputFilePattern[], int -main(int argc, char *argv[]) { +main(int argc, const char *argv[]) { struct cmdlineInfo cmdline; FILE * ifP; - bool eof; /* No more images in input */ + int eof; /* No more images in input */ unsigned int imageSeq; /* Sequence of current image in input file. First = 0 */ - pnm_init(&argc, argv); + pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); @@ -179,7 +179,7 @@ main(int argc, char *argv[]) { extractOneImage(ifP, ofP); pm_close(ofP); - strfree(outputFileName); + pm_strfree(outputFileName); pnm_nextimage(ifP, &eof); } @@ -187,3 +187,6 @@ main(int argc, char *argv[]) { return 0; } + + + diff --git a/other/pamstack.c b/other/pamstack.c index d826cf1f..308852c8 100644 --- a/other/pamstack.c +++ b/other/pamstack.c @@ -44,7 +44,7 @@ parseCommandLine(int argc, char ** argv, was passed to us as the argv array. -----------------------------------------------------------------------------*/ optEntry * option_def; - /* Instructions to optParseOptions3 on how to parse our options. + /* Instructions to pm_optParseOptions3 on how to parse our options. */ optStruct3 opt; extern struct pam pam; /* Just so we can look at field sizes */ @@ -62,7 +62,7 @@ parseCommandLine(int argc, char ** argv, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We may have parms that are negative numbers */ - optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (!tupletypeSpec) @@ -70,7 +70,8 @@ parseCommandLine(int argc, char ** argv, else if (strlen(cmdlineP->tupletype)+1 > sizeof(pam.tuple_type)) pm_error("Tuple type name specified is too long. Maximum of " - "%u characters allowed.", sizeof(pam.tuple_type)); + "%u characters allowed.", + (unsigned)sizeof(pam.tuple_type)); cmdlineP->nInput = 0; /* initial value */ { @@ -215,10 +216,10 @@ nextImageAllStreams(unsigned int const nInput, unsigned int inputSeq; for (inputSeq = 0; inputSeq < nInput; ++inputSeq) { - bool eof; + int eof; pnm_nextimage(ifP[inputSeq], &eof); if (eof) - *eofP = eof; + *eofP = true; } } diff --git a/other/pamsummcol.c b/other/pamsummcol.c index c31a9940..c84f38ad 100644 --- a/other/pamsummcol.c +++ b/other/pamsummcol.c @@ -54,7 +54,7 @@ parseCommandLine(int argc, char ** const argv, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ - optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (sumSpec + minSpec + maxSpec > 1) diff --git a/other/pamunlookup.c b/other/pamunlookup.c new file mode 100644 index 00000000..77c2807b --- /dev/null +++ b/other/pamunlookup.c @@ -0,0 +1,250 @@ +/*============================================================================ + pamunlookup +============================================================================== + Find tuple values from an input image in a lookup table and + produce a corresponding index image containing table indices. + + The lookup table is a one-row PAM image tuple type the same as the input + image. The output index image has the same width and height as the input + image depth 1, and maxval equal to the width of the lookup image (the + possible values include one for each column in the lookup image, plus one + for tuple values that are not in the lookup image). + + By Bryan Henderson, San Jose CA 2015.08.08 + +============================================================================*/ + +#include <assert.h> + +#include "pm_c_util.h" +#include "mallocvar.h" +#include "shhopt.h" +#include "pm_system.h" +#include "nstring.h" +#include "pam.h" +#include "pammap.h" + + + +struct CmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char * inputFileName; + char * lookupfile; +}; + + + +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 OptParseOptions2 on how to parse our options. + */ + optStruct3 opt; + + unsigned int option_def_index; + + unsigned int lookupfileSpec; + + MALLOCARRAY_NOFAIL(option_def, 100); + + option_def_index = 0; /* incremented by OPTENTRY */ + OPTENT3(0, "lookupfile", OPT_STRING, &cmdlineP->lookupfile, + &lookupfileSpec, 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, (char **)argv, opt, sizeof(opt), 0); + /* Uses and sets argc, argv, and some of *cmdlineP and others. */ + + if (!lookupfileSpec) + pm_error("You must specify the -lookupfile option"); + + if (argc-1 < 1) + cmdlineP->inputFileName = "-"; + else + cmdlineP->inputFileName = argv[1]; + + free(option_def); +} + + + +static void +getLookup(const char * const lookupFileName, + tuple *** const lookupP, + struct pam * const lookuppamP) { +/*---------------------------------------------------------------------------- + Get the lookup image (the one that maps integers to tuples, e.g. a + color index / color map / palette) from the file named + 'lookupFileName'. + + Return the image as *lookupP and *lookuppamP. +-----------------------------------------------------------------------------*/ + FILE * lookupfileP; + + struct pam inputLookuppam; + tuple ** inputLookup; + + lookupfileP = pm_openr(lookupFileName); + inputLookup = pnm_readpam(lookupfileP, + &inputLookuppam, PAM_STRUCT_SIZE(tuple_type)); + + pm_close(lookupfileP); + + if (inputLookuppam.height != 1) + pm_error("The lookup table image must be one row. " + "Yours is %u rows.", + inputLookuppam.height); + + *lookupP = inputLookup; + *lookuppamP = inputLookuppam; +} + + + +static void +makeReverseLookupHash(struct pam * const lookuppamP, + tuple ** const lookup, + tuplehash * const hashP) { +/*---------------------------------------------------------------------------- + Create a tuple hash that maps each tuple values in the first row of + 'lookup' to the number of the column in which it appears. + + Abort the program with an error if the same tuple value occurs in two + columns of the first row. +-----------------------------------------------------------------------------*/ + tuplehash hash; + unsigned int col; + + hash = pnm_createtuplehash(); + + for (col = 0; col < lookuppamP->width; ++col) { + tuple const thisValue = lookup[0][col]; + + int found; + int priorValue; + + pnm_lookuptuple(lookuppamP, hash, thisValue, &found, &priorValue); + + if (found) + pm_error("Same tuple value occurs in both Column %u and " + "Column %u of the lookup image", priorValue, col); + else { + int fits; + pnm_addtotuplehash(lookuppamP, hash, lookup[0][col], col, &fits); + + if (!fits) + pm_error("Out of memory constructing hash of lookup table"); + } + } + + *hashP = hash; +} + + + +static void +doUnlookup(struct pam * const inpamP, + tuplehash const lookupHash, + sample const maxIndex, + FILE * const ofP) { + + struct pam outpam; + unsigned int row; + tuple * inrow; + tuple * outrow; + + inrow = pnm_allocpamrow(inpamP); + + outpam.size = sizeof(outpam); + outpam.len = PAM_STRUCT_SIZE(tuple_type); + outpam.file = ofP; + outpam.format = PAM_FORMAT; + outpam.height = inpamP->height; + outpam.width = inpamP->width; + outpam.depth = 1; + outpam.maxval = maxIndex + 1; /* +1 for missing color */ + strcpy(outpam.tuple_type, "INDEX"); + + pnm_writepaminit(&outpam); + + outrow = pnm_allocpamrow(&outpam); + + for (row = 0; row < inpamP->height; ++row) { + unsigned int col; + + pnm_readpamrow(inpamP, inrow); + + for (col = 0; col < inpamP->width; ++col) { + int found; + int index; + pnm_lookuptuple(inpamP, lookupHash, inrow[col], &found, &index); + + if (found) { + assert(index <= outpam.maxval); + outrow[col][0] = index; + } else + outrow[col][0] = maxIndex + 1; + } + pnm_writepamrow(&outpam, outrow); + } + + pnm_freepamrow(outrow); + pnm_freepamrow(inrow); +} + + + +int +main(int argc, const char ** const argv) { + + struct CmdlineInfo cmdline; + struct pam inpam; + FILE * ifP; + struct pam lookuppam; + tuple ** lookup; + + tuplehash lookupHash; + + pm_proginit(&argc, argv); + + parseCommandLine(argc, argv, &cmdline); + + ifP = pm_openr(cmdline.inputFileName); + + pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type)); + + getLookup(cmdline.lookupfile, &lookup, &lookuppam); + + if (inpam.depth != lookuppam.depth) + pm_error("The lookup image has depth %u, but the input image " + "has depth %u. They must be the same", + lookuppam.depth, inpam.depth); + if (!streq(inpam.tuple_type, lookuppam.tuple_type)) + pm_error("The lookup image has tupel type '%s', " + "but the input image " + "has tuple type '%s'. They must be the same", + lookuppam.tuple_type, inpam.tuple_type); + + makeReverseLookupHash(&lookuppam, lookup, &lookupHash); + + doUnlookup(&inpam, lookupHash, lookuppam.width-1, stdout); + + pm_close(ifP); + + pnm_destroytuplehash(lookupHash); + pnm_freepamarray(lookup, &lookuppam); + + return 0; +} + + diff --git a/other/pamvalidate.c b/other/pamvalidate.c new file mode 100644 index 00000000..a7b08b8e --- /dev/null +++ b/other/pamvalidate.c @@ -0,0 +1,86 @@ +/*============================================================================= + pamvalidate +=============================================================================== + Part of the Netpbm package. + + Copy PAM and PNM (i.e. PBM, PGM, or PPM) images from Standard Input + to Standard Output. No output when input is invalid. + + Contributed to the public domain by its author. +=============================================================================*/ + +#include <string.h> +#include "pm_c_util.h" +#include "pam.h" + + + +int +main(int argc, const char * argv[]) { + + FILE * const tmpfile = pm_tmpfile(); + int eof; /* no more images in input stream */ + struct pam inpam; /* Input PAM image */ + struct pam outpam; /* Output PAM image */ + + pm_proginit(&argc, argv); + + if (argc-1 != 0) + pm_error("Program takes no arguments. Input is from Standard Input"); + + for (eof = FALSE; !eof; ) { + pnm_readpaminit(stdin, &inpam, PAM_STRUCT_SIZE(tuple_type)); + + outpam = inpam; /* initial value */ + outpam.file = tmpfile; + + pnm_writepaminit(&outpam); + + if (PNM_FORMAT_TYPE(inpam.format) == PBM_TYPE) { + /* Fast method for PBM */ + unsigned char * const inrow = pbm_allocrow_packed(inpam.width); + + unsigned int row; + + for (row = 0; row < inpam.height; ++row) { + pbm_readpbmrow_packed(inpam.file, inrow, inpam.width, + inpam.format); + pbm_writepbmrow_packed(tmpfile, inrow, inpam.width, 0); + } + pbm_freerow(inrow); + + } else { + /* General case. Logic works for PBM */ + tuple * const tuplerow = pnm_allocpamrow(&inpam); + + unsigned int row; + + for (row = 0; row < inpam.height; ++row) { + pnm_readpamrow(&inpam, tuplerow); + pnm_writepamrow(&outpam, tuplerow); + } + pnm_freepamrow(tuplerow); + } + pnm_nextimage(stdin, &eof); + } + + fseek(tmpfile, 0, SEEK_SET); + + while (!feof(tmpfile) && !ferror(tmpfile) && !ferror(stdout)) { + char buffer[4096]; + size_t bytesReadCt; + + bytesReadCt = fread(buffer, 1, sizeof(buffer), tmpfile); + + if (ferror(tmpfile)) + pm_error("Error reading from temporary file. " + "Incomplete output. " + "Errno = %s (%d)", strerror(errno), errno); + else + fwrite(buffer, 1, bytesReadCt, stdout); + } + pm_close(tmpfile); + pm_close(stdout); + + return 0; +} diff --git a/other/pamx/Makefile b/other/pamx/Makefile index a40ea3a6..4e06e0fd 100644 --- a/other/pamx/Makefile +++ b/other/pamx/Makefile @@ -8,30 +8,37 @@ VPATH=.:$(SRCDIR)/$(SUBDIR) include $(BUILDDIR)/config.mk EXTERN_INCLUDE = -ifneq ($(X11LIB),NONE) - ifneq ($(X11HDR_DIR),) - EXTERN_INCLUDES += -I$(X11HDR_DIR) + +ifeq ($(shell pkg-config x11 --modversion --silence-errors),) + # Pkg-config has never heard of X11, or doesn't even exist + + ifneq ($(X11LIB),NONE) + HAVE_X11LIB = Y + ifneq ($(X11HDR_DIR)x,x) + EXTERN_INCLUDES += -I$(X11HDR_DIR) + endif endif +else + HAVE_X11LIB = Y + X11LIB = $(shell pkg-config x11 --libs) + EXTERN_INCLUDES += $(shell pkg-config x11 --cflags) endif -ifneq ($(X11LIB),NONE) - BINARIES += pamx - - PAMX_OBJECTS = \ - pamx.o \ - image.o \ - send.o \ - window.o \ +ifeq ($(HAVE_X11LIB),Y) + PORTBINARIES += pamx - MERGE_OBJECTS = \ - pamx.o2 \ + EXTRA_OBJECTS = \ image.o \ send.o \ window.o \ endif -OBJECTS = $(PAMX_OBJECTS) +BINARIES = $(PORTBINARIES) + +OBJECTS = $(BINARIES:%=%.o) $(EXTRA_OBJECTS) + +MERGE_OBJECTS = $(BINARIES:%=%.o2) $(EXTRA_OBJECTS) MERGEBINARIES = $(BINARIES) @@ -39,7 +46,12 @@ all: $(BINARIES) include $(SRCDIR)/common.mk -pamx: $(PAMX_OBJECTS) $(NETPBMLIB) $(LIBOPT) - $(LD) -o $@ $(PAMX_OBJECTS) \ - $(shell $(LIBOPT) $(NETPBMLIB) $(X11LIB)) \ - $(LDFLAGS) $(LDLIBS) $(MATHLIB) $(RPATH) $(LADD) +ifeq ($(shell pkg-config x11 --libs),) + X11_LIBOPTS = $(shell $(LIBOPT) $(LIBOPTR) $(X11LIB)) +else + X11_LIBOPTS = $(shell pkg-config x11 --libs) +endif + +pamx: image.o send.o window.o +pamx: ADDL_OBJECTS = image.o send.o window.o +pamx: LDFLAGS_TARGET = $(X11_LIBOPTS) diff --git a/other/pamx/pamx.c b/other/pamx/pamx.c index 130cc64c..e22693ea 100644 --- a/other/pamx/pamx.c +++ b/other/pamx/pamx.c @@ -3,6 +3,7 @@ Copyright information is in the file COPYRIGHT */ +#define _XOPEN_SOURCE 500 /* Make sure strdup() is in string.h */ #define _BSD_SOURCE /* Make sure strdup() is in <string.h> */ #include <signal.h> #include <unistd.h> @@ -65,7 +66,7 @@ parseCommandLine(int argc, was passed to us as the argv array. We also trash *argv. --------------------------------------------------------------------------*/ optEntry *option_def; - /* Instructions to optParseOptions3 on how to parse our options. */ + /* Instructions to pm_optParseOptions3 on how to parse our options. */ optStruct3 opt; unsigned int option_def_index; @@ -110,7 +111,7 @@ parseCommandLine(int argc, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ - optParseOptions3(&argc, argv, opt, sizeof(opt), 0); + pm_optParseOptions3(&argc, argv, opt, sizeof(opt), 0); /* Uses and sets argc, argv, and some of *cmdlineP and others. */ if (geometrySpec) { @@ -360,7 +361,7 @@ main(int argc, destroyViewer(viewerP); if (title) - strfree(title); + pm_strfree(title); XCloseDisplay(dispP); diff --git a/other/pamx/send.c b/other/pamx/send.c index 5413308b..fd50d5e9 100644 --- a/other/pamx/send.c +++ b/other/pamx/send.c @@ -78,8 +78,8 @@ ximageToPixmap(Display * const disp, -/* find the best pixmap depth supported by the server for a particular - * visual and return that depth. +/* find the best pixmap depth the server can do for a particular visual and + * return that depth. * * this is complicated by R3's lack of XListPixmapFormats so we fake it * by looking at the structure ourselves. @@ -587,7 +587,7 @@ makeXImage(XImageInfo * const ximageinfoP, MALLOCARRAY(data, byteCount); if (data == NULL) pm_error("Can't allocate space for %u byte image", byteCount); - bcopy(imageP->data, data, byteCount); + memcpy(data, imageP->data, byteCount); ximageinfoP->ximageP = XCreateImage(disp, visualP, 1, XYBitmap, diff --git a/other/pamx/window.c b/other/pamx/window.c index 2eb48241..e2de1577 100644 --- a/other/pamx/window.c +++ b/other/pamx/window.c @@ -6,6 +6,7 @@ See COPYRIGHT file for copyright information. */ +#define _XOPEN_SOURCE 500 /* Make sure strdup() is in string.h */ #define _BSD_SOURCE /* Make sure strcaseeq() is in nstring.h */ #include <assert.h> @@ -112,11 +113,11 @@ getInitialViewerGeometry(const char * const geometryString, *userChoseP = TRUE; } else if (geometryString) { const char * defGeom; - asprintfN(&defGeom, "%ux%u+0+0", defaultWidth, defaultHeight); + pm_asprintf(&defGeom, "%ux%u+0+0", defaultWidth, defaultHeight); XGeometry(dispP, scrn, geometryString, defGeom, 0, 1, 1, 0, 0, (int *)xposP, (int *)yposP, (int *)widthP, (int *)heightP); - strfree(defGeom); + pm_strfree(defGeom); *userChoseP = TRUE; } else { *widthP = defaultWidth; @@ -193,7 +194,7 @@ determineRepaintStrategy(viewer * const viewerP, /* Decide how we're going to handle repaints. We have three modes: use backing-store, use background pixmap, and use exposures. - If the server supports backing-store, we enable it and use it. + If the server allows backing-store, we enable it and use it. This really helps servers which are memory constrained. If the server does not have backing-store, we try to send the image to a pixmap and use that as backing-store. If that fails, we use @@ -499,10 +500,10 @@ iconName(const char * const s) { char * t; STRSCPY(buf, s); - /* strip off stuff following 1st word. This strips + /* chop off stuff following 1st word. This strips info added by processing functions too. */ - t = index(buf, ' '); + t = strchr(buf, ' '); if (t) *t = '\0'; @@ -510,15 +511,15 @@ iconName(const char * const s) { You might want to change this. */ - t= rindex(buf, '/'); + t= strrchr(buf, '/'); if (t) { char * p; for (p = buf, ++t; *t; ++p, ++t) *p = *t; *p = '\0'; } - /* look for an extension and strip it off */ - t = index(buf, '.'); + /* Chop off any filename extension */ + t = strchr(buf, '.'); if (t) *t = '\0'; } @@ -652,9 +653,9 @@ bestVisual(Display * const disp, Visual * visualP; Visual * default_visualP; - /* Figure out the best depth the server supports. note that some servers - (such as the HP 11.3 server) actually say they support some depths but - have no visuals that support that depth. Seems silly to me ... + /* Figure out the best depth the server allows. note that some servers + (such as the HP 11.3 server) actually say they allow some depths but + have no visuals that allow that depth. Seems silly to me ... */ depth = 0; @@ -1079,7 +1080,7 @@ retvalueFromExitReason(exitReason const exitReason) { switch (exitReason) { case EXIT_NONE: assert(false); break; case EXIT_QUIT: retval = 0; break; - case EXIT_WM_KILL: retval = 10; break; + case EXIT_WM_KILL: retval = 0; break; case EXIT_DESTROYED: retval = 20; break; } return retval; @@ -1175,7 +1176,7 @@ displayInViewer(viewer * const viewerP, { const char * const name = iconName(title); XSetIconName(viewerP->dispP, viewerP->viewportWin, name); - strfree(name); + pm_strfree(name); } setNormalSizeHints(viewerP, imageP); diff --git a/other/pnmcolormap.c b/other/pnmcolormap.c index 42b03063..57db4329 100644 --- a/other/pnmcolormap.c +++ b/other/pnmcolormap.c @@ -77,7 +77,7 @@ parseCommandLine (int argc, char ** argv, was passed to us as the argv array. We also trash *argv. -----------------------------------------------------------------------------*/ optEntry *option_def; - /* Instructions to optParseOptions3 on how to parse our options. + /* Instructions to pm_optParseOptions3 on how to parse our options. */ optStruct3 opt; @@ -110,7 +110,7 @@ parseCommandLine (int argc, char ** argv, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ - optParseOptions3( &argc, argv, opt, sizeof(opt), 0 ); + pm_optParseOptions3( &argc, argv, opt, sizeof(opt), 0 ); /* Uses and sets argc, argv, and some of *cmdline_p and others. */ @@ -655,7 +655,7 @@ addImageColorsToHash(struct pam * const pamP, pnm_readpamrow(pamP, tuplerow); for (col = 0; col < pamP->width; ++col) { - bool firstOccurrence; + int firstOccurrence; pnm_addtuplefreqoccurrence(pamP, tuplerow[col], tuplehash, &firstOccurrence); @@ -688,7 +688,7 @@ computeHistogram(FILE * const ifP, struct pam firstPam; tuplehash tuplehash; unsigned int colorCount; - bool eof; + int eof; pm_message("making histogram..."); diff --git a/other/ppmdcfont.c b/other/ppmdcfont.c index 701277a9..130b6383 100644 --- a/other/ppmdcfont.c +++ b/other/ppmdcfont.c @@ -73,14 +73,14 @@ generateCommandTables(const struct ppmd_font * const fontP, if (fontP->glyphTable[relativeCodePoint].header.commandCount > 0) { const char * commandTableVariableName; - asprintfN(&commandTableVariableName, "%s_cmd_%u", - glyphTableVariableName, - fontP->header.firstCodePoint + relativeCodePoint); + pm_asprintf(&commandTableVariableName, "%s_cmd_%u", + glyphTableVariableName, + fontP->header.firstCodePoint + relativeCodePoint); generateCommandTable(fontP->glyphTable[relativeCodePoint], commandTableVariableName); - strfree(commandTableVariableName); + pm_strfree(commandTableVariableName); fprintf(stdout, "};\n"); fprintf(stdout, "\n"); @@ -130,14 +130,14 @@ generateGlyphTable(const struct ppmd_font * const fontP, const char * commandTableVariableName; - asprintfN(&commandTableVariableName, "%s_cmd_%u", - variableName, - fontP->header.firstCodePoint + relativeCodePoint); + pm_asprintf(&commandTableVariableName, "%s_cmd_%u", + variableName, + fontP->header.firstCodePoint + relativeCodePoint); generateGlyph(fontP->glyphTable[relativeCodePoint], commandTableVariableName); - strfree(commandTableVariableName); + pm_strfree(commandTableVariableName); if (relativeCodePoint < fontP->header.characterCount - 1) fprintf(stdout, " ,\n"); @@ -184,7 +184,7 @@ main(int argc, char **argv) { fprintf(stdout, "#include \"ppmdfont.h\"\n\n"); - asprintfN(&glyphTableVariableName, "%s_glyphTable", fontVariableName); + pm_asprintf(&glyphTableVariableName, "%s_glyphTable", fontVariableName); generateGlyphTable(fontP, glyphTableVariableName); @@ -192,7 +192,7 @@ main(int argc, char **argv) { generateFont(fontP, fontVariableName, glyphTableVariableName); - strfree(glyphTableVariableName); + pm_strfree(glyphTableVariableName); ppmd_free_font(fontP); diff --git a/other/ppmsvgalib.c b/other/ppmsvgalib.c index 5bcabdc1..c5700992 100644 --- a/other/ppmsvgalib.c +++ b/other/ppmsvgalib.c @@ -46,7 +46,7 @@ parseCommandLine (int argc, char ** argv, was passed to us as the argv array. We also trash *argv. -----------------------------------------------------------------------------*/ optEntry *option_def = malloc( 100*sizeof( optEntry ) ); - /* Instructions to optParseOptions3 on how to parse our options. + /* Instructions to pm_optParseOptions3 on how to parse our options. */ optStruct3 opt; @@ -64,7 +64,7 @@ parseCommandLine (int argc, char ** argv, opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */ opt.allowNegNum = FALSE; /* We have no parms that are negative numbers */ - optParseOptions3( &argc, argv, opt, sizeof(opt), 0 ); + pm_optParseOptions3( &argc, argv, opt, sizeof(opt), 0 ); /* Uses and sets argc, argv, and some of *cmdline_p and others. */ if (!modeSpec) @@ -253,10 +253,6 @@ main(int argc, char *argv[]) { ppm_init(&argc, argv); - rc = vga_init(); /* Initialize. */ - if (rc < 0) - pm_error("Svgalib unable to allocate a virtual console."); - parseCommandLine(argc, argv, &cmdline); ifP = pm_openr(cmdline.inputFilespec); @@ -269,6 +265,14 @@ main(int argc, char *argv[]) { &checkResult); } + /* We wait to initialize Svgalib to prevent it from interfering with + error messages the code above might issue, and leaving the console + in an undesirable state if the above code aborts the program. + */ + rc = vga_init(); /* Initialize. */ + if (rc < 0) + pm_error("Svgalib unable to allocate a virtual console."); + if (vga_hasmode(cmdline.mode)) display(ifP, cols, rows, maxval, format, cmdline.mode, cmdline.verbose); |