|
Packit |
78deda |
/*=============================================================================
|
|
Packit |
78deda |
pamdepth
|
|
Packit |
78deda |
===============================================================================
|
|
Packit |
78deda |
Change the maxval in a Netpbm image.
|
|
Packit |
78deda |
|
|
Packit |
78deda |
This replaces Pnmdepth.
|
|
Packit |
78deda |
|
|
Packit |
78deda |
By Bryan Henderson January 2006.
|
|
Packit |
78deda |
|
|
Packit |
78deda |
Contributed to the public domain by its author.
|
|
Packit |
78deda |
=============================================================================*/
|
|
Packit |
78deda |
#include <assert.h>
|
|
Packit |
78deda |
|
|
Packit |
78deda |
#include "pm_c_util.h"
|
|
Packit |
78deda |
#include "mallocvar.h"
|
|
Packit |
78deda |
#include "shhopt.h"
|
|
Packit |
78deda |
#include "pam.h"
|
|
Packit |
78deda |
|
|
Packit |
78deda |
struct cmdlineInfo {
|
|
Packit |
78deda |
/* All the information the user supplied in the command line,
|
|
Packit |
78deda |
in a form easy for the program to use.
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
const char * inputFileName;
|
|
Packit |
78deda |
unsigned int newMaxval;
|
|
Packit |
78deda |
unsigned int verbose;
|
|
Packit |
78deda |
};
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
static void
|
|
Packit |
78deda |
parseCommandLine(int argc, const char ** argv,
|
|
Packit |
78deda |
struct cmdlineInfo *cmdlineP) {
|
|
Packit |
78deda |
/*----------------------------------------------------------------------------
|
|
Packit |
78deda |
Note that the file spec strings we return are stored in the storage that
|
|
Packit |
78deda |
was passed to us as the argv array.
|
|
Packit |
78deda |
-----------------------------------------------------------------------------*/
|
|
Packit |
78deda |
optEntry * option_def;
|
|
Packit |
78deda |
/* Instructions to pm_optParseOptions3 on how to parse our options.
|
|
Packit |
78deda |
*/
|
|
Packit |
78deda |
optStruct3 opt;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
unsigned int option_def_index;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
MALLOCARRAY_NOFAIL(option_def, 100);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
option_def_index = 0; /* incremented by OPTENTRY */
|
|
Packit |
78deda |
OPTENT3(0, "verbose", OPT_STRING, NULL,
|
|
Packit |
78deda |
&cmdlineP->verbose, 0);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
opt.opt_table = option_def;
|
|
Packit |
78deda |
opt.short_allowed = FALSE; /* We have no short (old-fashioned) options */
|
|
Packit |
78deda |
opt.allowNegNum = FALSE; /* We may have parms that are negative numbers */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
pm_optParseOptions3(&argc, (char **)argv, opt, sizeof(opt), 0);
|
|
Packit |
78deda |
/* Uses and sets argc, argv, and some of *cmdlineP and others. */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (argc-1 < 1)
|
|
Packit |
78deda |
pm_error("You must specify at least one argument -- the new maxval");
|
|
Packit |
78deda |
else {
|
|
Packit |
78deda |
int const intval = atoi(argv[1]);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (intval < 1)
|
|
Packit |
78deda |
pm_error("New maxval must be at least 1. You specified %d",
|
|
Packit |
78deda |
intval);
|
|
Packit |
78deda |
else if (intval > PNM_OVERALLMAXVAL)
|
|
Packit |
78deda |
pm_error("newmaxval (%d) is too large.\n"
|
|
Packit |
78deda |
"The maximum allowed by the PNM formats is %d.",
|
|
Packit |
78deda |
intval, PNM_OVERALLMAXVAL);
|
|
Packit |
78deda |
else
|
|
Packit |
78deda |
cmdlineP->newMaxval = intval;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (argc-1 < 2)
|
|
Packit |
78deda |
cmdlineP->inputFileName = "-";
|
|
Packit |
78deda |
else
|
|
Packit |
78deda |
cmdlineP->inputFileName = argv[2];
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
static void
|
|
Packit |
78deda |
createSampleMap(sample const oldMaxval,
|
|
Packit |
78deda |
sample const newMaxval,
|
|
Packit |
78deda |
sample** const sampleMapP) {
|
|
Packit |
78deda |
|
|
Packit |
78deda |
unsigned int i;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
sample * sampleMap;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
MALLOCARRAY_NOFAIL(sampleMap, oldMaxval+1);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (i = 0; i <= oldMaxval; ++i)
|
|
Packit |
78deda |
sampleMap[i] = ROUNDDIV(i * newMaxval, oldMaxval);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
*sampleMapP = sampleMap;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
static void
|
|
Packit |
78deda |
transformRaster(struct pam * const inpamP,
|
|
Packit |
78deda |
struct pam * const outpamP) {
|
|
Packit |
78deda |
|
|
Packit |
78deda |
tuple * tuplerow;
|
|
Packit |
78deda |
unsigned int row;
|
|
Packit |
78deda |
sample * sampleMap; /* malloc'ed */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
createSampleMap(inpamP->maxval, outpamP->maxval, &sampleMap);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
assert(inpamP->height == outpamP->height);
|
|
Packit |
78deda |
assert(inpamP->width == outpamP->width);
|
|
Packit |
78deda |
assert(inpamP->depth == outpamP->depth);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
tuplerow = pnm_allocpamrow(inpamP);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (row = 0; row < inpamP->height; ++row) {
|
|
Packit |
78deda |
unsigned int col;
|
|
Packit |
78deda |
pnm_readpamrow(inpamP, tuplerow);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
for (col = 0; col < inpamP->width; ++col) {
|
|
Packit |
78deda |
unsigned int plane;
|
|
Packit |
78deda |
for (plane = 0; plane < inpamP->depth; ++plane)
|
|
Packit |
78deda |
tuplerow[col][plane] = sampleMap[tuplerow[col][plane]];
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
pnm_writepamrow(outpamP, tuplerow);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
pnm_freepamrow(tuplerow);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
free(sampleMap);
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
|
|
Packit |
78deda |
int
|
|
Packit |
78deda |
main(int argc, const char * argv[]) {
|
|
Packit |
78deda |
|
|
Packit |
78deda |
struct cmdlineInfo cmdline;
|
|
Packit |
78deda |
FILE * ifP;
|
|
Packit |
78deda |
struct pam inpam;
|
|
Packit |
78deda |
struct pam outpam;
|
|
Packit |
78deda |
int eof;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
pm_proginit(&argc, argv);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
parseCommandLine(argc, argv, &cmdline);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
ifP = pm_openr(cmdline.inputFileName);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
eof = FALSE;
|
|
Packit |
78deda |
while (!eof) {
|
|
Packit |
78deda |
pnm_readpaminit(ifP, &inpam, PAM_STRUCT_SIZE(tuple_type));
|
|
Packit |
78deda |
|
|
Packit |
78deda |
outpam = inpam; /* initial value */
|
|
Packit |
78deda |
|
|
Packit |
78deda |
outpam.file = stdout;
|
|
Packit |
78deda |
outpam.maxval = cmdline.newMaxval;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
if (PNM_FORMAT_TYPE(inpam.format) == PBM_TYPE) {
|
|
Packit |
78deda |
pm_message( "promoting from PBM to PGM" );
|
|
Packit |
78deda |
outpam.format = PGM_TYPE;
|
|
Packit |
78deda |
} else
|
|
Packit |
78deda |
outpam.format = inpam.format;
|
|
Packit |
78deda |
|
|
Packit |
78deda |
pnm_writepaminit(&outpam);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
transformRaster(&inpam, &outpam);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
pnm_nextimage(ifP, &eof;;
|
|
Packit |
78deda |
}
|
|
Packit |
78deda |
pm_close(ifP);
|
|
Packit |
78deda |
pm_close(stdout);
|
|
Packit |
78deda |
|
|
Packit |
78deda |
return 0;
|
|
Packit |
78deda |
}
|