diff options
Diffstat (limited to 'other')
-rw-r--r-- | other/Makefile | 9 | ||||
-rw-r--r-- | other/pamarith.c | 431 | ||||
-rw-r--r-- | other/pambayer.c | 1 | ||||
-rw-r--r-- | other/pamchannel.c | 1 | ||||
-rw-r--r-- | other/pamdepth.c | 5 | ||||
-rw-r--r-- | other/pamendian.c | 2 | ||||
-rw-r--r-- | other/pamfixtrunc.c | 176 | ||||
-rw-r--r-- | other/pamlookup.c | 1 | ||||
-rw-r--r-- | other/pampick.c | 1 | ||||
-rw-r--r-- | other/pamsplit.c | 2 | ||||
-rw-r--r-- | other/pamstack.c | 1 | ||||
-rw-r--r-- | other/pamsummcol.c | 1 | ||||
-rw-r--r-- | other/pamx/Makefile | 7 | ||||
-rw-r--r-- | other/pamx/Makefile2 | 51 | ||||
-rw-r--r-- | other/pamx/image.c | 92 | ||||
-rw-r--r-- | other/pamx/image.h | 5 | ||||
-rw-r--r-- | other/pamx/pamx.c | 53 | ||||
-rw-r--r-- | other/pamx/window.c | 4 | ||||
-rw-r--r-- | other/pnmcolormap.c | 13 | ||||
-rw-r--r-- | other/ppmsvgalib.c | 4 |
20 files changed, 609 insertions, 251 deletions
diff --git a/other/Makefile b/other/Makefile index 9aaa9d93..a6748347 100644 --- a/other/Makefile +++ b/other/Makefile @@ -5,13 +5,14 @@ endif SUBDIR = other VPATH=.:$(SRCDIR)/$(SUBDIR) -include $(BUILDDIR)/Makefile.config +include $(BUILDDIR)/config.mk SUBDIRS = pamx +EXTERN_INCLUDES = ifneq ($(LINUXSVGALIB),NONE) ifneq ($(LINUXSVGAHDR_DIR),) - INCLUDES += -I$(LINUXSVGAHDR_DIR) + EXTERN_INCLUDES += -I$(LINUXSVGAHDR_DIR) endif endif @@ -23,7 +24,7 @@ endif # build. PORTBINARIES = pamarith pambayer pamchannel pamdepth \ - pamendian pamlookup pampick pamsplit \ + pamendian pamfixtrunc pamlookup pampick pamsplit \ pamstack pamsummcol pnmcolormap \ ppmdcfont ppmddumpfont ppmdmkfont @@ -47,7 +48,7 @@ MERGE_OBJECTS = $(MERGEBINARIES:%=%.o2) .PHONY: all all: $(BINARIES) $(SUBDIRS:%=%/all) -include $(SRCDIR)/Makefile.common +include $(SRCDIR)/common.mk ppmsvgalib: %: %.o $(NETPBMLIB) $(LIBOPT) $(LD) -o $@ $< \ diff --git a/other/pamarith.c b/other/pamarith.c index c1e7f1ed..7d973222 100644 --- a/other/pamarith.c +++ b/other/pamarith.c @@ -1,6 +1,9 @@ #include <assert.h> #include <string.h> +#include <limits.h> +#include "pm_c_util.h" +#include "mallocvar.h" #include "shhopt.h" #include "pam.h" @@ -10,25 +13,59 @@ enum function {FN_ADD, FN_SUBTRACT, FN_MULTIPLY, FN_DIVIDE, FN_DIFFERENCE, FN_SHIFTLEFT, FN_SHIFTRIGHT }; + + +static bool +isDyadic(enum function const function) { + + bool retval; + + switch (function) { + case FN_ADD: + case FN_MEAN: + case FN_AND: + case FN_OR: + case FN_XOR: + retval = FALSE; + break; + case FN_SUBTRACT: + case FN_DIFFERENCE: + case FN_MINIMUM: + case FN_MAXIMUM: + case FN_COMPARE: + case FN_MULTIPLY: + case FN_DIVIDE: + case FN_NAND: + case FN_NOR: + case FN_SHIFTLEFT: + case FN_SHIFTRIGHT: + retval = TRUE; + break; + } + return retval; +} + + + struct cmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. */ - const char *input1Filespec; - const char *input2Filespec; enum function function; + unsigned int operandCt; + const char ** operandFileNames; }; static void -parseCommandLine(int argc, char ** const argv, +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; @@ -41,6 +78,8 @@ parseCommandLine(int argc, char ** const argv, andSpec, orSpec, nandSpec, norSpec, xorSpec, shiftleftSpec, shiftrightSpec; + MALLOCARRAY_NOFAIL(option_def, 100); + option_def_index = 0; /* incremented by OPTENTRY */ OPTENT3(0, "add", OPT_FLAG, NULL, &addSpec, 0); OPTENT3(0, "subtract", OPT_FLAG, NULL, &subtractSpec, 0); @@ -63,7 +102,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); + 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 + @@ -72,15 +111,6 @@ parseCommandLine(int argc, char ** const argv, shiftleftSpec + shiftrightSpec > 1) pm_error("You may specify only one function"); - if (argc-1 != 2) - pm_error("You must specify two arguments: the files which are " - "the operands of the " - "dyadic function. You specified %d", argc-1); - else { - cmdlineP->input1Filespec = argv[1]; - cmdlineP->input2Filespec = argv[2]; - } - if (addSpec) cmdlineP->function = FN_ADD; else if (subtractSpec) @@ -115,6 +145,21 @@ parseCommandLine(int argc, char ** const argv, cmdlineP->function = FN_SHIFTRIGHT; else pm_error("You must specify a function (e.g. '-add')"); + + if (argc-1 < 2) + pm_error("You must specify at least two arguments: the files which " + "are the operands of the function. You specified %u", + argc-1); + else { + if (isDyadic(cmdlineP->function) && argc-1 > 2) + pm_error("You specified %u arguments, but a dyadic function. " + "For a dyadic function, you must specify 2 arguments: " + "the operands of the function", argc-1); + else { + cmdlineP->operandCt = argc-1; + cmdlineP->operandFileNames = &argv[1]; + } + } } @@ -220,43 +265,124 @@ computeOutputType(struct pam * const outpamP, +static sample +samplenSum(samplen const operands[], + unsigned int const operandCt) { + + unsigned int i; + samplen total; + + for (i = 1, total = operands[0]; i < operandCt; ++i) { + total += operands[1]; + if (total > 1.) + total = 1.; + } + return total; +} + + + +static sample +samplenMin(samplen const operands[], + unsigned int const operandCt) { + + unsigned int i; + samplen min; + + for (i = 1, min = operands[0]; i < operandCt; ++i) { + if (operands[i] < min) + min = operands[i]; + } + return min; +} + + + +static sample +samplenMax(samplen const operands[], + unsigned int const operandCt) { + + unsigned int i; + samplen max; + + for (i = 1, max = operands[0]; i < operandCt; ++i) { + if (operands[i] > max) + max = operands[i]; + } + return max; +} + + + +static sample +samplenMean(samplen const operands[], + unsigned int const operandCt) { + + unsigned int i; + double sum; + + for (i = 0, sum = 0.; i < operandCt; ++i) + sum += operands[i]; + + return sum / operandCt; +} + + + +static sample +samplenProduct(samplen const operands[], + unsigned int const operandCt) { + + unsigned int i; + double product; + + for (i = 1, product = operands[0]; i < operandCt; ++i) + product *= operands[i]; + + return product; +} + + + static samplen applyNormalizedFunction(enum function const function, - samplen const leftArg, - samplen const rightArg) { + samplen const operands[], + unsigned int const operandCt) { samplen result; switch (function) { case FN_ADD: - result = MIN(1., leftArg + rightArg); + result = samplenSum(operands, operandCt); break; case FN_SUBTRACT: - result = MAX(0., leftArg - rightArg); + result = MAX(0., operands[0] - operands[1]); break; case FN_MULTIPLY: - result = leftArg * rightArg; + result = samplenProduct(operands, operandCt); break; case FN_DIVIDE: - result = (rightArg > leftArg) ? - leftArg / rightArg : 1.; + result = (operands[1] > operands[0]) ? + operands[0] / operands[1] : 1.; break; case FN_DIFFERENCE: - result = leftArg > rightArg ? - leftArg - rightArg : rightArg - leftArg; + result = operands[0] > operands[1] ? + operands[0] - operands[1] : operands[1] - operands[0]; break; case FN_MINIMUM: - result = MIN(leftArg, rightArg); + result = samplenMin(operands, operandCt); break; case FN_MAXIMUM: - result = MAX(leftArg, rightArg); + result = samplenMax(operands, operandCt); break; case FN_MEAN: - result = (leftArg + rightArg) / 2.0; + result = samplenMean(operands, operandCt); break; case FN_COMPARE: result = - leftArg > rightArg ? 1. : leftArg < rightArg ? 0. : .5; + operands[0] > operands[1] ? + 1. : operands[0] < operands[1] ? + 0. : .5; break; default: pm_error("Internal error. applyNormalizedFunction() called " @@ -292,13 +418,19 @@ doNormalizedArith(struct pam * const inpam1P, unsigned int outplane; for (outplane = 0; outplane < outpamP->depth; ++outplane) { + unsigned int const operandCt = 2; unsigned int const plane1 = MIN(outplane, inpam1P->depth-1); unsigned int const plane2 = MIN(outplane, inpam2P->depth-1); + samplen * operands; + + MALLOCARRAY_NOFAIL(operands, operandCt); + + operands[0] = tuplerown1[col][plane1]; + operands[1] = tuplerown2[col][plane2]; + tuplerownOut[col][outplane] = - applyNormalizedFunction(function, - tuplerown1[col][plane1], - tuplerown2[col][plane2]); + applyNormalizedFunction(function, operands, operandCt); assert(tuplerownOut[col][outplane] >= 0.); assert(tuplerownOut[col][outplane] <= 1.); @@ -315,70 +447,238 @@ doNormalizedArith(struct pam * const inpam1P, static sample +sampleSum(sample const operands[], + unsigned int const operandCt, + sample const maxval) { + + unsigned int i; + sample total; + + for (i = 1, total = operands[0]; i < operandCt; ++i) { + total += operands[i]; + if (total > maxval) + total = maxval; + } + return total; +} + + + +static sample +sampleMin(sample const operands[], + unsigned int const operandCt) { + + unsigned int i; + sample min; + + for (i = 1, min = operands[0]; i < operandCt; ++i) { + if (operands[i] < min) + min = operands[i]; + } + return min; +} + + + +static sample +sampleMax(sample const operands[], + unsigned int const operandCt) { + + unsigned int i; + sample max; + + for (i = 1, max = operands[0]; i < operandCt; ++i) { + if (operands[i] > max) + max = operands[i]; + } + return max; +} + + + +static sample +sampleMean(sample const operands[], + unsigned int const operandCt) { + + unsigned int i; + unsigned int sum; + + for (i = 0, sum = 0; i < operandCt; ++i) { + sum += operands[i]; + if (UINT_MAX - operands[i] < sum) + pm_error("Arithmetic overflow adding samples for mean"); + } + return ROUNDDIV(sum, operandCt); +} + + + +static sample +sampleProduct(sample const operands[], + unsigned int const operandCt, + sample const maxval) { + + unsigned int i; + double product; + + for (i = 0, product = 1.0; i < operandCt; ++i) { + product *= ((double)operands[0]/maxval); + } + return (sample)(product * maxval + 0.5); +} + + + +static sample +sampleAnd(sample const operands[], + unsigned int const operandCt) { + + unsigned int i; + sample accum; + + for (i = 1, accum = operands[0]; i < operandCt; ++i) { + accum &= operands[i]; + } + return accum; +} + + + +static sample +sampleOr(sample const operands[], + unsigned int const operandCt) { + + unsigned int i; + sample accum; + + for (i = 1, accum = operands[0]; i < operandCt; ++i) { + accum |= operands[i]; + } + return accum; +} + + + +static sample +sampleNand(sample const operands[], + unsigned int const operandCt, + sample const maxval) { + + unsigned int i; + sample accum; + + for (i = 1, accum = operands[0]; i < operandCt; ++i) { + accum &= operands[i]; + } + return ~accum & maxval; +} + + + +static sample +sampleNor(sample const operands[], + unsigned int const operandCt, + sample const maxval) { + + unsigned int i; + sample accum; + + for (i = 1, accum = operands[0]; i < operandCt; ++i) { + accum |= operands[i]; + } + return ~accum & maxval; +} + + + +static sample +sampleXor(sample const operands[], + unsigned int const operandCt) { + + unsigned int i; + sample accum; + + for (i = 1, accum = operands[0]; i < operandCt; ++i) { + accum ^= operands[i]; + } + return accum; +} + + + +static sample applyUnNormalizedFunction(enum function const function, - sample const leftArg, - sample const rightArg, + sample const operands[], + unsigned int const operandCt, sample const maxval) { /*---------------------------------------------------------------------------- - Apply dyadic function 'function' to the arguments 'leftArg' and - 'rightArg', assuming both are based on the same maxval 'maxval'. - Return a value which is also a fraction of 'maxval'. + Apply function 'function' to the arguments operands[] (there are + 'operandCt' of them), assuming both are based on the same maxval + 'maxval'. Return a value which is also a fraction of 'maxval'. - Exception: for the shift operations, 'rightArg' is not based on any + Exception: for the shift operations, operands[1] is not based on any maxval. It is an absolute bit count. + + We assume 'operandCount' is sensible for 'function'. E.g. if + 'function' is FN_DIFFERENCE, 'operandCt' is 2. + + For a function that has a concept of left and right argument, + operands[0] is the left and operands[1] is the right. -----------------------------------------------------------------------------*/ sample result; switch (function) { case FN_ADD: - result = MIN(maxval, leftArg + rightArg); + result = sampleSum(operands, operandCt, maxval); break; case FN_SUBTRACT: - result = MAX(0, (int)leftArg - (int)rightArg); + result = MAX(0, (int)operands[0] - (int)operands[1]); break; case FN_DIFFERENCE: - result = leftArg > rightArg ? leftArg - rightArg : rightArg - leftArg; + result = operands[0] > operands[1] ? + operands[0] - operands[1] : operands[1] - operands[0]; break; case FN_MINIMUM: - result = MIN(leftArg, rightArg); + result = sampleMin(operands, operandCt); break; case FN_MAXIMUM: - result = MAX(leftArg, rightArg); + result = sampleMax(operands, operandCt); break; case FN_MEAN: - result = (leftArg + rightArg + 1) / 2; + result = sampleMean(operands, operandCt); break; case FN_COMPARE: - result = leftArg > rightArg ? 2 : leftArg < rightArg ? 0 : 1; + result = operands[0] > operands[1] ? + 2 : operands[0] < operands[1] ? 0 : 1; break; case FN_MULTIPLY: - result = (leftArg * rightArg + maxval/2) / maxval; + result = sampleProduct(operands, operandCt, maxval); break; case FN_DIVIDE: - result = (rightArg > leftArg) ? - (leftArg * maxval + rightArg/2) / rightArg : maxval; + result = (operands[1] > operands[0]) ? + ROUNDDIV(operands[0] * maxval, operands[1]) : maxval; break; case FN_AND: - result = leftArg & rightArg; + result = sampleAnd(operands, operandCt); break; case FN_OR: - result = leftArg | rightArg; + result = sampleOr(operands, operandCt); break; case FN_NAND: - result = ~(leftArg & rightArg) & maxval; + result = sampleNand(operands, operandCt, maxval); break; case FN_NOR: - result = ~(leftArg | rightArg) & maxval; + result = sampleNor(operands, operandCt, maxval); break; case FN_XOR: - result = leftArg ^ rightArg; + result = sampleXor(operands, operandCt); break; case FN_SHIFTLEFT: - result = (leftArg << rightArg) & maxval; + result = (operands[0] << operands[1]) & maxval; break; case FN_SHIFTRIGHT: - result = leftArg >> rightArg; + result = operands[0] >> operands[1]; break; default: pm_error("Internal error. applyUnNormalizedFunction() called " @@ -425,13 +725,19 @@ doUnNormalizedArith(struct pam * const inpam1P, unsigned int outplane; for (outplane = 0; outplane < outpamP->depth; ++outplane) { + unsigned int const operandCt = 2; unsigned int const plane1 = MIN(outplane, inpam1P->depth-1); unsigned int const plane2 = MIN(outplane, inpam2P->depth-1); + sample * operands; + + MALLOCARRAY_NOFAIL(operands, operandCt); + + operands[0] = tuplerow1[col][plane1]; + operands[1] = tuplerow2[col][plane2]; + tuplerowOut[col][outplane] = - applyUnNormalizedFunction(function, - tuplerow1[col][plane1], - tuplerow2[col][plane2], + applyUnNormalizedFunction(function, operands, operandCt, maxval); assert(tuplerowOut[col][outplane] >= 0); @@ -449,7 +755,7 @@ doUnNormalizedArith(struct pam * const inpam1P, int -main(int argc, char *argv[]) { +main(int argc, const char *argv[]) { struct cmdlineInfo cmdline; struct pam inpam1; @@ -458,12 +764,17 @@ main(int argc, char *argv[]) { FILE * if1P; FILE * if2P; - pnm_init(&argc, argv); + pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); - if1P = pm_openr(cmdline.input1Filespec); - if2P = pm_openr(cmdline.input2Filespec); + if (cmdline.operandCt != 2) + /* Code for > 2 operands not written yet */ + pm_error("You specified %u operands. We understand only 2.", + cmdline.operandCt); + + if1P = pm_openr(cmdline.operandFileNames[0]); + if2P = pm_openr(cmdline.operandFileNames[1]); pnm_readpaminit(if1P, &inpam1, PAM_STRUCT_SIZE(tuple_type)); pnm_readpaminit(if2P, &inpam2, PAM_STRUCT_SIZE(tuple_type)); diff --git a/other/pambayer.c b/other/pambayer.c index 9c58a3f4..f8ce0db8 100644 --- a/other/pambayer.c +++ b/other/pambayer.c @@ -25,6 +25,7 @@ #include <unistd.h> #include <stdio.h> +#include "pm_c_util.h" #include "pam.h" #include "shhopt.h" #include "mallocvar.h" diff --git a/other/pamchannel.c b/other/pamchannel.c index ac7bae65..64ab728b 100644 --- a/other/pamchannel.c +++ b/other/pamchannel.c @@ -13,6 +13,7 @@ #include <string.h> +#include "pm_c_util.h" #include "pam.h" #include "shhopt.h" #include "mallocvar.h" diff --git a/other/pamdepth.c b/other/pamdepth.c index 0c4490ed..ee59a408 100644 --- a/other/pamdepth.c +++ b/other/pamdepth.c @@ -11,8 +11,9 @@ =============================================================================*/ #include <assert.h> -#include "shhopt.h" +#include "pm_c_util.h" #include "mallocvar.h" +#include "shhopt.h" #include "pam.h" struct cmdlineInfo { @@ -89,7 +90,7 @@ createSampleMap(sample const oldMaxval, MALLOCARRAY_NOFAIL(sampleMap, oldMaxval+1); for (i = 0; i <= oldMaxval; ++i) - sampleMap[i] = (i * newMaxval + oldMaxval / 2) / oldMaxval; + sampleMap[i] = ROUNDDIV(i * newMaxval, oldMaxval); *sampleMapP = sampleMap; } diff --git a/other/pamendian.c b/other/pamendian.c index 16e1fe56..d82ebd38 100644 --- a/other/pamendian.c +++ b/other/pamendian.c @@ -1,5 +1,5 @@ /****************************************************************************** - pnmendian + pamendian ******************************************************************************* Reverse the endianness of multi-byte samples in a Netpbm stream. diff --git a/other/pamfixtrunc.c b/other/pamfixtrunc.c new file mode 100644 index 00000000..6d71406f --- /dev/null +++ b/other/pamfixtrunc.c @@ -0,0 +1,176 @@ +/*============================================================================ + 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 2651d596..3b7a7f59 100644 --- a/other/pamlookup.c +++ b/other/pamlookup.c @@ -13,6 +13,7 @@ ============================================================================*/ +#include "pm_c_util.h" #include "pam.h" #include "shhopt.h" #include "pm_system.h" diff --git a/other/pampick.c b/other/pampick.c index 7c2d4385..c6b66fe1 100644 --- a/other/pampick.c +++ b/other/pampick.c @@ -12,6 +12,7 @@ #include <string.h> #include <stdio.h> +#include "pm_c_util.h" #include "pam.h" #include "shhopt.h" #include "nstring.h" diff --git a/other/pamsplit.c b/other/pamsplit.c index b9ff6247..a03353d7 100644 --- a/other/pamsplit.c +++ b/other/pamsplit.c @@ -14,6 +14,8 @@ #include <string.h> #include <stdio.h> + +#include "pm_c_util.h" #include "pam.h" #include "shhopt.h" #include "nstring.h" diff --git a/other/pamstack.c b/other/pamstack.c index d9691f74..d826cf1f 100644 --- a/other/pamstack.c +++ b/other/pamstack.c @@ -14,6 +14,7 @@ #include <string.h> +#include "pm_c_util.h" #include "mallocvar.h" #include "nstring.h" #include "shhopt.h" diff --git a/other/pamsummcol.c b/other/pamsummcol.c index c2c3e46b..c31a9940 100644 --- a/other/pamsummcol.c +++ b/other/pamsummcol.c @@ -10,6 +10,7 @@ ******************************************************************************/ +#include "pm_c_util.h" #include "pam.h" #include "shhopt.h" #include "mallocvar.h" diff --git a/other/pamx/Makefile b/other/pamx/Makefile index baff506d..a40ea3a6 100644 --- a/other/pamx/Makefile +++ b/other/pamx/Makefile @@ -5,11 +5,12 @@ endif SUBDIR = other/pamx VPATH=.:$(SRCDIR)/$(SUBDIR) -include $(BUILDDIR)/Makefile.config +include $(BUILDDIR)/config.mk +EXTERN_INCLUDE = ifneq ($(X11LIB),NONE) ifneq ($(X11HDR_DIR),) - INCLUDES += -I$(X11HDR_DIR) + EXTERN_INCLUDES += -I$(X11HDR_DIR) endif endif @@ -36,7 +37,7 @@ MERGEBINARIES = $(BINARIES) all: $(BINARIES) -include $(SRCDIR)/Makefile.common +include $(SRCDIR)/common.mk pamx: $(PAMX_OBJECTS) $(NETPBMLIB) $(LIBOPT) $(LD) -o $@ $(PAMX_OBJECTS) \ diff --git a/other/pamx/Makefile2 b/other/pamx/Makefile2 deleted file mode 100644 index f69e103f..00000000 --- a/other/pamx/Makefile2 +++ /dev/null @@ -1,51 +0,0 @@ -# C compiler to use, including special flags. -CC=gcc - -WARNINGS = -Wall -Wmissing-declarations -Wundef -Wimplicit -Wwrite-strings \ - -Winline \ - -Wstrict-prototypes -Wmissing-prototypes \ - -Werror - -CFLAGS = $(WARNINGS) -fno-common -g -INCLUDES = -I /home/bryanh/netpbm/other/importinc - -# X11 include and library information. -X11_LIB_DIR=-L/subsysx/X11R6/lib -X11_LIB_NAME=-lX11 -NETPBMLIB = /home/bryanh/netpbm/lib/libnetpbm.so - -LIBS=$(X11_LIB_DIR) $(X11_LIB_NAME) -lm - -default: pamx - -# files for the image library -IMAGE_SRCS= image.c -IMAGE_OBJS= ${IMAGE_SRCS:.c=.o} - -# files for the image processing library -PROCESS_HDRS= -# no image processing. -PROCESS_SRCS= fill.c -PROCESS_OBJS= ${PROCESS_SRCS:.c=.o} - -X_SRCS= send.c window.c pamx.c -X_OBJS= ${X_SRCS:.c=.o} - -OBJS= $(IMAGE_OBJS) $(PROCESS_OBJS) $(X_OBJS) $(NETPBMLIB) - -.c.o: $*.c - $(CC) -c $(CFLAGS) $(INCLUDES) $*.c $(CADD) - -pamx: $(OBJS) $(OPTIONAL_LIBS) - $(CC) -o $@ $(OBJS) $(OPTIONAL_LIBS) $(LIBS) - -clean:: - rm -f *.o pamx - -dep: - $(CC) -MM -MG $(INCLUDES) *.c >Makefile.depend - -include Makefile.depend - -Makefile.depend: - >$@ diff --git a/other/pamx/image.c b/other/pamx/image.c index 892a9768..0e719438 100644 --- a/other/pamx/image.c +++ b/other/pamx/image.c @@ -237,95 +237,3 @@ freeImage(Image * const imageP) { free(imageP); } - - - - -static void -fillRow1(struct pam * const pamP, - tuple * const tuplerow, - unsigned char ** const pP) { - - unsigned int col; - - for (col = 0; col < pamP->width; ++col) { - unsigned int plane; - for (plane = 0; plane < pamP->depth; ++plane) - *(*pP)++ = - pnm_scalesample(tuplerow[col][0], pamP->maxval, 255); - } -} - - - -static void -fillRow3(struct pam * const pamP, - tuple * const tuplerow, - unsigned char ** const pP) { - - unsigned int col; - - for (col = 0; col < pamP->width; ++col) { - unsigned int plane; - for (plane = 0; plane < pamP->depth; ++plane) - *(*pP)++ = - pnm_scalesample(tuplerow[col][plane], pamP->maxval, 255); - } -} - - - -Image * -pbmLoad(const char * const fullname, - const char * const name, - bool const verbose) { - - FILE * ifP; - struct pam pam; - Image * imageP; - unsigned int row; - const char * filename; - tuple * tuplerow; - unsigned char * p; - enum {DEPTH_1, DEPTH_3} depth; - - if (STREQ(fullname, "stdin")) - filename = "-"; - else - filename = fullname; - - ifP = pm_openr(filename); - - pnm_readpaminit(ifP, &pam, PAM_STRUCT_SIZE(tuple_type)); - - if (strncmp(pam.tuple_type, "RGB", 3) == 0) { - depth = DEPTH_3; - if (pam.depth < 3) - pm_error("Invalid depth %u for RGB tuple type.", pam.depth); - } else - depth = DEPTH_1; - - imageP = newTrueImage(pam.width, pam.height); - - p = &imageP->data[0]; /* initial value */ - - tuplerow = pnm_allocpamrow(&pam); - - for (row = 0; row < pam.height; ++row) { - pnm_readpamrow(&pam, tuplerow); - - switch (depth) { - case DEPTH_3: - fillRow3(&pam, tuplerow, &p); - break; - case DEPTH_1: - fillRow1(&pam, tuplerow, &p); - break; - } - } - pnm_freepamrow(tuplerow); - - pm_close(ifP); - - return imageP; -} diff --git a/other/pamx/image.h b/other/pamx/image.h index 9c9689ac..32a48c5a 100644 --- a/other/pamx/image.h +++ b/other/pamx/image.h @@ -82,9 +82,4 @@ colorIntensity(unsigned int const red, BlueIntensity[blu / 256]); } -Image * -pbmLoad(const char * const fullname, - const char * const name, - bool const verbose); - #endif diff --git a/other/pamx/pamx.c b/other/pamx/pamx.c index 5fd525b7..130cc64c 100644 --- a/other/pamx/pamx.c +++ b/other/pamx/pamx.c @@ -9,6 +9,7 @@ #include <errno.h> #include <string.h> +#include "pm_c_util.h" #include "pam.h" #include "shhopt.h" #include "mallocvar.h" @@ -176,35 +177,32 @@ errorHandler(Display * const disp, -static void -fillRow1(struct pam * const pamP, - tuple * const tuplerow, - unsigned char ** const pP) { - - unsigned int col; - - for (col = 0; col < pamP->width; ++col) { - unsigned int plane; - for (plane = 0; plane < 3; ++plane) - *(*pP)++ = - pnm_scalesample(tuplerow[col][0], pamP->maxval, 255); - } -} - - +enum usableDepth {DEPTH_1, DEPTH_3}; static void -fillRow3(struct pam * const pamP, - tuple * const tuplerow, - unsigned char ** const pP) { +fillRow(struct pam * const pamP, + tuple * const tuplerow, + enum usableDepth const depth, + unsigned char ** const pP) { +/*---------------------------------------------------------------------------- + Add one row to the 24-bit truecolor image data at *pP, and advance + *pP just past that row. + Use either the first plane or the first 3 planes of tuplerow[] + for its contents, according to 'depth'. +-----------------------------------------------------------------------------*/ unsigned int col; for (col = 0; col < pamP->width; ++col) { + /* Truecolor image data has 3 bytes per pixel, one each for + red, green, and blue. + */ unsigned int plane; - for (plane = 0; plane < pamP->depth; ++plane) + for (plane = 0; plane < 3; ++plane) { + unsigned int const tuplePlane = depth == DEPTH_3 ? plane : 0; *(*pP)++ = - pnm_scalesample(tuplerow[col][plane], pamP->maxval, 255); + pnm_scalesample(tuplerow[col][tuplePlane], pamP->maxval, 255); + } } } @@ -219,7 +217,7 @@ loadPamImage(FILE * const ifP, unsigned int row; tuple * tuplerow; unsigned char * p; - enum {DEPTH_1, DEPTH_3} depth; + enum usableDepth depth; pnm_readpaminit(ifP, &pam, PAM_STRUCT_SIZE(tuple_type)); @@ -239,12 +237,17 @@ loadPamImage(FILE * const ifP, for (row = 0; row < pam.height; ++row) { pnm_readpamrow(&pam, tuplerow); + /* This semantically wasteful code allows a dumb compiler + optimizer to recognize that the depth is constant and + therefore not generate code that checks the depth every + time it processes a sample. + */ switch (depth) { case DEPTH_3: - fillRow3(&pam, tuplerow, &p); + fillRow(&pam, tuplerow, DEPTH_3, &p); break; case DEPTH_1: - fillRow1(&pam, tuplerow, &p); + fillRow(&pam, tuplerow, DEPTH_1, &p); break; } } @@ -297,7 +300,7 @@ determineTitle(struct cmdlineInfo const cmdline, if (cmdline.title) title = strdup(cmdline.title); else { - if (STREQ(cmdline.inputFileName, "-")) + if (streq(cmdline.inputFileName, "-")) title = NULL; else { title = pm_basename(cmdline.inputFileName); diff --git a/other/pamx/window.c b/other/pamx/window.c index 1a6e510b..2eb48241 100644 --- a/other/pamx/window.c +++ b/other/pamx/window.c @@ -6,6 +6,8 @@ See COPYRIGHT file for copyright information. */ +#define _BSD_SOURCE /* Make sure strcaseeq() is in nstring.h */ + #include <assert.h> #include <ctype.h> #include <signal.h> @@ -555,7 +557,7 @@ visualClassFromName(const char * const name) { bool found; for (a = 0, found = FALSE; VisualClassName[a].name; ++a) { - if (STRCASEEQ(VisualClassName[a].name, name)) { + if (strcaseeq(VisualClassName[a].name, name)) { /* Check for uniqueness. We special-case StaticGray because we have two spellings but they are unique if we find either. diff --git a/other/pnmcolormap.c b/other/pnmcolormap.c index 1be54ef8..42b03063 100644 --- a/other/pnmcolormap.c +++ b/other/pnmcolormap.c @@ -26,11 +26,12 @@ #include <math.h> #include "pm_config.h" -#include "pam.h" -#include "pammap.h" -#include "shhopt.h" +#include "pm_c_util.h" #include "mallocvar.h" #include "nstring.h" +#include "shhopt.h" +#include "pam.h" +#include "pammap.h" enum methodForLargest {LARGE_NORM, LARGE_LUM}; @@ -380,7 +381,7 @@ averageColors(int const boxStart, for (i = 0; i < boxSize; ++i) sum += colorfreqtable.table[boxStart+i]->tuple[plane]; - newTuple[plane] = sum / boxSize; + newTuple[plane] = ROUNDDIV(sum, boxSize); } } @@ -414,7 +415,7 @@ averagePixels(int const boxStart, sum += colorfreqtable.table[boxStart+i]->tuple[plane] * colorfreqtable.table[boxStart+i]->value; - newTuple[plane] = sum / n; + newTuple[plane] = ROUNDDIV(sum, n); } } @@ -631,7 +632,7 @@ validateCompatibleImage(struct pam * const inpamP, if (inpamP->format != firstPamP->format) pm_error("Image %u format (%d) is not the same as Image 0 (%d)", imageSeq, inpamP->format, firstPamP->format); - if (!STREQ(inpamP->tuple_type, firstPamP->tuple_type)) + if (!streq(inpamP->tuple_type, firstPamP->tuple_type)) pm_error("Image %u tuple type (%s) is not the same as Image 0 (%s)", imageSeq, inpamP->tuple_type, firstPamP->tuple_type); } diff --git a/other/ppmsvgalib.c b/other/ppmsvgalib.c index 67cc2b1a..5bcabdc1 100644 --- a/other/ppmsvgalib.c +++ b/other/ppmsvgalib.c @@ -16,6 +16,8 @@ #include <errno.h> #include <signal.h> #include <unistd.h> + +#include "pm_c_util.h" #include "ppm.h" #include "shhopt.h" @@ -249,7 +251,7 @@ main(int argc, char *argv[]) { int format; int rc; - ppm_init( &argc, argv ); + ppm_init(&argc, argv); rc = vga_init(); /* Initialize. */ if (rc < 0) |