📄 subband.java
字号:
* Creates a Subband element with all the default values. The dimensions
* are (0,0), the upper left corner is (0,0) and the upper-left corner
* with respect to the canvas is (0,0) too.
* */
public Subband() {
}
/**
* Creates the top-level node and the entire subband tree, with the
* top-level dimensions, the number of decompositions, and the
* decomposition tree as specified.
*
* <P>For the analysis subband gain calculation it is assumed that
* analysis filters are normalized with a DC gain of 1 and a Nyquist gain
* of 2.
*
* <P>This constructor does not initialize the value of the magBits member
* variable. This variable is normally initialized by the quantizer, on
* the encoder side, or the bit stream reader, on the decoder side.
*
* @param w The top-level width
*
* @param h The top-level height
*
* @param ulcx The horizontal coordinate of the upper-left corner with
* respect to the canvas origin, in the component grid.
*
* @param ulcy The vertical coordinate of the upper-left corner with
* respect to the canvas origin, in the component grid.
*
* @param lvls The number of levels (or LL decompositions) in the tree.
*
* @param hfilters The horizontal wavelet filters (analysis or synthesis)
* for each resolution level, starting at resolution level 0. If there are
* less elements in the array than there are resolution levels, the last
* element is used for the remaining resolution levels.
*
* @param vfilters The vertical wavelet filters (analysis or synthesis)
* for each resolution level, starting at resolution level 0. If there are
* less elements in the array than there are resolution levels, the last
* element is used for the remaining resolution levels.
*
* @see WaveletTransform
* */
public Subband(int w, int h, int ulcx, int ulcy, int lvls,
WaveletFilter hfilters[], WaveletFilter vfilters[]) {
int i,hi,vi;
Subband cur; // The current subband
// Initialize top-level node
this.w = w;
this.h = h;
this.ulcx = ulcx;
this.ulcy = ulcy;
this.resLvl = lvls;
// First create dyadic decomposition.
cur = this;
for (i=0; i<lvls; i++) {
hi = (cur.resLvl <= hfilters.length) ? cur.resLvl-1 :
hfilters.length-1;
vi = (cur.resLvl <= vfilters.length) ? cur.resLvl-1 :
vfilters.length-1;
cur = cur.split(hfilters[hi],vfilters[vi]);
}
}
/**
* Returns the next subband in the same resolution level, following the
* subband index order. If already at the last subband then null is
* returned. If this subband is not a leaf an IllegalArgumentException is
* thrown.
*
* @return The next subband in the same resolution level, following the
* subband index order, or null if already at last subband.
* */
public Subband nextSubband() {
Subband sb;
if (isNode) {
throw new IllegalArgumentException();
}
switch (orientation) {
case WT_ORIENT_LL:
sb = getParent();
if (sb == null || sb.resLvl != resLvl) {
// Already at top-level or last subband in res. level
return null;
}
else {
return sb.getHL();
}
case WT_ORIENT_HL:
return getParent().getLH();
case WT_ORIENT_LH:
return getParent().getHH();
case WT_ORIENT_HH:
// This is the complicated one
sb = this;
while (sb.orientation == WT_ORIENT_HH) {
sb = sb.getParent();
}
switch (sb.orientation) {
case WT_ORIENT_LL:
sb = sb.getParent();
if (sb == null || sb.resLvl != resLvl) {
// Already at top-level or last subband in res. level
return null;
}
else {
sb = sb.getHL();
}
break;
case WT_ORIENT_HL:
sb = sb.getParent().getLH();
break;
case WT_ORIENT_LH:
sb = sb.getParent().getHH();
break;
default:
throw new Error("You have found a bug in JJ2000");
}
while (sb.isNode) {
sb = sb.getLL();
}
return sb;
default:
throw new Error("You have found a bug in JJ2000");
}
}
/**
* Returns the first leaf subband element in the next higher resolution
* level.
*
* @return The first leaf element in the next higher resolution level, or
* null if there is no higher resolution level.
* */
public Subband getNextResLevel() {
Subband sb;
if (level == 0) { // No higher res. level
return null;
}
// Go up until we get to a different resolution level
sb = this;
do {
sb = sb.getParent();
if (sb == null) { // No higher resolution level
return null;
}
} while (sb.resLvl == resLvl);
// Now go down to HL, which is in next higher resolution level
sb = sb.getHL();
// Now go down LL until get to a leaf
while (sb.isNode) {
sb = sb.getLL();
}
return sb;
}
/**
* Returns a subband element in the tree, given its resolution level and
* subband index. This method searches through the tree.
*
* @param rl The resolution level.
*
* @param sbi The subband index, within the resolution level.
* */
public Subband getSubbandByIdx(int rl, int sbi) {
Subband sb,sb2;
int d,ci;
// Find the root subband for the resolution level
if (rl > resLvl || rl < 0) {
throw new IllegalArgumentException();
}
sb = this;
while (sb.resLvl > rl) {
sb = sb.getLL();
}
// Find depth in this res. level
d = 0;
sb2 = sb;
while (sb2.isNode) {
d++;
sb2 = sb2.getHL();
}
// Check sbi
ci = 1<<(d<<1); // ci = 4^d;
if ((sbi < (ci>>2) || sbi >= ci)) {
// If ((sbi < 4^(d-1)) || sbi >= 4^d)
throw new IllegalArgumentException();
}
// Search for the subband
ci >>=2;
while (sb.isNode) {
switch (sbi / ci) {
case 0:
sb = sb.getLL();
break;
case 1:
sb = sb.getHL();
break;
case 2:
sb = sb.getLH();
break;
case 3:
sb = sb.getHH();
break;
default:
throw new IllegalArgumentException();
}
sbi %= ci;
ci >>= 2;
}
// Return subband
return sb;
}
/**
* Returns a reference to the Subband element to which the specified point
* belongs. The specified point must be inside this (i.e. the one defined
* by this object) subband. This method searches through the tree.
*
* @param x horizontal coordinate of the specified point.
*
* @param y horizontal coordinate of the specified point.
* */
public Subband getSubband(int x, int y) {
Subband cur,hhs;
// Check that we are inside this subband
if (x < ulx || y < uly || x >= ulx+w || y >= uly+h) {
throw new IllegalArgumentException();
}
cur = this;
while (cur.isNode) {
hhs = cur.getHH();
// While we are still at a node -> continue
if (x < hhs.ulx) {
// Is the result of horizontal low-pass
if (y < hhs.uly) {
// Vertical low-pass
cur = cur.getLL();
}
else {
// Vertical high-pass
cur = cur.getLH();
}
}
else {
// Is the result of horizontal high-pass
if (y < hhs.uly) {
// Vertical low-pass
cur = cur.getHL();
}
else {
// Vertical high-pass
cur = cur.getHH();
}
}
}
return cur;
}
/**
* Returns subband informations in a string.
*
* @return Subband informations
* */
public String toString() {
String string =
"w=" + w + ", h=" + h + ", ulx=" + ulx + ", uly=" + uly +
", ulcx= "+ulcx+", ulcy="+ulcy+", idx=" + sbandIdx +
"\norient=" + orientation + ", node=" + isNode +
", level=" + level + ", resLvl=" + resLvl+ ", nomCBlkW=" +
nomCBlkW + ", nomCBlkH=" + nomCBlkH;
return string;
}
/**
* This function returns the horizontal wavelet filter relevant to this
* subband
*
* @return The horizontal wavelet filter
* */
public abstract WaveletFilter getHorWFilter();
/**
* This function returns the vertical wavelet filter relevant to this
* subband
*
* @return The vertical wavelet filter
* */
public abstract WaveletFilter getVerWFilter();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -