From db2986c96fcebe10c8700081578e5305fd7bc7dc Mon Sep 17 00:00:00 2001 From: DRC Date: Tue, 4 Nov 2014 01:51:15 -0600 Subject: [PATCH] Restore backward ABI compatibility with libjpeg/libjpeg-turbo by moving the mozjpeg-specific parameters into the opaque jpeg_comp_master struct and implementing generic accessor functions for getting/setting those parameters. These functions can be used upstream, if the need for them arises in libjpeg-turbo, and they can also be easily extended to cover future extensions to the decompressor. Note that, in order to use jpeg_comp_master as a repository for extension parameters, cinfo->master is now allocated within the body of jpeg_CreateCompress(). It is later re-allocated in jinit_c_master_control(), because that function (and others in jcmaster.c) use an extended form of jpeg_comp_master, but the existing extension parameters are copied into the new master instance. Similar modifications would need to be made to the decompressor to support the same type of extension framework. --- CMakeLists.txt | 12 +-- Makefile.am | 14 +-- cjpeg.c | 61 +++++------ configure.ac | 4 +- jcapimin.c | 12 ++- jcapistd.c | 5 +- jccoefct.c | 7 +- jccompat.c | 217 +++++++++++++++++++++++++++++++++++++++ jcdctmgr.c | 29 +++--- jcinit.c | 3 +- jcmaster.c | 113 ++++++++++++-------- jcparam.c | 76 +++++++------- jcphuff.c | 2 +- jcstest.c | 3 +- jctrans.c | 8 +- jerror.h | 1 + jpegint.h | 32 ++++++ jpeglib.h | 91 ++++++++++------ jpegtran.c | 16 +-- rdswitch.c | 3 +- turbojpeg.c | 4 +- win/jpeg62-memsrcdst.def | 9 ++ win/jpeg62.def | 9 ++ win/jpeg7-memsrcdst.def | 9 ++ win/jpeg7.def | 9 ++ win/jpeg8.def | 9 ++ yuvjpeg.c | 3 +- 27 files changed, 575 insertions(+), 186 deletions(-) create mode 100644 jccompat.c diff --git a/CMakeLists.txt b/CMakeLists.txt index f0832421..709b90c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/Makefile.am b/Makefile.am index cc5435e2..1b47317c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/cjpeg.c b/cjpeg.c index 49203efa..098dbc32 100644 --- a/cjpeg.c +++ b/cjpeg.c @@ -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. diff --git a/configure.ac b/configure.ac index 12387c6a..5386e5d0 100644 --- a/configure.ac +++ b/configure.ac @@ -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) diff --git a/jcapimin.c b/jcapimin.c index 3b005d3f..b16f9e40 100644 --- a/jcapimin.c +++ b/jcapimin.c @@ -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)); } diff --git a/jcapistd.c b/jcapistd.c index 7c7bc1c3..2cc6d325 100644 --- a/jcapistd.c +++ b/jcapistd.c @@ -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); diff --git a/jccoefct.c b/jccoefct.c index 5d621508..ad8e4e36 100644 --- a/jccoefct.c +++ b/jccoefct.c @@ -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. */ diff --git a/jccompat.c b/jccompat.c new file mode 100644 index 00000000..cce130ef --- /dev/null +++ b/jccompat.c @@ -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; +} diff --git a/jcdctmgr.c b/jcdctmgr.c index d6439823..d64d655f 100644 --- a/jcdctmgr.c +++ b/jcdctmgr.c @@ -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; diff --git a/jcinit.c b/jcinit.c index 6dfb4f70..f5ecf5f5 100644 --- a/jcinit.c +++ b/jcinit.c @@ -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); diff --git a/jcmaster.c b/jcmaster.c index 17058678..37e577cd 100644 --- a/jcmaster.c +++ b/jcmaster.c @@ -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; diff --git a/jcparam.c b/jcparam.c index a299e86e..8af8ae64 100644 --- a/jcparam.c +++ b/jcparam.c @@ -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); diff --git a/jcphuff.c b/jcphuff.c index 4fbb36dd..da2464ad 100644 --- a/jcphuff.c +++ b/jcphuff.c @@ -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; diff --git a/jcstest.c b/jcstest.c index c0eec6e7..79829e6b 100644 --- a/jcstest.c +++ b/jcstest.c @@ -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); diff --git a/jctrans.c b/jctrans.c index 8fffde03..f4be9f3b 100644 --- a/jctrans.c +++ b/jctrans.c @@ -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. diff --git a/jerror.h b/jerror.h index 402613e0..816fdf9a 100644 --- a/jerror.h +++ b/jerror.h @@ -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 diff --git a/jpegint.h b/jpegint.h index 37742dde..bc0d3dbe 100644 --- a/jpegint.h +++ b/jpegint.h @@ -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) */ diff --git a/jpeglib.h b/jpeglib.h index 7d1b90bc..2f000723 100644 --- a/jpeglib.h +++ b/jpeglib.h @@ -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. diff --git a/jpegtran.c b/jpegtran.c index 5ee342db..8275d1a9 100644 --- a/jpegtran.c +++ b/jpegtran.c @@ -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; diff --git a/rdswitch.c b/rdswitch.c index 75b2081c..66f8e59c 100644 --- a/rdswitch.c +++ b/rdswitch.c @@ -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, diff --git a/turbojpeg.c b/turbojpeg.c index 657be0b9..d36ce5e8 100644 --- a/turbojpeg.c +++ b/turbojpeg.c @@ -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; diff --git a/win/jpeg62-memsrcdst.def b/win/jpeg62-memsrcdst.def index 95e33214..d325520b 100644 --- a/win/jpeg62-memsrcdst.def +++ b/win/jpeg62-memsrcdst.def @@ -102,4 +102,13 @@ EXPORTS jzero_far @ 101 ; jpeg_mem_dest @ 102 ; jpeg_mem_src @ 103 ; + jpeg_c_bool_param_supported @ 104 ; + jpeg_c_set_bool_param @ 105 ; + jpeg_c_get_bool_param @ 106 ; + jpeg_c_float_param_supported @ 107 ; + jpeg_c_set_float_param @ 108 ; + jpeg_c_get_float_param @ 109 ; + jpeg_c_int_param_supported @ 110 ; + jpeg_c_set_int_param @ 111 ; + jpeg_c_get_int_param @ 112 ; jpeg_float_quality_scaling @ 1000 ; diff --git a/win/jpeg62.def b/win/jpeg62.def index 7ade3f16..5a56944e 100644 --- a/win/jpeg62.def +++ b/win/jpeg62.def @@ -100,4 +100,13 @@ EXPORTS jpeg_write_tables @ 99 ; jround_up @ 100 ; jzero_far @ 101 ; + jpeg_c_bool_param_supported @ 102 ; + jpeg_c_set_bool_param @ 103 ; + jpeg_c_get_bool_param @ 104 ; + jpeg_c_float_param_supported @ 105 ; + jpeg_c_set_float_param @ 106 ; + jpeg_c_get_float_param @ 107 ; + jpeg_c_int_param_supported @ 108 ; + jpeg_c_set_int_param @ 109 ; + jpeg_c_get_int_param @ 110 ; jpeg_float_quality_scaling @ 1000 ; diff --git a/win/jpeg7-memsrcdst.def b/win/jpeg7-memsrcdst.def index 01815e9d..2a1fff11 100644 --- a/win/jpeg7-memsrcdst.def +++ b/win/jpeg7-memsrcdst.def @@ -104,4 +104,13 @@ EXPORTS jzero_far @ 103 ; jpeg_mem_dest @ 104 ; jpeg_mem_src @ 105 ; + jpeg_c_bool_param_supported @ 106 ; + jpeg_c_set_bool_param @ 107 ; + jpeg_c_get_bool_param @ 108 ; + jpeg_c_float_param_supported @ 109 ; + jpeg_c_set_float_param @ 110 ; + jpeg_c_get_float_param @ 111 ; + jpeg_c_int_param_supported @ 112 ; + jpeg_c_set_int_param @ 113 ; + jpeg_c_get_int_param @ 114 ; jpeg_float_quality_scaling @ 1000 ; diff --git a/win/jpeg7.def b/win/jpeg7.def index 577dd062..bfb5a0e5 100644 --- a/win/jpeg7.def +++ b/win/jpeg7.def @@ -102,4 +102,13 @@ EXPORTS jpeg_write_tables @ 101 ; jround_up @ 102 ; jzero_far @ 103 ; + jpeg_c_bool_param_supported @ 104 ; + jpeg_c_set_bool_param @ 105 ; + jpeg_c_get_bool_param @ 106 ; + jpeg_c_float_param_supported @ 107 ; + jpeg_c_set_float_param @ 108 ; + jpeg_c_get_float_param @ 109 ; + jpeg_c_int_param_supported @ 110 ; + jpeg_c_set_int_param @ 111 ; + jpeg_c_get_int_param @ 112 ; jpeg_float_quality_scaling @ 1000 ; diff --git a/win/jpeg8.def b/win/jpeg8.def index 985cbcb8..9fe8bf7c 100644 --- a/win/jpeg8.def +++ b/win/jpeg8.def @@ -105,4 +105,13 @@ EXPORTS jpeg_write_tables @ 104 ; jround_up @ 105 ; jzero_far @ 106 ; + jpeg_c_bool_param_supported @ 107 ; + jpeg_c_set_bool_param @ 108 ; + jpeg_c_get_bool_param @ 109 ; + jpeg_c_float_param_supported @ 110 ; + jpeg_c_set_float_param @ 111 ; + jpeg_c_get_float_param @ 112 ; + jpeg_c_int_param_supported @ 113 ; + jpeg_c_set_int_param @ 114 ; + jpeg_c_get_int_param @ 115 ; jpeg_float_quality_scaling @ 1000 ; diff --git a/yuvjpeg.c b/yuvjpeg.c index 542ca826..0a94079c 100644 --- a/yuvjpeg.c +++ b/yuvjpeg.c @@ -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;