Merge pull request #118 from dcommander/master
Backward ABI compatibility with libjpeg-turbo
This commit is contained in:
@@ -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.
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
14
Makefile.am
14
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
|
||||
|
||||
61
cjpeg.c
61
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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
12
jcapimin.c
12
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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
217
jccompat.c
Normal 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;
|
||||
}
|
||||
29
jcdctmgr.c
29
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;
|
||||
|
||||
3
jcinit.c
3
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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
113
jcmaster.c
113
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;
|
||||
|
||||
|
||||
76
jcparam.c
76
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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
1
jerror.h
1
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
|
||||
|
||||
|
||||
32
jpegint.h
32
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) */
|
||||
|
||||
91
jpeglib.h
91
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.
|
||||
|
||||
16
jpegtran.c
16
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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user