📄 std_kernel_info.c
字号:
pos = k;
}
}
neg = -neg;
high->neg_support = pos;
high->pos_support = neg;
high->taps = (float *)
local_malloc(INFO_MEM_KEY,sizeof(float)*(neg+pos+1));
taps = high->taps + high->neg_support;
for (n=-neg; n <= pos; n++)
{
if (n & 1)
taps[-n] = odd_buf_0[64+((n-1)>>1)];
else
taps[-n] = odd_buf_1[64+(n>>1)];
}
high->int_rdx = -1;
high->int_taps = NULL;
}
/*****************************************************************************/
/* STATIC construct_kernel_path */
/*****************************************************************************/
static char *
construct_kernel_path(char *kernels_dir, char *branch, int kernel_idx)
/* This function dynamically allocates a string buffer to hold the
concatenation of the `kernels_dir', `branch', and "kernel-xxx" path
names, where `xxx' stands for the value of `kernel_idx'. The function
automatically adjusts the separators within this final path name to
reflect the appropriate usage on the host platform (WIN32 or UNIX). */
{
char *path, *cp;
char sep, alt_sep;
if (kernels_dir == NULL)
local_error("Unable to load user-defined kernels until the "
"`kernels_dir' path can be established! This may be done "
"via the `-Fdir' argument or by defining the "
"JP2_KERNELS_DIR environment variable.");
#ifdef WIN32
sep = '\\';
alt_sep = '/';
#else
sep = '/';
alt_sep = '\\';
#endif /* WIN32 */
path = (char *) local_malloc(INFO_MEM_KEY,
strlen(kernels_dir)+strlen(branch)+strlen("kernel-")+8);
strcpy(path,kernels_dir);
cp = path + strlen(path);
if ((cp > path) && (cp[-1] != sep) && (cp[-1] != alt_sep))
*(cp++) = sep;
sprintf(cp,"%s/kernel-%03d",branch,kernel_idx);
for (cp=path; *cp != '\0'; cp++)
if (*cp == alt_sep)
*cp = sep;
return(path);
}
/*****************************************************************************/
/* STATIC read_float_lifting_kernel */
/*****************************************************************************/
static void
read_float_lifting_kernel(int kernel_idx, std_lifting_info_ptr lifting,
char *kernels_dir)
/* Reads floating-point lifting coefficients from the file identified by
the `kernel_idx' value, which must lie in the range 0 to 255. The
file format is as follows: The first line should contain a sequence
of positive integers, identifying the support of each lifting step.
The support of the first prediction step appears first, followed by
the support of the first update step, the support of the second predict
step and so forth. The number of integers on this line identifies the
total number of lifting steps. Trailing zeros on this line will
automatically be discarded for compatibility with the VM2.1 format.
This first line should be followed by the filter taps (impulse
response order) for each lifting step in sequence, with all taps for
a given lifting step appearing on the same line of text.
The remainder of the file is discarded, thereby ensuring that the
VM2.1 files will be correctly read.
The lifting coefficients are rounded to INFO__LIFTING_FRACTION
fractional bits so that they can be saved losslessly in the codestream.
As a result, the implementation of the W9X7 filter will be slightly
different if used as a built-in filter, as opposed to a user-defined
filter. In addition to the INFO__LIFTING_FRACTION fractional bits,
each lifting coefficient is represented using 2 non-fractional magnitude
bits and a sign bit. */
{
FILE *fp;
char line[257], *filename, *cp, *next_cp;
int num_steps = 0, supports[9];
std_tap_info_ptr taps;
int n, i;
double frac_scale;
frac_scale = (double)(1<<INFO__LIFTING_FRACTION);
filename = construct_kernel_path(kernels_dir,"float_lifting",kernel_idx);
if ((fp=fopen(filename,"r")) == NULL)
local_error("Unable to open the user-defined lifting filter "
"file, \"%s\"!",filename);
if ((fgets(line,256,fp) == NULL) ||
((num_steps =
sscanf(line,"%d %d %d %d %d %d %d %d %d",
supports+0,supports+1,supports+2,supports+3,supports+4,
supports+5,supports+6,supports+7,supports+8)) < 1) ||
(num_steps > INFO__MAX_LIFTING_STEPS))
local_error("Unable to parse the user-defined lifting steps "
"from file, \"%s\"! The first line of the file must "
"define the supports of 1 to %d lifting steps.",
filename,INFO__MAX_LIFTING_STEPS);
while (supports[num_steps-1] == 0)
{
if (num_steps == 1)
local_error("Unable to parse the user-defined lifting steps "
"from file, \"%s\"! The first line of the file must "
"define the supports of 1 to 8 lifting steps.",
filename);
num_steps--;
}
lifting->num_steps = num_steps;
lifting->steps = (std_tap_info_ptr)
local_malloc(INFO_MEM_KEY,sizeof(std_tap_info)*num_steps);
for (n=0; n < num_steps; n++)
{
taps = lifting->steps + n;
if (supports[n] > 7)
local_error("Unable to represent lifting kernels with more than "
"7 taps per liftint step!");
taps->neg_support = (supports[n] - ((n&1)?0:1)) >> 1;
taps->pos_support = (supports[n] - ((n&1)?1:0)) >> 1;
taps->taps = (float *)
local_malloc(INFO_MEM_KEY,sizeof(float)*supports[n]);
if (fgets(line,256,fp) == NULL)
local_error("Syntax error in user-defined lifting filter "
"file, \"%s\"! Tap values missing for one or more "
"lifting steps.",filename);
cp = line;
next_cp = NULL;
while ((*cp == ' ') || (*cp == '\t'))
cp++;
for (i=supports[n]-1; i >= 0; i--)
{
taps->taps[i] = (float) strtod(cp,&next_cp);
if (next_cp == cp)
local_error("Syntax error in user-defined lifting filter "
"file, \"%s\"! Insufficient tap values supplied "
"for lifting step %d out of %d.",filename,
supports[n]-i,supports[n]);
cp = next_cp;
taps->taps[i] = (float) /* Restrict number of fraction bits. */
(floor(0.5 + taps->taps[i] * frac_scale) / frac_scale);
}
taps->int_rdx = 0;
taps->int_taps = NULL;
}
fclose(fp);
local_free(filename);
}
/*****************************************************************************/
/* STATIC read_int_lifting_kernel */
/*****************************************************************************/
static void
read_int_lifting_kernel(int kernel_idx, std_lifting_info_ptr lifting,
char *kernels_dir)
/* Reads fixed-point lifting coefficients from the file identified by
the `kernel_idx' value, which must lie in the range 0 to 255. The
file format is as follows: The first line should contain a sequence
of positive integers, identifying the support of each lifting step.
The support of the first prediction step appears first, followed by
the support of the first update step, the support of the second predict
step and so forth. The number of integers on this line identifies the
total number of lifting steps. Trailing zeros on this line will
automatically be discarded for compatibility with the VM2.1 format.
This first line should be followed by the filter taps (impulse
response order) for each lifting step in sequence, with all taps for
a given lifting step appearing on the same line of text. The tap values
should be expressed as integers and the line on which they appear should
contain a trailing integer expressing the amount by which the integer
tap values should be downshifted to recover their floating-point
equivalents.
The remainder of the file is discarded, thereby ensuring that the
VM2.1 files will be correctly read. */
{
FILE *fp;
char line[257], *filename, *cp, *next_cp;
int num_steps = 0, supports[9];
std_tap_info_ptr taps;
int n, i;
filename = construct_kernel_path(kernels_dir,"int_lifting",kernel_idx);
if ((fp=fopen(filename,"r")) == NULL)
local_error("Unable to open the user-defined lifting filter "
"file, \"%s\"!",filename);
if ((fgets(line,256,fp) == NULL) ||
((num_steps =
sscanf(line,"%d %d %d %d %d %d %d %d %d",
supports+0,supports+1,supports+2,supports+3,supports+4,
supports+5,supports+6,supports+7,supports+8)) < 1) ||
(num_steps > INFO__MAX_LIFTING_STEPS))
local_error("Unable to parse the user-defined lifting steps "
"from file, \"%s\"! The first line of the file must "
"define the supports of 1 to %d lifting steps.",
filename,INFO__MAX_LIFTING_STEPS);
while (supports[num_steps-1] == 0)
{
if (num_steps == 1)
local_error("Unable to parse the user-defined lifting steps "
"from file, \"%s\"! The first line of the file must "
"define the supports of 1 to 8 lifting steps.",
filename);
num_steps--;
}
lifting->num_steps = num_steps;
lifting->steps = (std_tap_info_ptr)
local_malloc(INFO_MEM_KEY,sizeof(std_tap_info)*num_steps);
for (n=0; n < num_steps; n++)
{
taps = lifting->steps + n;
if (supports[n] > 7)
local_error("Unable to represent lifting kernels with more than "
"7 taps per liftint step!");
taps->neg_support = (supports[n] - ((n&1)?0:1)) >> 1;
taps->pos_support = (supports[n] - ((n&1)?1:0)) >> 1;
taps->taps = (float *)
local_malloc(INFO_MEM_KEY,sizeof(float)*supports[n]);
taps->int_taps = (int *)
local_malloc(INFO_MEM_KEY,sizeof(int)*supports[n]);
if (fgets(line,256,fp) == NULL)
local_error("Syntax error in user-defined lifting filter "
"file, \"%s\"! Tap values missing for one or more "
"lifting steps.",filename);
cp = line;
next_cp = NULL;
while ((*cp == ' ') || (*cp == '\t'))
cp++;
for (i=supports[n]-1; i >= 0; i--)
{
taps->int_taps[i] = (int) strtol(cp,&next_cp,10);
if (next_cp == cp)
local_error("Syntax error in user-defined lifting filter "
"file, \"%s\"! Insufficient tap values supplied "
"for lifting step %d out of %d.",filename,
supports[n]-i,supports[n]);
cp = next_cp;
}
if ((sscanf(cp,"%d",&(taps->int_rdx)) < 1) ||
(taps->int_rdx < 0))
local_error("Syntax error in user-defined lifting filter "
"file, \"%s\"! No integer shift found at the "
"end of the line of taps for lifting step %d "
"out of %d.",filename,supports[n]-1,supports[n]);
for (i=0; i < supports[n]; i++)
taps->taps[i] =
((float)(taps->int_taps[i])) / ((float)(1<<taps->int_rdx));
}
fclose(fp);
local_free(filename);
}
/*****************************************************************************/
/* STATIC get_float_lifting_kernel */
/*****************************************************************************/
static int
get_float_lifting_kernel(char *id, char *kernels_dir,
std_lifting_info_ptr lifting)
/* Loads the contents of the `lifting' structure to reflect the
non-reversible lifting implementation of the Wavelet kernel identified
by the `id' string. The kernel scaling factors are initially set to
1.0 here. */
{
int kernel_idx, n, i;
int num_steps = 0, step_supports[8];
double *step_taps[8];
std_tap_info_ptr taps;
int result;
result = 1;
if ((sscanf(id,"%d",&kernel_idx) == 1) &&
(kernel_idx >= 0) && (kernel_idx <= 255))
read_float_lifting_kernel(kernel_idx,lifting,kernels_dir);
else
{ /* Built-in kernel. */
if (strcmp(id,"W9X7") == 0)
{
num_steps = 4;
step_supports[0] = step_supports[1] = 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -