From 287c76a2f527155343889d48009629e5d2f59e00 Mon Sep 17 00:00:00 2001 From: giraffedata Date: Fri, 25 Aug 2023 18:46:38 +0000 Subject: cleanup git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@4616 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- converter/other/pnmtojpeg.c | 739 +++++++++++++++++++++++--------------------- 1 file changed, 386 insertions(+), 353 deletions(-) (limited to 'converter/other') diff --git a/converter/other/pnmtojpeg.c b/converter/other/pnmtojpeg.c index a2c9c670..5e639182 100644 --- a/converter/other/pnmtojpeg.c +++ b/converter/other/pnmtojpeg.c @@ -21,6 +21,7 @@ #define _XOPEN_SOURCE 500 /* Make sure strdup() is in string.h */ #include /* to declare isdigit(), etc. */ +#include #include #include #include @@ -39,11 +40,11 @@ #define EXIT_WARNING 2 /* Goes with EXIT_SUCCESS, EXIT_FAILURE in stdlib.h */ -enum restart_unit {RESTART_MCU, RESTART_ROW, RESTART_NONE}; -enum density_unit {DEN_UNSPECIFIED, DEN_DOTS_PER_INCH, DEN_DOTS_PER_CM}; +enum RestartUnit {RESTART_MCU, RESTART_ROW, RESTART_NONE}; +enum DensityUnit {DEN_UNSPECIFIED, DEN_DOTS_PER_INCH, DEN_DOTS_PER_CM}; -struct density { - enum density_unit unit; +struct Density { + enum DensityUnit unit; /* The units of density for 'horiz', 'vert' */ unsigned short horiz; /* Not 0 */ /* Horizontal density, in units specified by 'unit' */ @@ -51,92 +52,93 @@ struct density { /* Same as 'horiz', but vertical */ }; -struct cmdlineInfo { +struct CmdlineInfo { /* All the information the user supplied in the command line, in a form easy for the program to use. */ - char *input_filespec; - unsigned int verbose; - unsigned int quality; - unsigned int force_baseline; - unsigned int progressive; - unsigned int arith_code; - J_DCT_METHOD dct_method; - unsigned int grayscale; - unsigned int rgb; - long int max_memory_to_use; - unsigned int trace_level; - char *qslots; - char *qtablefile; - char *sample; - char *scans; - int smoothing_factor; - unsigned int optimize; - unsigned int restart_value; - enum restart_unit restart_unit; - char *restart; - char *comment; /* NULL if none */ - const char *exif_filespec; /* NULL if none */ - unsigned int density_spec; + char * inputFileNm; + unsigned int verbose; + unsigned int quality; + unsigned int baseline; + unsigned int progressive; + unsigned int arithmetic; + J_DCT_METHOD dctMethod; + unsigned int grayscale; + unsigned int rgb; + long int maxMemoryToUse; + unsigned int tracelevel; + char * qslots; + char * qtablefile; + char * sample; + char * scans; + int smooth; + unsigned int optimize; + unsigned int restartValue; + enum RestartUnit restartUnit; + char * restart; + char * comment; /* NULL if none */ + const char * exif; /* NULL if none */ + unsigned int densitySpec; /* boolean: JFIF should specify a density. If false, 'density' is undefined. */ - struct density density; + struct Density density; }; static void -interpret_maxmemory (const char * const maxmemory, - long int * const max_memory_to_use_p) { +interpretMaxmemory (const char * const maxmemory, + long int * const maxMemoryToUseP) { long int lval; char ch; if (maxmemory == NULL) { - *max_memory_to_use_p = -1; /* unspecified */ + *maxMemoryToUseP = -1; /* unspecified */ } else if (sscanf(maxmemory, "%ld%c", &lval, &ch) < 1) { pm_error("Invalid value for --maxmemory option: '%s'.", maxmemory); exit(EXIT_FAILURE); } else { if (ch == 'm' || ch == 'M') lval *= 1000L; - *max_memory_to_use_p = lval * 1000L; + *maxMemoryToUseP = lval * 1000L; } } static void -interpret_restart(const char * const restart, - unsigned int * const restart_value_p, - enum restart_unit * const restart_unit_p) { +interpretRestart(const char * const restartOpt, + unsigned int * const restartValueP, + enum RestartUnit * const restartUnitP) { /*---------------------------------------------------------------------------- Interpret the restart command line option. Return values suitable for plugging into a jpeg_compress_struct to control compression. -----------------------------------------------------------------------------*/ - if (restart == NULL) { + if (restartOpt == NULL) { /* No --restart option. Set default */ - *restart_unit_p = RESTART_NONE; + *restartUnitP = RESTART_NONE; } else { /* Restart interval in MCU rows (or in MCUs with 'b'). */ long lval; char ch; unsigned int matches; - matches= sscanf(restart, "%ld%c", &lval, &ch); + matches= sscanf(restartOpt, "%ld%c", &lval, &ch); if (matches == 0) pm_error("Invalid value for the --restart option : '%s'.", - restart); + restartOpt); else { if (lval < 0 || lval > 65535L) { pm_error("--restart value %ld is out of range.", lval); exit(EXIT_FAILURE); } else { if (matches == 1) { - *restart_value_p = lval; - *restart_unit_p = RESTART_ROW; + *restartValueP = lval; + *restartUnitP = RESTART_ROW; } else { if (ch == 'b' || ch == 'B') { - *restart_value_p = lval; - *restart_unit_p = RESTART_MCU; - } else pm_error("Invalid --restart value '%s'.", restart); + *restartValueP = lval; + *restartUnitP = RESTART_MCU; + } else + pm_error("Invalid --restart value '%s'.", restartOpt); } } } @@ -147,8 +149,8 @@ interpret_restart(const char * const restart, static void -interpret_density(const char * const densityString, - struct density * const densityP) { +interpretDensity(const char * const densityString, + struct Density * const densityP) { /*---------------------------------------------------------------------------- Interpret the value of the "-density" option. -----------------------------------------------------------------------------*/ @@ -200,8 +202,8 @@ interpret_density(const char * const densityString, static void -parseCommandLine(const int argc, char ** argv, - struct cmdlineInfo *cmdlineP) { +parseCommandLine(const int argc, const char ** argv, + struct CmdlineInfo * const cmdlineP) { /*---------------------------------------------------------------------------- Note that many of the strings that this function returns in the *cmdlineP structure are actually in the supplied argv array. And @@ -211,140 +213,143 @@ parseCommandLine(const int argc, char ** argv, On the other hand, unlike other option processing functions, we do not change argv at all. -----------------------------------------------------------------------------*/ - optEntry *option_def = malloc(100*sizeof(optEntry)); + optEntry * option_def; /* Instructions to OptParseOptions3 on how to parse our options. */ optStruct3 opt; int i; /* local loop variable */ - const char *dctval; - const char *maxmemory; - const char *restart; - const char *density; + const char * dctval; + const char * maxmemory; + const char * restart; + const char * density; unsigned int qualitySpec, smoothSpec; unsigned int option_def_index; - int argc_parse; /* argc, except we modify it as we parse */ - char ** argv_parse; + int argcParse; /* argc, except we modify it as we parse */ + const char ** argvParse; /* argv, except we modify it as we parse */ - MALLOCARRAY(argv_parse, argc + 1); /* +1 for the terminating null ptr */ + MALLOCARRAY_NOFAIL(option_def, 100); + + MALLOCARRAY(argvParse, argc + 1); /* +1 for the terminating null ptr */ option_def_index = 0; /* incremented by OPTENTRY */ OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); OPTENT3(0, "quality", OPT_UINT, &cmdlineP->quality, &qualitySpec, 0); - OPTENT3(0, "baseline", OPT_FLAG, NULL, &cmdlineP->force_baseline, 0); + OPTENT3(0, "baseline", OPT_FLAG, NULL, &cmdlineP->baseline, 0); OPTENT3(0, "progressive", OPT_FLAG, NULL, &cmdlineP->progressive, 0); - OPTENT3(0, "arithmetic", OPT_FLAG, NULL, &cmdlineP->arith_code, 0); - OPTENT3(0, "dct", OPT_STRING, &dctval, NULL, 0); + OPTENT3(0, "arithmetic", OPT_FLAG, NULL, &cmdlineP->arithmetic, 0); + OPTENT3(0, "dct", OPT_STRING, &dctval, NULL, 0); OPTENT3(0, "grayscale", OPT_FLAG, NULL, &cmdlineP->grayscale, 0); OPTENT3(0, "greyscale", OPT_FLAG, NULL, &cmdlineP->grayscale, 0); OPTENT3(0, "rgb", OPT_FLAG, NULL, &cmdlineP->rgb, 0); - OPTENT3(0, "maxmemory", OPT_STRING, &maxmemory, NULL, 0); - OPTENT3(0, "tracelevel", OPT_UINT, &cmdlineP->trace_level, NULL, 0); + OPTENT3(0, "maxmemory", OPT_STRING, &maxmemory, NULL, 0); + OPTENT3(0, "tracelevel", OPT_UINT, &cmdlineP->tracelevel, NULL, 0); OPTENT3(0, "qslots", OPT_STRING, &cmdlineP->qslots, NULL, 0); OPTENT3(0, "qtables", OPT_STRING, &cmdlineP->qtablefile, NULL, 0); OPTENT3(0, "sample", OPT_STRING, &cmdlineP->sample, NULL, 0); OPTENT3(0, "scans", OPT_STRING, &cmdlineP->scans, NULL, 0); - OPTENT3(0, "smooth", OPT_UINT, &cmdlineP->smoothing_factor, + OPTENT3(0, "smooth", OPT_UINT, &cmdlineP->smooth, &smoothSpec, 0); OPTENT3(0, "optimize", OPT_FLAG, NULL, &cmdlineP->optimize, 0); OPTENT3(0, "optimise", OPT_FLAG, NULL, &cmdlineP->optimize, 0); OPTENT3(0, "restart", OPT_STRING, &restart, NULL, 0); OPTENT3(0, "comment", OPT_STRING, &cmdlineP->comment, NULL, 0); - OPTENT3(0, "exif", OPT_STRING, &cmdlineP->exif_filespec, NULL, 0); + OPTENT3(0, "exif", OPT_STRING, &cmdlineP->exif, NULL, 0); OPTENT3(0, "density", OPT_STRING, &density, - &cmdlineP->density_spec, 0); + &cmdlineP->densitySpec, 0); + /* Set the defaults */ dctval = NULL; maxmemory = NULL; - cmdlineP->trace_level = 0; + cmdlineP->tracelevel = 0; cmdlineP->qslots = NULL; cmdlineP->qtablefile = NULL; cmdlineP->sample = NULL; cmdlineP->scans = NULL; restart = NULL; cmdlineP->comment = NULL; - cmdlineP->exif_filespec = NULL; + cmdlineP->exif = NULL; /* Make private copy of arguments for pm_optParseOptions to corrupt */ - argc_parse = argc; - for (i=0; i < argc+1; i++) argv_parse[i] = argv[i]; + argcParse = argc; + for (i = 0; i < argc+1; ++i) + argvParse[i] = argv[i]; 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_parse, argv_parse, opt, sizeof(opt), 0); + pm_optParseOptions3(&argcParse, (char **)argvParse, opt, sizeof(opt), 0); if (!qualitySpec) cmdlineP->quality = -1; /* unspecified */ if (!smoothSpec) - cmdlineP->smoothing_factor = -1; + cmdlineP->smooth = -1; if (cmdlineP->rgb && cmdlineP->grayscale) pm_error("You can't specify both -rgb and -grayscale"); - if (argc_parse - 1 == 0) - cmdlineP->input_filespec = strdup("-"); /* he wants stdin */ - else if (argc_parse - 1 == 1) - cmdlineP->input_filespec = strdup(argv_parse[1]); + if (argcParse - 1 == 0) + cmdlineP->inputFileNm = strdup("-"); /* he wants stdin */ + else if (argcParse - 1 == 1) + cmdlineP->inputFileNm = strdup(argvParse[1]); else pm_error("Too many arguments. The only argument accepted " "is the input file specification."); if (dctval == NULL) - cmdlineP->dct_method = JDCT_DEFAULT; + cmdlineP->dctMethod = JDCT_DEFAULT; else { if (streq(dctval, "int")) - cmdlineP->dct_method = JDCT_ISLOW; + cmdlineP->dctMethod = JDCT_ISLOW; else if (streq(dctval, "fast")) - cmdlineP->dct_method = JDCT_IFAST; + cmdlineP->dctMethod = JDCT_IFAST; else if (streq(dctval, "float")) - cmdlineP->dct_method = JDCT_FLOAT; + cmdlineP->dctMethod = JDCT_FLOAT; else pm_error("Invalid value for the --dct option: '%s'.", dctval); } - interpret_maxmemory(maxmemory, &cmdlineP->max_memory_to_use); - interpret_restart(restart, &cmdlineP->restart_value, - &cmdlineP->restart_unit); - if (cmdlineP->density_spec) - interpret_density(density, &cmdlineP->density); + interpretMaxmemory(maxmemory, &cmdlineP->maxMemoryToUse); + interpretRestart(restart, &cmdlineP->restartValue, + &cmdlineP->restartUnit); + if (cmdlineP->densitySpec) + interpretDensity(density, &cmdlineP->density); - if (cmdlineP->smoothing_factor > 100) + if (cmdlineP->smooth > 100) pm_error("Smoothing factor %d is greater than 100 (%%).", - cmdlineP->smoothing_factor); + cmdlineP->smooth); - if (streq(cmdlineP->input_filespec, "=") && - cmdlineP->exif_filespec && - streq(cmdlineP->exif_filespec, "-")) + if (streq(cmdlineP->inputFileNm, "=") && + cmdlineP->exif && streq(cmdlineP->exif, "-")) pm_error("Cannot have both input image and exif header be from " "Standard Input."); - free(argv_parse); + free(argvParse); } static void -report_compressor(const struct jpeg_compress_struct cinfo) { +reportCompressor(const struct jpeg_compress_struct cinfo) { if (cinfo.scan_info == NULL) pm_message("No scan script is being used"); else { - int i; + unsigned int i; pm_message("A scan script with %d entries is being used:", cinfo.num_scans); - for (i = 0; i < cinfo.num_scans; i++) { - int j; + for (i = 0; i < cinfo.num_scans; ++i) { + unsigned int j; pm_message(" Scan %2d: Ss=%2d Se=%2d Ah=%2d Al=%2d " "%d components", i, @@ -354,7 +359,7 @@ report_compressor(const struct jpeg_compress_struct cinfo) { cinfo.scan_info[i].Al, cinfo.scan_info[i].comps_in_scan ); - for (j = 0; j < cinfo.scan_info[i].comps_in_scan; j++) + for (j = 0; j < cinfo.scan_info[i].comps_in_scan; ++j) pm_message(" Color component %d index: %d", j, cinfo.scan_info[i].component_index[j]); } @@ -364,14 +369,14 @@ report_compressor(const struct jpeg_compress_struct cinfo) { static void -setup_jpeg_source_parameters(struct jpeg_compress_struct * const cinfoP, - int const width, int const height, - int const format) { +setupJpegSourceParameters(struct jpeg_compress_struct * const cinfoP, + unsigned int const width, + unsigned int const height, + int const format) { /*---------------------------------------------------------------------------- Set up in the compressor descriptor *cinfoP the description of the source image as required by the compressor. -----------------------------------------------------------------------------*/ - switch PNM_FORMAT_TYPE(format) { case PBM_TYPE: case PGM_TYPE: @@ -391,8 +396,8 @@ setup_jpeg_source_parameters(struct jpeg_compress_struct * const cinfoP, static void -setup_jpeg_density(struct jpeg_compress_struct * const cinfoP, - struct density const density) { +setupJpegDensity(struct jpeg_compress_struct * const cinfoP, + struct Density const density) { /*---------------------------------------------------------------------------- Set up in the compressor descriptor *cinfoP the density information 'density'. @@ -421,22 +426,25 @@ setup_jpeg_density(struct jpeg_compress_struct * const cinfoP, -----------------------------------------------------------------------------*/ static int -text_getc (FILE * file) -/* Read next char, skipping over any comments (# to end of line) */ -/* A comment/newline sequence is returned as a newline */ -{ - register int ch; +textGetc (FILE * fileP) { +/*---------------------------------------------------------------------------- + Read next char, skipping over any comments (# to end of line). - ch = getc(file); + Return a comment/newline sequence as a newline. +-----------------------------------------------------------------------------*/ + int ch; + + ch = getc(fileP); if (ch == '#') { do { - ch = getc(file); + ch = getc(fileP); } while (ch != '\n' && ch != EOF); } return ch; } + static boolean readTextInteger(FILE * const fileP, long * const resultP, @@ -457,7 +465,7 @@ readTextInteger(FILE * const fileP, /* Skip any leading whitespace, detect EOF */ do { - ch = text_getc(fileP); + ch = textGetc(fileP); } while (isspace(ch)); if (!isdigit(ch)) @@ -465,7 +473,7 @@ readTextInteger(FILE * const fileP, else { long val; val = ch - '0'; /* initial value */ - while ((ch = text_getc(fileP)) != EOF) { + while ((ch = textGetc(fileP)) != EOF) { if (! isdigit(ch)) break; val *= 10; @@ -479,22 +487,28 @@ readTextInteger(FILE * const fileP, } -static boolean -read_scan_integer (FILE * file, long * result, int * termchar) -/* Variant of readTextInteger that always looks for a non-space termchar; - * this simplifies parsing of punctuation in scan scripts. - */ -{ - register int ch; - - if (! readTextInteger(file, result, termchar)) - return FALSE; - ch = *termchar; + +static bool +readScanInteger (FILE * const fileP, + long * const resultP, + int * const termcharP) { +/*---------------------------------------------------------------------------- + Variant of readTextInteger that always looks for a non-space termchar; + this simplifies parsing of punctuation in scan scripts. +-----------------------------------------------------------------------------*/ + int ch; + + if (! readTextInteger(fileP, resultP, termcharP)) + return false; + + ch = *termcharP; /* initial value */ + while (ch != EOF && isspace(ch)) - ch = text_getc(file); + ch = textGetc(fileP); + if (isdigit(ch)) { /* oops, put it back */ - if (ungetc(ch, file) == EOF) - return FALSE; + if (ungetc(ch, fileP) == EOF) + return false; ch = ' '; } else { /* Any separators other than ';' and ':' are ignored; @@ -503,15 +517,15 @@ read_scan_integer (FILE * file, long * result, int * termchar) if (ch != EOF && ch != ';' && ch != ':') ch = ' '; } - *termchar = ch; - return TRUE; + *termcharP = ch; + return true; } -static boolean -read_scan_script(j_compress_ptr const cinfo, - const char * const filename) { +static bool +readScanScript(j_compress_ptr const cinfo, + const char * const fileNm) { /*---------------------------------------------------------------------------- Read a scan script from the specified text file. Each entry in the file defines one scan to be emitted. @@ -536,46 +550,46 @@ read_scan_script(j_compress_ptr const cinfo, #define MAX_SCANS 100 /* quite arbitrary limit */ jpeg_scan_info scans[MAX_SCANS]; - fp = fopen(filename, "r"); + fp = fopen(fileNm, "r"); if (fp == NULL) { - pm_message("Can't open scan definition file '%s'", filename); - return FALSE; + pm_message("Can't open scan definition file '%s'", fileNm); + return false; } nscans = 0; - while (read_scan_integer(fp, &val, &termchar)) { + while (readScanInteger(fp, &val, &termchar)) { ++nscans; /* We got another scan */ if (nscans > MAX_SCANS) { - pm_message("Too many scans defined in file '%s'", filename); + pm_message("Too many scans defined in file '%s'", fileNm); fclose(fp); - return FALSE; + return false; } scans[nscans-1].component_index[0] = (int) val; ncomps = 1; while (termchar == ' ') { if (ncomps >= MAX_COMPS_IN_SCAN) { pm_message("Too many components in one scan in file '%s'", - filename); + fileNm); fclose(fp); return FALSE; } - if (! read_scan_integer(fp, &val, &termchar)) + if (! readScanInteger(fp, &val, &termchar)) goto bogus; scans[nscans-1].component_index[ncomps] = (int) val; ++ncomps; } scans[nscans-1].comps_in_scan = ncomps; if (termchar == ':') { - if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ') + if (! readScanInteger(fp, &val, &termchar) || termchar != ' ') goto bogus; scans[nscans-1].Ss = (int) val; - if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ') + if (! readScanInteger(fp, &val, &termchar) || termchar != ' ') goto bogus; scans[nscans-1].Se = (int) val; - if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ') + if (! readScanInteger(fp, &val, &termchar) || termchar != ' ') goto bogus; scans[nscans-1].Ah = (int) val; - if (! read_scan_integer(fp, &val, &termchar)) + if (! readScanInteger(fp, &val, &termchar)) goto bogus; scans[nscans-1].Al = (int) val; } else { @@ -587,16 +601,16 @@ read_scan_script(j_compress_ptr const cinfo, } if (termchar != ';' && termchar != EOF) { bogus: - pm_message("Invalid scan entry format in file '%s'", filename); + pm_message("Invalid scan entry format in file '%s'", fileNm); fclose(fp); - return FALSE; + return false; } } if (termchar != EOF) { - pm_message("Non-numeric data in file '%s'", filename); + pm_message("Non-numeric data in file '%s'", fileNm); fclose(fp); - return FALSE; + return false; } if (nscans > 0) { @@ -605,47 +619,49 @@ read_scan_script(j_compress_ptr const cinfo, data, but if you want to compress multiple images you'd want JPOOL_PERMANENT. */ - const unsigned int scan_info_size = nscans * sizeof(jpeg_scan_info); - jpeg_scan_info * const scan_info = + unsigned int const scanInfoSz = nscans * sizeof(jpeg_scan_info); + jpeg_scan_info * const scanInfo = (jpeg_scan_info *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - scan_info_size); - memcpy(scan_info, scans, scan_info_size); - cinfo->scan_info = scan_info; + scanInfoSz); + memcpy(scanInfo, scans, scanInfoSz); + cinfo->scan_info = scanInfo; cinfo->num_scans = nscans; } fclose(fp); - return TRUE; + return true; } -static boolean -read_quant_tables (j_compress_ptr cinfo, char * filename, - int scale_factor, boolean force_baseline) -/* Read a set of quantization tables from the specified file. - * The file is plain ASCII text: decimal numbers with whitespace between. - * Comments preceded by '#' may be included in the file. - * There may be one to NUM_QUANT_TBLS tables in the file, each of 64 values. - * The tables are implicitly numbered 0,1,etc. - * NOTE: does not affect the qslots mapping, which will default to selecting - * table 0 for luminance (or primary) components, 1 for chrominance components. - * You must use -qslots if you want a different component->table mapping. - */ -{ +static bool +readQuantTables(j_compress_ptr const cinfo, + const char * const fileNm, + int const scaleFactor, + bool const forceBaseline) { +/*---------------------------------------------------------------------------- + Read a set of quantization tables from the specified file. + The file is plain ASCII text: decimal numbers with whitespace between. + Comments preceded by '#' may be included in the file. + There may be one to NUM_QUANT_TBLS tables in the file, each of 64 values. + The tables are implicitly numbered 0,1,etc. + NOTE: does not affect the qslots mapping, which will default to selecting + table 0 for luminance (or primary) components, 1 for chrominance components. + You must use -qslots if you want a different component->table mapping. +-----------------------------------------------------------------------------*/ FILE * fp; - boolean retval; + bool retval; - fp = fopen(filename, "rb"); + fp = fopen(fileNm, "rb"); if (fp == NULL) { - pm_message("Can't open table file '%s'", filename); - retval = FALSE; + pm_message("Can't open table file '%s'", fileNm); + retval = false; } else { boolean eof, error; unsigned int tblno; - for (tblno = 0, eof = FALSE, error = FALSE; !eof && !error; ++tblno) { + for (tblno = 0, eof = false, error = false; !eof && !error; ++tblno) { long val; int termchar; boolean gotOne; @@ -654,8 +670,8 @@ read_quant_tables (j_compress_ptr cinfo, char * filename, if (gotOne) { /* read 1st element of table */ if (tblno >= NUM_QUANT_TBLS) { - pm_message("Too many tables in file '%s'", filename); - error = TRUE; + pm_message("Too many tables in file '%s'", fileNm); + error = true; } else { unsigned int table[DCTSIZE2]; unsigned int i; @@ -664,20 +680,20 @@ read_quant_tables (j_compress_ptr cinfo, char * filename, for (i = 1; i < DCTSIZE2 && !error; ++i) { if (! readTextInteger(fp, &val, &termchar)) { pm_message("Invalid table data in file '%s'", - filename); - error = TRUE; + fileNm); + error = true; } else table[i] = (unsigned int) val; } if (!error) jpeg_add_quant_table( - cinfo, tblno, table, scale_factor, force_baseline); + cinfo, tblno, table, scaleFactor, forceBaseline); } } else { if (termchar == EOF) eof = TRUE; else { - pm_message("Non-numeric data in file '%s'", filename); + pm_message("Non-numeric data in file '%s'", fileNm); error = TRUE; } } @@ -692,75 +708,87 @@ read_quant_tables (j_compress_ptr cinfo, char * filename, -static boolean -set_quant_slots (j_compress_ptr cinfo, char *arg) -/* Process a quantization-table-selectors parameter string, of the form - * N[,N,...] - * If there are more components than parameters, the last value is replicated. - */ -{ - int val = 0; /* default table # */ +static bool +setQuantSlots(j_compress_ptr const cinfo, + const char * const arg) { +/*---------------------------------------------------------------------------- + Process a quantization-table-selectors parameter string, of the form + N[,N,...] + + If there are more components than parameters, the last value is replicated. +-----------------------------------------------------------------------------*/ + int val; int ci; char ch; + unsigned int i; - for (ci = 0; ci < MAX_COMPONENTS; ci++) { - if (*arg) { + val = 0; /* initial value - default table */ + + for (ci = 0, i = 0; ci < MAX_COMPONENTS; ++ci) { + if (arg[i]) { ch = ','; /* if not set by sscanf, will be ',' */ - if (sscanf(arg, "%d%c", &val, &ch) < 1) - return FALSE; + if (sscanf(&arg[i], "%d%c", &val, &ch) < 1) + return false; if (ch != ',') /* syntax check */ - return FALSE; + return false; if (val < 0 || val >= NUM_QUANT_TBLS) { pm_message("Invalid quantization table number: %d. " "JPEG quantization tables are numbered 0..%d", val, NUM_QUANT_TBLS - 1); - return FALSE; + return false; } cinfo->comp_info[ci].quant_tbl_no = val; - while (*arg && *arg++ != ',') + while (arg[i] && arg[i] != ',') { + ++i; /* advance to next segment of arg string */ - ; + } } else { /* reached end of parameter, set remaining components to last tbl*/ cinfo->comp_info[ci].quant_tbl_no = val; } } - return TRUE; + return true; } -static boolean -set_sample_factors (j_compress_ptr cinfo, char *arg) -/* Process a sample-factors parameter string, of the form - * HxV[,HxV,...] - * If there are more components than parameters, "1x1" is assumed for the rest. - */ -{ - int ci, val1, val2; +static bool +setSampleFactors (j_compress_ptr const cinfo, + const char * const arg) { +/*---------------------------------------------------------------------------- + Process a sample-factors parameter string, of the form + HxV[,HxV,...] + + If there are more components than parameters, "1x1" is assumed for the rest. +-----------------------------------------------------------------------------*/ + int val1, val2; char ch1, ch2; + unsigned int i; + unsigned int ci; - for (ci = 0; ci < MAX_COMPONENTS; ci++) { - if (*arg) { + for (ci = 0, i = 0; ci < MAX_COMPONENTS; ++ci) { + if (arg[i]) { ch2 = ','; /* if not set by sscanf, will be ',' */ - if (sscanf(arg, "%d%c%d%c", &val1, &ch1, &val2, &ch2) < 3) - return FALSE; + if (sscanf(&arg[i], "%d%c%d%c", &val1, &ch1, &val2, &ch2) < 3) + return false; if ((ch1 != 'x' && ch1 != 'X') || ch2 != ',') /* syntax check */ - return FALSE; + return false; if (val1 <= 0 || val1 > 4) { pm_message("Invalid sampling factor: %d. " "JPEG sampling factors must be 1..4", val1); - return FALSE; + return false; } if (val2 <= 0 || val2 > 4) { pm_message("Invalid sampling factor: %d. " "JPEG sampling factors must be 1..4", val2); - return FALSE; + return false; } cinfo->comp_info[ci].h_samp_factor = val1; cinfo->comp_info[ci].v_samp_factor = val2; - while (*arg && *arg++ != ',') + + while (arg[i] && arg[i] != ',') { /* advance to next segment of arg string */ - ; + ++i; + } } else { /* reached end of parameter, set remaining components to 1x1 sampling */ @@ -768,42 +796,42 @@ set_sample_factors (j_compress_ptr cinfo, char *arg) cinfo->comp_info[ci].v_samp_factor = 1; } } - return TRUE; + return true; } static void -setup_jpeg(struct jpeg_compress_struct * const cinfoP, - struct jpeg_error_mgr * const jerrP, - struct cmdlineInfo const cmdline, - int const width, - int const height, - pixval const maxval, - int const input_fmt, - FILE * const output_file) { +setupJpeg(struct jpeg_compress_struct * const cinfoP, + struct jpeg_error_mgr * const jerrP, + struct CmdlineInfo const cmdline, + unsigned int const width, + unsigned int const height, + pixval const maxval, + int const inputFmt, + FILE * const ofP) { int quality; - int q_scale_factor; + int qScaleFactor; /* Initialize the JPEG compression object with default error handling. */ cinfoP->err = jpeg_std_error(jerrP); jpeg_create_compress(cinfoP); - setup_jpeg_source_parameters(cinfoP, width, height, input_fmt); + setupJpegSourceParameters(cinfoP, width, height, inputFmt); jpeg_set_defaults(cinfoP); cinfoP->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */ - cinfoP->image_width = (unsigned int) width; - cinfoP->image_height = (unsigned int) height; + cinfoP->image_width = width; + cinfoP->image_height = height; - cinfoP->arith_code = cmdline.arith_code; - cinfoP->dct_method = cmdline.dct_method; - if (cmdline.trace_level == 0 && cmdline.verbose) + cinfoP->arith_code = cmdline.arithmetic; + cinfoP->dct_method = cmdline.dctMethod; + if (cmdline.tracelevel == 0 && cmdline.verbose) cinfoP->err->trace_level = 1; - else cinfoP->err->trace_level = cmdline.trace_level; + else cinfoP->err->trace_level = cmdline.tracelevel; if (cmdline.grayscale) jpeg_set_colorspace(cinfoP, JCS_GRAYSCALE); else if (cmdline.rgb) @@ -812,38 +840,38 @@ setup_jpeg(struct jpeg_compress_struct * const cinfoP, else /* This default will be based on the in_color_space set above */ jpeg_default_colorspace(cinfoP); - if (cmdline.max_memory_to_use != -1) - cinfoP->mem->max_memory_to_use = cmdline.max_memory_to_use; + if (cmdline.maxMemoryToUse != -1) + cinfoP->mem->max_memory_to_use = cmdline.maxMemoryToUse; cinfoP->optimize_coding = cmdline.optimize; if (cmdline.quality == -1) { quality = 75; - q_scale_factor = 100; + qScaleFactor = 100; } else { quality = cmdline.quality; - q_scale_factor = jpeg_quality_scaling(cmdline.quality); + qScaleFactor = jpeg_quality_scaling(cmdline.quality); } - if (cmdline.smoothing_factor != -1) - cinfoP->smoothing_factor = cmdline.smoothing_factor; + if (cmdline.smooth != -1) + cinfoP->smoothing_factor = cmdline.smooth; /* Set quantization tables for selected quality. */ /* Some or all may be overridden if user specified --qtables. */ - jpeg_set_quality(cinfoP, quality, cmdline.force_baseline); + jpeg_set_quality(cinfoP, quality, cmdline.baseline); if (cmdline.qtablefile != NULL) { - if (! read_quant_tables(cinfoP, cmdline.qtablefile, - q_scale_factor, cmdline.force_baseline)) + if (! readQuantTables(cinfoP, cmdline.qtablefile, + qScaleFactor, cmdline.baseline)) pm_error("Can't use quantization table file '%s'.", cmdline.qtablefile); } if (cmdline.qslots != NULL) { - if (! set_quant_slots(cinfoP, cmdline.qslots)) + if (! setQuantSlots(cinfoP, cmdline.qslots)) pm_error("Bad quantization-table-selectors parameter string '%s'.", cmdline.qslots); } if (cmdline.sample != NULL) { - if (! set_sample_factors(cinfoP, cmdline.sample)) + if (! setSampleFactors(cinfoP, cmdline.sample)) pm_error("Bad sample-factors parameters string '%s'.", cmdline.sample); } @@ -851,19 +879,20 @@ setup_jpeg(struct jpeg_compress_struct * const cinfoP, if (cmdline.progressive) jpeg_simple_progression(cinfoP); - if (cmdline.density_spec) - setup_jpeg_density(cinfoP, cmdline.density); + if (cmdline.densitySpec) + setupJpegDensity(cinfoP, cmdline.density); if (cmdline.scans != NULL) { - if (! read_scan_script(cinfoP, cmdline.scans)) { + if (! readScanScript(cinfoP, cmdline.scans)) { pm_message("Error in scan script '%s'.", cmdline.scans); } } /* Specify data destination for compression */ - jpeg_stdio_dest(cinfoP, output_file); + jpeg_stdio_dest(cinfoP, ofP); - if (cmdline.verbose) report_compressor(*cinfoP); + if (cmdline.verbose) + reportCompressor(*cinfoP); /* Start compressor */ jpeg_start_compress(cinfoP, TRUE); @@ -873,115 +902,120 @@ setup_jpeg(struct jpeg_compress_struct * const cinfoP, static void -write_exif_header(struct jpeg_compress_struct * const cinfoP, - const char * const exif_filespec) { +writeExifHeader(struct jpeg_compress_struct * const cinfoP, + const char * const exifFileNm) { /*---------------------------------------------------------------------------- Generate an APP1 marker in the JFIF output that is an Exif header. The contents of the Exif header are in the file with filespec - 'exif_filespec' (file spec and contents are not validated). + 'exifFileNm' (file spec and contents are not validated). - exif_filespec = "-" means Standard Input. + exifFileNm = "-" means Standard Input. If the file contains just two bytes of zero, don't write any marker but don't recognize any error either. -----------------------------------------------------------------------------*/ - FILE * exif_file; + FILE * exifFp; unsigned short length; - exif_file = pm_openr(exif_filespec); + exifFp = pm_openr(exifFileNm); - pm_readbigshort(exif_file, (short*)&length); + pm_readbigshort(exifFp, (short*)&length); if (length == 0) { /* Special value meaning "no header" */ } else if (length < 3) pm_error("Invalid length %u at start of exif file", length); else { - unsigned char * exif_data; - size_t rc; - size_t const data_length = length - 2; + unsigned char * exifData; + size_t const dataLength = length - 2; /* Subtract 2 byte length field*/ + size_t rc; - assert(data_length > 0); + assert(dataLength > 0); - exif_data = malloc(data_length); - if (exif_data == NULL) + MALLOCARRAY(exifData, dataLength); + if (!exifData) pm_error("Unable to allocate %u bytes for exif header buffer", - (unsigned)data_length); + (unsigned)dataLength); - rc = fread(exif_data, 1, data_length, exif_file); + rc = fread(exifData, 1, dataLength, exifFp); - if (rc != data_length) + if (rc != dataLength) pm_error("Premature end of file on exif header file. Should be " "%u bytes of data, read only %u", - (unsigned)data_length, (unsigned)rc); + (unsigned)dataLength, (unsigned)rc); jpeg_write_marker(cinfoP, JPEG_APP0+1, - (const JOCTET *) exif_data, data_length); + (const JOCTET *) exifData, dataLength); - free(exif_data); + free(exifData); } - pm_close(exif_file); + pm_close(exifFp); } static void -compute_rescaling_array(JSAMPLE ** const rescale_p, const pixval maxval, - const struct jpeg_compress_struct cinfo) { +computeRescalingArray(JSAMPLE ** const rescaleP, + pixval const maxval, + struct jpeg_compress_struct const cinfo) { /*---------------------------------------------------------------------------- Compute the rescaling array for a maximum pixval of 'maxval'. Allocate the memory for it too. -----------------------------------------------------------------------------*/ - const long half_maxval = maxval / 2; - long val; - - *rescale_p = (JSAMPLE *) - (cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_IMAGE, - (size_t) (((long) maxval + 1L) * - sizeof(JSAMPLE))); - for (val = 0; val <= maxval; val++) { - /* The multiplication here must be done in 32 bits to avoid overflow */ - (*rescale_p)[val] = (JSAMPLE) ((val*MAXJSAMPLE + half_maxval)/maxval); - } + long const halfMaxval = maxval / 2; + + JSAMPLE * rescale; + long val; + + rescale = (JSAMPLE *) + (cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_IMAGE, + (size_t) (((long) maxval + 1L) * + sizeof(JSAMPLE))); + for (val = 0; val <= maxval; val++) { + /* The multiplication here must be done in 32 bits to avoid overflow */ + rescale[val] = (JSAMPLE) ((val*MAXJSAMPLE + halfMaxval)/maxval); + } + + *rescaleP = rescale; } static void -translate_row(const pixel pnm_buffer[], - JSAMPLE jpeg_buffer[], - int const width, - int const input_components, - const JSAMPLE translate[]) { +translateRow(pixel const pnm_buffer[], + unsigned int const width, + unsigned int const inputComponentCt, + JSAMPLE const translate[], + JSAMPLE * const jpegBuffer) { /*---------------------------------------------------------------------------- Convert the input row, in pnm format, to an output row in JPEG compressor input format. This is a byte for byte copy, translated through the array 'translate'. -----------------------------------------------------------------------------*/ - unsigned int column; + unsigned int col; /* I'm not sure why the JPEG library data structures don't have some kind of pixel data structure (such that a row buffer is an array of pixels, rather than an array of samples). But because of this, we have to index jpeg_buffer the old fashioned way. */ - switch (input_components) { + switch (inputComponentCt) { case 1: - for (column = 0; column < width; column++) - jpeg_buffer[column] = translate[(int)PNM_GET1(pnm_buffer[column])]; + for (col = 0; col < width; ++col) + jpegBuffer[col] = translate[(int)PNM_GET1(pnm_buffer[col])]; break; case 3: - for (column = 0; column < width; column++) { - jpeg_buffer[column*3+0] = - translate[(int)PPM_GETR(pnm_buffer[column])]; - jpeg_buffer[column*3+1] = - translate[(int)PPM_GETG(pnm_buffer[column])]; - jpeg_buffer[column*3+2] = - translate[(int)PPM_GETB(pnm_buffer[column])]; + for (col = 0; col < width; ++col) { + jpegBuffer[col * 3 + 0] = + translate[(int)PPM_GETR(pnm_buffer[col])]; + jpegBuffer[col * 3 + 1] = + translate[(int)PPM_GETG(pnm_buffer[col])]; + jpegBuffer[col * 3 + 2] = + translate[(int)PPM_GETB(pnm_buffer[col])]; } break; default: @@ -994,72 +1028,72 @@ translate_row(const pixel pnm_buffer[], static void -convert_scanlines(struct jpeg_compress_struct * const cinfo_p, - FILE * const input_file, - pixval const maxval, - int const input_fmt, - JSAMPLE xlate_table[]){ +convertScanLines(struct jpeg_compress_struct * const cinfoP, + FILE * const inputFileNm, + pixval const maxval, + int const inputFmt, + const JSAMPLE * const xlateTable){ /*---------------------------------------------------------------------------- - Read scan lines from the input file, which is already opened in the - netpbm library sense and ready for reading, and write them to the - output JPEG object. Translate the pnm sample values to JPEG sample - values through the thable xlate_table[]. + Read scan lines from the input file, which is already opened in the + netpbm library sense and ready for reading, and write them to the + output JPEG object. Translate the pnm sample values to JPEG sample + values through the table xlateTable[]. -----------------------------------------------------------------------------*/ - xel * pnm_buffer; - /* contains the row of the input image currently being processed, - in pnm_readpnmrow format - */ - JSAMPARRAY buffer; - /* Row 0 of this array contains the row of the output image currently - being processed, in JPEG compressor input format. The array only - has that one row. - */ + xel * pnmBuffer; + /* contains the row of the input image currently being processed, + in pnm_readpnmrow format + */ + JSAMPARRAY buffer; + /* Row 0 of this array contains the row of the output image currently + being processed, in JPEG compressor input format. The array has + only that one row. + */ - /* Allocate the libpnm output and compressor input buffers */ - buffer = (*cinfo_p->mem->alloc_sarray) - ((j_common_ptr) cinfo_p, JPOOL_IMAGE, - (unsigned int) cinfo_p->image_width * cinfo_p->input_components, - (unsigned int) 1); - - pnm_buffer = pnm_allocrow(cinfo_p->image_width); - - while (cinfo_p->next_scanline < cinfo_p->image_height) { - if (cinfo_p->err->trace_level > 1) - pm_message("Converting Row %d...", cinfo_p->next_scanline); - pnm_readpnmrow(input_file, pnm_buffer, cinfo_p->image_width, - maxval, input_fmt); - translate_row(pnm_buffer, buffer[0], - cinfo_p->image_width, cinfo_p->input_components, - xlate_table); - jpeg_write_scanlines(cinfo_p, buffer, 1); - if (cinfo_p->err->trace_level > 1) - pm_message("Done."); - } + /* Allocate the libpnm output and compressor input buffers */ + buffer = (*cinfoP->mem->alloc_sarray) + ((j_common_ptr) cinfoP, JPOOL_IMAGE, + (unsigned int) cinfoP->image_width * cinfoP->input_components, + (unsigned int) 1); + + pnmBuffer = pnm_allocrow(cinfoP->image_width); + + while (cinfoP->next_scanline < cinfoP->image_height) { + if (cinfoP->err->trace_level > 1) + pm_message("Converting Row %d...", cinfoP->next_scanline); + pnm_readpnmrow(inputFileNm, pnmBuffer, cinfoP->image_width, + maxval, inputFmt); + translateRow(pnmBuffer, + cinfoP->image_width, cinfoP->input_components, + xlateTable, buffer[0]); + jpeg_write_scanlines(cinfoP, buffer, 1); + if (cinfoP->err->trace_level > 1) + pm_message("Done."); + } - pnm_freerow(pnm_buffer); - /* Don't worry about the compressor input buffer; it gets freed - automatically - */ + pnm_freerow(pnmBuffer); + /* Don't worry about the compressor input buffer; it gets freed + automatically + */ } int -main(int argc, - char ** argv) { +main(int argc, + const char ** argv) { - struct cmdlineInfo cmdline; + struct CmdlineInfo cmdline; struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; - FILE * input_file; - FILE * output_file; + FILE * ifP; + FILE * ofP; int height; /* height of the input image in rows, as specified by its header */ int width; /* width of the input image in columns, as specified by its header */ pixval maxval; /* maximum value of an input pixel component, as specified by header */ - int input_fmt; + int inputFmt; /* The input format, as determined by its header. */ JSAMPLE *rescale; /* => maxval-remapping array, or NULL */ /* This is an array that maps each possible pixval in the input to @@ -1067,48 +1101,47 @@ main(int argc, 0 .. maxval, the range of the output values is 0 .. MAXJSAMPLE. */ - pnm_init(&argc, argv); + pm_proginit(&argc, argv); parseCommandLine(argc, argv, &cmdline); - input_file = pm_openr(cmdline.input_filespec); - free(cmdline.input_filespec); + ifP = pm_openr(cmdline.inputFileNm); - output_file = stdout; + ofP = stdout; /* Open the pnm input */ - pnm_readpnminit(input_file, &width, &height, &maxval, &input_fmt); + pnm_readpnminit(ifP, &width, &height, &maxval, &inputFmt); if (cmdline.verbose) { pm_message("Input file has format %c%c.\n" "It has %d rows of %d columns of pixels " "with max sample value of %d.", - (char) (input_fmt/256), (char) (input_fmt % 256), + (char) (inputFmt/256), (char) (inputFmt % 256), height, width, maxval); } - setup_jpeg(&cinfo, &jerr, cmdline, width, height, maxval, input_fmt, - output_file); + setupJpeg(&cinfo, &jerr, cmdline, width, height, maxval, inputFmt, ofP); - compute_rescaling_array(&rescale, maxval, cinfo); + computeRescalingArray(&rescale, maxval, cinfo); if (cmdline.comment) jpeg_write_marker(&cinfo, JPEG_COM, (const JOCTET *) cmdline.comment, strlen(cmdline.comment)); - if (cmdline.exif_filespec) - write_exif_header(&cinfo, cmdline.exif_filespec); + if (cmdline.exif) + writeExifHeader(&cinfo, cmdline.exif); /* Translate and copy over the actual scanlines */ - convert_scanlines(&cinfo, input_file, maxval, input_fmt, rescale); + convertScanLines(&cinfo, ifP, maxval, inputFmt, rescale); /* Finish compression and release memory */ jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); /* Close files, if we opened them */ - if (input_file != stdin) - pm_close(input_file); + if (ifP != stdin) + pm_close(ifP); + free(cmdline.inputFileNm); /* Program may have exited with non-zero completion code via various function calls above. */ -- cgit 1.4.1