Initial version of scan optimisation
First implementation of scan optimisation as done by jpgcrush. Many parameters are currently hardcoded which should be changed. Implementation is missing for monochrome.
This commit is contained in:
4
jcinit.c
4
jcinit.c
@@ -3,6 +3,8 @@
|
||||
*
|
||||
* Copyright (C) 1991-1997, Thomas G. Lane.
|
||||
* This file is part of the Independent JPEG Group's software.
|
||||
* mozjpeg Modifications:
|
||||
* Copyright (C) 2014, Mozilla Corporation.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file contains initialization logic for the JPEG compressor.
|
||||
@@ -60,7 +62,7 @@ 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));
|
||||
(boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding || cinfo->optimize_scans));
|
||||
jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
|
||||
|
||||
jinit_marker_writer(cinfo);
|
||||
|
||||
217
jcmaster.c
217
jcmaster.c
@@ -6,6 +6,8 @@
|
||||
* Modified 2003-2010 by Guido Vollbeding.
|
||||
* libjpeg-turbo Modifications:
|
||||
* Copyright (C) 2010, D. R. Commander.
|
||||
* mozjpeg Modifications:
|
||||
* Copyright (C) 2014, Mozilla Corporation.
|
||||
* For conditions of distribution and use, see the accompanying README file.
|
||||
*
|
||||
* This file contains master control logic for the JPEG compressor.
|
||||
@@ -177,6 +179,14 @@ validate_script (j_compress_ptr cinfo)
|
||||
/* -1 until that coefficient has been seen; then last Al for it */
|
||||
#endif
|
||||
|
||||
if (cinfo->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
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (cinfo->num_scans <= 0)
|
||||
ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0);
|
||||
|
||||
@@ -488,6 +498,14 @@ prepare_for_pass (j_compress_ptr cinfo)
|
||||
select_scan_parameters(cinfo);
|
||||
per_scan_setup(cinfo);
|
||||
}
|
||||
if (cinfo->optimize_scans) {
|
||||
cinfo->saved_dest = cinfo->dest;
|
||||
cinfo->dest = NULL;
|
||||
cinfo->scan_buffer[master->scan_number] = NULL;
|
||||
cinfo->scan_size[master->scan_number] = 0;
|
||||
jpeg_mem_dest(cinfo, &cinfo->scan_buffer[master->scan_number], &cinfo->scan_size[master->scan_number]);
|
||||
(*cinfo->dest->init_destination)(cinfo);
|
||||
}
|
||||
(*cinfo->entropy->start_pass) (cinfo, FALSE);
|
||||
(*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
|
||||
/* We emit frame/scan headers now */
|
||||
@@ -530,6 +548,27 @@ pass_startup (j_compress_ptr cinfo)
|
||||
}
|
||||
|
||||
|
||||
LOCAL(void)
|
||||
copy_buffer (j_compress_ptr cinfo, int scan_idx)
|
||||
{
|
||||
int size = cinfo->scan_size[scan_idx];
|
||||
unsigned char * src = cinfo->scan_buffer[scan_idx];
|
||||
|
||||
while (size >= cinfo->dest->free_in_buffer)
|
||||
{
|
||||
MEMCOPY(cinfo->dest->next_output_byte, src, cinfo->dest->free_in_buffer);
|
||||
src += cinfo->dest->free_in_buffer;
|
||||
size -= cinfo->dest->free_in_buffer;
|
||||
cinfo->dest->next_output_byte += cinfo->dest->free_in_buffer;
|
||||
cinfo->dest->free_in_buffer = 0;
|
||||
(*cinfo->dest->empty_output_buffer)(cinfo);
|
||||
}
|
||||
|
||||
MEMCOPY(cinfo->dest->next_output_byte, src, size);
|
||||
cinfo->dest->next_output_byte += size;
|
||||
cinfo->dest->free_in_buffer -= size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finish up at end of pass.
|
||||
*/
|
||||
@@ -562,6 +601,184 @@ 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) {
|
||||
(*cinfo->dest->term_destination)(cinfo);
|
||||
cinfo->dest = cinfo->saved_dest;
|
||||
switch (master->scan_number) {
|
||||
case 0:
|
||||
{
|
||||
copy_buffer(cinfo, 0);
|
||||
break;
|
||||
}
|
||||
case 11:
|
||||
{
|
||||
int size[4];
|
||||
size[0] = cinfo->scan_size[1] + cinfo->scan_size[2];
|
||||
size[1] = cinfo->scan_size[3] + cinfo->scan_size[4] + cinfo->scan_size[5];
|
||||
size[2] = cinfo->scan_size[6] + cinfo->scan_size[7] + cinfo->scan_size[8] + cinfo->scan_size[5];
|
||||
size[3] = cinfo->scan_size[9] + cinfo->scan_size[10] + cinfo->scan_size[11] + cinfo->scan_size[8] + cinfo->scan_size[5];
|
||||
|
||||
int Al = 0;
|
||||
int i;
|
||||
for (i = 1; i <= 3; i++)
|
||||
if (size[i] < size[Al])
|
||||
Al = i;
|
||||
cinfo->best_Al = Al;
|
||||
|
||||
/* HACK! casting a const to a non-const :-( */
|
||||
jpeg_scan_info *scanptr = (jpeg_scan_info *)&cinfo->scan_info[12];
|
||||
|
||||
for (i = 0; i < 11; i++)
|
||||
scanptr[i].Al = Al;
|
||||
break;
|
||||
}
|
||||
|
||||
case 22:
|
||||
{
|
||||
int size[6];
|
||||
size[0] = cinfo->scan_size[12];
|
||||
size[1] = cinfo->scan_size[13] + cinfo->scan_size[14];
|
||||
size[2] = cinfo->scan_size[15] + cinfo->scan_size[16];
|
||||
size[3] = cinfo->scan_size[17] + cinfo->scan_size[18];
|
||||
size[4] = cinfo->scan_size[19] + cinfo->scan_size[20];
|
||||
size[5] = cinfo->scan_size[21] + cinfo->scan_size[22];
|
||||
int best = 0;
|
||||
if (size[1] < size[best])
|
||||
best = 1;
|
||||
if (size[2] < size[best])
|
||||
best = 2;
|
||||
if (best != 0) {
|
||||
if (size[3] < size[best])
|
||||
best = 3;
|
||||
if (best == 2) {
|
||||
if (size[4] < size[best]) {
|
||||
best = 4;
|
||||
if (size[5] < size[best])
|
||||
best = 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (best == 0)
|
||||
copy_buffer(cinfo, 12);
|
||||
else {
|
||||
copy_buffer(cinfo, 11+2*best);
|
||||
copy_buffer(cinfo, 12+2*best);
|
||||
}
|
||||
|
||||
if (cinfo->best_Al >= 3)
|
||||
copy_buffer(cinfo, 11);
|
||||
if (cinfo->best_Al >= 2)
|
||||
copy_buffer(cinfo, 8);
|
||||
if (cinfo->best_Al >= 1)
|
||||
copy_buffer(cinfo, 5);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 23; i++)
|
||||
free(cinfo->scan_buffer[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 25:
|
||||
{
|
||||
int size[2];
|
||||
size[0] = cinfo->scan_size[23];
|
||||
size[1] = cinfo->scan_size[24] + cinfo->scan_size[25];
|
||||
if (size[0] <= size[1])
|
||||
copy_buffer(cinfo, 23);
|
||||
else {
|
||||
copy_buffer(cinfo, 24);
|
||||
copy_buffer(cinfo, 25);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 41:
|
||||
{
|
||||
int size[3];
|
||||
size[0] = cinfo->scan_size[26] + cinfo->scan_size[27];
|
||||
size[0] += cinfo->scan_size[28] + cinfo->scan_size[29];
|
||||
size[1] = cinfo->scan_size[30] + cinfo->scan_size[31] + cinfo->scan_size[32];
|
||||
size[1] += cinfo->scan_size[33] + cinfo->scan_size[34] + cinfo->scan_size[35];
|
||||
size[2] = cinfo->scan_size[36] + cinfo->scan_size[37] + cinfo->scan_size[38] + cinfo->scan_size[39];
|
||||
size[2] += cinfo->scan_size[40] + cinfo->scan_size[41] + cinfo->scan_size[34] + cinfo->scan_size[35];
|
||||
|
||||
int Al = 0;
|
||||
int i;
|
||||
for (i = 1; i <= 3; i++)
|
||||
if (size[i] < size[Al])
|
||||
Al = i;
|
||||
cinfo->best_Al = Al;
|
||||
jpeg_scan_info *scanptr = (jpeg_scan_info *)&cinfo->scan_info[42];
|
||||
|
||||
for (i = 0; i < 22; i++)
|
||||
scanptr[i].Al = Al;
|
||||
break;
|
||||
}
|
||||
|
||||
case 63:
|
||||
{
|
||||
int size[6];
|
||||
size[0] = cinfo->scan_size[42];
|
||||
size[0] += cinfo->scan_size[43];
|
||||
size[1] = cinfo->scan_size[44] + cinfo->scan_size[45];
|
||||
size[1] += cinfo->scan_size[46] + cinfo->scan_size[47];
|
||||
size[2] = cinfo->scan_size[48] + cinfo->scan_size[49];
|
||||
size[2] += cinfo->scan_size[50] + cinfo->scan_size[51];
|
||||
size[3] = cinfo->scan_size[52] + cinfo->scan_size[53];
|
||||
size[3] += cinfo->scan_size[54] + cinfo->scan_size[55];
|
||||
size[4] = cinfo->scan_size[56] + cinfo->scan_size[57];
|
||||
size[4] += cinfo->scan_size[58] + cinfo->scan_size[59];
|
||||
size[5] = cinfo->scan_size[60] + cinfo->scan_size[61];
|
||||
size[5] += cinfo->scan_size[62] + cinfo->scan_size[63];
|
||||
|
||||
int best = 0;
|
||||
if (size[1] < size[best])
|
||||
best = 1;
|
||||
if (size[2] < size[best])
|
||||
best = 2;
|
||||
if (best != 0) {
|
||||
if (size[3] < size[best])
|
||||
best = 3;
|
||||
if (best == 2) {
|
||||
if (size[4] < size[best]) {
|
||||
best = 4;
|
||||
if (size[5] < size[best])
|
||||
best = 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (best == 0) {
|
||||
copy_buffer(cinfo, 42);
|
||||
copy_buffer(cinfo, 43);
|
||||
}
|
||||
else {
|
||||
copy_buffer(cinfo, 40+4*best);
|
||||
copy_buffer(cinfo, 41+4*best);
|
||||
copy_buffer(cinfo, 42+4*best);
|
||||
copy_buffer(cinfo, 43+4*best);
|
||||
}
|
||||
|
||||
if (cinfo->best_Al >= 2) {
|
||||
copy_buffer(cinfo, 40);
|
||||
copy_buffer(cinfo, 41);
|
||||
}
|
||||
if (cinfo->best_Al >= 1) {
|
||||
copy_buffer(cinfo, 34);
|
||||
copy_buffer(cinfo, 35);
|
||||
}
|
||||
int i;
|
||||
for (i = 23; i < 64; i++)
|
||||
free(cinfo->scan_buffer[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
master->scan_number++;
|
||||
break;
|
||||
}
|
||||
|
||||
162
jcparam.c
162
jcparam.c
@@ -325,6 +325,7 @@ jpeg_set_defaults (j_compress_ptr cinfo)
|
||||
}
|
||||
|
||||
#ifdef C_PROGRESSIVE_SUPPORTED
|
||||
cinfo->optimize_scans = TRUE;
|
||||
if (cinfo->use_moz_defaults)
|
||||
jpeg_simple_progression(cinfo);
|
||||
else {
|
||||
@@ -606,6 +607,162 @@ fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* List of scans to be tested
|
||||
* cinfo->num_components and cinfo->jpeg_color_space must be correct.
|
||||
*/
|
||||
|
||||
LOCAL(void)
|
||||
jpeg_search_progression (j_compress_ptr cinfo)
|
||||
{
|
||||
int ncomps = cinfo->num_components;
|
||||
int nscans;
|
||||
jpeg_scan_info * scanptr;
|
||||
|
||||
/* Safety check to ensure start_compress not called yet. */
|
||||
if (cinfo->global_state != CSTATE_START)
|
||||
ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
|
||||
|
||||
/* Figure space needed for script. Calculation must match code below! */
|
||||
if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
|
||||
/* Custom script for YCbCr color images. */
|
||||
nscans = 64;
|
||||
} else {
|
||||
/* All-purpose script for other color spaces. */
|
||||
if (cinfo->use_moz_defaults) {
|
||||
if (ncomps > MAX_COMPS_IN_SCAN)
|
||||
nscans = 5 * ncomps; /* 2 DC + 4 AC scans per component */
|
||||
else
|
||||
nscans = 1 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */
|
||||
} else {
|
||||
if (ncomps > MAX_COMPS_IN_SCAN)
|
||||
nscans = 6 * ncomps; /* 2 DC + 4 AC scans per component */
|
||||
else
|
||||
nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate space for script.
|
||||
* We need to put it in the permanent pool in case the application performs
|
||||
* multiple compressions without changing the settings. To avoid a memory
|
||||
* leak if jpeg_simple_progression is called repeatedly for the same JPEG
|
||||
* object, we try to re-use previously allocated space, and we allocate
|
||||
* enough space to handle YCbCr even if initially asked for grayscale.
|
||||
*/
|
||||
if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) {
|
||||
cinfo->script_space_size = MAX(nscans, 10);
|
||||
cinfo->script_space = (jpeg_scan_info *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
cinfo->script_space_size * SIZEOF(jpeg_scan_info));
|
||||
}
|
||||
scanptr = cinfo->script_space;
|
||||
cinfo->scan_info = scanptr;
|
||||
cinfo->num_scans = nscans;
|
||||
|
||||
if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
|
||||
|
||||
/* 23 scans for luma */
|
||||
/* 1 scan for DC */
|
||||
/* 11 scans to determine successive approximation */
|
||||
/* 11 scans to determine frequency approximation */
|
||||
/* after 12 scans need to update following 11 */
|
||||
/* after 23 scans need to determine which to keep */
|
||||
/* last 4 done conditionally */
|
||||
|
||||
/* luma DC by itself */
|
||||
scanptr = fill_dc_scans(scanptr, 1, 0, 0);
|
||||
/* luma approximation 1 */
|
||||
scanptr = fill_a_scan(scanptr, 0, 1, 8, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 0, 9, 63, 0, 0);
|
||||
/* luma approximation 2 */
|
||||
scanptr = fill_a_scan(scanptr, 0, 1, 8, 0, 1);
|
||||
scanptr = fill_a_scan(scanptr, 0, 9, 63, 0, 1);
|
||||
scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0);
|
||||
/* luma approximation 3 */
|
||||
scanptr = fill_a_scan(scanptr, 0, 1, 8, 0, 2);
|
||||
scanptr = fill_a_scan(scanptr, 0, 9, 63, 0, 2);
|
||||
scanptr = fill_a_scan(scanptr, 0, 1, 63, 2, 1);
|
||||
/* luma approximation 4 */
|
||||
scanptr = fill_a_scan(scanptr, 0, 1, 8, 0, 3);
|
||||
scanptr = fill_a_scan(scanptr, 0, 9, 63, 0, 3);
|
||||
scanptr = fill_a_scan(scanptr, 0, 1, 63, 3, 2);
|
||||
/* luma frequency split 1 */
|
||||
scanptr = fill_a_scan(scanptr, 0, 1, 63, 0, 0);
|
||||
/* luma frequency split 2 */
|
||||
scanptr = fill_a_scan(scanptr, 0, 1, 2, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 0, 3, 63, 0, 0);
|
||||
/* luma frequency split 3 */
|
||||
scanptr = fill_a_scan(scanptr, 0, 1, 8, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 0, 9, 63, 0, 0);
|
||||
/* luma frequency split 4, don't do if 2 and 3 didn't help */
|
||||
scanptr = fill_a_scan(scanptr, 0, 1, 5, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 0, 6, 63, 0, 0);
|
||||
/* luma frequency split 5, do only if 3 is best */
|
||||
scanptr = fill_a_scan(scanptr, 0, 1, 12, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 0, 13, 63, 0, 0);
|
||||
/* luma frequency split 6, don't do if 5 didn't help */
|
||||
scanptr = fill_a_scan(scanptr, 0, 1, 18, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 0, 19, 63, 0, 0);
|
||||
|
||||
/* 41 scans for chroma */
|
||||
|
||||
/* chroma DC combined */
|
||||
scanptr = fill_a_scan_pair(scanptr, 1, 0, 0, 0, 0);
|
||||
/* chroma DC separate */
|
||||
scanptr = fill_a_scan(scanptr, 1, 0, 0, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 2, 0, 0, 0, 0);
|
||||
/* chroma approximation 1 */
|
||||
scanptr = fill_a_scan(scanptr, 1, 1, 8, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 1, 9, 63, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 2, 1, 8, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 2, 9, 63, 0, 0);
|
||||
/* chroma approximation 2 */
|
||||
scanptr = fill_a_scan(scanptr, 1, 1, 8, 0, 1);
|
||||
scanptr = fill_a_scan(scanptr, 1, 9, 63, 0, 1);
|
||||
scanptr = fill_a_scan(scanptr, 2, 1, 8, 0, 1);
|
||||
scanptr = fill_a_scan(scanptr, 2, 9, 63, 0, 1);
|
||||
scanptr = fill_a_scan(scanptr, 1, 1, 63, 1, 0);
|
||||
scanptr = fill_a_scan(scanptr, 2, 1, 63, 1, 0);
|
||||
/* chroma approximation 3 */
|
||||
scanptr = fill_a_scan(scanptr, 1, 1, 8, 0, 2);
|
||||
scanptr = fill_a_scan(scanptr, 1, 9, 63, 0, 2);
|
||||
scanptr = fill_a_scan(scanptr, 2, 1, 8, 0, 2);
|
||||
scanptr = fill_a_scan(scanptr, 2, 9, 63, 0, 2);
|
||||
scanptr = fill_a_scan(scanptr, 1, 1, 63, 2, 1);
|
||||
scanptr = fill_a_scan(scanptr, 2, 1, 63, 2, 1);
|
||||
/* chroma frequency split 1 */
|
||||
scanptr = fill_a_scan(scanptr, 1, 1, 63, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 2, 1, 63, 0, 0);
|
||||
/* chroma frequency split 2 */
|
||||
scanptr = fill_a_scan(scanptr, 1, 1, 2, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 1, 3, 63, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 2, 1, 2, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 2, 3, 63, 0, 0);
|
||||
/* chroma frequency split 3 */
|
||||
scanptr = fill_a_scan(scanptr, 1, 1, 8, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 1, 9, 63, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 2, 1, 8, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 2, 9, 63, 0, 0);
|
||||
/* chroma frequency split 4 */
|
||||
scanptr = fill_a_scan(scanptr, 1, 1, 5, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 1, 6, 63, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 2, 1, 5, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 2, 6, 63, 0, 0);
|
||||
/* chroma frequency split 5 */
|
||||
scanptr = fill_a_scan(scanptr, 1, 1, 12, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 1, 13, 63, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 2, 1, 12, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 2, 13, 63, 0, 0);
|
||||
/* chroma frequency split 6 */
|
||||
scanptr = fill_a_scan(scanptr, 1, 1, 18, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 1, 19, 63, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 2, 1, 18, 0, 0);
|
||||
scanptr = fill_a_scan(scanptr, 2, 19, 63, 0, 0);
|
||||
} else {
|
||||
/* TODO */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a recommended progressive-JPEG script.
|
||||
* cinfo->num_components and cinfo->jpeg_color_space must be correct.
|
||||
@@ -614,6 +771,10 @@ fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al)
|
||||
GLOBAL(void)
|
||||
jpeg_simple_progression (j_compress_ptr cinfo)
|
||||
{
|
||||
if (cinfo->optimize_scans) {
|
||||
jpeg_search_progression(cinfo);
|
||||
return;
|
||||
}
|
||||
int ncomps = cinfo->num_components;
|
||||
int nscans;
|
||||
jpeg_scan_info * scanptr;
|
||||
@@ -724,4 +885,5 @@ jpeg_simple_progression (j_compress_ptr cinfo)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* C_PROGRESSIVE_SUPPORTED */
|
||||
|
||||
@@ -377,7 +377,12 @@ struct jpeg_compress_struct {
|
||||
J_DCT_METHOD dct_method; /* DCT algorithm selector */
|
||||
|
||||
boolean use_moz_defaults; /* TRUE if using Mozilla defaults */
|
||||
|
||||
boolean optimize_scans; /* TRUE=optimize progressive coding scans */
|
||||
struct jpeg_destination_mgr * saved_dest; /* saved value of dest */
|
||||
unsigned char * scan_buffer[64]; /* buffer for a given scan */
|
||||
unsigned long scan_size[64]; /* size for a given scan */
|
||||
int best_Al; /* best value for Al found in scan search */
|
||||
|
||||
/* 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
|
||||
|
||||
Reference in New Issue
Block a user