📄 component_mix.c
字号:
for (level_depth=0, n=third_d_levels; n >= 0; n--){
std_tap_info_ptr t_src, t_dst;
if (n > 0){
/* high-pass */
t_src = &conv_t1;
t_dst = &conv_t2;
convolve_waveforms(third_d_kernel.high+1,t_src,t_dst,
1<<level_depth);
low_size = num_components;
for(l=0;l<=level_depth;l++)
{
high_size = (low_size>>1);
low_size = (low_size>>1) + low_size%2;
high_start = low_size;
}
l2_norm = compute_waveform_l2_norm(t_dst);
/* Modify weights for all relevant components */
for (c=high_start; c < high_start+high_size; c++)
{
relative_l2_norm_gains[c] *= l2_norm;
relative_nominal_gains[c] *= nominal_gain*t_high_gain;
}
}
else{
/* LL band */
t_src = &conv_t1;
t_dst = &conv_t2;
convolve_waveforms(third_d_kernel.low+1,t_src,t_dst,
1<<level_depth);
low_size = num_components;
for(l=0;l<=level_depth;l++){
low_size = (low_size>>1) + low_size%2;
}
l2_norm = compute_waveform_l2_norm(t_dst);
/* Modify weights for all relevant components */
for (c=0; c < low_size; c++){
relative_l2_norm_gains[c] *= l2_norm;
relative_nominal_gains[c] *= nominal_gain*t_high_gain;
}
}
if(n > 0){
/* Now compute the next level's tree depth and base synthesis
waveforms. */
t_src = &conv_t1;
t_dst = &conv_t2;
convolve_waveforms(third_d_kernel.low+1,t_src,t_dst,1<<level_depth);
tmp_taps = *t_src; *t_src = *t_dst; *t_dst = tmp_taps;
if(n != 1)
level_depth++;
nominal_gain *= t_low_gain;
}
}
/* Cleanup. */
destroy_taps(&conv_t1);
destroy_taps(&conv_t2);
}
/*****************************************************************************/
/* STATIC compute_relative_component_gains */
/*****************************************************************************/
static void
compute_relative_component_gains(the_component_mix_ref self,
float ***relative_l2_norm_gains,
float ***relative_nominal_gains)
{
float subsampling_multiplier;
int hor_subsampling, vert_subsampling;
int tnum, c;
int min_Fx = 255, min_Fy = 255;
*relative_l2_norm_gains = (float **)
local_malloc(MIXING_MEM_KEY, sizeof(float *) * (self->num_tiles + 1));
*relative_nominal_gains = (float **)
local_malloc(MIXING_MEM_KEY, sizeof(float *) * (self->num_tiles + 1));
*relative_l2_norm_gains += 1;
*relative_nominal_gains += 1;
for (tnum=-1; tnum<self->num_tiles; tnum++) {
(*relative_l2_norm_gains)[tnum] = (float *)
local_malloc(MIXING_MEM_KEY, sizeof(float) * self->num_components);
(*relative_nominal_gains)[tnum] = (float *)
local_malloc(MIXING_MEM_KEY, sizeof(float) * self->num_components);
for (c=0; c<self->num_components; c++) {
(*relative_l2_norm_gains)[tnum][c] = 1.0F;
(*relative_nominal_gains)[tnum][c] = 1.0F;
}
}
for (tnum=-1; tnum<self->num_tiles; tnum++) {
if ((self->tile_xforms[tnum] == MIXING_XFORM_WLT_FLT) ||
(self->tile_xforms[tnum] == MIXING_XFORM_WLT_INT)) {
/* Modify l2_norm and nominal_gain for wavelet transform in third
dimension */
modify_for_wavelet(self->tile_kernels[tnum].third_d_kernel,
(*relative_l2_norm_gains)[tnum],
(*relative_nominal_gains)[tnum],
self->num_components);
}
else if ((self->tile_xforms[tnum] == MIXING_XFORM__RCT) ||
(self->tile_xforms[tnum] == MIXING_XFORM__YCbCr)) {
/* Set relative l2_norm changes for colour transform */
/* Determine color l2_norm multipliers: */
/* In the case where no color transform takes place, the multipliers
* are 1. In the case where the color transform is the irreversible
* RGB->YUV transform the multipliers are pre-computed via the
* following matlab/ octave script.
*
* % Setup the transform matrix (YUV/RCT = Transform * RGB, see p.22
* of N1143)
* YCrCb:
* Transform=[ 0.299 0.587 0.114;
* -0.16875 -0.33126 0.5;
* 0.5 -0.41869 -0.08131]
*
* RCT:
* Transform=[ 0.25 0.5 0.25;
* 1.0 -1.0 0.0;
* 0.0 -1.0 1.0]
*
* % Compute reconstruction basis vectors
* Inverse = inv(Transform)
*
* % Print out the energy weights (square of l2 norms)
* [rows,cols]=size(Inverse);
* for iCol=1:cols
* sqrt(norm( Inverse(:,iCol),2 ) * norm( Inverse(:,iCol),2 ))
* end
***********************************************************************/
if (self->tile_xforms[tnum] == MIXING_XFORM__RCT) {
(*relative_l2_norm_gains)[tnum][0] *= 1.7321F;
(*relative_l2_norm_gains)[tnum][1] *= 0.8292F;
(*relative_l2_norm_gains)[tnum][2] *= 0.8292F;
}
else {
(*relative_l2_norm_gains)[tnum][0] *= 1.7321F;
(*relative_l2_norm_gains)[tnum][1] *= 1.8051F;
(*relative_l2_norm_gains)[tnum][2] *= 1.5734F;
}
}
}
for (c = 0; c < self->num_components; c++) {
/* MITRE General Offset/SQ Begin */ /* Begin Aerospace MCT mods */
self->info->get_fixed_tile_info(self->info, c, 0, NULL, NULL, NULL,
&hor_subsampling, &vert_subsampling,
NULL,NULL,NULL,NULL,NULL);
/* MITRE General Offset/SQ End */ /* End Aerospace MCT mods */
if (hor_subsampling < min_Fx)
min_Fx = hor_subsampling;
if (vert_subsampling < min_Fy)
min_Fy = vert_subsampling;
}
for (c = 0; c < self->num_components; c++) {
/* MITRE General Offset/SQ Begin */ /* Begin Aerospace MCT mods */
self->info->get_fixed_tile_info(self->info, c, 0, NULL, NULL, NULL,
&hor_subsampling, &vert_subsampling,
NULL,NULL,NULL,NULL,NULL);
/* MITRE General Offset/SQ End */ /* End Aerospace MCT mods */
subsampling_multiplier =
(float) sqrt(((double) (hor_subsampling *
vert_subsampling)) /
((double) (min_Fx*min_Fy)));
for (tnum=-1; tnum<self->num_tiles; tnum++) {
(*relative_l2_norm_gains)[tnum][c] *= subsampling_multiplier;
}
}
}
/*****************************************************************************/
/* STATIC destroy_buffers */
/*****************************************************************************/
static void
destroy_buffers(mixing_component_info_ptr comp)
{
mixing_row_buffer_ptr buf;
while ((buf = comp->head) != NULL)
{
comp->head = buf->next;
local_free(buf);
}
comp->tail = NULL;
comp->num_buffered_rows = 0;
}
/*****************************************************************************/
/* STATIC start_tile */
/*****************************************************************************/
static void
start_tile(the_component_mix_ref self)
{
int tnum = self->current_tile_idx;
stream_out_ref stream = self->stream;
int c, reversible;
canvas_dims dims, last_dims;
mixing_component_info_ptr comp;
/* UofA Begin */
int b, n;
char *default_filter = NULL;
/* UofA End */
self->current_xform = self->tile_xforms[tnum];
if(self->current_xform != self->main_xform){
stream->declare_marker_elt(stream,tnum,MARKER_COD_CXFORM,0,3,1);
stream->set_marker_val(stream,tnum,MARKER_COD_CXFORM,0,(std_uint)
(self->current_xform),0);
}
for(c=0;c<self->num_components;c++){
comp = self->components + c;
assert(comp->num_buffered_rows == 0);
self->info->get_var_tile_info(self->info,c,NULL,&dims,&reversible,NULL,
NULL);
if (((self->current_xform == MIXING_XFORM__RCT) ||
(self->current_xform == MIXING_XFORM__YCbCr)) &&
(c < 3)){
if (c == 0)
last_dims = dims;
else if ((dims.rows != last_dims.rows) ||
(dims.cols != last_dims.cols) ||
(dims.top_row != last_dims.top_row) ||
(dims.left_col != last_dims.left_col))
local_error("Colour transforms may not be used with image "
"components of different dimensions!");
}
/* UofA Begin */
else if ((self->current_xform == MIXING_XFORM_WLT_INT) ||
(self->current_xform == MIXING_XFORM_WLT_FLT))
{
/* LANL start */
#ifdef LANL_CMPNT_WVLT
if (self->current_xform == MIXING_XFORM_WLT_INT) {
if (self->intX)
local_free(self->intX);
if (self->intY)
local_free(self->intY);
self->intX = local_malloc(MIXING_MEM_KEY,
(self->num_components)*sizeof(int));
self->intY = local_malloc(MIXING_MEM_KEY,
(self->num_components)*sizeof(int));
} else {
if (self->floatX)
local_free(self->floatX);
if (self->floatY)
local_free(self->floatY);
self->floatX = local_malloc(MIXING_MEM_KEY,
(self->num_components)*sizeof(float));
self->floatY = local_malloc(MIXING_MEM_KEY,
(self->num_components)*sizeof(float));
}
#endif
/* LANL end */
if (c == 0)
last_dims = dims;
else if ((dims.rows != last_dims.rows) ||
(dims.cols != last_dims.cols) ||
(dims.top_row != last_dims.top_row) ||
(dims.left_col != last_dims.left_col))
local_error("Wavelet component transforms may not be used with "
"image components of different dimensions!");
default_filter = (reversible == INFO__REVERSIBLE)?"W5X3":"W9X7";
}
/* UofA End */
/* Kodak/SAIC Linear Transform Begin */
else if (self->current_xform == MIXING_XFORM_LIN)
{
if (c == 0)
last_dims = dims;
else if ((dims.rows != last_dims.rows) ||
(dims.cols != last_dims.cols) ||
(dims.top_row != last_dims.top_row) ||
(dims.left_col != last_dims.left_col))
local_error("Linear component transforms may not be used with "
"image components of different dimensions!");
}
/* Kodak/SAIC Linear Transform End */
if (dims.cols > comp->tile_cols)
destroy_buffers(comp);
comp->tile_cols = dims.cols;
}
/* UofA Begin */
if ((self->current_xform == MIXING_XFORM_WLT_INT) ||
(self->current_xform == MIXING_XFORM_WLT_FLT)) {
self->kernel_type =
get_third_d_kernel_type(self, INFO__ANALYSIS, default_filter,
self->conv.branch_neg_supports,
self->conv.branch_pos_supports,
self->conv.branch_neg_supports+1,
self->conv.branch_pos_supports+1);
if(self->kernel_type == INFO__CONVOLUTION)
{
get_third_d_convolution_taps(self, self->conv.branch_taps,
self->conv.branch_taps+1);
self->conv.even_taps =
((self->conv.branch_neg_supports[0]
+self->conv.branch_pos_supports[0]) & 1);
if(self->conv.in_buf != NULL) {
local_free(self->conv.in_buf-self->conv.extend);
self->conv.in_buf = NULL;
}
for (self->conv.extend=0, b=0; b < 2; b++)
{
if (self->conv.branch_neg_supports[b] > self->conv.extend)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -