ReactOS 0.4.16-dev-106-g10b08aa
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-2019 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
22LOCAL(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
39LOCAL(boolean)
40read_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
74GLOBAL(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
130LOCAL(boolean)
131read_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
159GLOBAL(boolean)
160read_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) {
233bogus:
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 *) (*cinfo->mem->alloc_small)
253 ((j_common_ptr) cinfo, JPOOL_IMAGE, scanno * SIZEOF(jpeg_scan_info));
254 MEMCOPY(scanptr, scans, scanno * SIZEOF(jpeg_scan_info));
255 cinfo->scan_info = scanptr;
256 cinfo->num_scans = scanno;
257 }
258
259 fclose(fp);
260 return TRUE;
261}
262
263#endif /* C_MULTISCAN_FILES_SUPPORTED */
264
265
266GLOBAL(boolean)
268/* Process a quality-ratings parameter string, of the form
269 * N[,N,...]
270 * If there are more q-table slots than parameters, the last value is replicated.
271 */
272{
273 int val = 75; /* default value */
274 int tblno;
275 char ch;
276
277 for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
278 if (*arg) {
279 ch = ','; /* if not set by sscanf, will be ',' */
280 if (sscanf(arg, "%d%c", &val, &ch) < 1)
281 return FALSE;
282 if (ch != ',') /* syntax check */
283 return FALSE;
284 /* Convert user 0-100 rating to percentage scaling */
285 cinfo->q_scale_factor[tblno] = jpeg_quality_scaling(val);
286 while (*arg && *arg++ != ',') /* advance to next segment of arg string */
287 ;
288 } else {
289 /* reached end of parameter, set remaining factors to last value */
290 cinfo->q_scale_factor[tblno] = jpeg_quality_scaling(val);
291 }
292 }
294 return TRUE;
295}
296
297
298GLOBAL(boolean)
300/* Process a quantization-table-selectors parameter string, of the form
301 * N[,N,...]
302 * If there are more components than parameters, the last value is replicated.
303 */
304{
305 int val = 0; /* default table # */
306 int ci;
307 char ch;
308
309 for (ci = 0; ci < MAX_COMPONENTS; ci++) {
310 if (*arg) {
311 ch = ','; /* if not set by sscanf, will be ',' */
312 if (sscanf(arg, "%d%c", &val, &ch) < 1)
313 return FALSE;
314 if (ch != ',') /* syntax check */
315 return FALSE;
316 if (val < 0 || val >= NUM_QUANT_TBLS) {
317 fprintf(stderr, "JPEG quantization tables are numbered 0..%d\n",
319 return FALSE;
320 }
321 cinfo->comp_info[ci].quant_tbl_no = val;
322 while (*arg && *arg++ != ',') /* advance to next segment of arg string */
323 ;
324 } else {
325 /* reached end of parameter, set remaining components to last table */
326 cinfo->comp_info[ci].quant_tbl_no = val;
327 }
328 }
329 return TRUE;
330}
331
332
333GLOBAL(boolean)
335/* Process a sample-factors parameter string, of the form
336 * HxV[,HxV,...]
337 * If there are more components than parameters, "1x1" is assumed for the rest.
338 */
339{
340 int ci, val1, val2;
341 char ch1, ch2;
342
343 for (ci = 0; ci < MAX_COMPONENTS; ci++) {
344 if (*arg) {
345 ch2 = ','; /* if not set by sscanf, will be ',' */
346 if (sscanf(arg, "%d%c%d%c", &val1, &ch1, &val2, &ch2) < 3)
347 return FALSE;
348 if ((ch1 != 'x' && ch1 != 'X') || ch2 != ',') /* syntax check */
349 return FALSE;
350 if (val1 <= 0 || val1 > MAX_SAMP_FACTOR ||
351 val2 <= 0 || val2 > MAX_SAMP_FACTOR) {
352 fprintf(stderr, "JPEG sampling factors must be 1..%d\n", MAX_SAMP_FACTOR);
353 return FALSE;
354 }
355 cinfo->comp_info[ci].h_samp_factor = val1;
356 cinfo->comp_info[ci].v_samp_factor = val2;
357 while (*arg && *arg++ != ',') /* advance to next segment of arg string */
358 ;
359 } else {
360 /* reached end of parameter, set remaining components to 1x1 sampling */
361 cinfo->comp_info[ci].h_samp_factor = 1;
362 cinfo->comp_info[ci].v_samp_factor = 1;
363 }
364 }
365 return TRUE;
366}
#define isspace(c)
Definition: acclib.h:69
#define isdigit(c)
Definition: acclib.h:68
#define SIZEOF(_ar)
Definition: calc.h:97
char boolean force_baseline
Definition: cdjpeg.h:137
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
GLuint GLfloat * val
Definition: glext.h:7180
GLuint64EXT * result
Definition: glext.h:11304
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
_Check_return_ _CRTIMP int __cdecl getc(_Inout_ FILE *_File)
#define EOF
Definition: stdio.h:24
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP_ALT int __cdecl ungetc(_In_ int _Ch, _Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
const char * filename
Definition: ioapi.h:137
jpeg_default_qtables(j_compress_ptr cinfo, boolean force_baseline)
Definition: jcparam.c:91
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
jpeg_quality_scaling(int quality)
Definition: jcparam.c:123
#define MEMCOPY(dest, src, size)
Definition: jinclude.h:69
#define MAX_COMPONENTS
Definition: jmorecfg.h:45
#define LOCAL(type)
Definition: jmorecfg.h:289
#define GLOBAL(type)
Definition: jmorecfg.h:291
struct jpeg_common_struct * j_common_ptr
Definition: jpeglib.h:284
#define MAX_SAMP_FACTOR
Definition: jpeglib.h:56
#define NUM_QUANT_TBLS
Definition: jpeglib.h:52
boolean int tblno
Definition: jpeglib.h:1010
#define JPOOL_IMAGE
Definition: jpeglib.h:808
#define MAX_COMPS_IN_SCAN
Definition: jpeglib.h:55
#define DCTSIZE2
Definition: jpeglib.h:51
read_text_integer(FILE *file, long *result, int *termchar)
Definition: rdswitch.c:40
set_quality_ratings(j_compress_ptr cinfo, char *arg, boolean force_baseline)
Definition: rdswitch.c:267
read_quant_tables(j_compress_ptr cinfo, char *filename, boolean force_baseline)
Definition: rdswitch.c:75
set_sample_factors(j_compress_ptr cinfo, char *arg)
Definition: rdswitch.c:334
set_quant_slots(j_compress_ptr cinfo, char *arg)
Definition: rdswitch.c:299
text_getc(FILE *file)
Definition: rdswitch.c:23
Definition: fci.c:127
const jpeg_scan_info * scan_info
Definition: jpeglib.h:351
int component_index[MAX_COMPS_IN_SCAN]
Definition: jpeglib.h:200
int comps_in_scan
Definition: jpeglib.h:199