Regroup copying of scan buffers

This commit is contained in:
fbossen
2014-02-19 15:38:20 -05:00
parent 579d16b032
commit 3d26a0a343
2 changed files with 76 additions and 77 deletions

View File

@@ -44,7 +44,11 @@ typedef struct {
unsigned char * scan_buffer[64]; /* buffer for a given scan */
unsigned long scan_size[64]; /* size for a given scan */
unsigned long best_freq_split_cost; /* bit count for best frequency split */
int best_freq_split_idx; /* index for best frequency split */
int best_freq_split_idx_luma; /* index for best frequency split (luma) */
int best_freq_split_idx_chroma; /* index for best frequency split (chroma) */
int best_Al_luma; /* best value for Al found in scan search (luma) */
int best_Al_chroma; /* best value for Al found in scan search (luma) */
boolean interleave_chroma_dc; /* indicate whether to interleave chroma DC scans */
} my_comp_master;
typedef my_comp_master * my_master_ptr;
@@ -339,11 +343,11 @@ select_scan_parameters (j_compress_ptr cinfo)
/* 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)
cinfo->Al = cinfo->best_Al;
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) &&
master->scan_number < cinfo->num_scans)
cinfo->Al = cinfo->best_Al;
cinfo->Al = master->best_Al_chroma;
}
}
else
@@ -594,15 +598,13 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
unsigned long size[8];
int base_scan_idx;
int luma_freq_split_scan_start = cinfo->num_scans_luma_dc + 3 * cinfo->Al_max_luma + 2;
if (next_scan_number == cinfo->num_scans_luma_dc) {
copy_buffer(cinfo, 0);
} else if (next_scan_number == luma_freq_split_scan_start) {
int chroma_freq_split_scan_start = cinfo->num_scans_luma+cinfo->num_scans_chroma_dc+(6*cinfo->Al_max_chroma+4);
if (next_scan_number == luma_freq_split_scan_start) {
int Al;
int i;
cinfo->best_Al = 0;
master->best_Al_luma = 0;
for (Al = 0; Al <= cinfo->Al_max_luma; Al++) {
size[Al] = master->scan_size[1 + 2 * Al];
@@ -611,15 +613,15 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
for (i = 0; i < Al; i++)
size[Al] += master->scan_size[3 + 2*cinfo->Al_max_luma + i];
if (Al == 0 || size[Al] < size[cinfo->best_Al])
cinfo->best_Al = Al;
if (Al == 0 || size[Al] < size[master->best_Al_luma])
master->best_Al_luma = Al;
else
break;
}
} else if (next_scan_number > luma_freq_split_scan_start && next_scan_number <= cinfo->num_scans_luma) {
if (next_scan_number == luma_freq_split_scan_start + 1) {
master->best_freq_split_idx = 0;
master->best_freq_split_idx_luma = 0;
master->best_freq_split_cost = master->scan_size[next_scan_number-1];
} else if ((next_scan_number - luma_freq_split_scan_start) % 2 == 1) {
@@ -630,57 +632,31 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
if (cost < master->best_freq_split_cost) {
master->best_freq_split_cost = cost;
master->best_freq_split_idx = idx;
master->best_freq_split_idx_luma = idx;
}
/* if after testing first 3, no split is the best, don't search further */
if ((idx == 2 && master->best_freq_split_idx == 0) ||
(idx == 3 && master->best_freq_split_idx != 2) ||
(idx == 4 && master->best_freq_split_idx != 4)) {
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->pass_number = 2 * master->scan_number + 1;
master->pub.is_last_pass = (master->pass_number == master->total_passes - 1);
}
}
if (master->scan_number == cinfo->num_scans_luma - 1) {
int Al, i;
if (master->best_freq_split_idx == 0)
copy_buffer(cinfo, luma_freq_split_scan_start);
else {
copy_buffer(cinfo, luma_freq_split_scan_start+2*(master->best_freq_split_idx-1)+1);
copy_buffer(cinfo, luma_freq_split_scan_start+2*(master->best_freq_split_idx-1)+2);
}
/* copy the LSB refinements as well */
for (Al = cinfo->best_Al-1; Al >= 0; Al--)
copy_buffer(cinfo, 2*cinfo->Al_max_luma + 3 + Al);
/* free the memory allocated for the luma buffers */
for (i = 0; i < cinfo->num_scans_luma; i++)
if (master->scan_buffer[i] != NULL)
free(master->scan_buffer[i]);
}
} else if (cinfo->num_scans > cinfo->num_scans_luma) {
int chroma_freq_split_scan_start = cinfo->num_scans_luma+cinfo->num_scans_chroma_dc+(6*cinfo->Al_max_chroma+4);
if (next_scan_number == cinfo->num_scans_luma+cinfo->num_scans_chroma_dc) {
base_scan_idx = cinfo->num_scans_luma;
if (master->scan_size[base_scan_idx] <= master->scan_size[base_scan_idx+1] + master->scan_size[base_scan_idx+2])
copy_buffer(cinfo, base_scan_idx);
else {
copy_buffer(cinfo, base_scan_idx+1);
copy_buffer(cinfo, base_scan_idx+2);
}
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 == chroma_freq_split_scan_start) {
int Al;
int i;
base_scan_idx = cinfo->num_scans_luma + cinfo->num_scans_chroma_dc;
cinfo->best_Al = 0;
master->best_Al_chroma = 0;
for (Al = 0; Al <= cinfo->Al_max_chroma; Al++) {
size[Al] = master->scan_size[base_scan_idx + 0 + 4 * Al];
@@ -693,15 +669,15 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
size[Al] += master->scan_size[base_scan_idx + 5 + 4*cinfo->Al_max_chroma + 2*i];
}
if (Al == 0 || size[Al] < size[cinfo->best_Al])
cinfo->best_Al = Al;
if (Al == 0 || size[Al] < size[master->best_Al_chroma])
master->best_Al_chroma = Al;
else
break;
}
} else if (next_scan_number > chroma_freq_split_scan_start && next_scan_number <= cinfo->num_scans) {
if (next_scan_number == chroma_freq_split_scan_start + 2) {
master->best_freq_split_idx = 0;
master->best_freq_split_idx_chroma = 0;
master->best_freq_split_cost = master->scan_size[next_scan_number-2];
master->best_freq_split_cost += master->scan_size[next_scan_number-1];
@@ -715,46 +691,70 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
if (cost < master->best_freq_split_cost) {
master->best_freq_split_cost = cost;
master->best_freq_split_idx = idx;
master->best_freq_split_idx_chroma = idx;
}
/* if after testing first 3, no split is the best, don't search further */
if ((idx == 2 && master->best_freq_split_idx == 0) ||
(idx == 3 && master->best_freq_split_idx != 2) ||
(idx == 4 && master->best_freq_split_idx != 4)) {
if ((idx == 2 && master->best_freq_split_idx_chroma == 0) ||
(idx == 3 && master->best_freq_split_idx_chroma != 2) ||
(idx == 4 && master->best_freq_split_idx_chroma != 4)) {
master->scan_number = cinfo->num_scans - 1;
master->pass_number = 2 * master->scan_number + 1;
master->pub.is_last_pass = (master->pass_number == master->total_passes - 1);
}
}
}
}
if (master->scan_number == cinfo->num_scans - 1) {
int i, Al;
copy_buffer(cinfo, 0);
if (master->best_freq_split_idx_luma == 0)
copy_buffer(cinfo, luma_freq_split_scan_start);
else {
copy_buffer(cinfo, luma_freq_split_scan_start+2*(master->best_freq_split_idx_luma-1)+1);
copy_buffer(cinfo, luma_freq_split_scan_start+2*(master->best_freq_split_idx_luma-1)+2);
}
/* copy the LSB refinements as well */
for (Al = master->best_Al_luma-1; Al >= 0; Al--)
copy_buffer(cinfo, 2*cinfo->Al_max_luma + 3 + Al);
if (cinfo->num_scans > cinfo->num_scans_luma) {
base_scan_idx = cinfo->num_scans_luma;
if (master->interleave_chroma_dc)
copy_buffer(cinfo, base_scan_idx);
else {
copy_buffer(cinfo, base_scan_idx+1);
copy_buffer(cinfo, base_scan_idx+2);
}
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);
}
else {
copy_buffer(cinfo, chroma_freq_split_scan_start+4*(master->best_freq_split_idx_chroma-1)+2);
copy_buffer(cinfo, chroma_freq_split_scan_start+4*(master->best_freq_split_idx_chroma-1)+3);
copy_buffer(cinfo, chroma_freq_split_scan_start+4*(master->best_freq_split_idx_chroma-1)+4);
copy_buffer(cinfo, chroma_freq_split_scan_start+4*(master->best_freq_split_idx_chroma-1)+5);
}
if (master->scan_number == cinfo->num_scans - 1) {
int Al, i;
if (master->best_freq_split_idx == 0) {
copy_buffer(cinfo, chroma_freq_split_scan_start);
copy_buffer(cinfo, chroma_freq_split_scan_start+1);
}
else {
copy_buffer(cinfo, chroma_freq_split_scan_start+4*(master->best_freq_split_idx-1)+2);
copy_buffer(cinfo, chroma_freq_split_scan_start+4*(master->best_freq_split_idx-1)+3);
copy_buffer(cinfo, chroma_freq_split_scan_start+4*(master->best_freq_split_idx-1)+4);
copy_buffer(cinfo, chroma_freq_split_scan_start+4*(master->best_freq_split_idx-1)+5);
}
base_scan_idx = cinfo->num_scans_luma + cinfo->num_scans_chroma_dc;
for (Al = cinfo->best_Al-1; Al >= 0; Al--) {
copy_buffer(cinfo, base_scan_idx + 4*(cinfo->Al_max_chroma+1) + 2*Al + 0);
copy_buffer(cinfo, base_scan_idx + 4*(cinfo->Al_max_chroma+1) + 2*Al + 1);
}
/* free the memory allocated for the chroma buffers */
for (i = cinfo->num_scans_luma; i < cinfo->num_scans; i++)
if (master->scan_buffer[i])
free(master->scan_buffer[i]);
base_scan_idx = cinfo->num_scans_luma + cinfo->num_scans_chroma_dc;
for (Al = master->best_Al_chroma-1; Al >= 0; Al--) {
copy_buffer(cinfo, base_scan_idx + 4*(cinfo->Al_max_chroma+1) + 2*Al + 0);
copy_buffer(cinfo, base_scan_idx + 4*(cinfo->Al_max_chroma+1) + 2*Al + 1);
}
}
/* free the memory allocated for buffers */
for (i = 0; i < cinfo->num_scans; i++)
if (master->scan_buffer[i])
free(master->scan_buffer[i]);
}
}

View File

@@ -387,7 +387,6 @@ struct jpeg_compress_struct {
struct jpeg_destination_mgr * saved_dest; /* saved value of dest */
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) */
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