ReactOS  0.4.14-dev-342-gdc047f9
rdswitch.c
Go to the documentation of this file.
1 /*
2  * rdswitch.c
3  *
4  * Copyright (C) 1991-1996, Thomas G. Lane.
5  * Modified 2003-2015 by Guido Vollbeding.
6  * This file is part of the Independent JPEG Group's software.
7  * For conditions of distribution and use, see the accompanying README file.
8  *
9  * This file contains routines to process some of cjpeg's more complicated
10  * command-line switches. Switches processed here are:
11  * -qtables file Read quantization tables from text file
12  * -scans file Read scan script from text file
13  * -quality N[,N,...] Set quality ratings
14  * -qslots N[,N,...] Set component quantization table selectors
15  * -sample HxV[,HxV,...] Set component sampling factors
16  */
17 
18 #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
19 #include <ctype.h> /* to declare isdigit(), isspace() */
20 
21 
22 LOCAL(int)
24 /* Read next char, skipping over any comments (# to end of line) */
25 /* A comment/newline sequence is returned as a newline */
26 {
27  register int ch;
28 
29  ch = getc(file);
30  if (ch == '#') {
31  do {
32  ch = getc(file);
33  } while (ch != '\n' && ch != EOF);
34  }
35  return ch;
36 }
37 
38 
39 LOCAL(boolean)
40 read_text_integer (FILE * file, long * result, int * termchar)
41 /* Read an unsigned decimal integer from a file, store it in result */
42 /* Reads one trailing character after the integer; returns it in termchar */
43 {
44  register int ch;
45  register long val;
46 
47  /* Skip any leading whitespace, detect EOF */
48  do {
49  ch = text_getc(file);
50  if (ch == EOF) {
51  *termchar = ch;
52  return FALSE;
53  }
54  } while (isspace(ch));
55 
56  if (! isdigit(ch)) {
57  *termchar = ch;
58  return FALSE;
59  }
60 
61  val = ch - '0';
62  while ((ch = text_getc(file)) != EOF) {
63  if (! isdigit(ch))
64  break;
65  val *= 10;
66  val += ch - '0';
67  }
68  *result = val;
69  *termchar = ch;
70  return TRUE;
71 }
72 
73 
74 GLOBAL(boolean)
76 /* Read a set of quantization tables from the specified file.
77  * The file is plain ASCII text: decimal numbers with whitespace between.
78  * Comments preceded by '#' may be included in the file.
79  * There may be one to NUM_QUANT_TBLS tables in the file, each of 64 values.
80  * The tables are implicitly numbered 0,1,etc.
81  * NOTE: does not affect the qslots mapping, which will default to selecting
82  * table 0 for luminance (or primary) components, 1 for chrominance components.
83  * You must use -qslots if you want a different component->table mapping.
84  */
85 {
86  FILE * fp;
87  int tblno, i, termchar;
88  long val;
89  unsigned int table[DCTSIZE2];
90 
91  if ((fp = fopen(filename, "r")) == NULL) {
92  fprintf(stderr, "Can't open table file %s\n", filename);
93  return FALSE;
94  }
95  tblno = 0;
96 
97  while (read_text_integer(fp, &val, &termchar)) { /* read 1st element of table */
98  if (tblno >= NUM_QUANT_TBLS) {
99  fprintf(stderr, "Too many tables in file %s\n", filename);
100  fclose(fp);
101  return FALSE;
102  }
103  table[0] = (unsigned int) val;
104  for (i = 1; i < DCTSIZE2; i++) {
105  if (! read_text_integer(fp, &val, &termchar)) {
106  fprintf(stderr, "Invalid table data in file %s\n", filename);
107  fclose(fp);
108  return FALSE;
109  }
110  table[i] = (unsigned int) val;
111  }
112  jpeg_add_quant_table(cinfo, tblno, table, cinfo->q_scale_factor[tblno],
114  tblno++;
115  }
116 
117  if (termchar != EOF) {
118  fprintf(stderr, "Non-numeric data in file %s\n", filename);
119  fclose(fp);
120  return FALSE;
121  }
122 
123  fclose(fp);
124  return TRUE;
125 }
126 
127 
128 #ifdef C_MULTISCAN_FILES_SUPPORTED
129 
130 LOCAL(boolean)
131 read_scan_integer (FILE * file, long * result, int * termchar)
132 /* Variant of read_text_integer that always looks for a non-space termchar;
133  * this simplifies parsing of punctuation in scan scripts.
134  */
135 {
136  register int ch;
137 
138  if (! read_text_integer(file, result, termchar))
139  return FALSE;
140  ch = *termchar;
141  while (ch != EOF && isspace(ch))
142  ch = text_getc(file);
143  if (isdigit(ch)) { /* oops, put it back */
144  if (ungetc(ch, file) == EOF)
145  return FALSE;
146  ch = ' ';
147  } else {
148  /* Any separators other than ';' and ':' are ignored;
149  * this allows user to insert commas, etc, if desired.
150  */
151  if (ch != EOF && ch != ';' && ch != ':')
152  ch = ' ';
153  }
154  *termchar = ch;
155  return TRUE;
156 }
157 
158 
159 GLOBAL(boolean)
160 read_scan_script (j_compress_ptr cinfo, char * filename)
161 /* Read a scan script from the specified text file.
162  * Each entry in the file defines one scan to be emitted.
163  * Entries are separated by semicolons ';'.
164  * An entry contains one to four component indexes,
165  * optionally followed by a colon ':' and four progressive-JPEG parameters.
166  * The component indexes denote which component(s) are to be transmitted
167  * in the current scan. The first component has index 0.
168  * Sequential JPEG is used if the progressive-JPEG parameters are omitted.
169  * The file is free format text: any whitespace may appear between numbers
170  * and the ':' and ';' punctuation marks. Also, other punctuation (such
171  * as commas or dashes) can be placed between numbers if desired.
172  * Comments preceded by '#' may be included in the file.
173  * Note: we do very little validity checking here;
174  * jcmaster.c will validate the script parameters.
175  */
176 {
177  FILE * fp;
178  int scanno, ncomps, termchar;
179  long val;
180  jpeg_scan_info * scanptr;
181 #define MAX_SCANS 100 /* quite arbitrary limit */
182  jpeg_scan_info scans[MAX_SCANS];
183 
184  if ((fp = fopen(filename, "r")) == NULL) {
185  fprintf(stderr, "Can't open scan definition file %s\n", filename);
186  return FALSE;
187  }
188  scanptr = scans;
189  scanno = 0;
190 
191  while (read_scan_integer(fp, &val, &termchar)) {
192  if (scanno >= MAX_SCANS) {
193  fprintf(stderr, "Too many scans defined in file %s\n", filename);
194  fclose(fp);
195  return FALSE;
196  }
197  scanptr->component_index[0] = (int) val;
198  ncomps = 1;
199  while (termchar == ' ') {
200  if (ncomps >= MAX_COMPS_IN_SCAN) {
201  fprintf(stderr, "Too many components in one scan in file %s\n",
202  filename);
203  fclose(fp);
204  return FALSE;
205  }
206  if (! read_scan_integer(fp, &val, &termchar))
207  goto bogus;
208  scanptr->component_index[ncomps] = (int) val;
209  ncomps++;
210  }
211  scanptr->comps_in_scan = ncomps;
212  if (termchar == ':') {
213  if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ')
214  goto bogus;
215  scanptr->Ss = (int) val;
216  if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ')
217  goto bogus;
218  scanptr->Se = (int) val;
219  if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ')
220  goto bogus;
221  scanptr->Ah = (int) val;
222  if (! read_scan_integer(fp, &val, &termchar))
223  goto bogus;
224  scanptr->Al = (int) val;
225  } else {
226  /* set non-progressive parameters */
227  scanptr->Ss = 0;
228  scanptr->Se = DCTSIZE2-1;
229  scanptr->Ah = 0;
230  scanptr->Al = 0;
231  }
232  if (termchar != ';' && termchar != EOF) {
233 bogus:
234  fprintf(stderr, "Invalid scan entry format in file %s\n", filename);
235  fclose(fp);
236  return FALSE;
237  }
238  scanptr++, scanno++;
239  }
240 
241  if (termchar != EOF) {
242  fprintf(stderr, "Non-numeric data in file %s\n", filename);
243  fclose(fp);
244  return FALSE;
245  }
246 
247  if (scanno > 0) {
248  /* Stash completed scan list in cinfo structure.
249  * NOTE: for cjpeg's use, JPOOL_IMAGE is the right lifetime for this data,
250  * but if you want to compress multiple images you'd want JPOOL_PERMANENT.
251  */
252  scanptr = (jpeg_scan_info *)
253  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
254  scanno * SIZEOF(jpeg_scan_info));
255  MEMCOPY(scanptr, scans, scanno * SIZEOF(jpeg_scan_info));
256  cinfo->scan_info = scanptr;
257  cinfo->num_scans = scanno;
258  }
259 
260  fclose(fp);
261  return TRUE;
262 }
263 
264 #endif /* C_MULTISCAN_FILES_SUPPORTED */
265 
266 
267 GLOBAL(boolean)
269 /* Process a quality-ratings parameter string, of the form
270  * N[,N,...]
271  * If there are more q-table slots than parameters, the last value is replicated.
272  */
273 {
274  int val = 75; /* default value */
275  int tblno;
276  char ch;
277 
278  for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
279  if (*arg) {
280  ch = ','; /* if not set by sscanf, will be ',' */
281  if (sscanf(arg, "%d%c", &val, &ch) < 1)
282  return FALSE;
283  if (ch != ',') /* syntax check */
284  return FALSE;
285  /* Convert user 0-100 rating to percentage scaling */
286  cinfo->q_scale_factor[tblno] = jpeg_quality_scaling(val);
287  while (*arg && *arg++ != ',') /* advance to next segment of arg string */
288  ;
289  } else {
290  /* reached end of parameter, set remaining factors to last value */
291  cinfo->q_scale_factor[tblno] = jpeg_quality_scaling(val);
292  }
293  }
295  return TRUE;
296 }
297 
298 
299 GLOBAL(boolean)
301 /* Process a quantization-table-selectors parameter string, of the form
302  * N[,N,...]
303  * If there are more components than parameters, the last value is replicated.
304  */
305 {
306  int val = 0; /* default table # */
307  int ci;
308  char ch;
309 
310  for (ci = 0; ci < MAX_COMPONENTS; ci++) {
311  if (*arg) {
312  ch = ','; /* if not set by sscanf, will be ',' */
313  if (sscanf(arg, "%d%c", &val, &ch) < 1)
314  return FALSE;
315  if (ch != ',') /* syntax check */
316  return FALSE;
318  fprintf(stderr, "JPEG quantization tables are numbered 0..%d\n",
319  NUM_QUANT_TBLS-1);
320  return FALSE;
321  }
322  cinfo->comp_info[ci].quant_tbl_no = val;
323  while (*arg && *arg++ != ',') /* advance to next segment of arg string */
324  ;
325  } else {
326  /* reached end of parameter, set remaining components to last table */
327  cinfo->comp_info[ci].quant_tbl_no = val;
328  }
329  }
330  return TRUE;
331 }
332 
333 
334 GLOBAL(boolean)
336 /* Process a sample-factors parameter string, of the form
337  * HxV[,HxV,...]
338  * If there are more components than parameters, "1x1" is assumed for the rest.
339  */
340 {
341  int ci, val1, val2;
342  char ch1, ch2;
343 
344  for (ci = 0; ci < MAX_COMPONENTS; ci++) {
345  if (*arg) {
346  ch2 = ','; /* if not set by sscanf, will be ',' */
347  if (sscanf(arg, "%d%c%d%c", &val1, &ch1, &val2, &ch2) < 3)
348  return FALSE;
349  if ((ch1 != 'x' && ch1 != 'X') || ch2 != ',') /* syntax check */
350  return FALSE;
351  if (val1 <= 0 || val1 > MAX_SAMP_FACTOR ||
352  val2 <= 0 || val2 > MAX_SAMP_FACTOR) {
353  fprintf(stderr, "JPEG sampling factors must be 1..%d\n", MAX_SAMP_FACTOR);
354  return FALSE;
355  }
356  cinfo->comp_info[ci].h_samp_factor = val1;
357  cinfo->comp_info[ci].v_samp_factor = val2;
358  while (*arg && *arg++ != ',') /* advance to next segment of arg string */
359  ;
360  } else {
361  /* reached end of parameter, set remaining components to 1x1 sampling */
362  cinfo->comp_info[ci].h_samp_factor = 1;
363  cinfo->comp_info[ci].v_samp_factor = 1;
364  }
365  }
366  return TRUE;
367 }
set_quality_ratings(j_compress_ptr cinfo, char *arg, boolean force_baseline)
Definition: rdswitch.c:268
char boolean force_baseline
Definition: cdjpeg.h:134
#define isspace(c)
Definition: acclib.h:69
#define TRUE
Definition: types.h:120
read_quant_tables(j_compress_ptr cinfo, char *filename, boolean force_baseline)
Definition: rdswitch.c:75
#define NUM_QUANT_TBLS
Definition: jpeglib.h:52
text_getc(FILE *file)
Definition: rdswitch.c:23
struct jpeg_common_struct * j_common_ptr
Definition: jpeglib.h:284
const jpeg_scan_info * scan_info
Definition: jpeglib.h:351
_Check_return_ _CRTIMP int __cdecl getc(_Inout_ FILE *_File)
#define MAX_COMPONENTS
Definition: jmorecfg.h:45
const char * filename
Definition: ioapi.h:135
int comps_in_scan
Definition: jpeglib.h:199
jpeg_default_qtables(j_compress_ptr cinfo, boolean force_baseline)
Definition: jcparam.c:91
int component_index[MAX_COMPS_IN_SCAN]
Definition: jpeglib.h:200
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define SIZEOF(_ar)
Definition: calc.h:97
#define JPOOL_IMAGE
Definition: jpeglib.h:808
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
smooth NULL
Definition: ftsmooth.c:416
#define MEMCOPY(dest, src, size)
Definition: jinclude.h:69
_Check_return_opt_ _CRTIMP_ALT int __cdecl ungetc(_In_ int _Ch, _Inout_ FILE *_File)
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
set_sample_factors(j_compress_ptr cinfo, char *arg)
Definition: rdswitch.c:335
read_text_integer(FILE *file, long *result, int *termchar)
Definition: rdswitch.c:40
#define DCTSIZE2
Definition: jpeglib.h:51
#define isdigit(c)
Definition: acclib.h:68
#define LOCAL(type)
Definition: jmorecfg.h:289
GLuint GLfloat * val
Definition: glext.h:7180
#define MAX_SAMP_FACTOR
Definition: jpeglib.h:56
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
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:24
#define GLOBAL(type)
Definition: jmorecfg.h:291
set_quant_slots(j_compress_ptr cinfo, char *arg)
Definition: rdswitch.c:300
#define EOF
Definition: stdio.h:24
FILE * stderr
jpeg_quality_scaling(int quality)
Definition: jcparam.c:123
GLuint64EXT * result
Definition: glext.h:11304
#define MAX_COMPS_IN_SCAN
Definition: jpeglib.h:55
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
Definition: fci.c:126