From c49e2bfb92ebe11c4b04342dc0aa81898b53e8fc Mon Sep 17 00:00:00 2001 From: giraffedata Date: Sun, 6 Mar 2022 21:45:37 +0000 Subject: cleanup git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@4293 9d0c8265-081b-0410-96cb-a4ca84ce46f8 --- converter/other/pnmtorle.c | 280 +++++++++++++++++++++++++++++++-------------- 1 file changed, 191 insertions(+), 89 deletions(-) (limited to 'converter/other') diff --git a/converter/other/pnmtorle.c b/converter/other/pnmtorle.c index c3751752..17c9cfbc 100644 --- a/converter/other/pnmtorle.c +++ b/converter/other/pnmtorle.c @@ -33,71 +33,157 @@ * 2000.04.13 adapted for Netpbm by Bryan Henderson. Quieted compiler * warnings. * + * 2022.03.06 revision by Akira F Urushibata + * use shhopt instead of scanargs + * proper handling of multiple image files with -h + * */ /*----------------------------------------------------- * System includes. */ #include #include +#include #include "pnm.h" #include "mallocvar.h" #include "rle.h" +#include "shhopt.h" +#include "pm_c_util.h" + + +struct CmdlineInfo { + /* All the information the user supplied in the command line, + in a form easy for the program to use. + */ + const char * inFileName; + const char * outfile; + unsigned int verbose; + unsigned int header; + unsigned int alpha; +}; + -#define VPRINTF if (verbose || header) fprintf -typedef unsigned char U_CHAR; -/* - * Global variables. - */ -static FILE *fp; -static rle_hdr hdr; -static int format; -static int width, height; -static int verbose = 0, header = 0, do_alpha = 0; -static gray maxval; -/*----------------------------------------------------------------------------- - * Read the pnm image file header. - */ static void -read_pnm_header(void) { +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 pm_optParseOptions3 on how to parse our options. */ + + optStruct3 opt; + + unsigned int option_def_index; + unsigned int outfileSpec; + + MALLOCARRAY_NOFAIL(option_def, 100); + + option_def_index = 0; /* incremented by OPTENTRY */ + OPTENT3(0, "alpha", OPT_FLAG, NULL, &cmdlineP->alpha, 0); + OPTENT3(0, "header", OPT_FLAG, NULL, &cmdlineP->header, 0); + OPTENT3(0, "verbose", OPT_FLAG, NULL, &cmdlineP->verbose, 0); + OPTENT3(0, "outfile", OPT_STRING, &cmdlineP->outfile, + &outfileSpec, 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. */ + + free(option_def); + + if (argc-1 == 0) + cmdlineP->inFileName = "-"; + else if (argc-1 != 1) { + pm_error("Program takes zero or one argument (filename). You " + "specified %d", argc-1); + } + else + cmdlineP->inFileName = argv[1]; + + if (!outfileSpec) + cmdlineP->outfile = "-"; +} + + + +static void +readPnmHeader(bool const verbose, + bool const wantAlpha, + FILE * const ifP, + int * const widthP, + int * const heightP, + gray * const maxvalP, + int * const formatP) { +/*----------------------------------------------------------------------------- + Read the pnm image file header. +---------------------------------------------------------------------------- */ + int width; + int height; + gray maxval; + int format; + const char * type; + + pnm_readpnminit(ifP, &width, &height, &maxval, &format); - pnm_readpnminit(fp, &width, &height, &maxval, &format); switch (format) { case PBM_FORMAT: - VPRINTF(stderr, "Image type: plain pbm format\n"); + type="plain pbm"; break; case RPBM_FORMAT: - VPRINTF(stderr, "Image type: raw pbm format\n"); + type="raw pbm"; break; case PGM_FORMAT: - VPRINTF(stderr, "Image type: plain pgm format\n"); + type="plain pgm"; break; case RPGM_FORMAT: - VPRINTF(stderr, "Image type: raw pgm format\n"); + type="raw pgm"; break; case PPM_FORMAT: - VPRINTF(stderr, "Image type: plain ppm format\n"); + type="plain ppm"; break; case RPPM_FORMAT: - VPRINTF(stderr, "Image type: raw ppm format\n"); + type="raw ppm"; break; } - VPRINTF(stderr, "Full image: %dx%d\n", width, height); - VPRINTF(stderr, "Maxval: %d\n", maxval); - if (do_alpha) - VPRINTF(stderr, "Computing alpha channel...\n"); + if (verbose) { + pm_message("Image type: %s format", type); + pm_message("Full image: %dx%d", width, height); + pm_message("Maxval: %d", maxval); + + if (wantAlpha) + pm_message("Computing alpha channel..."); + } + *widthP = width; + *heightP = height; + *maxvalP = maxval; + *formatP = format; } static void -write_rle_header(void) { +writeRleHeader(bool const wantAlpha, + int const format, + unsigned int const width, + unsigned int const height, + rle_hdr * const hdrP) { + + rle_hdr hdr; + + hdr = *hdrP; /* initial value */ hdr.xmin = 0; hdr.xmax = width-1; hdr.ymin = 0; hdr.ymax = height-1; hdr.background = 0; + switch (format) { case PBM_FORMAT: case RPBM_FORMAT: @@ -114,31 +200,42 @@ write_rle_header(void) { RLE_SET_BIT(hdr, RLE_BLUE); break; } - if (do_alpha) { + if (wantAlpha) { hdr.alpha = 1; RLE_SET_BIT(hdr, RLE_ALPHA); } rle_put_setup(&hdr); + + *hdrP = hdr; } static void -write_rle_data(void) { +writeRleData(bool const verbose, + bool const wantAlpha, + FILE * const ifP, + rle_hdr * const hdrP, + unsigned int const width, + unsigned int const height, + gray const maxval, + int const format) { unsigned int scan; xel * xelrow; rle_pixel *** scanlines; MALLOCARRAY(xelrow, width); - MALLOCARRAY(scanlines, height); + if (xelrow == NULL) + pm_error("Failed to allocate memory for row of %u pixels", width); - if (!scanlines) + MALLOCARRAY(scanlines, height); + if (scanlines == NULL) pm_error("Failed to allocate memory for %u scanline pointers", height); for (scan = 0; scan < height; ++scan) { int rc; - rc = rle_row_alloc(&hdr, &scanlines[scan]); + rc = rle_row_alloc(hdrP, &scanlines[scan]); if (rc < 0) pm_error("Failed to allocate memory for a scanline"); } @@ -151,10 +248,10 @@ write_rle_data(void) { for (scan = 0; scan < height; ++scan) { rle_pixel ** const scanline = scanlines[height - scan - 1]; unsigned int col; - pnm_readpnmrow(fp, xelrow, width, maxval, format); + pnm_readpnmrow(ifP, xelrow, width, maxval, format); for (col = 0; col < width; ++col) { scanline[RLE_RED][col] = PNM_GET1(xelrow[col]) ? 255 : 0; - if (do_alpha) + if (wantAlpha) scanline[RLE_ALPHA][col] = scanline[RLE_RED][col]; } } @@ -165,10 +262,10 @@ write_rle_data(void) { for (scan = 0; scan < height; ++scan) { rle_pixel ** const scanline = scanlines[height - scan - 1]; unsigned int col; - pnm_readpnmrow(fp, xelrow, width, maxval, format); + pnm_readpnmrow(ifP, xelrow, width, maxval, format); for (col = 0; col < width; ++col) { scanline[RLE_RED][col] = PNM_GET1(xelrow[col]); - if (do_alpha) + if (wantAlpha) scanline[RLE_ALPHA][col] = scanline[RLE_RED][col] ? 255 : 0; } @@ -179,13 +276,16 @@ write_rle_data(void) { unsigned int scan; for (scan = 0; scan < height; scan++) { rle_pixel ** const scanline = scanlines[height - scan - 1]; + unsigned int col; - pnm_readpnmrow(fp, xelrow, width, maxval, format); + + pnm_readpnmrow(ifP, xelrow, width, maxval, format); + for (col = 0; col < width; ++col) { scanline[RLE_RED][col] = PPM_GETR(xelrow[col]); scanline[RLE_GREEN][col] = PPM_GETG(xelrow[col]); scanline[RLE_BLUE][col] = PPM_GETB(xelrow[col]); - if (do_alpha) + if (wantAlpha) scanline[RLE_ALPHA][col] = (scanline[RLE_RED][col] || scanline[RLE_GREEN][col] || @@ -196,25 +296,27 @@ write_rle_data(void) { } /* Write out data in URT order (bottom to top). */ for (scan = 0; scan < height; ++scan) - rle_putrow(scanlines[scan], width, &hdr); + rle_putrow(scanlines[scan], width, hdrP); for (scan = 0; scan < height; ++scan) - rle_row_free(&hdr, scanlines[scan]); + rle_row_free(hdrP, scanlines[scan]); free(scanlines); free(xelrow); - VPRINTF(stderr, "Done -- write eof to RLE data.\n"); - rle_puteof(&hdr); + if (verbose) + pm_message("Done -- write eof to RLE data."); + + rle_puteof(hdrP); } static void -skip_data(FILE * const fp, - int const width, - int const height, - gray const maxval, - int const format) { +skipData(FILE * const ifP, + unsigned int const width, + unsigned int const height, + gray const maxval, + int const format) { xel * xelrow; unsigned int scan; @@ -223,8 +325,8 @@ skip_data(FILE * const fp, if (xelrow == NULL) pm_error("Failed to allocate memory for row of %u pixels", width); - for(scan=0; scan < height; ++scan) - pnm_readpnmrow(fp, xelrow, width, maxval, format); + for (scan=0; scan < height; ++scan) + pnm_readpnmrow(ifP, xelrow, width, maxval, format); free(xelrow); } @@ -232,57 +334,57 @@ skip_data(FILE * const fp, int -main(int argc, char ** argv) { - - const char * pnmname; - const char * outname; - int oflag; - - pnm_init(&argc, argv); - - pnmname = NULL; /* initial value */ - outname = NULL; /* initial value */ - - /* Get those options. */ - if (!scanargs(argc,argv, - "% v%- h%- a%- o%-outfile!s pnmfile%s\n(\ -\tConvert a PNM file to URT RLE format.\n\ -\t-a\tFake an alpha channel. Alpha=0 when input=0, 255 otherwise.\n\ -\t-h\tPrint header of PNM file and exit.\n\ -\t-v\tVerbose mode.)", - &verbose, - &header, - &do_alpha, - &oflag, &outname, - &pnmname)) - exit(-1); +main(int argc, char ** argv) { + + struct CmdlineInfo cmdline; + + FILE * ifP; + rle_hdr hdr; + int format; + int width, height; + gray maxval; + bool verbose; + const char ** argvWork; + unsigned int i; + int eof; + + MALLOCARRAY_NOFAIL(argvWork, argc + 1); + + for (i = 0; i < argc; ++i) /* Make a copy of argv */ + argvWork[i] = argv[i]; + + pm_proginit(&argc, argvWork); + + parseCommandLine(argc, argvWork, &cmdline); + + verbose = cmdline.verbose || cmdline.header; hdr = *rle_hdr_init(NULL); - rle_names(&hdr, cmd_name(argv), outname, 0); + + rle_names(&hdr, "pnmtorle", cmdline.outfile, 0); /* Open the file. */ - if (pnmname == NULL) { - fp = pm_openr("-"); - } else { - fp = pm_openr(pnmname); - } + assert(cmdline.inFileName != NULL); + ifP = pm_openr(cmdline.inFileName); - hdr.rle_file = rle_open_f( hdr.cmd, outname, "wb" ); + hdr.rle_file = rle_open_f(hdr.cmd, cmdline.outfile, "wb"); - int eof; for (eof = 0; !eof; ) { - read_pnm_header(); + readPnmHeader(verbose, cmdline.alpha, ifP, + &width, &height, &maxval, &format); - if (header) - skip_data(fp, width, height, maxval, format); - else { + if (cmdline.header) { + skipData(ifP, width, height, maxval, format); + } else { rle_addhist(argv, NULL, &hdr); - write_rle_header(); - write_rle_data(); + writeRleHeader(cmdline.alpha, format, width, height, &hdr); + writeRleData(verbose, cmdline.alpha, ifP, &hdr, + width, height, maxval, format); } - pnm_nextimage(fp, &eof); + pnm_nextimage(ifP, &eof); } - pm_close(fp); + + pm_close(ifP); return 0; } -- cgit 1.4.1