📄 dwt_aux.cpp
字号:
end = i;
SegLength = end-start;
odd = start%2;
if(SegLength==1) { /* special case for single poInt */
#ifdef _DWT_INT_
ret=DecomposeSegmentOddSymInt(InBuf+start, OutBuf+(start>>1),
OutBuf+(Length>>1)+(start>>1), odd,
SegLength, Filter);
#else
ret=DecomposeSegmentOddSymDbl(InBuf+start, OutBuf+(start>>1),
OutBuf+(Length>>1)+(start>>1), odd,
SegLength, Filter);
#endif
if(ret!=DWT_OK) return(ret);
/* swap the subsampled mask for single poInt if highpass is IN */
if(Direction == DWT_HORIZONTAL) {
/* After horizontal decomposition,
LP mask symbols: IN, OUT0;
HP mask symbols: IN, OUT0, OUT1 */
if(OutMaskBuf[start>>1]==DWT_OUT0) {
OutMaskBuf[start>>1] = DWT_IN;
OutMaskBuf[(start>>1)+(Length>>1)]=DWT_OUT1;
}
}
else { /* vertical */
/* After vertical decomposition,
LLP mask symbols: IN, OUT0;
LHP mask symbols: IN, OUT2, OUT3;
HLP mask symbols: IN, OUT0, OUT1;
HHP mask symbols: IN, OUT0, OUT1, OUT2, OUT3 */
if(OutMaskBuf[start>>1] == DWT_OUT0) {
OutMaskBuf[(start>>1)+(Length>>1)]= DWT_OUT2 ;
OutMaskBuf[start>>1] = DWT_IN;
}
else if(OutMaskBuf[start>>1] == DWT_OUT1) {
OutMaskBuf[(start>>1)+(Length>>1)]= DWT_OUT3 ;
OutMaskBuf[start>>1] = DWT_IN;
}
}
}
else {
#ifdef _DWT_INT_
ret=DecomposeSegmentOddSymInt(InBuf+start, OutBuf+((start+1)>>1),
OutBuf+(Length>>1)+(start>>1), odd,
SegLength, Filter);
#else
ret=DecomposeSegmentOddSymDbl(InBuf+start, OutBuf+((start+1)>>1),
OutBuf+(Length>>1)+(start>>1), odd,
SegLength, Filter);
#endif
if(ret!=DWT_OK) return(ret);
}
}
return(DWT_OK);
}
/*
Function: DecomposeSegmentOddSymInt() or DecomposeSegmentOddSymDbl()
Description: SA-Decompose a 1D segment based on its InitPos and Length using
Odd-Symmetric Filters
Input:
In -- Input data segment;
PosFlag -- Start position of this segment (ODD or EVEN);
Length -- Length of this Segment;
Filter -- Filter used;
Output:
OutL -- Low pass data;
OutH -- High pass data;
Return: Return DWT_OK if Successful
*/
#ifdef _DWT_INT_
Int VTCDWT:: DecomposeSegmentOddSymInt(DWTDATA *In, DWTDATA *OutL, DWTDATA *OutH,
Int PosFlag, Int Length, FILTER *Filter)
#else
Int VTCDWT:: DecomposeSegmentOddSymDbl(DWTDATA *In, DWTDATA *OutL, DWTDATA *OutH,
Int PosFlag, Int Length, FILTER *Filter)
#endif
{
/* filter coefficients */
#ifdef _DWT_INT_
Short *LPCoeff = (Short *)Filter->LPCoeff, *HPCoeff = (Short *)Filter->HPCoeff;
Short *fi;
#else
double *LPCoeff = (double *)Filter->LPCoeff, *HPCoeff = (double *)Filter->HPCoeff;
double *fi;
#endif
Int ltaps = Filter->LPLength, htaps = Filter->HPLength; /* filter lengths*/
Int loffset = ltaps/2, hoffset = htaps/2; /* Filter offset */
Int border = (ltaps>htaps)?ltaps:htaps; /*the larger of ltaps and htaps */
Int m, n;
DWTDATA *f,*pixel, *pixel1, val, *buf, *a;
Int r = Length-1;
/* prIntf("Length=%d\n", Length); */
if(Length == 1) {
*OutL = 0; // hjlee 0928
for (m=0; m<ltaps;m++)
*OutL += *In * (*(LPCoeff+m));
/* *OutL = *In * Filter->Scale; */
return (DWT_OK);
}
/* allocate proper buffer */
buf = (DWTDATA *) malloc((Length+2*border)*sizeof(DWTDATA));
if(buf==NULL) return(DWT_MEMORY_FAILED);
/* now symmetric extend this segment */
a = buf+border;
for(m=0;m< Length; m++) {
a[m] = In[m];
/* prIntf("%f ", a[m]); */
}
/* prIntf("\n"); */
/* symmetric extension */
for (m=1 ; m<=border; m++)
{
a[-m] = a[m]; /* to allow Shorter seg */
a[r+m] = a[r-m];
}
f = buf + border + Length;
/* always subsample even positions in a line for LP coefficents */
if (PosFlag==DWT_ODD) a = buf + border + 1;
else a = buf + border;
for (; a<f; a +=2)
{
/* filter the pixel with lowpass filter */
for( fi=LPCoeff, pixel=a-loffset, pixel1=pixel+ltaps-1,val=0, n=0;
n<(ltaps>>1);
n++, fi++, pixel++, pixel1--)
val += (*fi * (*pixel + *pixel1)); /* symmetric */
val += (*fi * *pixel);
*OutL++ = val;
}
/* always subsample odd positions in a line for HP coefficients */
if (PosFlag==DWT_ODD) a = buf + border;
else a = buf + border+1;
for (; a<f; a +=2)
{
/* filter the pixel with highpass filter */
for(fi=HPCoeff, pixel=a-hoffset, pixel1 = pixel+htaps-1, val=0, n=0;
n<(htaps>>1);
n++, fi++, pixel++, pixel1--)
val += (*fi * (*pixel + *pixel1)); /* symmetric */
val += (*fi * *pixel);
*OutH++ = val;
}
free(buf);
return(DWT_OK);
}
/* Function: SADWT1dEvenSymInt() or SADWT1dEvenSymDbl()
Description: 1D SA-DWT using Even Symmetric Filter
Input:
InBuf -- Input 1d data buffer
InMaskBuf -- Input 1d mask buffer
Length -- length of the input data
Filter -- filter used
Direction -- vertical or horizontal decomposition (used for inversible
mask decomposition)
Output:
OutBuf -- Transformed 1d Data
OutMask -- Mask for the Transformed 1d Data
Return: return DWT_OK if successful
*/
#ifdef _DWT_INT_
Int VTCDWT:: SADWT1dEvenSymInt(DWTDATA *InBuf, UChar *InMaskBuf, DWTDATA *OutBuf,
UChar *OutMaskBuf, Int Length, FILTER *Filter,
Int Direction)
#else
Int VTCDWT:: SADWT1dEvenSymDbl(DWTDATA *InBuf, UChar *InMaskBuf, DWTDATA *OutBuf,
UChar *OutMaskBuf, Int Length, FILTER *Filter,
Int Direction)
#endif
{
Int i;
Int SegLength = 0;
Int odd;
Int start, end;
UChar *a, *b, *c;
Int ret;
/* double check filter class and type */
if(Filter->DWT_Class != DWT_EVEN_SYMMETRIC) return(DWT_INTERNAL_ERROR);
#ifdef _DWT_INT_
if(Filter->DWT_Type != DWT_INT_TYPE) return(DWT_INTERNAL_ERROR);
#else
if(Filter->DWT_Type != DWT_DBL_TYPE) return(DWT_INTERNAL_ERROR);
#endif
/* double check if Length is even */
if(Length & 1) return(DWT_INTERNAL_ERROR);
/* initial mask output */
for(a=InMaskBuf, b = OutMaskBuf, c= OutMaskBuf+(Length>>1); a<InMaskBuf+Length;) {
*b++ = *a++;
*c++ = *a++;
}
/* initial OutBuf to zeros */
memset(OutBuf, (UChar)0, sizeof(DWTDATA)*Length);
i = 0;
a = InMaskBuf;
while(i<Length) {
/* search for a segment */
while(i<Length && (a[i])!=DWT_IN) i++;
start = i;
if(i >= Length) break;
while(i<Length && (a[i])==DWT_IN) i++;
end = i;
SegLength = end-start;
odd = start%2;
if(SegLength==1) { /* special case for single poInt */
#ifdef _DWT_INT_
ret=DecomposeSegmentEvenSymInt(InBuf+start, OutBuf+(start>>1),
OutBuf+(Length>>1)+(start>>1), odd,
SegLength, Filter);
#else
ret=DecomposeSegmentEvenSymDbl(InBuf+start, OutBuf+(start>>1),
OutBuf+(Length>>1)+(start>>1), odd,
SegLength, Filter);
#endif
if(ret!=DWT_OK) return(ret);
}
else {
#ifdef _DWT_INT_
ret=DecomposeSegmentEvenSymInt(InBuf+start, OutBuf+(start>>1),
OutBuf+(Length>>1)+((start+1)>>1), odd,
SegLength, Filter);
#else
ret=DecomposeSegmentEvenSymDbl(InBuf+start, OutBuf+(start>>1),
OutBuf+(Length>>1)+((start+1)>>1), odd,
SegLength, Filter);
#endif
if(ret!=DWT_OK) return(ret);
}
/* swap the subsampled mask for the start of segment if it is odd*/
if(odd) {
if(Direction == DWT_HORIZONTAL) {
/* After horizontal decomposition,
LP mask symbols: IN, OUT0;
HP mask symbols: IN, OUT0, OUT1 */
if(OutMaskBuf[start>>1]==DWT_OUT0) {
OutMaskBuf[start>>1] = DWT_IN;
OutMaskBuf[(start>>1)+(Length>>1)]=DWT_OUT1;
}
}
else { /* vertical */
/* After vertical decomposition,
LLP mask symbols: IN, OUT0;
LHP mask symbols: IN, OUT2, OUT3;
HLP mask symbols: IN, OUT0, OUT1;
HHP mask symbols: IN, OUT0, OUT1, OUT2, OUT3 */
if(OutMaskBuf[start>>1] == DWT_OUT0) {
OutMaskBuf[(start>>1)+(Length>>1)]= DWT_OUT2 ;
OutMaskBuf[start>>1] = DWT_IN;
}
else if(OutMaskBuf[start>>1] == DWT_OUT1) {
OutMaskBuf[(start>>1)+(Length>>1)]= DWT_OUT3 ;
OutMaskBuf[start>>1] = DWT_IN;
}
}
}
}
return(DWT_OK);
}
/*
Function: DecomposeSegmentEvenSymInt() or DecomposeSegmentEvenSymDbl()
Description: SA-Decompose a 1D segment based on its InitPos and Length using
Even-Symmetric Filters
Input:
In -- Input data segment;
PosFlag -- Start position of this segment (ODD or EVEN);
Length -- Length of this Segment;
Filter -- Filter used;
Output:
OutL -- Low pass data;
OutH -- High pass data;
Return: Return DWT_OK if Successful
*/
#ifdef _DWT_INT_
Int VTCDWT:: DecomposeSegmentEvenSymInt(DWTDATA *In, DWTDATA *OutL, DWTDATA *OutH,
Int PosFlag, Int Length, FILTER *Filter)
#else
Int VTCDWT:: DecomposeSegmentEvenSymDbl(DWTDATA *In, DWTDATA *OutL, DWTDATA *OutH,
Int PosFlag, Int Length, FILTER *Filter)
#endif
{
/* filter coefficients */
#ifdef _DWT_INT_
Short *LPCoeff = (Short *)Filter->LPCoeff, *HPCoeff = (Short *)Filter->HPCoeff;
Short *fi;
#else
double *LPCoeff = (double *)Filter->LPCoeff, *HPCoeff = (double *)Filter->HPCoeff;
double *fi;
#endif
Int ltaps = Filter->LPLength, htaps = Filter->HPLength; /* filter lengths*/
Int loffset = ltaps/2-1, hoffset = htaps/2-1; /* Filter offset */
Int border = (ltaps>htaps)?ltaps:htaps; /*the larger of ltaps and htaps */
Int m, n;
DWTDATA *f,*pixel, *pixel1, val, *buf, *a;
Int r = Length-1;
if(Length == 1) {
*OutL = 0; // hjlee 0928
for (m=0;m<ltaps; m++)
*OutL += *In * (*(LPCoeff+m)); // hjlee 0928
/* *OutL = *In * Filter->Scale; */
return (DWT_OK);
}
/* allocate proper buffer */
buf = (DWTDATA *) malloc((Length+2*border)*sizeof(DWTDATA));
if(buf==NULL) return(DWT_MEMORY_FAILED);
/* now symmetric extend this segment */
a = buf+border;
for(m=0;m< Length; m++) {
a[m] = In[m];
}
/* symmetric extension */
for (m=1 ; m<=border; m++)
{
a[-m] = a[m-1]; /* to allow Shorter seg */
a[r+m] = a[r-m+1];
}
f = buf + border + Length;
/* always subsample even positions in a line for LP coefficents */
if (PosFlag==DWT_ODD) a = buf + border - 1;
else a = buf + border;
for (; a<f; a +=2)
{
/* filter the pixel with lowpass filter */
for( fi=LPCoeff, pixel=a-loffset, pixel1=pixel+ltaps-1, val=0, n=0;
n<(ltaps>>1);
n++, fi++, pixel++, pixel1--)
val += (*fi * (*pixel + *pixel1)); /* symmetric */
*OutL++ = val;
}
/* always subsample even positions in a line for HP coefficients */
if (PosFlag==DWT_ODD) a = buf + border +1;
else a = buf + border;
for (; a<f; a +=2)
{
/* filter the pixel with highpass filter */
for(fi=HPCoeff, pixel=a-hoffset, pixel1 = pixel+htaps-1, val=0, n=0;
n<(htaps>>1);
n++, fi++, pixel++, pixel1--)
val += (*fi * (*pixel - *pixel1)); /* antisymmetric */
*OutH++ = val;
}
free(buf);
return(DWT_OK);
}
#ifdef _DWT_INT_
#undef _DWT_INT_
#define _DWT_DBL_
#include "dwt_aux.cpp"
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -