Merge pull request #118 from dcommander/master

Backward ABI compatibility with libjpeg-turbo
This commit is contained in:
fbossen
2014-11-12 13:31:34 -10:00
30 changed files with 578 additions and 189 deletions

View File

@@ -99,7 +99,7 @@ This will generate the following files under .libs/
cygjpeg-{version}.dll (Cygwin)
Shared library for the libjpeg API
By default, {version} is 62.1.0, 7.1.0, or 8.0.2, depending on whether
By default, {version} is 62.2.0, 7.2.0, or 8.1.2, depending on whether
libjpeg v6b (default), v7, or v8 emulation is enabled. If using Cygwin,
{version} is 62, 7, or 8.

View File

@@ -180,12 +180,12 @@ endif()
#
set(JPEG_SOURCES jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c
jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c jcphuff.c
jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c jdatadst.c jdatasrc.c
jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c
jdmaster.c jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c jerror.c
jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c
jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c)
jccompat.c jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c
jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c jdatadst.c
jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c jdinput.c jdmainct.c
jdmarker.c jdmaster.c jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c
jerror.c jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c
jidctred.c jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c)
if(WITH_ARITH_ENC OR WITH_ARITH_DEC)
set(JPEG_SOURCES ${JPEG_SOURCES} jaricom.c)

View File

@@ -16,13 +16,13 @@ HDRS = jchuff.h jdct.h jdhuff.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
jpeg_nbits_table.h
libjpeg_la_SOURCES = $(HDRS) jcapimin.c jcapistd.c jccoefct.c jccolor.c \
jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c jcmaster.c \
jcomapi.c jcparam.c jcphuff.c jcprepct.c jcsample.c jctrans.c \
jdapimin.c jdapistd.c jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c \
jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c jdmaster.c \
jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c jerror.c \
jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c \
jidctred.c jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c
jccompat.c jcdctmgr.c jchuff.c jcinit.c jcmainct.c jcmarker.c \
jcmaster.c jcomapi.c jcparam.c jcphuff.c jcprepct.c jcsample.c \
jctrans.c jdapimin.c jdapistd.c jdatadst.c jdatasrc.c jdcoefct.c \
jdcolor.c jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c \
jdmaster.c jdmerge.c jdphuff.c jdpostct.c jdsample.c jdtrans.c \
jerror.c jfdctflt.c jfdctfst.c jfdctint.c jidctflt.c jidctfst.c \
jidctint.c jidctred.c jquant1.c jquant2.c jutils.c jmemmgr.c jmemnobs.c
if WITH_ARITH
libjpeg_la_SOURCES += jaricom.c

61
cjpeg.c
View File

@@ -325,10 +325,10 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
cinfo->err->trace_level++;
} else if (keymatch(arg, "fastcrush", 4)) {
cinfo->optimize_scans = FALSE;
jpeg_c_set_bool_param(cinfo, JBOOLEAN_OPTIMIZE_SCANS, FALSE);
} else if (keymatch(arg, "flat", 4)) {
cinfo->use_flat_quant_tbl = TRUE;
jpeg_c_set_bool_param(cinfo, JBOOLEAN_USE_FLAT_QUANT_TBL, TRUE);
jpeg_set_quality(cinfo, 75, TRUE);
} else if (keymatch(arg, "grayscale", 2) || keymatch(arg, "greyscale",2)) {
@@ -342,12 +342,14 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
} else if (keymatch(arg, "lambda1", 7)) {
if (++argn >= argc) /* advance to next argument */
usage();
cinfo->lambda_log_scale1 = atof(argv[argn]);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE1,
atof(argv[argn]));
} else if (keymatch(arg, "lambda2", 7)) {
if (++argn >= argc) /* advance to next argument */
usage();
cinfo->lambda_log_scale2 = atof(argv[argn]);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE2,
atof(argv[argn]));
} else if (keymatch(arg, "maxmemory", 3)) {
/* Maximum memory in Kb (or Mb with 'm'). */
@@ -363,7 +365,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
cinfo->mem->max_memory_to_use = lval * 1000L;
} else if (keymatch(arg, "opt-dc-scan", 6)) {
cinfo->one_dc_scan = FALSE;
jpeg_c_set_bool_param(cinfo, JBOOLEAN_ONE_DC_SCAN, FALSE);
} else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) {
/* Enable entropy parm optimization. */
@@ -450,7 +452,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
} else if (keymatch(arg, "revert", 3)) {
/* revert to old JPEG default */
cinfo->use_moz_defaults = FALSE;
jpeg_c_set_bool_param(cinfo, JBOOLEAN_USE_MOZ_DEFAULTS, FALSE);
jpeg_set_defaults(cinfo);
} else if (keymatch(arg, "sample", 2)) {
@@ -489,8 +491,8 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
cinfo->smoothing_factor = val;
} else if (keymatch(arg, "split-dc-scans", 3)) {
cinfo->one_dc_scan = FALSE;
cinfo->sep_dc_scan = TRUE;
jpeg_c_set_bool_param(cinfo, JBOOLEAN_ONE_DC_SCAN, FALSE);
jpeg_c_set_bool_param(cinfo, JBOOLEAN_SEP_DC_SCAN, TRUE);
} else if (keymatch(arg, "targa", 1)) {
/* Input file is Targa format. */
@@ -498,46 +500,46 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
} else if (keymatch(arg, "notrellis-dc", 11)) {
/* disable trellis quantization */
cinfo->trellis_quant_dc = FALSE;
jpeg_c_set_bool_param(cinfo, JBOOLEAN_TRELLIS_QUANT_DC, FALSE);
} else if (keymatch(arg, "notrellis", 1)) {
/* disable trellis quantization */
cinfo->trellis_quant = FALSE;
jpeg_c_set_bool_param(cinfo, JBOOLEAN_TRELLIS_QUANT, FALSE);
} else if (keymatch(arg, "trellis-dc", 9)) {
/* enable DC trellis quantization */
cinfo->trellis_quant_dc = TRUE;
jpeg_c_set_bool_param(cinfo, JBOOLEAN_TRELLIS_QUANT_DC, TRUE);
} else if (keymatch(arg, "tune-psnr", 6)) {
cinfo->use_flat_quant_tbl = TRUE;
cinfo->lambda_log_scale1 = 9.0;
cinfo->lambda_log_scale2 = 0.0;
cinfo->use_lambda_weight_tbl = FALSE;
jpeg_c_set_bool_param(cinfo, JBOOLEAN_USE_FLAT_QUANT_TBL, TRUE);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE1, 9.0);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE2, 0.0);
jpeg_c_set_bool_param(cinfo, JBOOLEAN_USE_LAMBDA_WEIGHT_TBL, FALSE);
jpeg_set_quality(cinfo, 75, TRUE);
} else if (keymatch(arg, "tune-ssim", 6)) {
cinfo->use_flat_quant_tbl = TRUE;
cinfo->lambda_log_scale1 = 12.0;
cinfo->lambda_log_scale2 = 13.5;
cinfo->use_lambda_weight_tbl = FALSE;
jpeg_c_set_bool_param(cinfo, JBOOLEAN_USE_FLAT_QUANT_TBL, TRUE);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE1, 12.0);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE2, 13.5);
jpeg_c_set_bool_param(cinfo, JBOOLEAN_USE_LAMBDA_WEIGHT_TBL, FALSE);
jpeg_set_quality(cinfo, 75, TRUE);
} else if (keymatch(arg, "tune-ms-ssim", 6)) {
cinfo->use_flat_quant_tbl = FALSE;
cinfo->lambda_log_scale1 = 14.25;
cinfo->lambda_log_scale2 = 12.75;
cinfo->use_lambda_weight_tbl = TRUE;
jpeg_c_set_bool_param(cinfo, JBOOLEAN_USE_FLAT_QUANT_TBL, FALSE);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE1, 14.25);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE2, 12.75);
jpeg_c_set_bool_param(cinfo, JBOOLEAN_USE_LAMBDA_WEIGHT_TBL, TRUE);
jpeg_set_quality(cinfo, 75, TRUE);
} else if (keymatch(arg, "tune-hvs-psnr", 6)) {
cinfo->use_flat_quant_tbl = FALSE;
cinfo->lambda_log_scale1 = 16.0;
cinfo->lambda_log_scale2 = 15.5;
cinfo->use_lambda_weight_tbl = TRUE;
jpeg_c_set_bool_param(cinfo, JBOOLEAN_USE_FLAT_QUANT_TBL, FALSE);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE1, 16.0);
jpeg_c_set_float_param(cinfo, JFLOAT_LAMBDA_LOG_SCALE2, 15.5);
jpeg_c_set_bool_param(cinfo, JBOOLEAN_USE_LAMBDA_WEIGHT_TBL, TRUE);
jpeg_set_quality(cinfo, 75, TRUE);
} else if (keymatch(arg, "noovershoot", 11)) {
cinfo->overshoot_deringing = FALSE;
jpeg_c_set_bool_param(cinfo, JBOOLEAN_OVERSHOOT_DERINGING, FALSE);
} else {
fprintf(stderr, "%s: unknown option '%s'\n", progname, arg);
usage(); /* bogus switch */
@@ -632,7 +634,8 @@ main (int argc, char **argv)
*/
cinfo.in_color_space = JCS_RGB; /* arbitrary guess */
cinfo.use_moz_defaults = TRUE;
if (jpeg_c_bool_param_supported(&cinfo, JBOOLEAN_USE_MOZ_DEFAULTS))
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_USE_MOZ_DEFAULTS, TRUE);
jpeg_set_defaults(&cinfo);
/* Scan command line to find file names.

View File

@@ -189,7 +189,7 @@ fi
RPM_CONFIG_ARGS=
# Memory source/destination managers
SO_AGE=0
SO_AGE=1
MEM_SRCDST_FUNCTIONS=
if test "x${with_jpeg8}" != "xyes"; then
AC_MSG_CHECKING([whether to include in-memory source/destination managers])
@@ -200,7 +200,7 @@ if test "x${with_jpeg8}" != "xyes"; then
AC_MSG_RESULT(yes)
AC_DEFINE([MEM_SRCDST_SUPPORTED], [1],
[Support in-memory source/destination managers])
SO_AGE=1
SO_AGE=2
MEM_SRCDST_FUNCTIONS="global: jpeg_mem_dest; jpeg_mem_src;";
else
AC_MSG_RESULT(no)

View File

@@ -126,7 +126,7 @@ write_JPEG_file (char * filename, int quality)
cinfo.image_height = image_height;
cinfo.input_components = 3; /* # of color components per pixel */
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
cinfo.use_moz_defaults = TRUE; /* use Mozilla defaults for improved compression */
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_USE_MOZ_DEFAULTS, TRUE); /* use Mozilla defaults for improved compression */
/* Now use the library's routine to set default compression parameters.
* (You must set at least cinfo.in_color_space before calling this,

View File

@@ -4,8 +4,8 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1994-1998, Thomas G. Lane.
* Modified 2003-2010 by Guido Vollbeding.
* It was modified by The libjpeg-turbo Project to include only code relevant
* to libjpeg-turbo.
* libjpeg-turbo Modifications:
* Copyright (C) 2014, D. R. Commander.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains application interface code for the compression half
@@ -22,6 +22,7 @@
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
#include "jmemsys.h"
/*
@@ -91,6 +92,13 @@ jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
/* OK, I'm ready */
cinfo->global_state = CSTATE_START;
/* The master struct is used to store extension parameters, so we allocate it
* here. It is later reallocated by jinit_c_master_control().
*/
cinfo->master = (struct jpeg_comp_master *)
jpeg_get_small ((j_common_ptr) cinfo, sizeof(struct jpeg_comp_master));
MEMZERO(cinfo->master, sizeof(struct jpeg_comp_master));
}

View File

@@ -46,8 +46,9 @@ jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)
jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */
/* setting up scan optimisation pattern failed, disable scan optimisation */
if (cinfo->num_scans_luma == 0 || cinfo->scan_info == NULL || cinfo->num_scans == 0)
cinfo->optimize_scans = FALSE;
if (cinfo->master->num_scans_luma == 0 || cinfo->scan_info == NULL ||
cinfo->num_scans == 0)
cinfo->master->optimize_scans = FALSE;
/* (Re)initialize error mgr and destination modules */
(*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);

View File

@@ -402,7 +402,12 @@ compress_trellis_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
*/
for (block_row = 0; block_row < block_rows; block_row++) {
thisblockrow = buffer[block_row];
quantize_trellis(cinfo, dctbl, actbl, thisblockrow, buffer_dst[block_row], blocks_across, cinfo->quant_tbl_ptrs[compptr->quant_tbl_no], cinfo->norm_src[compptr->quant_tbl_no], cinfo->norm_coef[compptr->quant_tbl_no], &lastDC);
quantize_trellis(cinfo, dctbl, actbl, thisblockrow,
buffer_dst[block_row], blocks_across,
cinfo->quant_tbl_ptrs[compptr->quant_tbl_no],
cinfo->master->norm_src[compptr->quant_tbl_no],
cinfo->master->norm_coef[compptr->quant_tbl_no],
&lastDC);
if (ndummy > 0) {
/* Create dummy blocks at the right edge of the image. */

217
jccompat.c Normal file
View File

@@ -0,0 +1,217 @@
/*
* jccompat.c
*
* Copyright (C) 2014, D. R. Commander.
* Copyright (C) 2014, Mozilla Corporation.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains accessor functions for extension parameters. These
* allow for extending the functionality of the libjpeg API without breaking
* backward ABI compatibility.
*/
#define JPEG_INTERNALS
#include "jinclude.h"
#include "jpeglib.h"
GLOBAL(boolean)
jpeg_c_bool_param_supported (j_compress_ptr cinfo, J_BOOLEAN_PARAM param)
{
switch (param) {
case JBOOLEAN_USE_MOZ_DEFAULTS:
case JBOOLEAN_OPTIMIZE_SCANS:
case JBOOLEAN_ONE_DC_SCAN:
case JBOOLEAN_SEP_DC_SCAN:
case JBOOLEAN_TRELLIS_QUANT:
case JBOOLEAN_TRELLIS_QUANT_DC:
case JBOOLEAN_TRELLIS_EOB_OPT:
case JBOOLEAN_USE_FLAT_QUANT_TBL:
case JBOOLEAN_USE_LAMBDA_WEIGHT_TBL:
case JBOOLEAN_USE_SCANS_IN_TRELLIS:
case JBOOLEAN_TRELLIS_PASSES:
case JBOOLEAN_TRELLIS_Q_OPT:
case JBOOLEAN_OVERSHOOT_DERINGING:
return TRUE;
}
return FALSE;
}
GLOBAL(void)
jpeg_c_set_bool_param (j_compress_ptr cinfo, J_BOOLEAN_PARAM param,
boolean value)
{
switch(param) {
case JBOOLEAN_USE_MOZ_DEFAULTS:
cinfo->master->use_moz_defaults = value;
break;
case JBOOLEAN_OPTIMIZE_SCANS:
cinfo->master->optimize_scans = value;
break;
case JBOOLEAN_ONE_DC_SCAN:
cinfo->master->one_dc_scan = value;
break;
case JBOOLEAN_SEP_DC_SCAN:
cinfo->master->sep_dc_scan = value;
break;
case JBOOLEAN_TRELLIS_QUANT:
cinfo->master->trellis_quant = value;
break;
case JBOOLEAN_TRELLIS_QUANT_DC:
cinfo->master->trellis_quant_dc = value;
break;
case JBOOLEAN_TRELLIS_EOB_OPT:
cinfo->master->trellis_eob_opt = value;
break;
case JBOOLEAN_USE_FLAT_QUANT_TBL:
cinfo->master->use_flat_quant_tbl = value;
break;
case JBOOLEAN_USE_LAMBDA_WEIGHT_TBL:
cinfo->master->use_lambda_weight_tbl = value;
break;
case JBOOLEAN_USE_SCANS_IN_TRELLIS:
cinfo->master->use_scans_in_trellis = value;
break;
case JBOOLEAN_TRELLIS_PASSES:
cinfo->master->trellis_passes = value;
break;
case JBOOLEAN_TRELLIS_Q_OPT:
cinfo->master->trellis_q_opt = value;
break;
case JBOOLEAN_OVERSHOOT_DERINGING:
cinfo->master->overshoot_deringing = value;
break;
default:
ERREXIT(cinfo, JERR_BAD_PARAM);
}
}
GLOBAL(boolean)
jpeg_c_get_bool_param (j_compress_ptr cinfo, J_BOOLEAN_PARAM param)
{
switch(param) {
case JBOOLEAN_USE_MOZ_DEFAULTS:
return cinfo->master->use_moz_defaults;
case JBOOLEAN_OPTIMIZE_SCANS:
return cinfo->master->optimize_scans;
case JBOOLEAN_ONE_DC_SCAN:
return cinfo->master->one_dc_scan;
case JBOOLEAN_SEP_DC_SCAN:
return cinfo->master->sep_dc_scan;
case JBOOLEAN_TRELLIS_QUANT:
return cinfo->master->trellis_quant;
case JBOOLEAN_TRELLIS_QUANT_DC:
return cinfo->master->trellis_quant_dc;
case JBOOLEAN_TRELLIS_EOB_OPT:
return cinfo->master->trellis_eob_opt;
case JBOOLEAN_USE_FLAT_QUANT_TBL:
return cinfo->master->use_flat_quant_tbl;
case JBOOLEAN_USE_LAMBDA_WEIGHT_TBL:
return cinfo->master->use_lambda_weight_tbl;
case JBOOLEAN_USE_SCANS_IN_TRELLIS:
return cinfo->master->use_scans_in_trellis;
case JBOOLEAN_TRELLIS_PASSES:
return cinfo->master->trellis_passes;
case JBOOLEAN_TRELLIS_Q_OPT:
return cinfo->master->trellis_q_opt;
case JBOOLEAN_OVERSHOOT_DERINGING:
return cinfo->master->overshoot_deringing;
default:
ERREXIT(cinfo, JERR_BAD_PARAM);
}
return FALSE;
}
GLOBAL(boolean)
jpeg_c_float_param_supported (j_compress_ptr cinfo, J_FLOAT_PARAM param)
{
switch (param) {
case JFLOAT_LAMBDA_LOG_SCALE1:
case JFLOAT_LAMBDA_LOG_SCALE2:
return TRUE;
}
return FALSE;
}
GLOBAL(void)
jpeg_c_set_float_param (j_compress_ptr cinfo, J_FLOAT_PARAM param, float value)
{
switch (param) {
case JFLOAT_LAMBDA_LOG_SCALE1:
cinfo->master->lambda_log_scale1 = value;
break;
case JFLOAT_LAMBDA_LOG_SCALE2:
cinfo->master->lambda_log_scale2 = value;
break;
default:
ERREXIT(cinfo, JERR_BAD_PARAM);
}
}
GLOBAL(float)
jpeg_c_get_float_param (j_compress_ptr cinfo, J_FLOAT_PARAM param)
{
switch (param) {
case JFLOAT_LAMBDA_LOG_SCALE1:
return cinfo->master->lambda_log_scale1;
case JFLOAT_LAMBDA_LOG_SCALE2:
return cinfo->master->lambda_log_scale2;
default:
ERREXIT(cinfo, JERR_BAD_PARAM);
}
return -1;
}
GLOBAL(boolean)
jpeg_c_int_param_supported (j_compress_ptr cinfo, J_INT_PARAM param)
{
switch (param) {
case JINT_TRELLIS_FREQ_SPLIT:
case JINT_TRELLIS_NUM_LOOPS:
return TRUE;
}
return FALSE;
}
GLOBAL(void)
jpeg_c_set_int_param (j_compress_ptr cinfo, J_INT_PARAM param, int value)
{
switch (param) {
case JINT_TRELLIS_FREQ_SPLIT:
cinfo->master->trellis_freq_split = value;
break;
case JINT_TRELLIS_NUM_LOOPS:
cinfo->master->trellis_num_loops = value;
break;
default:
ERREXIT(cinfo, JERR_BAD_PARAM);
}
}
GLOBAL(int)
jpeg_c_get_int_param (j_compress_ptr cinfo, J_INT_PARAM param)
{
switch (param) {
case JINT_TRELLIS_FREQ_SPLIT:
return cinfo->master->trellis_freq_split;
case JINT_TRELLIS_NUM_LOOPS:
return cinfo->master->trellis_num_loops;
default:
ERREXIT(cinfo, JERR_BAD_PARAM);
}
return -1;
}

View File

@@ -889,7 +889,9 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *dctbl, c_derived_tbl *actb
float lambda_base;
float lambda;
float lambda_dc;
const float *lambda_tbl = (cinfo->use_lambda_weight_tbl) ? jpeg_lambda_weights_csf_luma : jpeg_lambda_weights_flat;
const float *lambda_tbl = (cinfo->master->use_lambda_weight_tbl) ?
jpeg_lambda_weights_csf_luma :
jpeg_lambda_weights_flat;
int Ss, Se;
float *accumulated_zero_block_cost = NULL;
float *accumulated_block_cost = NULL;
@@ -912,7 +914,7 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *dctbl, c_derived_tbl *actb
Ss = 1;
if (Se < Ss)
return;
if (cinfo->trellis_eob_opt) {
if (cinfo->master->trellis_eob_opt) {
accumulated_zero_block_cost = (float *)malloc((num_blocks + 1) * sizeof(float));
accumulated_block_cost = (float *)malloc((num_blocks + 1) * sizeof(float));
block_run_start = (int *)malloc(num_blocks * sizeof(int));
@@ -928,7 +930,7 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *dctbl, c_derived_tbl *actb
accumulated_block_cost[0] = 0;
requires_eob[0] = 0;
}
if (cinfo->trellis_quant_dc) {
if (cinfo->master->trellis_quant_dc) {
for (i = 0; i < 3; i++) {
accumulated_dc_cost[i] = (float *)malloc(num_blocks * sizeof(float));
dc_cost_backtrack[i] = (int *)malloc(num_blocks * sizeof(int));
@@ -956,10 +958,11 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *dctbl, c_derived_tbl *actb
}
norm /= 63.0;
if (cinfo->lambda_log_scale2 > 0.0)
lambda = pow(2.0, cinfo->lambda_log_scale1) * lambda_base / (pow(2.0, cinfo->lambda_log_scale2) + norm);
if (cinfo->master->lambda_log_scale2 > 0.0)
lambda = pow(2.0, cinfo->master->lambda_log_scale1) * lambda_base /
(pow(2.0, cinfo->master->lambda_log_scale2) + norm);
else
lambda = pow(2.0, cinfo->lambda_log_scale1-12.0) * lambda_base;
lambda = pow(2.0, cinfo->master->lambda_log_scale1 - 12.0) * lambda_base;
lambda_dc = lambda * lambda_tbl[0];
@@ -967,7 +970,7 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *dctbl, c_derived_tbl *actb
accumulated_cost[Ss-1] = 0.0;
/* Do DC coefficient */
if (cinfo->trellis_quant_dc) {
if (cinfo->master->trellis_quant_dc) {
int sign = src[bi][0] >> 31;
int x = abs(src[bi][0]);
int q = 8 * qtbl->quantval[0];
@@ -1120,7 +1123,7 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *dctbl, c_derived_tbl *actb
i--;
}
if (cinfo->trellis_eob_opt) {
if (cinfo->master->trellis_eob_opt) {
accumulated_zero_block_cost[bi+1] = accumulated_zero_block_cost[bi];
accumulated_zero_block_cost[bi+1] += cost_all_zeros;
requires_eob[bi+1] = has_eob;
@@ -1154,7 +1157,7 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *dctbl, c_derived_tbl *actb
}
}
if (cinfo->trellis_eob_opt) {
if (cinfo->master->trellis_eob_opt) {
int last_block = num_blocks;
best_cost = 1e38;
@@ -1195,7 +1198,7 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *dctbl, c_derived_tbl *actb
free(requires_eob);
}
if (cinfo->trellis_q_opt) {
if (cinfo->master->trellis_q_opt) {
for (bi = 0; bi < num_blocks; bi++) {
for (i = 1; i < DCTSIZE2; i++) {
norm_src[i] += src[bi][i] * coef_blocks[bi][i];
@@ -1204,7 +1207,7 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *dctbl, c_derived_tbl *actb
}
}
if (cinfo->trellis_quant_dc) {
if (cinfo->master->trellis_quant_dc) {
j = 0;
for (i = 1; i < 3; i++) {
if (accumulated_dc_cost[i][num_blocks-1] < accumulated_dc_cost[j][num_blocks-1])
@@ -1291,7 +1294,7 @@ jinit_forward_dct (j_compress_ptr cinfo)
else
fdct->convsamp = convsamp;
if (cinfo->overshoot_deringing) {
if (cinfo->master->overshoot_deringing) {
fdct->preprocess = preprocess_deringing;
} else {
fdct->preprocess = NULL;
@@ -1310,7 +1313,7 @@ jinit_forward_dct (j_compress_ptr cinfo)
else
fdct->float_convsamp = convsamp_float;
if (cinfo->overshoot_deringing) {
if (cinfo->master->overshoot_deringing) {
fdct->float_preprocess = float_preprocess_deringing;
} else {
fdct->float_preprocess = NULL;

View File

@@ -62,7 +62,8 @@ jinit_compress_master (j_compress_ptr cinfo)
/* Need a full-image coefficient buffer in any multi-pass mode. */
jinit_c_coef_controller(cinfo,
(boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding || cinfo->optimize_scans));
(boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding ||
cinfo->master->optimize_scans));
jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
jinit_marker_writer(cinfo);

View File

@@ -192,6 +192,7 @@ emit_multi_dqt (j_compress_ptr cinfo)
int seen[MAX_COMPONENTS] = { 0 };
int fin_prec = 0;
int ci;
int size = 0;
for (ci = 0; ci < cinfo->num_components; ci++) {
int tbl_num = cinfo->comp_info[ci].quant_tbl_no;
@@ -210,7 +211,6 @@ emit_multi_dqt (j_compress_ptr cinfo)
emit_marker(cinfo, M_DQT);
int size = 0;
for (ci = 0; ci < cinfo->num_components; ci++) {
int tbl_num = cinfo->comp_info[ci].quant_tbl_no;

View File

@@ -5,7 +5,7 @@
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2003-2010 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2010, D. R. Commander.
* Copyright (C) 2010, 2014, D. R. Commander.
* mozjpeg Modifications:
* Copyright (C) 2014, Mozilla Corporation.
* For conditions of distribution and use, see the accompanying README file.
@@ -20,6 +20,7 @@
#include "jinclude.h"
#include "jpeglib.h"
#include "jpegcomp.h"
#include "jmemsys.h"
/* Private state */
@@ -193,7 +194,7 @@ validate_script (j_compress_ptr cinfo)
/* -1 until that coefficient has been seen; then last Al for it */
#endif
if (cinfo->optimize_scans) {
if (cinfo->master->optimize_scans) {
cinfo->progressive_mode = TRUE;
/* When we optimize scans, there is redundancy in the scan list
* and this function will fail. Therefore skip all this checking
@@ -332,12 +333,18 @@ select_scan_parameters (j_compress_ptr cinfo)
my_master_ptr master = (my_master_ptr) cinfo->master;
if (master->pass_number < master->pass_number_scan_opt_base) {
cinfo->comps_in_scan = 1;
if (cinfo->use_scans_in_trellis) {
cinfo->cur_comp_info[0] = &cinfo->comp_info[master->pass_number/(4*cinfo->trellis_num_loops)];
cinfo->Ss = (master->pass_number%4 < 2) ? 1 : cinfo->trellis_freq_split+1;
cinfo->Se = (master->pass_number%4 < 2) ? cinfo->trellis_freq_split : DCTSIZE2-1;
if (cinfo->master->use_scans_in_trellis) {
cinfo->cur_comp_info[0] =
&cinfo->comp_info[master->pass_number /
(4 * cinfo->master->trellis_num_loops)];
cinfo->Ss = (master->pass_number % 4 < 2) ?
1 : cinfo->master->trellis_freq_split + 1;
cinfo->Se = (master->pass_number % 4 < 2) ?
cinfo->master->trellis_freq_split : DCTSIZE2 - 1;
} else {
cinfo->cur_comp_info[0] = &cinfo->comp_info[master->pass_number/(2*cinfo->trellis_num_loops)];
cinfo->cur_comp_info[0] =
&cinfo->comp_info[master->pass_number /
(2 * cinfo->master->trellis_num_loops)];
cinfo->Ss = 1;
cinfo->Se = DCTSIZE2-1;
}
@@ -355,13 +362,16 @@ select_scan_parameters (j_compress_ptr cinfo)
cinfo->Se = scanptr->Se;
cinfo->Ah = scanptr->Ah;
cinfo->Al = scanptr->Al;
if (cinfo->optimize_scans) {
if (cinfo->master->optimize_scans) {
/* luma frequency split passes */
if (master->scan_number >= cinfo->num_scans_luma_dc+3*cinfo->Al_max_luma+2 &&
master->scan_number < cinfo->num_scans_luma)
if (master->scan_number >= cinfo->master->num_scans_luma_dc +
3 * cinfo->master->Al_max_luma + 2 &&
master->scan_number < cinfo->master->num_scans_luma)
cinfo->Al = master->best_Al_luma;
/* chroma frequency split passes */
if (master->scan_number >= cinfo->num_scans_luma+cinfo->num_scans_chroma_dc+(6*cinfo->Al_max_chroma+4) &&
if (master->scan_number >= cinfo->master->num_scans_luma +
cinfo->master->num_scans_chroma_dc +
(6 * cinfo->master->Al_max_chroma + 4) &&
master->scan_number < cinfo->num_scans)
cinfo->Al = master->best_Al_chroma;
}
@@ -484,7 +494,8 @@ METHODDEF(void)
prepare_for_pass (j_compress_ptr cinfo)
{
my_master_ptr master = (my_master_ptr) cinfo->master;
cinfo->trellis_passes = master->pass_number < master->pass_number_scan_opt_base;
cinfo->master->trellis_passes =
master->pass_number < master->pass_number_scan_opt_base;
switch (master->pass_type) {
case main_pass:
@@ -537,7 +548,7 @@ prepare_for_pass (j_compress_ptr cinfo)
select_scan_parameters(cinfo);
per_scan_setup(cinfo);
}
if (cinfo->optimize_scans) {
if (cinfo->master->optimize_scans) {
master->saved_dest = cinfo->dest;
cinfo->dest = NULL;
master->scan_size[master->scan_number] = 0;
@@ -553,13 +564,15 @@ prepare_for_pass (j_compress_ptr cinfo)
master->pub.call_pass_startup = FALSE;
break;
case trellis_pass:
if (master->pass_number%(cinfo->num_components*(cinfo->use_scans_in_trellis?4:2)) == 1 && cinfo->trellis_q_opt) {
if (master->pass_number %
(cinfo->num_components * (cinfo->master->use_scans_in_trellis ? 4 : 2)) == 1 &&
cinfo->master->trellis_q_opt) {
int i, j;
for (i = 0; i < NUM_QUANT_TBLS; i++) {
for (j = 1; j < DCTSIZE2; j++) {
cinfo->norm_src[i][j] = 0.0;
cinfo->norm_coef[i][j] = 0.0;
cinfo->master->norm_src[i][j] = 0.0;
cinfo->master->norm_coef[i][j] = 0.0;
}
}
}
@@ -641,8 +654,11 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
my_master_ptr master = (my_master_ptr) cinfo->master;
int base_scan_idx = 0;
int luma_freq_split_scan_start = cinfo->num_scans_luma_dc + 3 * cinfo->Al_max_luma + 2;
int chroma_freq_split_scan_start = cinfo->num_scans_luma+cinfo->num_scans_chroma_dc+(6*cinfo->Al_max_chroma+4);
int luma_freq_split_scan_start = cinfo->master->num_scans_luma_dc +
3 * cinfo->master->Al_max_luma + 2;
int chroma_freq_split_scan_start = cinfo->master->num_scans_luma +
cinfo->master->num_scans_chroma_dc +
(6 * cinfo->master->Al_max_chroma + 4);
if (next_scan_number > 1 && next_scan_number <= luma_freq_split_scan_start) {
if ((next_scan_number - 1) % 3 == 2) {
@@ -663,7 +679,8 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
}
}
} else if (next_scan_number > luma_freq_split_scan_start && next_scan_number <= cinfo->num_scans_luma) {
} else if (next_scan_number > luma_freq_split_scan_start &&
next_scan_number <= cinfo->master->num_scans_luma) {
if (next_scan_number == luma_freq_split_scan_start + 1) {
master->best_freq_split_idx_luma = 0;
master->best_cost = master->scan_size[next_scan_number-1];
@@ -683,21 +700,25 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
if ((idx == 2 && master->best_freq_split_idx_luma == 0) ||
(idx == 3 && master->best_freq_split_idx_luma != 2) ||
(idx == 4 && master->best_freq_split_idx_luma != 4)) {
master->scan_number = cinfo->num_scans_luma - 1;
master->scan_number = cinfo->master->num_scans_luma - 1;
master->pass_number = 2 * master->scan_number + 1 + master->pass_number_scan_opt_base;
master->pub.is_last_pass = (master->pass_number == master->total_passes - 1);
}
}
} else if (cinfo->num_scans > cinfo->num_scans_luma) {
} else if (cinfo->num_scans > cinfo->master->num_scans_luma) {
if (next_scan_number == cinfo->master->num_scans_luma +
cinfo->master->num_scans_chroma_dc) {
base_scan_idx = cinfo->master->num_scans_luma;
if (next_scan_number == cinfo->num_scans_luma+cinfo->num_scans_chroma_dc) {
base_scan_idx = cinfo->num_scans_luma;
master->interleave_chroma_dc = master->scan_size[base_scan_idx] <= master->scan_size[base_scan_idx+1] + master->scan_size[base_scan_idx+2];
} else if (next_scan_number > cinfo->num_scans_luma+cinfo->num_scans_chroma_dc && next_scan_number <= chroma_freq_split_scan_start) {
base_scan_idx = cinfo->num_scans_luma + cinfo->num_scans_chroma_dc;
} else if (next_scan_number > cinfo->master->num_scans_luma +
cinfo->master->num_scans_chroma_dc &&
next_scan_number <= chroma_freq_split_scan_start) {
base_scan_idx = cinfo->master->num_scans_luma +
cinfo->master->num_scans_chroma_dc;
if ((next_scan_number - base_scan_idx) % 6 == 4) {
int Al = (next_scan_number - base_scan_idx) / 6;
int i;
@@ -757,10 +778,11 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
copy_buffer(cinfo, 0);
if (cinfo->num_scans > cinfo->num_scans_luma && !cinfo->one_dc_scan) {
base_scan_idx = cinfo->num_scans_luma;
if (cinfo->num_scans > cinfo->master->num_scans_luma &&
!cinfo->master->one_dc_scan) {
base_scan_idx = cinfo->master->num_scans_luma;
if (master->interleave_chroma_dc && !cinfo->sep_dc_scan)
if (master->interleave_chroma_dc && !cinfo->master->sep_dc_scan)
copy_buffer(cinfo, base_scan_idx);
else {
copy_buffer(cinfo, base_scan_idx+1);
@@ -779,7 +801,7 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
for (Al = master->best_Al_luma-1; Al >= min_Al; Al--)
copy_buffer(cinfo, 3 + 3*Al);
if (cinfo->num_scans > cinfo->num_scans_luma) {
if (cinfo->num_scans > cinfo->master->num_scans_luma) {
if (master->best_freq_split_idx_chroma == 0) {
copy_buffer(cinfo, chroma_freq_split_scan_start);
copy_buffer(cinfo, chroma_freq_split_scan_start+1);
@@ -791,7 +813,8 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
copy_buffer(cinfo, chroma_freq_split_scan_start+4*(master->best_freq_split_idx_chroma-1)+5);
}
base_scan_idx = cinfo->num_scans_luma + cinfo->num_scans_chroma_dc;
base_scan_idx = cinfo->master->num_scans_luma +
cinfo->master->num_scans_chroma_dc;
for (Al = master->best_Al_chroma-1; Al >= min_Al; Al--) {
copy_buffer(cinfo, base_scan_idx + 6*Al + 4);
@@ -802,7 +825,7 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
for (Al = min_Al-1; Al >= 0; Al--) {
copy_buffer(cinfo, 3 + 3*Al);
if (cinfo->num_scans > cinfo->num_scans_luma) {
if (cinfo->num_scans > cinfo->master->num_scans_luma) {
copy_buffer(cinfo, base_scan_idx + 6*Al + 4);
copy_buffer(cinfo, base_scan_idx + 6*Al + 5);
}
@@ -835,7 +858,7 @@ finish_pass_master (j_compress_ptr cinfo)
/* next pass is either output of scan 0 (after optimization)
* or output of scan 1 (if no optimization).
*/
if (cinfo->trellis_quant)
if (cinfo->master->trellis_quant)
master->pass_type = trellis_pass;
else {
master->pass_type = output_pass;
@@ -851,7 +874,7 @@ finish_pass_master (j_compress_ptr cinfo)
/* next pass is either optimization or output of next scan */
if (cinfo->optimize_coding)
master->pass_type = huff_opt_pass;
if (cinfo->optimize_scans) {
if (cinfo->master->optimize_scans) {
(*cinfo->dest->term_destination)(cinfo);
cinfo->dest = master->saved_dest;
select_scans(cinfo, master->scan_number + 1);
@@ -862,13 +885,16 @@ finish_pass_master (j_compress_ptr cinfo)
case trellis_pass:
master->pass_type = (cinfo->optimize_coding || master->pass_number < master->pass_number_scan_opt_base-1) ? huff_opt_pass : output_pass;
if ((master->pass_number+1)%(cinfo->num_components*(cinfo->use_scans_in_trellis?4:2)) == 0 && cinfo->trellis_q_opt) {
if ((master->pass_number + 1) %
(cinfo->num_components * (cinfo->master->use_scans_in_trellis ? 4 : 2)) == 0 &&
cinfo->master->trellis_q_opt) {
int i, j;
for (i = 0; i < NUM_QUANT_TBLS; i++) {
for (j = 1; j < DCTSIZE2; j++) {
if (cinfo->norm_coef[i][j] != 0.0) {
int q = (int)(cinfo->norm_src[i][j] / cinfo->norm_coef[i][j] + 0.5);
if (cinfo->master->norm_coef[i][j] != 0.0) {
int q = (int)(cinfo->master->norm_src[i][j] /
cinfo->master->norm_coef[i][j] + 0.5);
if (q > 254) q = 254;
if (q < 1) q = 1;
cinfo->quant_tbl_ptrs[i]->quantval[j] = q;
@@ -895,6 +921,11 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
master = (my_master_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
sizeof(my_comp_master));
if (cinfo->master) {
MEMCOPY(&master->pub, cinfo->master, sizeof(struct jpeg_comp_master));
jpeg_free_small((j_common_ptr) cinfo, cinfo->master,
sizeof(struct jpeg_comp_master));
}
cinfo->master = (struct jpeg_comp_master *) master;
master->pub.prepare_for_pass = prepare_for_pass;
master->pub.pass_startup = pass_startup;
@@ -937,12 +968,14 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
master->total_passes = cinfo->num_scans;
master->pass_number_scan_opt_base = 0;
if (cinfo->trellis_quant) {
master->pass_number_scan_opt_base = ((cinfo->use_scans_in_trellis) ? 4 : 2) * cinfo->num_components * cinfo->trellis_num_loops;
if (cinfo->master->trellis_quant) {
master->pass_number_scan_opt_base =
((cinfo->master->use_scans_in_trellis) ? 4 : 2) * cinfo->num_components *
cinfo->master->trellis_num_loops;
master->total_passes += master->pass_number_scan_opt_base;
}
if (cinfo->optimize_scans) {
if (cinfo->master->optimize_scans) {
int i;
master->best_Al_chroma = 0;

View File

@@ -136,7 +136,7 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
*/
{
/* Set up two quantization tables using the specified scaling */
if (cinfo->use_flat_quant_tbl) {
if (cinfo->master->use_flat_quant_tbl) {
jpeg_add_quant_table(cinfo, 0, flat_quant_tbl,
scale_factor, force_baseline);
jpeg_add_quant_table(cinfo, 1, flat_quant_tbl,
@@ -248,7 +248,7 @@ jpeg_set_defaults (j_compress_ptr cinfo)
#ifdef C_PROGRESSIVE_SUPPORTED
cinfo->scan_info = NULL;
cinfo->num_scans = 0;
if (!cinfo->use_moz_defaults) {
if (!cinfo->master->use_moz_defaults) {
/* Default is no multiple-scan output */
cinfo->scan_info = NULL;
cinfo->num_scans = 0;
@@ -266,7 +266,7 @@ jpeg_set_defaults (j_compress_ptr cinfo)
cinfo->arith_code = FALSE;
#ifdef ENTROPY_OPT_SUPPORTED
if (cinfo->use_moz_defaults)
if (cinfo->master->use_moz_defaults)
/* By default, do extra passes to optimize entropy coding */
cinfo->optimize_coding = TRUE;
else
@@ -293,7 +293,7 @@ jpeg_set_defaults (j_compress_ptr cinfo)
cinfo->do_fancy_downsampling = TRUE;
#endif
cinfo->overshoot_deringing = cinfo->use_moz_defaults;
cinfo->master->overshoot_deringing = cinfo->master->use_moz_defaults;
/* No input smoothing */
cinfo->smoothing_factor = 0;
@@ -324,26 +324,26 @@ jpeg_set_defaults (j_compress_ptr cinfo)
jpeg_default_colorspace(cinfo);
cinfo->one_dc_scan = TRUE;
cinfo->master->one_dc_scan = TRUE;
#ifdef C_PROGRESSIVE_SUPPORTED
if (cinfo->use_moz_defaults) {
cinfo->optimize_scans = TRUE;
if (cinfo->master->use_moz_defaults) {
cinfo->master->optimize_scans = TRUE;
jpeg_simple_progression(cinfo);
} else
cinfo->optimize_scans = FALSE;
cinfo->master->optimize_scans = FALSE;
#endif
cinfo->trellis_quant = cinfo->use_moz_defaults;
cinfo->lambda_log_scale1 = 16.0;
cinfo->lambda_log_scale2 = 15.5;
cinfo->master->trellis_quant = cinfo->master->use_moz_defaults;
cinfo->master->lambda_log_scale1 = 16.0;
cinfo->master->lambda_log_scale2 = 15.5;
cinfo->use_lambda_weight_tbl = TRUE;
cinfo->use_scans_in_trellis = FALSE;
cinfo->trellis_freq_split = 8;
cinfo->trellis_num_loops = 1;
cinfo->trellis_q_opt = FALSE;
cinfo->trellis_quant_dc = TRUE;
cinfo->master->use_lambda_weight_tbl = TRUE;
cinfo->master->use_scans_in_trellis = FALSE;
cinfo->master->trellis_freq_split = 8;
cinfo->master->trellis_num_loops = 1;
cinfo->master->trellis_q_opt = FALSE;
cinfo->master->trellis_quant_dc = TRUE;
}
@@ -576,7 +576,7 @@ jpeg_search_progression (j_compress_ptr cinfo)
} else if (ncomps == 1) {
nscans = 23;
} else {
cinfo->num_scans_luma = 0;
cinfo->master->num_scans_luma = 0;
return FALSE;
}
@@ -597,10 +597,12 @@ jpeg_search_progression (j_compress_ptr cinfo)
cinfo->scan_info = scanptr;
cinfo->num_scans = nscans;
cinfo->Al_max_luma = 3;
cinfo->num_scans_luma_dc = 1;
cinfo->num_frequency_splits = 5;
cinfo->num_scans_luma = cinfo->num_scans_luma_dc + (3 * cinfo->Al_max_luma + 2) + (2 * cinfo->num_frequency_splits + 1);
cinfo->master->Al_max_luma = 3;
cinfo->master->num_scans_luma_dc = 1;
cinfo->master->num_frequency_splits = 5;
cinfo->master->num_scans_luma =
cinfo->master->num_scans_luma_dc + (3 * cinfo->master->Al_max_luma + 2) +
(2 * cinfo->master->num_frequency_splits + 1);
/* 23 scans for luma */
/* 1 scan for DC */
@@ -611,7 +613,7 @@ jpeg_search_progression (j_compress_ptr cinfo)
/* last 4 done conditionally */
/* luma DC by itself */
if (cinfo->one_dc_scan)
if (cinfo->master->one_dc_scan)
scanptr = fill_dc_scans(scanptr, ncomps, 0, 0);
else
scanptr = fill_dc_scans(scanptr, 1, 0, 0);
@@ -619,7 +621,7 @@ jpeg_search_progression (j_compress_ptr cinfo)
scanptr = fill_a_scan(scanptr, 0, 1, 8, 0, 0);
scanptr = fill_a_scan(scanptr, 0, 9, 63, 0, 0);
for (Al = 0; Al < cinfo->Al_max_luma; Al++) {
for (Al = 0; Al < cinfo->master->Al_max_luma; Al++) {
scanptr = fill_a_scan(scanptr, 0, 1, 63, Al+1, Al);
scanptr = fill_a_scan(scanptr, 0, 1, 8, 0, Al+1);
scanptr = fill_a_scan(scanptr, 0, 9, 63, 0, Al+1);
@@ -627,17 +629,17 @@ jpeg_search_progression (j_compress_ptr cinfo)
scanptr = fill_a_scan(scanptr, 0, 1, 63, 0, 0);
for (i = 0; i < cinfo->num_frequency_splits; i++) {
for (i = 0; i < cinfo->master->num_frequency_splits; i++) {
scanptr = fill_a_scan(scanptr, 0, 1, frequency_split[i], 0, 0);
scanptr = fill_a_scan(scanptr, 0, frequency_split[i]+1, 63, 0, 0);
}
if (ncomps == 1) {
cinfo->Al_max_chroma = 0;
cinfo->num_scans_chroma_dc = 0;
cinfo->master->Al_max_chroma = 0;
cinfo->master->num_scans_chroma_dc = 0;
} else {
cinfo->Al_max_chroma = 2;
cinfo->num_scans_chroma_dc = 3;
cinfo->master->Al_max_chroma = 2;
cinfo->master->num_scans_chroma_dc = 3;
/* 41 scans for chroma */
/* chroma DC combined */
@@ -651,7 +653,7 @@ jpeg_search_progression (j_compress_ptr cinfo)
scanptr = fill_a_scan(scanptr, 2, 1, 8, 0, 0);
scanptr = fill_a_scan(scanptr, 2, 9, 63, 0, 0);
for (Al = 0; Al < cinfo->Al_max_chroma; Al++) {
for (Al = 0; Al < cinfo->master->Al_max_chroma; Al++) {
scanptr = fill_a_scan(scanptr, 1, 1, 63, Al+1, Al);
scanptr = fill_a_scan(scanptr, 2, 1, 63, Al+1, Al);
scanptr = fill_a_scan(scanptr, 1, 1, 8, 0, Al+1);
@@ -663,7 +665,7 @@ jpeg_search_progression (j_compress_ptr cinfo)
scanptr = fill_a_scan(scanptr, 1, 1, 63, 0, 0);
scanptr = fill_a_scan(scanptr, 2, 1, 63, 0, 0);
for (i = 0; i < cinfo->num_frequency_splits; i++) {
for (i = 0; i < cinfo->master->num_frequency_splits; i++) {
scanptr = fill_a_scan(scanptr, 1, 1, frequency_split[i], 0, 0);
scanptr = fill_a_scan(scanptr, 1, frequency_split[i]+1, 63, 0, 0);
scanptr = fill_a_scan(scanptr, 2, 1, frequency_split[i], 0, 0);
@@ -686,7 +688,7 @@ jpeg_simple_progression (j_compress_ptr cinfo)
int nscans;
jpeg_scan_info * scanptr;
if (cinfo->optimize_scans) {
if (cinfo->master->optimize_scans) {
if (jpeg_search_progression(cinfo) == TRUE)
return;
}
@@ -702,7 +704,7 @@ jpeg_simple_progression (j_compress_ptr cinfo)
nscans = 10;
} else {
/* All-purpose script for other color spaces. */
if (cinfo->use_moz_defaults == TRUE) {
if (cinfo->master->use_moz_defaults == TRUE) {
if (ncomps > MAX_COMPS_IN_SCAN)
nscans = 5 * ncomps; /* 2 DC + 4 AC scans per component */
else
@@ -734,12 +736,12 @@ jpeg_simple_progression (j_compress_ptr cinfo)
if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
/* Custom script for YCbCr color images. */
if (cinfo->use_moz_defaults == TRUE) {
if (cinfo->master->use_moz_defaults == TRUE) {
/* scan defined in jpeg_scan_rgb.txt in jpgcrush */
/* Initial DC scan */
if (cinfo->one_dc_scan)
if (cinfo->master->one_dc_scan)
scanptr = fill_dc_scans(scanptr, ncomps, 0, 0);
else if (cinfo->sep_dc_scan) {
else if (cinfo->master->sep_dc_scan) {
scanptr = fill_a_scan(scanptr, 0, 0, 0, 0, 0);
scanptr = fill_a_scan(scanptr, 1, 0, 0, 0, 0);
scanptr = fill_a_scan(scanptr, 2, 0, 0, 0, 0);
@@ -782,7 +784,7 @@ jpeg_simple_progression (j_compress_ptr cinfo)
}
} else {
/* All-purpose script for other color spaces. */
if (cinfo->use_moz_defaults == TRUE) {
if (cinfo->master->use_moz_defaults == TRUE) {
/* scan defined in jpeg_scan_bw.txt in jpgcrush */
/* DC component, no successive approximation */
scanptr = fill_dc_scans(scanptr, ncomps, 0, 0);

View File

@@ -171,7 +171,7 @@ start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
257 * sizeof(long));
MEMZERO(entropy->count_ptrs[tbl], 257 * sizeof(long));
if (cinfo->trellis_passes) {
if (cinfo->master->trellis_passes) {
/* When generating tables for trellis passes, make sure that all */
/* codewords have an assigned length */
int i, j;

View File

@@ -87,7 +87,8 @@ int main(void)
jpeg_create_compress(&cinfo);
cinfo.input_components = 3;
cinfo.use_moz_defaults = TRUE;
if (jpeg_c_bool_param_supported(&cinfo, JBOOLEAN_USE_MOZ_DEFAULTS))
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_USE_MOZ_DEFAULTS, TRUE);
jpeg_set_defaults(&cinfo);
cinfo.in_color_space = JCS_EXT_RGB;
jpeg_default_colorspace(&cinfo);

View File

@@ -6,6 +6,8 @@
* Modified 2000-2009 by Guido Vollbeding.
* It was modified by The libjpeg-turbo Project to include only code relevant
* to libjpeg-turbo.
* mozjpeg Modifications:
* Copyright (C) 2014, Mozilla Corporation.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains library routines for transcoding compression,
@@ -41,8 +43,8 @@ GLOBAL(void)
jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)
{
/* setting up scan optimisation pattern failed, disable scan optimisation */
if (cinfo->num_scans_luma == 0)
cinfo->optimize_scans = FALSE;
if (cinfo->master->num_scans_luma == 0)
cinfo->master->optimize_scans = FALSE;
if (cinfo->global_state != CSTATE_START)
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
@@ -91,7 +93,7 @@ jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
#endif
/* Initialize all parameters to default values */
jpeg_set_defaults(dstinfo);
dstinfo->trellis_quant = FALSE;
dstinfo->master->trellis_quant = FALSE;
/* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
* Fix it to get the right header markers for the image colorspace.

View File

@@ -207,6 +207,7 @@ JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined")
JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code")
#endif
#endif
JMESSAGE(JERR_BAD_PARAM, "Bogus parameter")
#ifdef JMAKE_ENUM_LIST

View File

@@ -57,6 +57,38 @@ struct jpeg_comp_master {
/* State variables made visible to other modules */
boolean call_pass_startup; /* True if pass_startup must be called */
boolean is_last_pass; /* True during last pass */
/* Extension parameters */
boolean use_moz_defaults; /* TRUE=use Mozilla defaults */
boolean optimize_scans; /* TRUE=optimize progressive coding scans */
boolean one_dc_scan; /* TRUE=use a single DC scan interleaving all components */
boolean sep_dc_scan; /* TRUE=each DC scan is separate */
boolean trellis_quant; /* TRUE=use trellis quantization */
boolean trellis_quant_dc; /* TRUE=use trellis quant for DC coefficient */
boolean trellis_eob_opt; /* TRUE=optimize for sequences of EOB */
boolean use_flat_quant_tbl; /* TRUE=use flat quantization table */
boolean use_lambda_weight_tbl; /* TRUE=use lambda weighting table */
boolean use_scans_in_trellis; /* TRUE=use scans in trellis optimization */
boolean trellis_passes; /* TRUE=currently doing trellis-related passes */
boolean trellis_q_opt; /* TRUE=optimize quant table in trellis loop */
boolean overshoot_deringing; /* TRUE=preprocess input to reduce ringing of edges on white background */
double norm_src[NUM_QUANT_TBLS][DCTSIZE2];
double norm_coef[NUM_QUANT_TBLS][DCTSIZE2];
int trellis_freq_split; /* splitting point for frequency in trellis quantization */
int trellis_num_loops; /* number of trellis loops */
int num_scans_luma; /* # of entries in scan_info array pertaining to luma (used when optimize_scans is TRUE */
int num_scans_luma_dc;
int num_scans_chroma_dc;
int num_frequency_splits;
int Al_max_luma; /* maximum value of Al tested when optimizing scans (luma) */
int Al_max_chroma; /* maximum value of Al tested when optimizing scans (chroma) */
float lambda_log_scale1;
float lambda_log_scale2;
};
/* Main buffer control (downsampled-data buffer) */

View File

@@ -265,6 +265,45 @@ typedef enum {
} J_DITHER_MODE;
/* These 32-bit GUIDs and the corresponding jpeg_*_get_*_param()/
* jpeg_*_set_*_param() functions allow for extending the libjpeg API without
* breaking backward ABI compatibility. The actual parameters are stored in
* the opaque jpeg_comp_master and jpeg_decomp_master structs.
*/
/* Boolean extension parameters */
typedef enum {
JBOOLEAN_USE_MOZ_DEFAULTS = 0xAE2F5D7F, /* TRUE=use Mozilla defaults */
JBOOLEAN_OPTIMIZE_SCANS = 0x680C061E, /* TRUE=optimize progressive coding scans */
JBOOLEAN_ONE_DC_SCAN = 0x3DA6A269, /* TRUE=use a single DC scan interleaving all components */
JBOOLEAN_SEP_DC_SCAN = 0xE20DFA9F, /* TRUE=each DC scan is separate */
JBOOLEAN_TRELLIS_QUANT = 0xC5122033, /* TRUE=use trellis quantization */
JBOOLEAN_TRELLIS_QUANT_DC = 0x339D4C0C, /* TRUE=use trellis quant for DC coefficient */
JBOOLEAN_TRELLIS_EOB_OPT = 0xD7F73780, /* TRUE=optimize for sequences of EOB */
JBOOLEAN_USE_FLAT_QUANT_TBL = 0xE807EC6C, /* TRUE=use flat quantization table */
JBOOLEAN_USE_LAMBDA_WEIGHT_TBL = 0x339DB65F, /* TRUE=use lambda weighting table */
JBOOLEAN_USE_SCANS_IN_TRELLIS = 0xFD841435, /* TRUE=use scans in trellis optimization */
JBOOLEAN_TRELLIS_PASSES = 0x3FF8A439, /* TRUE=currently doing trellis-related passes */
JBOOLEAN_TRELLIS_Q_OPT = 0xE12AE269, /* TRUE=optimize quant table in trellis loop */
JBOOLEAN_OVERSHOOT_DERINGING = 0x3F4BBBF9 /* TRUE=preprocess input to reduce ringing of edges on white background */
} J_BOOLEAN_PARAM;
/* Floating point parameters */
typedef enum {
JFLOAT_LAMBDA_LOG_SCALE1 = 0x5B61A599,
JFLOAT_LAMBDA_LOG_SCALE2 = 0xB9BBAE03
} J_FLOAT_PARAM;
/* Integer parameters */
typedef enum {
JINT_TRELLIS_FREQ_SPLIT = 0x6FAFF127, /* splitting point for frequency in trellis quantization */
JINT_TRELLIS_NUM_LOOPS = 0xB63EBF39 /* number of trellis loops */
} J_INT_PARAM;
/* Common fields between JPEG compression and decompression master structs. */
#define jpeg_common_fields \
@@ -374,37 +413,6 @@ struct jpeg_compress_struct {
int smoothing_factor; /* 1..100, or 0 for no input smoothing */
J_DCT_METHOD dct_method; /* DCT algorithm selector */
boolean use_moz_defaults; /* TRUE=use Mozilla defaults */
boolean optimize_scans; /* TRUE=optimize progressive coding scans */
boolean one_dc_scan; /* TRUE=use a single DC scan interleaving all components */
boolean sep_dc_scan; /* TRUE=each DC scan is separate */
boolean trellis_quant; /* TRUE=use trellis quantization */
boolean trellis_quant_dc; /* TRUE=use trellis quant for DC coefficient */
boolean trellis_eob_opt; /* TRUE=optimize for sequences of EOB */
boolean use_flat_quant_tbl; /* TRUE=use flat quantization table */
boolean use_lambda_weight_tbl; /* TRUE=use lambda weighting table */
boolean use_scans_in_trellis; /* TRUE=use scans in trellis optimization */
boolean trellis_passes; /* TRUE=currently doing trellis-related passes */
boolean trellis_q_opt; /* TRUE=optimize quant table in trellis loop */
boolean overshoot_deringing; /* TRUE=preprocess input to reduce ringing of edges on white background */
double norm_src[NUM_QUANT_TBLS][DCTSIZE2];
double norm_coef[NUM_QUANT_TBLS][DCTSIZE2];
int trellis_freq_split; /* splitting point for frequency in trellis quantization */
int trellis_num_loops; /* number of trellis loops */
int num_scans_luma; /* # of entries in scan_info array pertaining to luma (used when optimize_scans is TRUE */
int num_scans_luma_dc;
int num_scans_chroma_dc;
int num_frequency_splits;
int Al_max_luma; /* maximum value of Al tested when optimizing scans (luma) */
int Al_max_chroma; /* maximum value of Al tested when optimizing scans (chroma) */
float lambda_log_scale1;
float lambda_log_scale2;
/* The restart interval can be specified in absolute MCUs by setting
* restart_interval, or in MCU rows by setting restart_in_rows
* (in which case the correct restart_interval will be figured
@@ -1074,6 +1082,27 @@ EXTERN(void) jpeg_destroy (j_common_ptr cinfo);
/* Default restart-marker-resync procedure for use by data source modules */
EXTERN(boolean) jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired);
/* Accessor functions for extension parameters */
EXTERN(boolean) jpeg_c_bool_param_supported (j_compress_ptr cinfo,
J_BOOLEAN_PARAM param);
EXTERN(void) jpeg_c_set_bool_param (j_compress_ptr cinfo,
J_BOOLEAN_PARAM param, boolean value);
EXTERN(boolean) jpeg_c_get_bool_param (j_compress_ptr cinfo,
J_BOOLEAN_PARAM param);
EXTERN(boolean) jpeg_c_float_param_supported (j_compress_ptr cinfo,
J_FLOAT_PARAM param);
EXTERN(void) jpeg_c_set_float_param (j_compress_ptr cinfo, J_FLOAT_PARAM param,
float value);
EXTERN(float) jpeg_c_get_float_param (j_compress_ptr cinfo,
J_FLOAT_PARAM param);
EXTERN(boolean) jpeg_c_int_param_supported (j_compress_ptr cinfo,
J_INT_PARAM param);
EXTERN(void) jpeg_c_set_int_param (j_compress_ptr cinfo, J_INT_PARAM param,
int value);
EXTERN(int) jpeg_c_get_int_param (j_compress_ptr cinfo, J_INT_PARAM param);
/* These marker codes are exported since applications and data source modules
* are likely to want to use them.

View File

@@ -234,7 +234,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
usage();
} else if (keymatch(arg, "fastcrush", 4)) {
cinfo->optimize_scans = FALSE;
jpeg_c_set_bool_param(cinfo, JBOOLEAN_OPTIMIZE_SCANS, FALSE);
} else if (keymatch(arg, "grayscale", 1) || keymatch(arg, "greyscale",1)) {
/* Force to grayscale. */
@@ -310,7 +310,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
} else if (keymatch(arg, "revert", 3)) {
/* revert to old JPEG default */
cinfo->use_moz_defaults = FALSE;
jpeg_c_set_bool_param(cinfo, JBOOLEAN_USE_MOZ_DEFAULTS, FALSE);
} else if (keymatch(arg, "rotate", 2)) {
/* Rotate 90, 180, or 270 degrees (measured clockwise). */
@@ -415,7 +415,8 @@ main (int argc, char **argv)
/* Initialize the JPEG compression object with default error handling. */
dstinfo.err = jpeg_std_error(&jdsterr);
jpeg_create_compress(&dstinfo);
dstinfo.use_moz_defaults = TRUE;
if (jpeg_c_bool_param_supported(&dstinfo, JBOOLEAN_USE_MOZ_DEFAULTS))
jpeg_c_set_bool_param(&dstinfo, JBOOLEAN_USE_MOZ_DEFAULTS, TRUE);
/* Scan command line to find file names.
* It is convenient to use just one switch-parsing routine, but the switch
@@ -469,7 +470,8 @@ main (int argc, char **argv)
#endif
/* Specify data source for decompression */
memsrc = dstinfo.use_moz_defaults; /* needed to revert to original */
if (jpeg_c_bool_param_supported(&dstinfo, JBOOLEAN_USE_MOZ_DEFAULTS))
memsrc = jpeg_c_get_bool_param(&dstinfo, JBOOLEAN_USE_MOZ_DEFAULTS); /* needed to revert to original */
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
if (memsrc) {
size_t nbytes;
@@ -555,7 +557,8 @@ main (int argc, char **argv)
/* Specify data destination for compression */
#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
if (dstinfo.use_moz_defaults)
if (jpeg_c_bool_param_supported(&dstinfo, JBOOLEAN_USE_MOZ_DEFAULTS) &&
jpeg_c_get_bool_param(&dstinfo, JBOOLEAN_USE_MOZ_DEFAULTS))
jpeg_mem_dest(&dstinfo, &outbuffer, &outsize);
else
#endif
@@ -577,7 +580,8 @@ main (int argc, char **argv)
/* Finish compression and release memory */
jpeg_finish_compress(&dstinfo);
if (dstinfo.use_moz_defaults) {
if (jpeg_c_bool_param_supported(&dstinfo, JBOOLEAN_USE_MOZ_DEFAULTS) &&
jpeg_c_get_bool_param(&dstinfo, JBOOLEAN_USE_MOZ_DEFAULTS)) {
size_t nbytes;
unsigned char *buffer = outbuffer;

View File

@@ -314,7 +314,8 @@ static const unsigned int flat_quant_tbl[DCTSIZE2] = {
LOCAL(void)
jpeg_default_qtables (j_compress_ptr cinfo, boolean force_baseline)
{
if (cinfo->use_flat_quant_tbl) {
if (jpeg_c_bool_param_supported(cinfo, JBOOLEAN_USE_FLAT_QUANT_TBL) &&
jpeg_c_get_bool_param(cinfo, JBOOLEAN_USE_FLAT_QUANT_TBL)) {
jpeg_add_quant_table(cinfo, 0, flat_quant_tbl,
q_scale_factor[0], force_baseline);
jpeg_add_quant_table(cinfo, 1, flat_quant_tbl,

View File

@@ -206,7 +206,7 @@ static int setCompDefaults(struct jpeg_compress_struct *cinfo,
}
cinfo->input_components=tjPixelSize[pixelFormat];
cinfo->use_moz_defaults = TRUE;
cinfo->master->use_moz_defaults = TRUE;
jpeg_set_defaults(cinfo);
if((env=getenv("TJ_OPTIMIZE"))!=NULL && strlen(env)>0 && !strcmp(env, "1"))
@@ -241,7 +241,7 @@ static int setCompDefaults(struct jpeg_compress_struct *cinfo,
else jpeg_set_colorspace(cinfo, JCS_YCbCr);
/* Set scan pattern again as colorspace might have changed */
if (cinfo->use_moz_defaults)
if (cinfo->master->use_moz_defaults)
jpeg_simple_progression(cinfo);
cinfo->comp_info[0].h_samp_factor=tjMCUWidth[subsamp]/8;

View File

@@ -102,4 +102,13 @@ EXPORTS
jzero_far @ 101 ;
jpeg_mem_dest @ 102 ;
jpeg_mem_src @ 103 ;
jpeg_c_bool_param_supported @ 200 ;
jpeg_c_set_bool_param @ 201 ;
jpeg_c_get_bool_param @ 202 ;
jpeg_c_float_param_supported @ 203 ;
jpeg_c_set_float_param @ 204 ;
jpeg_c_get_float_param @ 205 ;
jpeg_c_int_param_supported @ 206 ;
jpeg_c_set_int_param @ 207 ;
jpeg_c_get_int_param @ 208 ;
jpeg_float_quality_scaling @ 1000 ;

View File

@@ -100,4 +100,13 @@ EXPORTS
jpeg_write_tables @ 99 ;
jround_up @ 100 ;
jzero_far @ 101 ;
jpeg_c_bool_param_supported @ 200 ;
jpeg_c_set_bool_param @ 201 ;
jpeg_c_get_bool_param @ 202 ;
jpeg_c_float_param_supported @ 203 ;
jpeg_c_set_float_param @ 204 ;
jpeg_c_get_float_param @ 205 ;
jpeg_c_int_param_supported @ 206 ;
jpeg_c_set_int_param @ 207 ;
jpeg_c_get_int_param @ 208 ;
jpeg_float_quality_scaling @ 1000 ;

View File

@@ -104,4 +104,13 @@ EXPORTS
jzero_far @ 103 ;
jpeg_mem_dest @ 104 ;
jpeg_mem_src @ 105 ;
jpeg_c_bool_param_supported @ 200 ;
jpeg_c_set_bool_param @ 201 ;
jpeg_c_get_bool_param @ 202 ;
jpeg_c_float_param_supported @ 203 ;
jpeg_c_set_float_param @ 204 ;
jpeg_c_get_float_param @ 205 ;
jpeg_c_int_param_supported @ 206 ;
jpeg_c_set_int_param @ 207 ;
jpeg_c_get_int_param @ 208 ;
jpeg_float_quality_scaling @ 1000 ;

View File

@@ -102,4 +102,13 @@ EXPORTS
jpeg_write_tables @ 101 ;
jround_up @ 102 ;
jzero_far @ 103 ;
jpeg_c_bool_param_supported @ 200 ;
jpeg_c_set_bool_param @ 201 ;
jpeg_c_get_bool_param @ 202 ;
jpeg_c_float_param_supported @ 203 ;
jpeg_c_set_float_param @ 204 ;
jpeg_c_get_float_param @ 205 ;
jpeg_c_int_param_supported @ 206 ;
jpeg_c_set_int_param @ 207 ;
jpeg_c_get_int_param @ 208 ;
jpeg_float_quality_scaling @ 1000 ;

View File

@@ -105,4 +105,13 @@ EXPORTS
jpeg_write_tables @ 104 ;
jround_up @ 105 ;
jzero_far @ 106 ;
jpeg_c_bool_param_supported @ 200 ;
jpeg_c_set_bool_param @ 201 ;
jpeg_c_get_bool_param @ 202 ;
jpeg_c_float_param_supported @ 203 ;
jpeg_c_set_float_param @ 204 ;
jpeg_c_get_float_param @ 205 ;
jpeg_c_int_param_supported @ 206 ;
jpeg_c_set_int_param @ 207 ;
jpeg_c_get_int_param @ 208 ;
jpeg_float_quality_scaling @ 1000 ;

View File

@@ -217,7 +217,8 @@ int main(int argc, char *argv[]) {
jpeg_stdio_dest(&cinfo, jpg_fd);
cinfo.use_moz_defaults = TRUE;
if (jpeg_c_bool_param_supported(&cinfo, JBOOLEAN_USE_MOZ_DEFAULTS))
jpeg_c_set_bool_param(&cinfo, JBOOLEAN_USE_MOZ_DEFAULTS, TRUE);
cinfo.image_width = luma_width;
cinfo.image_height = luma_height;