Blame other/pamdepth.c

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
}