📄 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 + -