/****************************************************************************** pnmsplit ******************************************************************************* Split a Netpbm format input file into multiple Netpbm format output files with one image per output file. By Bryan Henderson, Olympia WA; June 2000 Contributed to the public domain by its author. ******************************************************************************/ #define _BSD_SOURCE 2 /* This ensures that strdup() is in string.h */ #include #include #include "pnm.h" #include "shhopt.h" #include "nstring.h" struct cmdline_info { /* All the information the user supplied in the command line, in a form easy for the program to use. */ const char *input_file; const char *output_file_pattern; int debug; } cmdline; static void parse_command_line(int argc, char ** argv, struct cmdline_info *cmdline_p) { /*---------------------------------------------------------------------------- Note that the pointers we place into *cmdline_p are sometimes to storage in the argv array. -----------------------------------------------------------------------------*/ optStruct *option_def = malloc(100*sizeof(optStruct)); /* Instructions to OptParseOptions2 on how to parse our options. */ optStruct2 opt; unsigned int option_def_index; option_def_index = 0; /* incremented by OPTENTRY */ OPTENTRY(0, "debug", OPT_FLAG, &cmdline_p->debug, 0); /* Set the defaults */ cmdline_p->debug = FALSE; 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 */ optParseOptions2(&argc, argv, opt, 0); /* Uses and sets argc, argv, and all of *cmdline_p. */ if (argc - 1 < 1) cmdline_p->input_file = "-"; else cmdline_p->input_file = argv[1]; if (argc -1 < 2) cmdline_p->output_file_pattern = "image%d"; else cmdline_p->output_file_pattern = argv[2]; if (!strstr(cmdline_p->output_file_pattern, "%d")) pm_error("output file spec pattern parameter must include the " "string '%%d',\n" "to stand for the image sequence number.\n" "You specified '%s'.", cmdline_p->output_file_pattern); } static void extract_one_image(FILE *infile, const char outputfilename[]) { FILE *outfile; xelval maxval; int rows, cols, format; enum pm_check_code check_retval; int row; xel *xelrow; pnm_readpnminit(infile, &cols, &rows, &maxval, &format); pnm_check(infile, PM_CHECK_BASIC, format, cols, rows, maxval, &check_retval); outfile = pm_openw(outputfilename); pnm_writepnminit(outfile, cols, rows, maxval, format, 0); xelrow = pnm_allocrow(cols); for (row = 0; row < rows; row++) { pnm_readpnmrow(infile, xelrow, cols, maxval, format); pnm_writepnmrow(outfile, xelrow, cols, maxval, format, 0); } pnm_freerow(xelrow); pm_close(outfile); } static void compute_output_name(char const output_file_pattern[], unsigned int const image_seq, const char ** const output_name_p) { /*---------------------------------------------------------------------------- Compute the name of an output file given the pattern output_file_pattern[] and the image sequence number 'image_seq'. output_file_pattern[] contains at least one instance of the string "%d" and we substitute the ASCII decimal representation of image_seq for it to generate the output file name. -----------------------------------------------------------------------------*/ char *before_sub, *after_sub; before_sub = strdup(output_file_pattern); *(strstr(before_sub, "%d")) = '\0'; after_sub = strstr(output_file_pattern, "%d") + 2; asprintfN(output_name_p, "%s%d%s", before_sub, image_seq, after_sub); free(before_sub); } int main(int argc, char *argv[]) { FILE* ifp; int eof; /* No more images in input */ unsigned int image_seq; /* Sequence of current image in input file. First = 0 */ pnm_init( &argc, argv ); parse_command_line(argc, argv, &cmdline); ifp = pm_openr(cmdline.input_file); eof = FALSE; for (image_seq = 0; !eof; image_seq++) { const char *output_file_name; /* malloc'ed */ compute_output_name(cmdline.output_file_pattern, image_seq, &output_file_name); pm_message("WRITING %s\n", output_file_name); extract_one_image(ifp, output_file_name); strfree(output_file_name); pnm_nextimage(ifp, &eof); } pm_close(ifp); exit( 0 ); }