w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

ppmtojpeg.c
Go to the documentation of this file.
1 /*****************************************************************************
2  ppmtojpeg
3 ******************************************************************************
4  This program is part of the Netpbm package.
5 
6  This program converts from the fundamental ppm format to the JFIF format
7  which is based on JPEG.
8 
9  This program is by Bryan Henderson on 2000.03.06, but is derived
10  with permission from the program cjpeg, which is in the Independent
11  Jpeg Group's JPEG library package. Under the terms of that permission,
12  redistribution of this software is restricted as described in the
13  file README.JPEG.
14 
15  Copyright (C) 1991-1998, Thomas G. Lane.
16 
17  TODO:
18  - Make it pnmtojpeg instead of ppmtojpeg. If input is PGM or PBM,
19  produce JCS_GRAYSCALE output directly.
20 
21 *****************************************************************************/
22 
23 #include <ctype.h> /* to declare isdigit(), etc. */
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <stdio.h>
28 #include <jpeglib.h>
29 #include "ppm.h"
30 #include "shhopt.h"
31 
32 #define EXIT_WARNING 2 /* Goes with EXIT_SUCCESS, EXIT_FAILURE in stdlib.h */
33 
34 static const char * progname; /* program name for error messages */
35 
37 
38 struct cmdline_info {
39  /* All the information the user supplied in the command line,
40  in a form easy for the program to use.
41  */
42  char *input_filename;
43  int verbose;
44  unsigned int quality;
49  int grayscale;
50  long int max_memory_to_use;
51  unsigned int trace_level;
52  char *qslots;
53  char *qtablefile;
54  char *sample;
55  char *scans;
57  int optimize;
58  unsigned int restart_value;
60  char *restart;
62 
63 static void
64 parse_command_line(const int argc, char ** argv,
65  struct cmdline_info *cmdline_p);
66 
67 static void
68 compute_rescaling_array(JSAMPLE ** const rescale_p, const pixval maxval,
69  const struct jpeg_compress_struct cinfo);
70 static void
72  const pixval maxval, const int input_fmt,
73  JSAMPLE xlate_table[]);
74 
75 static boolean read_quant_tables (j_compress_ptr cinfo, char * filename,
76  int scale_factor, boolean force_baseline);
77 
78 static boolean read_scan_script (j_compress_ptr cinfo, char * filename);
79 
80 static boolean set_quant_slots (j_compress_ptr cinfo, char *arg);
81 
82 static boolean set_sample_factors (j_compress_ptr cinfo, char *arg);
83 
84 
85 
86 int
87 main(int argc, char ** argv) {
88  struct jpeg_compress_struct cinfo;
89  struct jpeg_error_mgr jerr;
91  FILE * output_file;
92  int height;
93  /* height of the input image in rows, as specified by its header */
94  int width;
95  /* width of the input image in columns, as specified by its header */
96  pixval maxval;
97  /* maximum value of an input pixel component, as specified by header */
98  int input_fmt;
99  /* The input format, as determined by its header. */
100  JSAMPLE *rescale; /* => maxval-remapping array, or NULL */
101  /* This is an array that maps each possible pixval in the input to
102  a new value such that while the range of the input values is
103  0 .. maxval, the range of the output values is 0 .. MAXJSAMPLE.
104  */
105  int quality;
106  int q_scale_factor;
107 
108  ppm_init(&argc, argv);
109 
110  progname = argv[0];
111 
113 
114  /* Initialize the JPEG compression object with default error handling. */
115  cinfo.err = jpeg_std_error(&jerr);
116  jpeg_create_compress(&cinfo);
117 
118  /* Initialize JPEG parameters.
119  * Much of this may be overridden later.
120  * In particular, we don't yet know the input file's color space,
121  * but we need to provide some value for jpeg_set_defaults() to work.
122  */
123 
124  cinfo.in_color_space = JCS_RGB; /* arbitrary guess */
125  jpeg_set_defaults(&cinfo);
126 
127  /* Open the input file */
128  if (cmdline.input_filename == NULL)
129  input_file = stdin;
130  else {
131  if ((input_file = fopen(cmdline.input_filename, "rb")) == NULL)
132  pm_error("can't open %s. Errno=%s(%d).\n",
135  }
136 
138 
139  /* Open the ppm input */
140  ppm_readppminit(input_file, &width, &height, &maxval, &input_fmt);
141  if (cmdline.verbose) {
142  pm_message("Input file has format %c%c.\n"
143  "It has %d rows of %d columns of pixels "
144  "with max sample value of %d.",
145  (char) (input_fmt/256), (char) (input_fmt % 256),
146  height, width, maxval);
147  }
148 
149  cinfo.data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */
150  cinfo.image_width = (unsigned int) width;
151  cinfo.image_height = (unsigned int) height;
152 
153  /* For the pnm version, we need to change these based on PBM/PGM/PPM */
154  cinfo.in_color_space = JCS_RGB; /* format of input to compressor */
155  cinfo.input_components = 3;
156 
157  compute_rescaling_array(&rescale, maxval, cinfo);
158 
159  cinfo.arith_code = cmdline.arith_code;
160  cinfo.dct_method = cmdline.dct_method;
161  if (cmdline.trace_level == 0 && cmdline.verbose) cinfo.err->trace_level = 1;
162  else cinfo.err->trace_level = cmdline.trace_level;
163  if (cmdline.grayscale)
165  else
166  /* This default will be based on the in_color_space set above */
167  jpeg_default_colorspace(&cinfo);
168  if (cmdline.max_memory_to_use != -1)
171  if (cmdline.quality == -1) {
172  quality = 75;
173  q_scale_factor = 100;
174  } else {
176  q_scale_factor = jpeg_quality_scaling(cmdline.quality);
177  }
178  if (cmdline.smoothing_factor != -1)
180 
181  /* Set quantization tables for selected quality. */
182  /* Some or all may be overridden if user specified --qtables. */
184 
185  if (cmdline.qtablefile != NULL) {
186  if (! read_quant_tables(&cinfo, cmdline.qtablefile,
187  q_scale_factor, cmdline.force_baseline))
188  pm_error("Can't use quantization table file '%s'.",
190  }
191 
192  if (cmdline.qslots != NULL) {
193  if (! set_quant_slots(&cinfo, cmdline.qslots))
194  pm_error("Bad quantization-table-selectors parameter string '%s'.",
195  cmdline.qslots);
196  }
197 
198  if (cmdline.sample != NULL) {
199  if (! set_sample_factors(&cinfo, cmdline.sample))
200  pm_error("Bad sample-factors parameters string '%s'.",
201  cmdline.sample);
202  }
203 
204  if (cmdline.progressive)
205  jpeg_simple_progression(&cinfo);
206 
207  if (cmdline.scans != NULL) {
208  if (! read_scan_script(&cinfo, cmdline.scans)) {
209  pm_message("Error in scan script '%s'.", cmdline.scans);
210  }
211  }
212 
213  /* Specify data destination for compression */
214  jpeg_stdio_dest(&cinfo, output_file);
215 
216  /* Start compressor */
217  jpeg_start_compress(&cinfo, TRUE);
218 
219  /* Translate and copy over the actual scanlines */
220  convert_scanlines(&cinfo, input_file, maxval, input_fmt, rescale);
221 
222  /* Finish compression and release memory */
223  jpeg_finish_compress(&cinfo);
224  jpeg_destroy_compress(&cinfo);
225 
226  /* Close files, if we opened them */
227  if (input_file != stdin)
229 
230  /* Program may have exited with non-zero completion code vie various function
231  calls above.
232  */
233  exit((jerr.num_warnings > 0) ? EXIT_WARNING : EXIT_SUCCESS);
234 }
235 
236 
237 
238 static void
239 interpret_restart(const char * const restart,
240  unsigned int * const restart_value_p,
241  enum restart_unit * const restart_unit_p) {
242 /*----------------------------------------------------------------------------
243  Interpret the restart command line option. Return values suitable
244  for plugging into a jpeg_compress_struct to control compression.
245 -----------------------------------------------------------------------------*/
246  if (restart == NULL) {
247  /* No --restart option. Set default */
248  *restart_unit_p = RESTART_NONE;
249  } else {
250  /* Restart interval in MCU rows (or in MCUs with 'b'). */
251  long lval;
252  char ch;
253  unsigned int matches;
254 
255  matches= sscanf(restart, "%ld%c", &lval, &ch);
256  if (matches == 0)
257  pm_error("Invalid value for the --restart option : '%s'.",
258  restart);
259  else {
260  if (lval < 0 || lval > 65535L) {
261  pm_error("--restart value %ld is out of range.", lval);
263  } else {
264  if (matches == 1) {
265  *restart_value_p = lval;
266  *restart_unit_p = RESTART_ROW;
267  } else {
268  if (ch == 'b' || ch == 'B') {
269  *restart_value_p = lval;
270  *restart_unit_p = RESTART_MCU;
271  } else pm_error("Invalid --restart value '%s'.", restart);
272  }
273  }
274  }
275  }
276 }
277 
278 
279 
280 static void
281 interpret_maxmemory (const char * const maxmemory,
282  long int * const max_memory_to_use_p) {
283  long int lval;
284  char ch;
285 
286  if (maxmemory == NULL) {
287  *max_memory_to_use_p = -1; /* unspecified */
288  } else if (sscanf(maxmemory, "%ld%c", &lval, &ch) < 1) {
289  pm_error("Invalid value for --maxmemory option: '%s'.", maxmemory);
291  } else {
292  if (ch == 'm' || ch == 'M') lval *= 1000L;
293  *max_memory_to_use_p = lval * 1000L;
294  }
295 }
296 
297 
298 
299 static void
300 parse_command_line(const int argc, char ** argv,
301  struct cmdline_info *cmdline_p) {
302 /*----------------------------------------------------------------------------
303  Note that many of the strings that this function returns in the
304  *cmdline_p structure are actually in the supplied argv array. And
305  sometimes, one of these strings is actually just a suffix of an entry
306  in argv!
307 
308  On the other hand, unlike other option processing functions, we do
309  not change argv at all.
310 -----------------------------------------------------------------------------*/
311 
312  int i; /* local loop variable */
313 
314  char *dctval;
315  char *maxmemory;
316  char *restart;
317 
318  optStruct *option_def = malloc(100*sizeof(optStruct));
319  /* Instructions to OptParseOptions on how to parse our options.
320  */
321  unsigned int option_def_index;
322 
323  int argc_parse; /* argc, except we modify it as we parse */
324  char ** const argv_parse = malloc(argc*sizeof(char *));
325  /* argv, except we modify it as we parse */
326 
327  option_def_index = 0; /* incremented by OPTENTRY */
328  OPTENTRY(0, "verbose", OPT_FLAG, &cmdline_p->verbose, 0);
329  OPTENTRY(0, "quality", OPT_UINT, &cmdline_p->quality, 0);
330  OPTENTRY(0, "baseline", OPT_FLAG, &cmdline_p->force_baseline, 0);
331  OPTENTRY(0, "progressive", OPT_FLAG, &cmdline_p->progressive, 0);
332  OPTENTRY(0, "arithmetic", OPT_FLAG, &cmdline_p->arith_code, 0);
333  OPTENTRY(0, "dct", OPT_STRING, &dctval, 0);
334  OPTENTRY(0, "grayscale", OPT_FLAG, &cmdline_p->grayscale, 0);
335  OPTENTRY(0, "greyscale", OPT_FLAG, &cmdline_p->grayscale, 0);
336  OPTENTRY(0, "maxmemory", OPT_STRING, &maxmemory, 0);
337  OPTENTRY(0, "tracelevel", OPT_UINT, &cmdline_p->trace_level, 0);
338  OPTENTRY(0, "qslots", OPT_STRING, &cmdline_p->qslots, 0);
339  OPTENTRY(0, "qtables", OPT_STRING, &cmdline_p->qtablefile, 0);
340  OPTENTRY(0, "sample", OPT_STRING, &cmdline_p->sample, 0);
341  OPTENTRY(0, "scans", OPT_STRING, &cmdline_p->scans, 0);
342  OPTENTRY(0, "smooth", OPT_UINT, &cmdline_p->smoothing_factor, 0);
343  OPTENTRY(0, "optimize", OPT_FLAG, &cmdline_p->optimize, 0);
344  OPTENTRY(0, "optimise", OPT_FLAG, &cmdline_p->optimize, 0);
345  OPTENTRY(0, "restart", OPT_STRING, &restart, 0);
346 
347  /* Set the defaults */
348  cmdline_p->verbose = FALSE;
349  cmdline_p->quality = -1; /* unspecified */
350  cmdline_p->force_baseline = FALSE;
351  cmdline_p->progressive = FALSE;
352  cmdline_p->arith_code = FALSE;
353  dctval = NULL;
354  cmdline_p->grayscale = FALSE;
355  maxmemory = NULL;
356  cmdline_p->trace_level = 0;
357  cmdline_p->qslots = NULL;
358  cmdline_p->qtablefile = NULL;
359  cmdline_p->sample = NULL;
360  cmdline_p->scans = NULL;
361  cmdline_p->smoothing_factor = -1;
362  cmdline_p->optimize = FALSE;
363  restart = NULL;
364 
365  /* Make private copy of arguments for optParseOptions to corrupt */
366  argc_parse = argc;
367  for (i=0; i < argc; i++) argv_parse[i] = argv[i];
368 
369  pm_optParseOptions(&argc_parse, argv_parse, option_def, 0);
370  /* Uses and sets argc_parse, argv_parse and all of *cmdline_p. */
371 
372  if (argc_parse - 1 == 0)
373  cmdline_p->input_filename = NULL; /* he wants stdin */
374  else if (argc_parse - 1 == 1)
375  cmdline_p->input_filename = strdup(argv_parse[1]);
376  else
377  pm_error("Too many arguments. The only argument accepted"
378  "is the input file specification.");
379 
380  if (dctval == NULL)
381  cmdline_p->dct_method = JDCT_DEFAULT;
382  else {
383  if (strcmp(dctval, "int") == 0)
384  cmdline_p->dct_method = JDCT_ISLOW;
385  else if (strcmp(dctval, "fast") == 0)
386  cmdline_p->dct_method = JDCT_IFAST;
387  else if (strcmp(dctval, "float") == 0)
388  cmdline_p->dct_method = JDCT_FLOAT;
389  else
390  pm_error("Invalid value for the --dct option: '%s'.", dctval);
391  }
392 
393  interpret_maxmemory(maxmemory, &cmdline_p->max_memory_to_use);
394  interpret_restart(restart, &cmdline_p->restart_value,
395  &cmdline_p->restart_unit);
396 
397  if (cmdline_p->smoothing_factor > 100)
398  pm_error("Smoothing factor %d is greater than 100 (%%).",
399  cmdline_p->smoothing_factor);
400  free(argv_parse);
401 }
402 
403 
404 static void
405 compute_rescaling_array(JSAMPLE ** const rescale_p, const pixval maxval,
406  const struct jpeg_compress_struct cinfo) {
407 /*----------------------------------------------------------------------------
408  Compute the rescaling array for a maximum pixval of 'maxval'.
409  Allocate the memory for it too.
410 -----------------------------------------------------------------------------*/
411  const long half_maxval = maxval / 2;
412  long val;
413 
414  *rescale_p = (JSAMPLE *)
415  (cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_IMAGE,
416  (size_t) (((long) maxval + 1L) *
417  sizeof(JSAMPLE)));
418  for (val = 0; val <= maxval; val++) {
419  /* The multiplication here must be done in 32 bits to avoid overflow */
420  (*rescale_p)[val] = (JSAMPLE) ((val*MAXJSAMPLE + half_maxval)/maxval);
421  }
422 }
423 
424 
425 
426 static void
427 translate_row(const pixel ppm_buffer[],
428  JSAMPLE jpeg_buffer[],
429  const int width,
430  const JSAMPLE translate[]) {
431 /*----------------------------------------------------------------------------
432  Convert the input row, in ppm format, to an output row in JPEG compressor
433  input format.
434 
435  This is a byte for byte copy, translated through the array 'translate'.
436 -----------------------------------------------------------------------------*/
437  unsigned int column;
438  /* I'm not sure why the JPEG library data structures don't have some kind
439  of pixel data structure (such that a row buffer is an array of pixels,
440  rather than an array of samples). But because of this, we have to
441  index jpeg_buffer the old fashioned way.
442  */
443 
444  for (column = 0; column < width; column++) {
445  jpeg_buffer[column*3+0] = translate[(int)PPM_GETR(ppm_buffer[column])];
446  jpeg_buffer[column*3+1] = translate[(int)PPM_GETG(ppm_buffer[column])];
447  jpeg_buffer[column*3+2] = translate[(int)PPM_GETB(ppm_buffer[column])];
448  }
449 }
450 
451 
452 
453 static void translate_row(const pixel ppm_buffer[],
454  JSAMPLE jpeg_buffer[],
455  const int width,
456  const JSAMPLE translate[]);
457 static void
459  const pixval maxval, const int input_fmt,
460  JSAMPLE xlate_table[]){
461 /*----------------------------------------------------------------------------
462  Read scan lines from the input file, which is already opened in the
463  netpbm library sense and ready for reading, and write them to the
464  output JPEG object. Translate the ppm sample values to JPEG sample
465  values through the thable xlate_table[].
466 -----------------------------------------------------------------------------*/
467  pixel* ppm_buffer;
468  /* contains the row of the input image currently being processed,
469  in ppm_readrow format
470  */
472  /* Row 0 of this array contains the row of the output image currently
473  being processed, in JPEG compressor input format. The array only
474  has that one row.
475  */
476 
477  /* Allocate the libppm output and compressor input buffers */
478  buffer = (*cinfo_p->mem->alloc_sarray)
479  ((j_common_ptr) cinfo_p, JPOOL_IMAGE,
480  (unsigned int) cinfo_p->image_width * cinfo_p->input_components,
481  (unsigned int) 1);
482 
483  ppm_buffer = ppm_allocrow(cinfo_p->image_width);
484 
485  while (cinfo_p->next_scanline < cinfo_p->image_height) {
486  if (cinfo_p->err->trace_level > 1)
487  pm_message("Converting Row %d...", cinfo_p->next_scanline);
488  ppm_readppmrow(input_file, ppm_buffer, cinfo_p->image_width,
489  maxval, input_fmt);
490  translate_row(ppm_buffer, buffer[0], cinfo_p->image_width, xlate_table);
491  jpeg_write_scanlines(cinfo_p, buffer, 1);
492  if (cinfo_p->err->trace_level > 1)
493  pm_message("Done.");
494  }
495 
496  ppm_freerow(ppm_buffer);
497  /* Dont' worry about the compressor input buffer; it gets freed
498  automatically
499  */
500 
501 }
502 
503 /*----------------------------------------------------------------------------
504  The functions below here are essentially the file rdswitch.c from
505  the JPEG library. They perform the functions specifed by the following
506  ppmtojpeg options:
507 
508  -qtables file Read quantization tables from text file
509  -scans file Read scan script from text file
510  -qslots N[,N,...] Set component quantization table selectors
511  -sample HxV[,HxV,...] Set component sampling factors
512 -----------------------------------------------------------------------------*/
513 
514 static int
516 /* Read next char, skipping over any comments (# to end of line) */
517 /* A comment/newline sequence is returned as a newline */
518 {
519  register int ch;
520 
521  ch = getc(file);
522  if (ch == '#') {
523  do {
524  ch = getc(file);
525  } while (ch != '\n' && ch != EOF);
526  }
527  return ch;
528 }
529 
530 
531 static boolean
532 read_text_integer (FILE * file, long * result, int * termchar)
533 /* Read an unsigned decimal integer from a file, store it in result */
534 /* Reads one trailing character after the integer; returns it in termchar */
535 {
536  register int ch;
537  register long val;
538 
539  /* Skip any leading whitespace, detect EOF */
540  do {
541  ch = text_getc(file);
542  if (ch == EOF) {
543  *termchar = ch;
544  return FALSE;
545  }
546  } while (isspace(ch));
547 
548  if (! isdigit(ch)) {
549  *termchar = ch;
550  return FALSE;
551  }
552 
553  val = ch - '0';
554  while ((ch = text_getc(file)) != EOF) {
555  if (! isdigit(ch))
556  break;
557  val *= 10;
558  val += ch - '0';
559  }
560  *result = val;
561  *termchar = ch;
562  return TRUE;
563 }
564 
565 
566 static boolean
568  int scale_factor, boolean force_baseline)
569 /* Read a set of quantization tables from the specified file.
570  * The file is plain ASCII text: decimal numbers with whitespace between.
571  * Comments preceded by '#' may be included in the file.
572  * There may be one to NUM_QUANT_TBLS tables in the file, each of 64 values.
573  * The tables are implicitly numbered 0,1,etc.
574  * NOTE: does not affect the qslots mapping, which will default to selecting
575  * table 0 for luminance (or primary) components, 1 for chrominance components.
576  * You must use -qslots if you want a different component->table mapping.
577  */
578 {
579  FILE * fp;
580  int tblno, i, termchar;
581  long val;
582  unsigned int table[DCTSIZE2];
583 
584  if ((fp = fopen(filename, "rb")) == NULL) {
585  fprintf(stderr, "%s: Can't open table file %s\n", progname, filename);
586  return FALSE;
587  }
588  tblno = 0;
589 
590  while (read_text_integer(fp, &val, &termchar)) { /* read 1st element of table */
591  if (tblno >= NUM_QUANT_TBLS) {
592  fprintf(stderr, "%s: Too many tables in file %s\n", progname, filename);
593  fclose(fp);
594  return FALSE;
595  }
596  table[0] = (unsigned int) val;
597  for (i = 1; i < DCTSIZE2; i++) {
598  if (! read_text_integer(fp, &val, &termchar)) {
599  fprintf(stderr, "%s: Invalid table data in file %s\n", progname, filename);
600  fclose(fp);
601  return FALSE;
602  }
603  table[i] = (unsigned int) val;
604  }
605  jpeg_add_quant_table(cinfo, tblno, table, scale_factor, force_baseline);
606  tblno++;
607  }
608 
609  if (termchar != EOF) {
610  fprintf(stderr, "%s: Non-numeric data in file %s\n", progname, filename);
611  fclose(fp);
612  return FALSE;
613  }
614 
615  fclose(fp);
616  return TRUE;
617 }
618 
619 
620 static boolean
621 read_scan_integer (FILE * file, long * result, int * termchar)
622 /* Variant of read_text_integer that always looks for a non-space termchar;
623  * this simplifies parsing of punctuation in scan scripts.
624  */
625 {
626  register int ch;
627 
628  if (! read_text_integer(file, result, termchar))
629  return FALSE;
630  ch = *termchar;
631  while (ch != EOF && isspace(ch))
632  ch = text_getc(file);
633  if (isdigit(ch)) { /* oops, put it back */
634  if (ungetc(ch, file) == EOF)
635  return FALSE;
636  ch = ' ';
637  } else {
638  /* Any separators other than ';' and ':' are ignored;
639  * this allows user to insert commas, etc, if desired.
640  */
641  if (ch != EOF && ch != ';' && ch != ':')
642  ch = ' ';
643  }
644  *termchar = ch;
645  return TRUE;
646 }
647 
648 
649 boolean
651 /* Read a scan script from the specified text file.
652  * Each entry in the file defines one scan to be emitted.
653  * Entries are separated by semicolons ';'.
654  * An entry contains one to four component indexes,
655  * optionally followed by a colon ':' and four progressive-JPEG parameters.
656  * The component indexes denote which component(s) are to be transmitted
657  * in the current scan. The first component has index 0.
658  * Sequential JPEG is used if the progressive-JPEG parameters are omitted.
659  * The file is free format text: any whitespace may appear between numbers
660  * and the ':' and ';' punctuation marks. Also, other punctuation (such
661  * as commas or dashes) can be placed between numbers if desired.
662  * Comments preceded by '#' may be included in the file.
663  * Note: we do very little validity checking here;
664  * jcmaster.c will validate the script parameters.
665  */
666 {
667  FILE * fp;
668  int scanno, ncomps, termchar;
669  long val;
670  jpeg_scan_info * scanptr;
671 #define MAX_SCANS 100 /* quite arbitrary limit */
672  jpeg_scan_info scans[MAX_SCANS];
673 
674  if ((fp = fopen(filename, "r")) == NULL) {
675  fprintf(stderr, "%s: Can't open scan definition file %s\n",
676  progname, filename);
677  return FALSE;
678  }
679  scanptr = scans;
680  scanno = 0;
681 
682  while (read_scan_integer(fp, &val, &termchar)) {
683  if (scanno >= MAX_SCANS) {
684  fprintf(stderr, "%s: Too many scans defined in file %s\n",
685  progname, filename);
686  fclose(fp);
687  return FALSE;
688  }
689  scanptr->component_index[0] = (int) val;
690  ncomps = 1;
691  while (termchar == ' ') {
692  if (ncomps >= MAX_COMPS_IN_SCAN) {
693  fprintf(stderr, "%s: Too many components in one scan in file %s\n",
694  progname, filename);
695  fclose(fp);
696  return FALSE;
697  }
698  if (! read_scan_integer(fp, &val, &termchar))
699  goto bogus;
700  scanptr->component_index[ncomps] = (int) val;
701  ncomps++;
702  }
703  scanptr->comps_in_scan = ncomps;
704  if (termchar == ':') {
705  if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ')
706  goto bogus;
707  scanptr->Ss = (int) val;
708  if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ')
709  goto bogus;
710  scanptr->Se = (int) val;
711  if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ')
712  goto bogus;
713  scanptr->Ah = (int) val;
714  if (! read_scan_integer(fp, &val, &termchar))
715  goto bogus;
716  scanptr->Al = (int) val;
717  } else {
718  /* set non-progressive parameters */
719  scanptr->Ss = 0;
720  scanptr->Se = DCTSIZE2-1;
721  scanptr->Ah = 0;
722  scanptr->Al = 0;
723  }
724  if (termchar != ';' && termchar != EOF) {
725 bogus:
726  fprintf(stderr, "%s: Invalid scan entry format in file %s\n",
727  progname, filename);
728  fclose(fp);
729  return FALSE;
730  }
731  scanptr++, scanno++;
732  }
733 
734  if (termchar != EOF) {
735  fprintf(stderr, "%s: Non-numeric data in file %s\n", progname, filename);
736  fclose(fp);
737  return FALSE;
738  }
739 
740  if (scanno > 0) {
741  /* Stash completed scan list in cinfo structure.
742  * NOTE: for cjpeg's use, JPOOL_IMAGE is the right lifetime for this data,
743  * but if you want to compress multiple images you'd want JPOOL_PERMANENT.
744  */
745  scanptr = (jpeg_scan_info *)
746  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
747  scanno * sizeof(jpeg_scan_info));
748  memcpy(scanptr, scans, sizeof(jpeg_scan_info));
749  cinfo->scan_info = scanptr;
750  cinfo->num_scans = scanno;
751  }
752 
753  fclose(fp);
754  return TRUE;
755 }
756 
757 
758 static boolean
759 set_quant_slots (j_compress_ptr cinfo, char *arg)
760 /* Process a quantization-table-selectors parameter string, of the form
761  * N[,N,...]
762  * If there are more components than parameters, the last value is replicated.
763  */
764 {
765  int val = 0; /* default table # */
766  int ci;
767  char ch;
768 
769  for (ci = 0; ci < MAX_COMPONENTS; ci++) {
770  if (*arg) {
771  ch = ','; /* if not set by sscanf, will be ',' */
772  if (sscanf(arg, "%d%c", &val, &ch) < 1)
773  return FALSE;
774  if (ch != ',') /* syntax check */
775  return FALSE;
777  fprintf(stderr, "%s: Invalid quantization table number: %d. "
778  "JPEG quantization tables are numbered 0..%d\n",
779  progname, val, NUM_QUANT_TBLS - 1);
780  return FALSE;
781  }
782  cinfo->comp_info[ci].quant_tbl_no = val;
783  while (*arg && *arg++ != ',') /* advance to next segment of arg string */
784  ;
785  } else {
786  /* reached end of parameter, set remaining components to last table */
787  cinfo->comp_info[ci].quant_tbl_no = val;
788  }
789  }
790  return TRUE;
791 }
792 
793 
794 static boolean
796 /* Process a sample-factors parameter string, of the form
797  * HxV[,HxV,...]
798  * If there are more components than parameters, "1x1" is assumed for the rest.
799  */
800 {
801  int ci, val1, val2;
802  char ch1, ch2;
803 
804  for (ci = 0; ci < MAX_COMPONENTS; ci++) {
805  if (*arg) {
806  ch2 = ','; /* if not set by sscanf, will be ',' */
807  if (sscanf(arg, "%d%c%d%c", &val1, &ch1, &val2, &ch2) < 3)
808  return FALSE;
809  if ((ch1 != 'x' && ch1 != 'X') || ch2 != ',') /* syntax check */
810  return FALSE;
811  if (val1 <= 0 || val1 > 4) {
812  fprintf(stderr, "%s: Invalid sampling factor: %d. "
813  "JPEG sampling factors must be 1..4\n", progname, val1);
814  return FALSE;
815  }
816  if (val2 <= 0 || val2 > 4) {
817  fprintf(stderr, "%s: Invalid sampling factor: %d. "
818  "JPEG sampling factors must be 1..4\n", progname, val2);
819  return FALSE;
820  }
821  cinfo->comp_info[ci].h_samp_factor = val1;
822  cinfo->comp_info[ci].v_samp_factor = val2;
823  while (*arg && *arg++ != ',') /* advance to next segment of arg string */
824  ;
825  } else {
826  /* reached end of parameter, set remaining components to 1x1 sampling */
827  cinfo->comp_info[ci].h_samp_factor = 1;
828  cinfo->comp_info[ci].v_samp_factor = 1;
829  }
830  }
831  return TRUE;
832 }
#define strdup
Definition: Utility.h:167
#define width(a)
Definition: aptex-macros.h:198
#define height(a)
Definition: aptex-macros.h:200
static gray maxval
Definition: asciitopgm.c:38
static int column
Definition: backend_svg.c:38
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
#define free(a)
Definition: decNumber.cpp:310
#define fopen
Definition: xxstdio.h:21
int strcmp()
Definition: coll.cpp:143
int sscanf()
void translate(struct DVIFILE_INFO_REC *dvi, struct DIMENSION_REC *dim)
Definition: dvispc.c:839
#define memcpy(d, s, n)
Definition: gsftopk.c:64
#define EXIT_SUCCESS
Definition: cdjpeg.h:175
#define EXIT_FAILURE
Definition: cdjpeg.h:169
void jpeg_destroy_compress(j_compress_ptr cinfo)
Definition: jcapimin.c:88
void jpeg_finish_compress(j_compress_ptr cinfo)
Definition: jcapimin.c:147
void jpeg_start_compress(j_compress_ptr cinfo, boolean write_all_tables)
Definition: jcapistd.c:38
JDIMENSION jpeg_write_scanlines(j_compress_ptr cinfo, JSAMPARRAY scanlines, JDIMENSION num_lines)
Definition: jcapistd.c:77
boolean int tblno
Definition: jchuff.h:42
void jpeg_set_defaults(j_compress_ptr cinfo)
Definition: jcparam.c:268
void jpeg_add_quant_table(j_compress_ptr cinfo, int which_tbl, const unsigned int *basic_table, int scale_factor, boolean force_baseline)
Definition: jcparam.c:23
void jpeg_default_colorspace(j_compress_ptr cinfo)
Definition: jcparam.c:359
void jpeg_set_colorspace(j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
Definition: jcparam.c:391
void jpeg_set_quality(j_compress_ptr cinfo, int quality, boolean force_baseline)
Definition: jcparam.c:132
void jpeg_simple_progression(j_compress_ptr cinfo)
Definition: jcparam.c:537
int jpeg_quality_scaling(int quality)
Definition: jcparam.c:106
void jpeg_stdio_dest(j_compress_ptr cinfo, FILE *outfile)
Definition: jdatadst.c:130
struct jpeg_error_mgr * jpeg_std_error(struct jpeg_error_mgr *err)
Definition: jerror.c:231
#define MAXJSAMPLE
Definition: jmorecfg.h:73
char JSAMPLE
Definition: jmorecfg.h:64
#define MAX_COMPONENTS
Definition: jmorecfg.h:35
#define BITS_IN_JSAMPLE
Definition: jmorecfg.h:23
struct jpeg_common_struct * j_common_ptr
Definition: jpeglib.h:261
#define JDCT_DEFAULT
Definition: jpeglib.h:224
@ JCS_GRAYSCALE
Definition: jpeglib.h:208
@ JCS_RGB
Definition: jpeglib.h:209
#define jpeg_create_compress(cinfo)
Definition: jpeglib.h:894
#define NUM_QUANT_TBLS
Definition: jpeglib.h:43
JSAMPROW * JSAMPARRAY
Definition: jpeglib.h:67
#define JPOOL_IMAGE
Definition: jpeglib.h:749
#define MAX_COMPS_IN_SCAN
Definition: jpeglib.h:46
J_DCT_METHOD
Definition: jpeglib.h:217
@ JDCT_IFAST
Definition: jpeglib.h:219
@ JDCT_FLOAT
Definition: jpeglib.h:220
@ JDCT_ISLOW
Definition: jpeglib.h:218
#define DCTSIZE2
Definition: jpeglib.h:42
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
void exit()
#define EOF
Definition: afmparse.c:59
#define JSAMPLE
Definition: gd_topal.c:62
int errno
#define fclose
Definition: debug.h:100
#define getc
Definition: line.c:39
#define fprintf
Definition: mendex.h:64
static char * strerror(int errnum)
Definition: error.c:56
#define malloc
Definition: alloca.c:91
#define isdigit(c)
Definition: snprintf.c:177
#define lval(L)
Definition: list_routines.h:69
void pm_optParseOptions(int *argc, char *argv[], optStruct opt[], int allowNegNum)
Definition: libpbm1.c:149
#define OPTENTRY(shortvalue, longvalue, typevalue, outputvalue, flagvalue)
Definition: pbmplus.h:311
char * filename[256]
Definition: pbmtopk.c:46
static FILE * output_file
Definition: pdftocairo.cc:236
#define fp
#define pm_error
Definition: png22pnm.c:118
#define pm_message
Definition: png22pnm.c:116
void ppm_readppmrow(FILE *file, pixel *pixelrow, int cols, pixval maxval, int format)
Definition: libppm1.c:87
void ppm_init(int *argcP, argv)
Definition: libppm1.c:21
void ppm_readppminit(FILE *file, int *colsP, int *rowsP, pixval *maxvalP, int *formatP)
Definition: libppm1.c:53
#define PPM_GETR(p)
Definition: ppm.h:36
#define PPM_GETG(p)
Definition: ppm.h:37
#define ppm_freerow(pixelrow)
Definition: ppm.h:74
#define PPM_GETB(p)
Definition: ppm.h:38
gray pixval
Definition: ppm.h:9
#define ppm_allocrow(cols)
Definition: ppm.h:72
struct cmdline_info cmdline
static boolean read_text_integer(FILE *file, long *result, int *termchar)
Definition: ppmtojpeg.c:532
#define MAX_SCANS
static void convert_scanlines(struct jpeg_compress_struct *cinfo_p, FILE *input_file, const pixval maxval, const int input_fmt, JSAMPLE xlate_table[])
Definition: ppmtojpeg.c:458
static void parse_command_line(const int argc, char **argv, struct cmdline_info *cmdline_p)
Definition: ppmtojpeg.c:300
restart_unit
Definition: ppmtojpeg.c:36
@ RESTART_NONE
Definition: ppmtojpeg.c:36
@ RESTART_ROW
Definition: ppmtojpeg.c:36
@ RESTART_MCU
Definition: ppmtojpeg.c:36
static void translate_row(const pixel ppm_buffer[], JSAMPLE jpeg_buffer[], const int width, const JSAMPLE translate[])
Definition: ppmtojpeg.c:427
int main(int argc, char **argv)
Definition: ppmtojpeg.c:87
static int text_getc(FILE *file)
Definition: ppmtojpeg.c:515
#define EXIT_WARNING
Definition: ppmtojpeg.c:32
static void interpret_restart(const char *const restart, unsigned int *const restart_value_p, enum restart_unit *const restart_unit_p)
Definition: ppmtojpeg.c:239
static boolean read_quant_tables(j_compress_ptr cinfo, char *filename, int scale_factor, boolean force_baseline)
Definition: ppmtojpeg.c:567
static void interpret_maxmemory(const char *const maxmemory, long int *const max_memory_to_use_p)
Definition: ppmtojpeg.c:281
static const char * progname
Definition: ppmtojpeg.c:34
static boolean set_quant_slots(j_compress_ptr cinfo, char *arg)
Definition: ppmtojpeg.c:759
static boolean read_scan_integer(FILE *file, long *result, int *termchar)
Definition: ppmtojpeg.c:621
static boolean set_sample_factors(j_compress_ptr cinfo, char *arg)
Definition: ppmtojpeg.c:795
static boolean read_scan_script(j_compress_ptr cinfo, char *filename)
Definition: ppmtojpeg.c:650
static void compute_rescaling_array(JSAMPLE **const rescale_p, const pixval maxval, const struct jpeg_compress_struct cinfo)
Definition: ppmtojpeg.c:405
static int quality
Definition: ppmtopjxl.c:45
#define isspace(ch)
Definition: utype.h:87
@ OPT_UINT
Definition: shhopt.h:15
@ OPT_FLAG
Definition: shhopt.h:12
@ OPT_STRING
Definition: shhopt.h:13
Definition: utils.c:300
int progressive
Definition: ppmtojpeg.c:46
enum restart_unit restart_unit
Definition: ppmtojpeg.c:59
char * sample
Definition: ppmtojpeg.c:54
char * qtablefile
Definition: ppmtojpeg.c:53
int arith_code
Definition: ppmtojpeg.c:47
char * scans
Definition: ppmtojpeg.c:55
char * qslots
Definition: ppmtojpeg.c:52
J_DCT_METHOD dct_method
Definition: jpegtopnm.c:59
unsigned int restart_value
Definition: ppmtojpeg.c:58
char * input_filename
Definition: jpegtopnm.c:56
int force_baseline
Definition: ppmtojpeg.c:45
long int max_memory_to_use
Definition: jpegtopnm.c:61
int grayscale
Definition: jpegtopnm.c:60
int smoothing_factor
Definition: ppmtojpeg.c:56
unsigned int quality
Definition: ppmtojpeg.c:44
unsigned int trace_level
Definition: jpegtopnm.c:62
int optimize
Definition: ppmtojpeg.c:57
char * restart
Definition: ppmtojpeg.c:60
Definition: filedef.h:30
boolean optimize_coding
Definition: jpeglib.h:322
JDIMENSION image_height
Definition: jpeglib.h:280
const jpeg_scan_info * scan_info
Definition: jpeglib.h:314
struct jpeg_error_mgr * err
Definition: jpeglib.h:269
boolean arith_code
Definition: jpeglib.h:321
J_DCT_METHOD dct_method
Definition: jpeglib.h:325
J_COLOR_SPACE in_color_space
Definition: jpeglib.h:282
jpeg_component_info * comp_info
Definition: jpeglib.h:299
JDIMENSION image_width
Definition: jpeglib.h:279
JDIMENSION next_scanline
Definition: jpeglib.h:354
struct jpeg_memory_mgr * mem
Definition: jpeglib.h:269
long num_warnings
Definition: jpeglib.h:676
int trace_level
Definition: jpeglib.h:668
void *(* alloc_small)(j_common_ptr cinfo, int pool_id, size_t sizeofobject)
Definition: jpeglib.h:759
long max_memory_to_use
Definition: jpeglib.h:799
JSAMPARRAY(* alloc_sarray)(j_common_ptr cinfo, int pool_id, JDIMENSION samplesperrow, JDIMENSION numrows)
Definition: jpeglib.h:764
int comps_in_scan
Definition: jpeglib.h:185
int component_index[4]
Definition: jpeglib.h:186
Definition: ppm.h:33
Definition: table.h:30
Definition: strexpr.c:21
#define FILE
Definition: t1stdio.h:34
#define ungetc(c, f)
Definition: t1stdio.h:106
ch
Definition: t4ht.c:1443
ch2
Definition: tex4ht.c:3229
val
Definition: tex4ht.c:3227
return() int(((double) *(font_tbl[cur_fnt].wtbl+(int)(*(font_tbl[cur_fnt].char_wi+(int)(ch - font_tbl[cur_fnt].char_f)% 256)))/(double)(1L<< 20)) *(double) font_tbl[cur_fnt].scale)
static double scale_factor
Definition: ttf2pt1.c:170
#define argv
Definition: xmain.c:270
#define argc
Definition: xmain.c:269
#define buffer
Definition: xmlparse.c:611