diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2023-06-28 17:29:32 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2023-06-28 17:29:32 +0000 |
commit | 23ce26f64c34e30951ad9ade2151552ed77e7357 (patch) | |
tree | d73b31a0c2f7c7be4a69f8a8e84e00dd39c432b5 /converter/other/pnmtorle.c | |
parent | 1b6e51a266008348ad93ed8b6ac9ec91b5024fea (diff) | |
download | netpbm-mirror-23ce26f64c34e30951ad9ade2151552ed77e7357.tar.gz netpbm-mirror-23ce26f64c34e30951ad9ade2151552ed77e7357.tar.xz netpbm-mirror-23ce26f64c34e30951ad9ade2151552ed77e7357.zip |
promote Advanced to Stable
git-svn-id: http://svn.code.sf.net/p/netpbm/code/stable@4558 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'converter/other/pnmtorle.c')
-rw-r--r-- | converter/other/pnmtorle.c | 290 |
1 files changed, 197 insertions, 93 deletions
diff --git a/converter/other/pnmtorle.c b/converter/other/pnmtorle.c index 7c378246..17c9cfbc 100644 --- a/converter/other/pnmtorle.c +++ b/converter/other/pnmtorle.c @@ -1,7 +1,7 @@ /* * This is derived from the file of the same name dated June 5, 1995, * copied from the Army High Performance Computing Research Center's - * media-tools.tar.gz package, received from + * media-tools.tar.gz package, received from * http://www.arc.umn.edu/gvl-software/media-tools.tar.gz on 2000.04.13. * * This software is copyrighted as noted below. It may be freely copied, @@ -29,75 +29,161 @@ * Minnesota Supercomputer Center, Inc. * Date: March 30, 1994 * Copyright (c) Minnesota Supercomputer Center, Inc. - * - * 2000.04.13 adapted for Netpbm by Bryan Henderson. Quieted compiler + * + * 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 <string.h> #include <stdio.h> +#include <assert.h> #include "pnm.h" #include "mallocvar.h" #include "rle.h" +#include "shhopt.h" +#include "pm_c_util.h" -#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; +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; +}; + + + +static 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. - */ -static void -read_pnm_header(void) { + 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) { +static 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,44 @@ 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) { +static 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); - RLE_CHECK_ALLOC(hdr.cmd, scanlines, "scanline pointers"); + 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]); - RLE_CHECK_ALLOC(hdr.cmd, rc >= 0, "pixel memory"); + rc = rle_row_alloc(hdrP, &scanlines[scan]); + if (rc < 0) + pm_error("Failed to allocate memory for a scanline"); } /* Loop through the pnm files image window, read data and flip vertically. */ @@ -149,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]; } } @@ -163,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; } @@ -177,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] || @@ -194,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; @@ -221,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); } @@ -230,57 +334,57 @@ skip_data(FILE * const fp, int -main(int argc, char ** argv) { - - const char * pnmname; - const char * outname; - int oflag; +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; - 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); + 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"); 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; } |