Add option for setting luminance & chrominance quality independently (currently only works if using libjpeg v7 or v8 code base)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@248 632fc199-4ca6-4c93-a231-07263d6284db
This commit is contained in:
5
cdjpeg.h
5
cdjpeg.h
@@ -104,6 +104,7 @@ typedef struct cdjpeg_progress_mgr * cd_progress_ptr;
|
|||||||
#define jinit_write_targa jIWrTarga
|
#define jinit_write_targa jIWrTarga
|
||||||
#define read_quant_tables RdQTables
|
#define read_quant_tables RdQTables
|
||||||
#define read_scan_script RdScnScript
|
#define read_scan_script RdScnScript
|
||||||
|
#define set_quality_ratings SetQRates
|
||||||
#define set_quant_slots SetQSlots
|
#define set_quant_slots SetQSlots
|
||||||
#define set_sample_factors SetSFacts
|
#define set_sample_factors SetSFacts
|
||||||
#define read_color_map RdCMap
|
#define read_color_map RdCMap
|
||||||
@@ -131,8 +132,10 @@ EXTERN(djpeg_dest_ptr) jinit_write_targa JPP((j_decompress_ptr cinfo));
|
|||||||
/* cjpeg support routines (in rdswitch.c) */
|
/* cjpeg support routines (in rdswitch.c) */
|
||||||
|
|
||||||
EXTERN(boolean) read_quant_tables JPP((j_compress_ptr cinfo, char * filename,
|
EXTERN(boolean) read_quant_tables JPP((j_compress_ptr cinfo, char * filename,
|
||||||
int scale_factor, boolean force_baseline));
|
boolean force_baseline));
|
||||||
EXTERN(boolean) read_scan_script JPP((j_compress_ptr cinfo, char * filename));
|
EXTERN(boolean) read_scan_script JPP((j_compress_ptr cinfo, char * filename));
|
||||||
|
EXTERN(boolean) set_quality_ratings JPP((j_compress_ptr cinfo, char *arg,
|
||||||
|
boolean force_baseline));
|
||||||
EXTERN(boolean) set_quant_slots JPP((j_compress_ptr cinfo, char *arg));
|
EXTERN(boolean) set_quant_slots JPP((j_compress_ptr cinfo, char *arg));
|
||||||
EXTERN(boolean) set_sample_factors JPP((j_compress_ptr cinfo, char *arg));
|
EXTERN(boolean) set_sample_factors JPP((j_compress_ptr cinfo, char *arg));
|
||||||
|
|
||||||
|
|||||||
40
cjpeg.1
40
cjpeg.1
@@ -1,4 +1,4 @@
|
|||||||
.TH CJPEG 1 "20 March 1998"
|
.TH CJPEG 1 "30 December 2009"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
cjpeg \- compress an image file to a JPEG file
|
cjpeg \- compress an image file to a JPEG file
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@@ -36,7 +36,7 @@ though for brevity these are not mentioned below.
|
|||||||
.PP
|
.PP
|
||||||
The basic switches are:
|
The basic switches are:
|
||||||
.TP
|
.TP
|
||||||
.BI \-quality " N"
|
.BI \-quality " N[,...]"
|
||||||
Scale quantization tables to adjust image quality. Quality is 0 (worst) to
|
Scale quantization tables to adjust image quality. Quality is 0 (worst) to
|
||||||
100 (best); default is 75. (See below for more info.)
|
100 (best); default is 75. (See below for more info.)
|
||||||
.TP
|
.TP
|
||||||
@@ -109,6 +109,34 @@ other JPEG programs may be unable to decode the resulting file. Use
|
|||||||
if you need to ensure compatibility at low quality values.)
|
if you need to ensure compatibility at low quality values.)
|
||||||
.PP
|
.PP
|
||||||
The
|
The
|
||||||
|
.B \-quality
|
||||||
|
option has been extended in IJG version 7 for support of separate quality
|
||||||
|
settings for luminance and chrominance (or in general, for every provided
|
||||||
|
quantization table slot). This feature is useful for high-quality
|
||||||
|
applications which cannot accept the damage of color data by coarse
|
||||||
|
subsampling settings. You can now easily reduce the color data amount more
|
||||||
|
smoothly with finer control without separate subsampling. The resulting file
|
||||||
|
is fully compliant with standard JPEG decoders.
|
||||||
|
Note that the
|
||||||
|
.B \-quality
|
||||||
|
ratings refer to the quantization table slots, and that the last value is
|
||||||
|
replicated if there are more q-table slots than parameters. The default
|
||||||
|
q-table slots are 0 for luminance and 1 for chrominance with default tables as
|
||||||
|
given in the JPEG standard. This is compatible with the old behaviour in case
|
||||||
|
that only one parameter is given, which is then used for both luminance and
|
||||||
|
chrominance (slots 0 and 1). More or custom quantization tables can be set
|
||||||
|
with
|
||||||
|
.B \-qtables
|
||||||
|
and assigned to components with
|
||||||
|
.B \-qslots
|
||||||
|
parameter (see the "wizard" switches below).
|
||||||
|
.B Caution:
|
||||||
|
You must explicitly add
|
||||||
|
.BI \-sample " 1x1"
|
||||||
|
for efficient separate color
|
||||||
|
quality selection, since the default value used by library is 2x2!
|
||||||
|
.PP
|
||||||
|
The
|
||||||
.B \-progressive
|
.B \-progressive
|
||||||
switch creates a "progressive JPEG" file. In this type of JPEG file, the data
|
switch creates a "progressive JPEG" file. In this type of JPEG file, the data
|
||||||
is stored in multiple scans of increasing quality. If the file is being
|
is stored in multiple scans of increasing quality. If the file is being
|
||||||
@@ -117,9 +145,6 @@ scan to display a low-quality image very quickly, and can then improve the
|
|||||||
display with each subsequent scan. The final image is exactly equivalent to a
|
display with each subsequent scan. The final image is exactly equivalent to a
|
||||||
standard JPEG file of the same quality setting, and the total file size is
|
standard JPEG file of the same quality setting, and the total file size is
|
||||||
about the same --- often a little smaller.
|
about the same --- often a little smaller.
|
||||||
.B Caution:
|
|
||||||
progressive JPEG is not yet widely implemented, so many decoders will be
|
|
||||||
unable to view a progressive JPEG file at all.
|
|
||||||
.PP
|
.PP
|
||||||
Switches for advanced users:
|
Switches for advanced users:
|
||||||
.TP
|
.TP
|
||||||
@@ -279,8 +304,7 @@ Independent JPEG Group
|
|||||||
Arithmetic coding is not supported for legal reasons.
|
Arithmetic coding is not supported for legal reasons.
|
||||||
.PP
|
.PP
|
||||||
GIF input files are no longer supported, to avoid the Unisys LZW patent.
|
GIF input files are no longer supported, to avoid the Unisys LZW patent.
|
||||||
Use a Unisys-licensed program if you need to read a GIF file. (Conversion
|
(Conversion of GIF files to JPEG is usually a bad idea anyway.)
|
||||||
of GIF files to JPEG is usually a bad idea anyway.)
|
|
||||||
.PP
|
.PP
|
||||||
Not all variants of BMP and Targa file formats are supported.
|
Not all variants of BMP and Targa file formats are supported.
|
||||||
.PP
|
.PP
|
||||||
@@ -288,5 +312,3 @@ The
|
|||||||
.B \-targa
|
.B \-targa
|
||||||
switch is not a bug, it's a feature. (It would be a bug if the Targa format
|
switch is not a bug, it's a feature. (It would be a bug if the Targa format
|
||||||
designers had not been clueless.)
|
designers had not been clueless.)
|
||||||
.PP
|
|
||||||
Still not as fast as we'd like.
|
|
||||||
|
|||||||
28
cjpeg.c
28
cjpeg.c
@@ -2,6 +2,7 @@
|
|||||||
* cjpeg.c
|
* cjpeg.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 1991-1998, Thomas G. Lane.
|
* Copyright (C) 1991-1998, Thomas G. Lane.
|
||||||
|
* Modified 2003-2008 by Guido Vollbeding.
|
||||||
* Copyright (C) 2010, D. R. Commander.
|
* Copyright (C) 2010, D. R. Commander.
|
||||||
* This file is part of the Independent JPEG Group's software.
|
* This file is part of the Independent JPEG Group's software.
|
||||||
* For conditions of distribution and use, see the accompanying README file.
|
* For conditions of distribution and use, see the accompanying README file.
|
||||||
@@ -151,7 +152,7 @@ usage (void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
fprintf(stderr, "Switches (names may be abbreviated):\n");
|
fprintf(stderr, "Switches (names may be abbreviated):\n");
|
||||||
fprintf(stderr, " -quality N Compression quality (0..100; 5-95 is useful range)\n");
|
fprintf(stderr, " -quality N[,...] Compression quality (0..100; 5-95 is useful range)\n");
|
||||||
fprintf(stderr, " -grayscale Create monochrome JPEG file\n");
|
fprintf(stderr, " -grayscale Create monochrome JPEG file\n");
|
||||||
#ifdef ENTROPY_OPT_SUPPORTED
|
#ifdef ENTROPY_OPT_SUPPORTED
|
||||||
fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n");
|
fprintf(stderr, " -optimize Optimize Huffman table (smaller file, but slow compression)\n");
|
||||||
@@ -211,21 +212,16 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
|
|||||||
{
|
{
|
||||||
int argn;
|
int argn;
|
||||||
char * arg;
|
char * arg;
|
||||||
int quality; /* -quality parameter */
|
|
||||||
int q_scale_factor; /* scaling percentage for -qtables */
|
|
||||||
boolean force_baseline;
|
boolean force_baseline;
|
||||||
boolean simple_progressive;
|
boolean simple_progressive;
|
||||||
|
char * qualityarg = NULL; /* saves -quality parm if any */
|
||||||
char * qtablefile = NULL; /* saves -qtables filename if any */
|
char * qtablefile = NULL; /* saves -qtables filename if any */
|
||||||
char * qslotsarg = NULL; /* saves -qslots parm if any */
|
char * qslotsarg = NULL; /* saves -qslots parm if any */
|
||||||
char * samplearg = NULL; /* saves -sample parm if any */
|
char * samplearg = NULL; /* saves -sample parm if any */
|
||||||
char * scansarg = NULL; /* saves -scans parm if any */
|
char * scansarg = NULL; /* saves -scans parm if any */
|
||||||
|
|
||||||
/* Set up default JPEG parameters. */
|
/* Set up default JPEG parameters. */
|
||||||
/* Note that default -quality level need not, and does not,
|
|
||||||
* match the default scaling for an explicit -qtables argument.
|
|
||||||
*/
|
|
||||||
quality = 75; /* default -quality value */
|
|
||||||
q_scale_factor = 100; /* default to no scaling for -qtables */
|
|
||||||
force_baseline = FALSE; /* by default, allow 16-bit quantizers */
|
force_baseline = FALSE; /* by default, allow 16-bit quantizers */
|
||||||
simple_progressive = FALSE;
|
simple_progressive = FALSE;
|
||||||
is_targa = FALSE;
|
is_targa = FALSE;
|
||||||
@@ -333,13 +329,10 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
} else if (keymatch(arg, "quality", 1)) {
|
} else if (keymatch(arg, "quality", 1)) {
|
||||||
/* Quality factor (quantization table scaling factor). */
|
/* Quality ratings (quantization table scaling factors). */
|
||||||
if (++argn >= argc) /* advance to next argument */
|
if (++argn >= argc) /* advance to next argument */
|
||||||
usage();
|
usage();
|
||||||
if (sscanf(argv[argn], "%d", &quality) != 1)
|
qualityarg = argv[argn];
|
||||||
usage();
|
|
||||||
/* Change scale factor in case -qtables is present. */
|
|
||||||
q_scale_factor = jpeg_quality_scaling(quality);
|
|
||||||
|
|
||||||
} else if (keymatch(arg, "qslots", 2)) {
|
} else if (keymatch(arg, "qslots", 2)) {
|
||||||
/* Quantization table slot numbers. */
|
/* Quantization table slot numbers. */
|
||||||
@@ -387,7 +380,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
|
|||||||
* default sampling factors.
|
* default sampling factors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
} else if (keymatch(arg, "scans", 2)) {
|
} else if (keymatch(arg, "scans", 4)) {
|
||||||
/* Set scan script. */
|
/* Set scan script. */
|
||||||
#ifdef C_MULTISCAN_FILES_SUPPORTED
|
#ifdef C_MULTISCAN_FILES_SUPPORTED
|
||||||
if (++argn >= argc) /* advance to next argument */
|
if (++argn >= argc) /* advance to next argument */
|
||||||
@@ -427,11 +420,12 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
|
|||||||
|
|
||||||
/* Set quantization tables for selected quality. */
|
/* Set quantization tables for selected quality. */
|
||||||
/* Some or all may be overridden if -qtables is present. */
|
/* Some or all may be overridden if -qtables is present. */
|
||||||
jpeg_set_quality(cinfo, quality, force_baseline);
|
if (qualityarg != NULL) /* process -quality if it was present */
|
||||||
|
if (! set_quality_ratings(cinfo, qualityarg, force_baseline))
|
||||||
|
usage();
|
||||||
|
|
||||||
if (qtablefile != NULL) /* process -qtables if it was present */
|
if (qtablefile != NULL) /* process -qtables if it was present */
|
||||||
if (! read_quant_tables(cinfo, qtablefile,
|
if (! read_quant_tables(cinfo, qtablefile, force_baseline))
|
||||||
q_scale_factor, force_baseline))
|
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
if (qslotsarg != NULL) /* process -qslots if it was present */
|
if (qslotsarg != NULL) /* process -qslots if it was present */
|
||||||
|
|||||||
55
rdswitch.c
55
rdswitch.c
@@ -9,6 +9,7 @@
|
|||||||
* command-line switches. Switches processed here are:
|
* command-line switches. Switches processed here are:
|
||||||
* -qtables file Read quantization tables from text file
|
* -qtables file Read quantization tables from text file
|
||||||
* -scans file Read scan script from text file
|
* -scans file Read scan script from text file
|
||||||
|
* -quality N[,N,...] Set quality ratings
|
||||||
* -qslots N[,N,...] Set component quantization table selectors
|
* -qslots N[,N,...] Set component quantization table selectors
|
||||||
* -sample HxV[,HxV,...] Set component sampling factors
|
* -sample HxV[,HxV,...] Set component sampling factors
|
||||||
*/
|
*/
|
||||||
@@ -69,9 +70,12 @@ read_text_integer (FILE * file, long * result, int * termchar)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if JPEG_LIB_VERSION < 70
|
||||||
|
static int q_scale_factor = 100;
|
||||||
|
#endif
|
||||||
|
|
||||||
GLOBAL(boolean)
|
GLOBAL(boolean)
|
||||||
read_quant_tables (j_compress_ptr cinfo, char * filename,
|
read_quant_tables (j_compress_ptr cinfo, char * filename, boolean force_baseline)
|
||||||
int scale_factor, boolean force_baseline)
|
|
||||||
/* Read a set of quantization tables from the specified file.
|
/* Read a set of quantization tables from the specified file.
|
||||||
* The file is plain ASCII text: decimal numbers with whitespace between.
|
* The file is plain ASCII text: decimal numbers with whitespace between.
|
||||||
* Comments preceded by '#' may be included in the file.
|
* Comments preceded by '#' may be included in the file.
|
||||||
@@ -108,7 +112,12 @@ read_quant_tables (j_compress_ptr cinfo, char * filename,
|
|||||||
}
|
}
|
||||||
table[i] = (unsigned int) val;
|
table[i] = (unsigned int) val;
|
||||||
}
|
}
|
||||||
jpeg_add_quant_table(cinfo, tblno, table, scale_factor, force_baseline);
|
#if JPEG_LIB_VERSION >= 70
|
||||||
|
jpeg_add_quant_table(cinfo, tblno, table, cinfo->q_scale_factor[tblno],
|
||||||
|
force_baseline);
|
||||||
|
#else
|
||||||
|
jpeg_add_quant_table(cinfo, tblno, table, q_scale_factor, force_baseline);
|
||||||
|
#endif
|
||||||
tblno++;
|
tblno++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,6 +271,46 @@ bogus:
|
|||||||
#endif /* C_MULTISCAN_FILES_SUPPORTED */
|
#endif /* C_MULTISCAN_FILES_SUPPORTED */
|
||||||
|
|
||||||
|
|
||||||
|
GLOBAL(boolean)
|
||||||
|
set_quality_ratings (j_compress_ptr cinfo, char *arg, boolean force_baseline)
|
||||||
|
/* Process a quality-ratings parameter string, of the form
|
||||||
|
* N[,N,...]
|
||||||
|
* If there are more q-table slots than parameters, the last value is replicated.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int val = 75; /* default value */
|
||||||
|
int tblno;
|
||||||
|
char ch;
|
||||||
|
|
||||||
|
for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
|
||||||
|
if (*arg) {
|
||||||
|
ch = ','; /* if not set by sscanf, will be ',' */
|
||||||
|
if (sscanf(arg, "%d%c", &val, &ch) < 1)
|
||||||
|
return FALSE;
|
||||||
|
if (ch != ',') /* syntax check */
|
||||||
|
return FALSE;
|
||||||
|
/* Convert user 0-100 rating to percentage scaling */
|
||||||
|
#if JPEG_LIB_VERSION >= 70
|
||||||
|
cinfo->q_scale_factor[tblno] = jpeg_quality_scaling(val);
|
||||||
|
#endif
|
||||||
|
while (*arg && *arg++ != ',') /* advance to next segment of arg string */
|
||||||
|
;
|
||||||
|
} else {
|
||||||
|
/* reached end of parameter, set remaining factors to last value */
|
||||||
|
#if JPEG_LIB_VERSION >= 70
|
||||||
|
cinfo->q_scale_factor[tblno] = jpeg_quality_scaling(val);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if JPEG_LIB_VERSION >= 70
|
||||||
|
jpeg_default_qtables(cinfo, force_baseline);
|
||||||
|
#else
|
||||||
|
jpeg_set_quality(cinfo, val, force_baseline);
|
||||||
|
#endif
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GLOBAL(boolean)
|
GLOBAL(boolean)
|
||||||
set_quant_slots (j_compress_ptr cinfo, char *arg)
|
set_quant_slots (j_compress_ptr cinfo, char *arg)
|
||||||
/* Process a quantization-table-selectors parameter string, of the form
|
/* Process a quantization-table-selectors parameter string, of the form
|
||||||
|
|||||||
Reference in New Issue
Block a user