SAMV71 Xplained Ultra Software Package 1.5

rdswitch.c

00001 /*
00002  * rdswitch.c
00003  *
00004  * Copyright (C) 1991-1996, Thomas G. Lane.
00005  * This file is part of the Independent JPEG Group's software.
00006  * For conditions of distribution and use, see the accompanying README file.
00007  *
00008  * This file contains routines to process some of cjpeg's more complicated
00009  * command-line switches.  Switches processed here are:
00010  *  -qtables file       Read quantization tables from text file
00011  *  -scans file     Read scan script from text file
00012  *  -quality N[,N,...]  Set quality ratings
00013  *  -qslots N[,N,...]   Set component quantization table selectors
00014  *  -sample HxV[,HxV,...]   Set component sampling factors
00015  */
00016 
00017 #include "cdjpeg.h"     /* Common decls for cjpeg/djpeg applications */
00018 #include <ctype.h>      /* to declare isdigit(), isspace() */
00019 
00020 
00021 LOCAL(int)
00022 text_getc (FILE * file)
00023 /* Read next char, skipping over any comments (# to end of line) */
00024 /* A comment/newline sequence is returned as a newline */
00025 {
00026   register int ch;
00027   
00028   ch = getc(file);
00029   if (ch == '#') {
00030     do {
00031       ch = getc(file);
00032     } while (ch != '\n' && ch != EOF);
00033   }
00034   return ch;
00035 }
00036 
00037 
00038 LOCAL(boolean)
00039 read_text_integer (FILE * file, long * result, int * termchar)
00040 /* Read an unsigned decimal integer from a file, store it in result */
00041 /* Reads one trailing character after the integer; returns it in termchar */
00042 {
00043   register int ch;
00044   register long val;
00045   
00046   /* Skip any leading whitespace, detect EOF */
00047   do {
00048     ch = text_getc(file);
00049     if (ch == EOF) {
00050       *termchar = ch;
00051       return FALSE;
00052     }
00053   } while (isspace(ch));
00054   
00055   if (! isdigit(ch)) {
00056     *termchar = ch;
00057     return FALSE;
00058   }
00059 
00060   val = ch - '0';
00061   while ((ch = text_getc(file)) != EOF) {
00062     if (! isdigit(ch))
00063       break;
00064     val *= 10;
00065     val += ch - '0';
00066   }
00067   *result = val;
00068   *termchar = ch;
00069   return TRUE;
00070 }
00071 
00072 
00073 GLOBAL(boolean)
00074 read_quant_tables (j_compress_ptr cinfo, char * filename, boolean force_baseline)
00075 /* Read a set of quantization tables from the specified file.
00076  * The file is plain ASCII text: decimal numbers with whitespace between.
00077  * Comments preceded by '#' may be included in the file.
00078  * There may be one to NUM_QUANT_TBLS tables in the file, each of 64 values.
00079  * The tables are implicitly numbered 0,1,etc.
00080  * NOTE: does not affect the qslots mapping, which will default to selecting
00081  * table 0 for luminance (or primary) components, 1 for chrominance components.
00082  * You must use -qslots if you want a different component->table mapping.
00083  */
00084 {
00085   FILE * fp;
00086   int tblno, i, termchar;
00087   long val;
00088   unsigned int table[DCTSIZE2];
00089 
00090   if ((fp = fopen(filename, "r")) == NULL) {
00091     fprintf(stderr, "Can't open table file %s\n", filename);
00092     return FALSE;
00093   }
00094   tblno = 0;
00095 
00096   while (read_text_integer(fp, &val, &termchar)) { /* read 1st element of table */
00097     if (tblno >= NUM_QUANT_TBLS) {
00098       fprintf(stderr, "Too many tables in file %s\n", filename);
00099       fclose(fp);
00100       return FALSE;
00101     }
00102     table[0] = (unsigned int) val;
00103     for (i = 1; i < DCTSIZE2; i++) {
00104       if (! read_text_integer(fp, &val, &termchar)) {
00105     fprintf(stderr, "Invalid table data in file %s\n", filename);
00106     fclose(fp);
00107     return FALSE;
00108       }
00109       table[i] = (unsigned int) val;
00110     }
00111     jpeg_add_quant_table(cinfo, tblno, table, cinfo->q_scale_factor[tblno],
00112              force_baseline);
00113     tblno++;
00114   }
00115 
00116   if (termchar != EOF) {
00117     fprintf(stderr, "Non-numeric data in file %s\n", filename);
00118     fclose(fp);
00119     return FALSE;
00120   }
00121 
00122   fclose(fp);
00123   return TRUE;
00124 }
00125 
00126 
00127 #ifdef C_MULTISCAN_FILES_SUPPORTED
00128 
00129 LOCAL(boolean)
00130 read_scan_integer (FILE * file, long * result, int * termchar)
00131 /* Variant of read_text_integer that always looks for a non-space termchar;
00132  * this simplifies parsing of punctuation in scan scripts.
00133  */
00134 {
00135   register int ch;
00136 
00137   if (! read_text_integer(file, result, termchar))
00138     return FALSE;
00139   ch = *termchar;
00140   while (ch != EOF && isspace(ch))
00141     ch = text_getc(file);
00142   if (isdigit(ch)) {        /* oops, put it back */
00143     if (ungetc(ch, file) == EOF)
00144       return FALSE;
00145     ch = ' ';
00146   } else {
00147     /* Any separators other than ';' and ':' are ignored;
00148      * this allows user to insert commas, etc, if desired.
00149      */
00150     if (ch != EOF && ch != ';' && ch != ':')
00151       ch = ' ';
00152   }
00153   *termchar = ch;
00154   return TRUE;
00155 }
00156 
00157 
00158 GLOBAL(boolean)
00159 read_scan_script (j_compress_ptr cinfo, char * filename)
00160 /* Read a scan script from the specified text file.
00161  * Each entry in the file defines one scan to be emitted.
00162  * Entries are separated by semicolons ';'.
00163  * An entry contains one to four component indexes,
00164  * optionally followed by a colon ':' and four progressive-JPEG parameters.
00165  * The component indexes denote which component(s) are to be transmitted
00166  * in the current scan.  The first component has index 0.
00167  * Sequential JPEG is used if the progressive-JPEG parameters are omitted.
00168  * The file is free format text: any whitespace may appear between numbers
00169  * and the ':' and ';' punctuation marks.  Also, other punctuation (such
00170  * as commas or dashes) can be placed between numbers if desired.
00171  * Comments preceded by '#' may be included in the file.
00172  * Note: we do very little validity checking here;
00173  * jcmaster.c will validate the script parameters.
00174  */
00175 {
00176   FILE * fp;
00177   int scanno, ncomps, termchar;
00178   long val;
00179   jpeg_scan_info * scanptr;
00180 #define MAX_SCANS  100      /* quite arbitrary limit */
00181   jpeg_scan_info scans[MAX_SCANS];
00182 
00183   if ((fp = fopen(filename, "r")) == NULL) {
00184     fprintf(stderr, "Can't open scan definition file %s\n", filename);
00185     return FALSE;
00186   }
00187   scanptr = scans;
00188   scanno = 0;
00189 
00190   while (read_scan_integer(fp, &val, &termchar)) {
00191     if (scanno >= MAX_SCANS) {
00192       fprintf(stderr, "Too many scans defined in file %s\n", filename);
00193       fclose(fp);
00194       return FALSE;
00195     }
00196     scanptr->component_index[0] = (int) val;
00197     ncomps = 1;
00198     while (termchar == ' ') {
00199       if (ncomps >= MAX_COMPS_IN_SCAN) {
00200     fprintf(stderr, "Too many components in one scan in file %s\n",
00201         filename);
00202     fclose(fp);
00203     return FALSE;
00204       }
00205       if (! read_scan_integer(fp, &val, &termchar))
00206     goto bogus;
00207       scanptr->component_index[ncomps] = (int) val;
00208       ncomps++;
00209     }
00210     scanptr->comps_in_scan = ncomps;
00211     if (termchar == ':') {
00212       if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ')
00213     goto bogus;
00214       scanptr->Ss = (int) val;
00215       if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ')
00216     goto bogus;
00217       scanptr->Se = (int) val;
00218       if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ')
00219     goto bogus;
00220       scanptr->Ah = (int) val;
00221       if (! read_scan_integer(fp, &val, &termchar))
00222     goto bogus;
00223       scanptr->Al = (int) val;
00224     } else {
00225       /* set non-progressive parameters */
00226       scanptr->Ss = 0;
00227       scanptr->Se = DCTSIZE2-1;
00228       scanptr->Ah = 0;
00229       scanptr->Al = 0;
00230     }
00231     if (termchar != ';' && termchar != EOF) {
00232 bogus:
00233       fprintf(stderr, "Invalid scan entry format in file %s\n", filename);
00234       fclose(fp);
00235       return FALSE;
00236     }
00237     scanptr++, scanno++;
00238   }
00239 
00240   if (termchar != EOF) {
00241     fprintf(stderr, "Non-numeric data in file %s\n", filename);
00242     fclose(fp);
00243     return FALSE;
00244   }
00245 
00246   if (scanno > 0) {
00247     /* Stash completed scan list in cinfo structure.
00248      * NOTE: for cjpeg's use, JPOOL_IMAGE is the right lifetime for this data,
00249      * but if you want to compress multiple images you'd want JPOOL_PERMANENT.
00250      */
00251     scanptr = (jpeg_scan_info *)
00252       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00253                   scanno * SIZEOF(jpeg_scan_info));
00254     MEMCOPY(scanptr, scans, scanno * SIZEOF(jpeg_scan_info));
00255     cinfo->scan_info = scanptr;
00256     cinfo->num_scans = scanno;
00257   }
00258 
00259   fclose(fp);
00260   return TRUE;
00261 }
00262 
00263 #endif /* C_MULTISCAN_FILES_SUPPORTED */
00264 
00265 
00266 GLOBAL(boolean)
00267 set_quality_ratings (j_compress_ptr cinfo, char *arg, boolean force_baseline)
00268 /* Process a quality-ratings parameter string, of the form
00269  *     N[,N,...]
00270  * If there are more q-table slots than parameters, the last value is replicated.
00271  */
00272 {
00273   int val = 75;         /* default value */
00274   int tblno;
00275   char ch;
00276 
00277   for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
00278     if (*arg) {
00279       ch = ',';         /* if not set by sscanf, will be ',' */
00280       if (sscanf(arg, "%d%c", &val, &ch) < 1)
00281     return FALSE;
00282       if (ch != ',')        /* syntax check */
00283     return FALSE;
00284       /* Convert user 0-100 rating to percentage scaling */
00285       cinfo->q_scale_factor[tblno] = jpeg_quality_scaling(val);
00286       while (*arg && *arg++ != ',') /* advance to next segment of arg string */
00287     ;
00288     } else {
00289       /* reached end of parameter, set remaining factors to last value */
00290       cinfo->q_scale_factor[tblno] = jpeg_quality_scaling(val);
00291     }
00292   }
00293   jpeg_default_qtables(cinfo, force_baseline);
00294   return TRUE;
00295 }
00296 
00297 
00298 GLOBAL(boolean)
00299 set_quant_slots (j_compress_ptr cinfo, char *arg)
00300 /* Process a quantization-table-selectors parameter string, of the form
00301  *     N[,N,...]
00302  * If there are more components than parameters, the last value is replicated.
00303  */
00304 {
00305   int val = 0;          /* default table # */
00306   int ci;
00307   char ch;
00308 
00309   for (ci = 0; ci < MAX_COMPONENTS; ci++) {
00310     if (*arg) {
00311       ch = ',';         /* if not set by sscanf, will be ',' */
00312       if (sscanf(arg, "%d%c", &val, &ch) < 1)
00313     return FALSE;
00314       if (ch != ',')        /* syntax check */
00315     return FALSE;
00316       if (val < 0 || val >= NUM_QUANT_TBLS) {
00317     fprintf(stderr, "JPEG quantization tables are numbered 0..%d\n",
00318         NUM_QUANT_TBLS-1);
00319     return FALSE;
00320       }
00321       cinfo->comp_info[ci].quant_tbl_no = val;
00322       while (*arg && *arg++ != ',') /* advance to next segment of arg string */
00323     ;
00324     } else {
00325       /* reached end of parameter, set remaining components to last table */
00326       cinfo->comp_info[ci].quant_tbl_no = val;
00327     }
00328   }
00329   return TRUE;
00330 }
00331 
00332 
00333 GLOBAL(boolean)
00334 set_sample_factors (j_compress_ptr cinfo, char *arg)
00335 /* Process a sample-factors parameter string, of the form
00336  *     HxV[,HxV,...]
00337  * If there are more components than parameters, "1x1" is assumed for the rest.
00338  */
00339 {
00340   int ci, val1, val2;
00341   char ch1, ch2;
00342 
00343   for (ci = 0; ci < MAX_COMPONENTS; ci++) {
00344     if (*arg) {
00345       ch2 = ',';        /* if not set by sscanf, will be ',' */
00346       if (sscanf(arg, "%d%c%d%c", &val1, &ch1, &val2, &ch2) < 3)
00347     return FALSE;
00348       if ((ch1 != 'x' && ch1 != 'X') || ch2 != ',') /* syntax check */
00349     return FALSE;
00350       if (val1 <= 0 || val1 > 4 || val2 <= 0 || val2 > 4) {
00351     fprintf(stderr, "JPEG sampling factors must be 1..4\n");
00352     return FALSE;
00353       }
00354       cinfo->comp_info[ci].h_samp_factor = val1;
00355       cinfo->comp_info[ci].v_samp_factor = val2;
00356       while (*arg && *arg++ != ',') /* advance to next segment of arg string */
00357     ;
00358     } else {
00359       /* reached end of parameter, set remaining components to 1x1 sampling */
00360       cinfo->comp_info[ci].h_samp_factor = 1;
00361       cinfo->comp_info[ci].v_samp_factor = 1;
00362     }
00363   }
00364   return TRUE;
00365 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines