4 * This file was part of the Independent JPEG Group's software:
5 * Copyright (C) 1991-1996, Thomas G. Lane.
6 * libjpeg-turbo Modifications:
7 * Copyright (C) 2010, 2018, D. R. Commander.
8 * For conditions of distribution and use, see the accompanying README.ijg
11 * This file contains routines to process some of cjpeg's more complicated
12 * command-line switches. Switches processed here are:
13 * -qtables file Read quantization tables from text file
14 * -scans file Read scan script from text file
15 * -quality N[,N,...] Set quality ratings
16 * -qslots N[,N,...] Set component quantization table selectors
17 * -sample HxV[,HxV,...] Set component sampling factors
20 #include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
21 #include <ctype.h> /* to declare isdigit(), isspace() */
26 /* Read next char, skipping over any comments (# to end of line) */
27 /* A comment/newline sequence is returned as a newline */
35 } while (ch != '\n' && ch != EOF);
42 read_text_integer(FILE *file, long *result, int *termchar)
43 /* Read an unsigned decimal integer from a file, store it in result */
44 /* Reads one trailing character after the integer; returns it in termchar */
49 /* Skip any leading whitespace, detect EOF */
56 } while (isspace(ch));
64 while ((ch = text_getc(file)) != EOF) {
76 #if JPEG_LIB_VERSION < 70
77 static int q_scale_factor[NUM_QUANT_TBLS] = { 100, 100, 100, 100 };
81 read_quant_tables(j_compress_ptr cinfo, char *filename, boolean force_baseline)
82 /* Read a set of quantization tables from the specified file.
83 * The file is plain ASCII text: decimal numbers with whitespace between.
84 * Comments preceded by '#' may be included in the file.
85 * There may be one to NUM_QUANT_TBLS tables in the file, each of 64 values.
86 * The tables are implicitly numbered 0,1,etc.
87 * NOTE: does not affect the qslots mapping, which will default to selecting
88 * table 0 for luminance (or primary) components, 1 for chrominance components.
89 * You must use -qslots if you want a different component->table mapping.
93 int tblno, i, termchar;
95 unsigned int table[DCTSIZE2];
97 if ((fp = fopen(filename, "r")) == NULL) {
98 fprintf(stderr, "Can't open table file %s\n", filename);
103 while (read_text_integer(fp, &val, &termchar)) { /* read 1st element of table */
104 if (tblno >= NUM_QUANT_TBLS) {
105 fprintf(stderr, "Too many tables in file %s\n", filename);
109 table[0] = (unsigned int)val;
110 for (i = 1; i < DCTSIZE2; i++) {
111 if (!read_text_integer(fp, &val, &termchar)) {
112 fprintf(stderr, "Invalid table data in file %s\n", filename);
116 table[i] = (unsigned int)val;
118 #if JPEG_LIB_VERSION >= 70
119 jpeg_add_quant_table(cinfo, tblno, table, cinfo->q_scale_factor[tblno],
122 jpeg_add_quant_table(cinfo, tblno, table, q_scale_factor[tblno],
128 if (termchar != EOF) {
129 fprintf(stderr, "Non-numeric data in file %s\n", filename);
139 #ifdef C_MULTISCAN_FILES_SUPPORTED
142 read_scan_integer(FILE *file, long *result, int *termchar)
143 /* Variant of read_text_integer that always looks for a non-space termchar;
144 * this simplifies parsing of punctuation in scan scripts.
149 if (!read_text_integer(file, result, termchar))
152 while (ch != EOF && isspace(ch))
153 ch = text_getc(file);
154 if (isdigit(ch)) { /* oops, put it back */
155 if (ungetc(ch, file) == EOF)
159 /* Any separators other than ';' and ':' are ignored;
160 * this allows user to insert commas, etc, if desired.
162 if (ch != EOF && ch != ';' && ch != ':')
171 read_scan_script(j_compress_ptr cinfo, char *filename)
172 /* Read a scan script from the specified text file.
173 * Each entry in the file defines one scan to be emitted.
174 * Entries are separated by semicolons ';'.
175 * An entry contains one to four component indexes,
176 * optionally followed by a colon ':' and four progressive-JPEG parameters.
177 * The component indexes denote which component(s) are to be transmitted
178 * in the current scan. The first component has index 0.
179 * Sequential JPEG is used if the progressive-JPEG parameters are omitted.
180 * The file is free format text: any whitespace may appear between numbers
181 * and the ':' and ';' punctuation marks. Also, other punctuation (such
182 * as commas or dashes) can be placed between numbers if desired.
183 * Comments preceded by '#' may be included in the file.
184 * Note: we do very little validity checking here;
185 * jcmaster.c will validate the script parameters.
189 int scanno, ncomps, termchar;
191 jpeg_scan_info *scanptr;
192 #define MAX_SCANS 100 /* quite arbitrary limit */
193 jpeg_scan_info scans[MAX_SCANS];
195 if ((fp = fopen(filename, "r")) == NULL) {
196 fprintf(stderr, "Can't open scan definition file %s\n", filename);
202 while (read_scan_integer(fp, &val, &termchar)) {
203 if (scanno >= MAX_SCANS) {
204 fprintf(stderr, "Too many scans defined in file %s\n", filename);
208 scanptr->component_index[0] = (int)val;
210 while (termchar == ' ') {
211 if (ncomps >= MAX_COMPS_IN_SCAN) {
212 fprintf(stderr, "Too many components in one scan in file %s\n",
217 if (!read_scan_integer(fp, &val, &termchar))
219 scanptr->component_index[ncomps] = (int)val;
222 scanptr->comps_in_scan = ncomps;
223 if (termchar == ':') {
224 if (!read_scan_integer(fp, &val, &termchar) || termchar != ' ')
226 scanptr->Ss = (int)val;
227 if (!read_scan_integer(fp, &val, &termchar) || termchar != ' ')
229 scanptr->Se = (int)val;
230 if (!read_scan_integer(fp, &val, &termchar) || termchar != ' ')
232 scanptr->Ah = (int)val;
233 if (!read_scan_integer(fp, &val, &termchar))
235 scanptr->Al = (int)val;
237 /* set non-progressive parameters */
239 scanptr->Se = DCTSIZE2 - 1;
243 if (termchar != ';' && termchar != EOF) {
245 fprintf(stderr, "Invalid scan entry format in file %s\n", filename);
252 if (termchar != EOF) {
253 fprintf(stderr, "Non-numeric data in file %s\n", filename);
259 /* Stash completed scan list in cinfo structure.
260 * NOTE: for cjpeg's use, JPOOL_IMAGE is the right lifetime for this data,
261 * but if you want to compress multiple images you'd want JPOOL_PERMANENT.
263 scanptr = (jpeg_scan_info *)
264 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
265 scanno * sizeof(jpeg_scan_info));
266 MEMCOPY(scanptr, scans, scanno * sizeof(jpeg_scan_info));
267 cinfo->scan_info = scanptr;
268 cinfo->num_scans = scanno;
275 #endif /* C_MULTISCAN_FILES_SUPPORTED */
278 #if JPEG_LIB_VERSION < 70
279 /* These are the sample quantization tables given in Annex K (Clause K.1) of
280 * Recommendation ITU-T T.81 (1992) | ISO/IEC 10918-1:1994.
281 * The spec says that the values given produce "good" quality, and
282 * when divided by 2, "very good" quality.
284 static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
285 16, 11, 10, 16, 24, 40, 51, 61,
286 12, 12, 14, 19, 26, 58, 60, 55,
287 14, 13, 16, 24, 40, 57, 69, 56,
288 14, 17, 22, 29, 51, 87, 80, 62,
289 18, 22, 37, 56, 68, 109, 103, 77,
290 24, 35, 55, 64, 81, 104, 113, 92,
291 49, 64, 78, 87, 103, 121, 120, 101,
292 72, 92, 95, 98, 112, 100, 103, 99
294 static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
295 17, 18, 24, 47, 99, 99, 99, 99,
296 18, 21, 26, 66, 99, 99, 99, 99,
297 24, 26, 56, 99, 99, 99, 99, 99,
298 47, 66, 99, 99, 99, 99, 99, 99,
299 99, 99, 99, 99, 99, 99, 99, 99,
300 99, 99, 99, 99, 99, 99, 99, 99,
301 99, 99, 99, 99, 99, 99, 99, 99,
302 99, 99, 99, 99, 99, 99, 99, 99
307 jpeg_default_qtables(j_compress_ptr cinfo, boolean force_baseline)
309 jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl, q_scale_factor[0],
311 jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl, q_scale_factor[1],
318 set_quality_ratings(j_compress_ptr cinfo, char *arg, boolean force_baseline)
319 /* Process a quality-ratings parameter string, of the form
321 * If there are more q-table slots than parameters, the last value is replicated.
324 int val = 75; /* default value */
328 for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
330 ch = ','; /* if not set by sscanf, will be ',' */
331 if (sscanf(arg, "%d%c", &val, &ch) < 1)
333 if (ch != ',') /* syntax check */
335 /* Convert user 0-100 rating to percentage scaling */
336 #if JPEG_LIB_VERSION >= 70
337 cinfo->q_scale_factor[tblno] = jpeg_quality_scaling(val);
339 q_scale_factor[tblno] = jpeg_quality_scaling(val);
341 while (*arg && *arg++ != ','); /* advance to next segment of arg
344 /* reached end of parameter, set remaining factors to last value */
345 #if JPEG_LIB_VERSION >= 70
346 cinfo->q_scale_factor[tblno] = jpeg_quality_scaling(val);
348 q_scale_factor[tblno] = jpeg_quality_scaling(val);
352 jpeg_default_qtables(cinfo, force_baseline);
358 set_quant_slots(j_compress_ptr cinfo, char *arg)
359 /* Process a quantization-table-selectors parameter string, of the form
361 * If there are more components than parameters, the last value is replicated.
364 int val = 0; /* default table # */
368 for (ci = 0; ci < MAX_COMPONENTS; ci++) {
370 ch = ','; /* if not set by sscanf, will be ',' */
371 if (sscanf(arg, "%d%c", &val, &ch) < 1)
373 if (ch != ',') /* syntax check */
375 if (val < 0 || val >= NUM_QUANT_TBLS) {
376 fprintf(stderr, "JPEG quantization tables are numbered 0..%d\n",
380 cinfo->comp_info[ci].quant_tbl_no = val;
381 while (*arg && *arg++ != ','); /* advance to next segment of arg
384 /* reached end of parameter, set remaining components to last table */
385 cinfo->comp_info[ci].quant_tbl_no = val;
393 set_sample_factors(j_compress_ptr cinfo, char *arg)
394 /* Process a sample-factors parameter string, of the form
396 * If there are more components than parameters, "1x1" is assumed for the rest.
402 for (ci = 0; ci < MAX_COMPONENTS; ci++) {
404 ch2 = ','; /* if not set by sscanf, will be ',' */
405 if (sscanf(arg, "%d%c%d%c", &val1, &ch1, &val2, &ch2) < 3)
407 if ((ch1 != 'x' && ch1 != 'X') || ch2 != ',') /* syntax check */
409 if (val1 <= 0 || val1 > 4 || val2 <= 0 || val2 > 4) {
410 fprintf(stderr, "JPEG sampling factors must be 1..4\n");
413 cinfo->comp_info[ci].h_samp_factor = val1;
414 cinfo->comp_info[ci].v_samp_factor = val2;
415 while (*arg && *arg++ != ','); /* advance to next segment of arg
418 /* reached end of parameter, set remaining components to 1x1 sampling */
419 cinfo->comp_info[ci].h_samp_factor = 1;
420 cinfo->comp_info[ci].v_samp_factor = 1;