📄 forwwtfull.java
字号:
} while(nextsb.isNode); return nextsb; } /** * Performs the forward wavelet transform on the whole band. It * iteratively decomposes the subbands from the top node to the leaves. * * @param band The band containing the float data to decompose * * @param subband The structure containing the coordinates of the current * subband in the whole band to decompose. * * @param c The index of the current component to decompose * */ private void waveletTreeDecomposition(DataBlk band, SubbandAn subband, int c) { //If the current subband is a leaf then nothing to be done (a leaf is //not decomposed). if(!subband.isNode) { return; } else { //Perform the 2D wavelet decomposition of the current subband wavelet2DDecomposition(band, (SubbandAn)subband, c); //Perform the decomposition of the four resulting subbands waveletTreeDecomposition(band, (SubbandAn)subband.getHH(), c); waveletTreeDecomposition(band, (SubbandAn)subband.getLH(), c); waveletTreeDecomposition(band, (SubbandAn)subband.getHL(), c); waveletTreeDecomposition(band, (SubbandAn)subband.getLL(), c); } } /** * Performs the 2D forward wavelet transform on a subband of the initial * band. This method will successively perform 1D filtering steps on all * lines and then all columns of the subband. In this class only filters * with floating point implementations can be used. * * @param band The band containing the float data to decompose * * @param subband The structure containing the coordinates of the subband * in the whole band to decompose. * * @param c The index of the current component to decompose * */ private void wavelet2DDecomposition(DataBlk band,SubbandAn subband,int c) { int ulx, uly, w, h; int band_w, band_h; // If subband is empty (i.e. zero size) nothing to do if (subband.w == 0 || subband.h == 0) { return; } ulx = subband.ulx; uly = subband.uly; w = subband.w; h = subband.h; band_w = getTileCompWidth(tIdx,c); band_h = getTileCompHeight(tIdx,c); if (intData) { //Perform the decompositions if the filter is implemented with an //integer arithmetic. int i, j; int offset; int[] tmpVector = new int[java.lang.Math.max(w,h)]; int[] data = ((DataBlkInt)band).getDataInt(); //Perform the vertical decomposition if (subband.ulcy%2==0) { // Even start index => use LPF for(j=0; j<w; j++) { offset = uly*band_w + ulx+j; for(i=0; i<h; i++) tmpVector[i] = data[offset+(i*band_w)]; subband.vFilter.analyze_lpf(tmpVector, 0, h, 1, data, offset, band_w, data, offset+((h+1)/2)*band_w, band_w); } } else { // Odd start index => use HPF for(j=0; j<w; j++) { offset = uly*band_w + ulx+j; for(i=0; i<h; i++) tmpVector[i] = data[offset+(i*band_w)]; subband.vFilter.analyze_hpf(tmpVector, 0, h, 1, data, offset, band_w, data, offset+(h/2)*band_w, band_w); } } //Perform the horizontal decomposition. if (subband.ulcx%2==0) { // Even start index => use LPF for(i=0; i<h; i++) { offset = (uly+i)*band_w + ulx; for(j=0; j<w; j++) tmpVector[j] = data[offset+j]; subband.hFilter.analyze_lpf(tmpVector, 0, w, 1, data, offset, 1, data, offset+(w+1)/2, 1); } } else { // Odd start index => use HPF for(i=0; i<h; i++) { offset = (uly+i)*band_w + ulx; for(j=0; j<w; j++) tmpVector[j] = data[offset+j]; subband.hFilter.analyze_hpf(tmpVector, 0, w, 1, data, offset, 1, data, offset+w/2, 1); } } } else { //Perform the decompositions if the filter is implemented with a //float arithmetic. int i, j; int offset; float[] tmpVector = new float[java.lang.Math.max(w,h)]; float[]data = ((DataBlkFloat)band).getDataFloat(); //Perform the vertical decomposition. if (subband.ulcy%2==0) { // Even start index => use LPF for(j=0; j<w; j++) { offset = uly*band_w + ulx+j; for(i=0; i<h; i++) tmpVector[i] = data[offset+(i*band_w)]; subband.vFilter.analyze_lpf(tmpVector, 0, h, 1, data, offset, band_w, data, offset+((h+1)/2)*band_w, band_w); } } else { // Odd start index => use HPF for(j=0; j<w; j++) { offset = uly*band_w + ulx+j; for(i=0; i<h; i++) tmpVector[i] = data[offset+(i*band_w)]; subband.vFilter.analyze_hpf(tmpVector, 0, h, 1, data, offset, band_w, data, offset+(h/2)*band_w, band_w); } } //Perform the horizontal decomposition. if (subband.ulcx%2==0) { // Even start index => use LPF for(i=0; i<h; i++) { offset = (uly+i)*band_w + ulx; for(j=0; j<w; j++) tmpVector[j] = data[offset+j]; subband.hFilter.analyze_lpf(tmpVector, 0, w, 1, data, offset, 1, data, offset+(w+1)/2, 1); } } else { // Odd start index => use HPF for(i=0; i<h; i++) { offset = (uly+i)*band_w + ulx; for(j=0; j<w; j++) tmpVector[j] = data[offset+j]; subband.hFilter.analyze_hpf(tmpVector, 0, w, 1, data, offset, 1, data, offset+w/2, 1); } } } } /** * Changes the current tile, given the new coordinates. * * <p>This method resets the 'subbTrees' array, and recalculates the * values of the 'reversible' array. It also resets the decomposed * component buffers.</p> * * @param x The horizontal coordinate of the tile. * * @param y The vertical coordinate of the new tile. * */ public void setTile(int x, int y) { int i; // Change tile super.setTile(x,y); // Reset the decomposed component buffers. if (decomposedComps != null) { for (i=decomposedComps.length-1; i>=0; i--) { decomposedComps[i] = null; currentSubband[i] = null; } } } /** * Advances to the next tile, in standard scan-line order (by rows then * columns). An NoNextElementException is thrown if the current tile is * the last one (i.e. there is no next tile). * * <p>This method resets the 'subbTrees' array, and recalculates the * values of the 'reversible' array. It also resets the decomposed * component buffers.</p> * */ public void nextTile() { int i; // Change tile super.nextTile(); // Reset the decomposed component buffers if (decomposedComps != null) { for (i=decomposedComps.length-1; i>=0; i--) { decomposedComps[i] = null; currentSubband[i] = null; } } } /** * Returns a reference to the subband tree structure representing the * subband decomposition for the specified tile-component of the source. * * @param t The index of the tile. * * @param c The index of the component. * * @return The subband tree structure, see Subband. * * @see SubbandAn * @see Subband * */ public SubbandAn getAnSubbandTree(int t,int c) { if (subbTrees[t][c] == null) { subbTrees[t][c] = new SubbandAn(getTileCompWidth(t,c),getTileCompHeight(t,c), getCompULX(c),getCompULY(c), getDecompLevels(t,c), getHorAnWaveletFilters(t,c), getVertAnWaveletFilters(t,c)); initSubbandsFields(t,c,subbTrees[t][c]); } return subbTrees[t][c]; } /** * Initialises subbands fields, such as number of code-blocks and * code-blocks dimension, in the subband tree. The nominal code-block * width/height depends on the precincts dimensions if used. * * @param t The tile index of the subband * * @param c The component index * * @param sb The subband tree to be initialised. * */ private void initSubbandsFields(int t,int c,Subband sb) { int cbw = cblks.getCBlkWidth(ModuleSpec.SPEC_TILE_COMP,t,c); int cbh = cblks.getCBlkHeight(ModuleSpec.SPEC_TILE_COMP,t,c); if (!sb.isNode) { // Code-blocks dimension int ppx, ppy; int ppxExp, ppyExp, cbwExp, cbhExp; ppx = pss.getPPX(t,c,sb.resLvl); ppy = pss.getPPY(t,c,sb.resLvl); if (ppx!=Markers.PRECINCT_PARTITION_DEF_SIZE || ppy!=Markers.PRECINCT_PARTITION_DEF_SIZE ) { ppxExp = MathUtil.log2(ppx); ppyExp = MathUtil.log2(ppy); cbwExp = MathUtil.log2(cbw); cbhExp = MathUtil.log2(cbh); // Precinct partition is used switch (sb.resLvl) { case 0: sb.nomCBlkW = ( cbwExp<ppxExp ? (1<<cbwExp) : (1<<ppxExp) ); sb.nomCBlkH = ( cbhExp<ppyExp ? (1<<cbhExp) : (1<<ppyExp) ); break; default: sb.nomCBlkW = ( cbwExp<ppxExp-1 ? (1<<cbwExp) : (1<<(ppxExp-1)) ); sb.nomCBlkH = ( cbhExp<ppyExp-1 ? (1<<cbhExp) : (1<<(ppyExp-1)) ); break; } } else { sb.nomCBlkW = cbw; sb.nomCBlkH = cbh; } // Number of code-blocks if(sb.numCb==null) sb.numCb = new Coord(); if(sb.w!=0 && sb.h!=0) { int acb0x = cb0x; int acb0y = cb0y; int tmp; // Project code-block partition origin to subband. Since the // origin is always 0 or 1, it projects to the low-pass side // (throught the ceil operator) as itself (i.e. no change) and // to the high-pass side (through the floor operator) as 0, // always. switch (sb.sbandIdx) { case Subband.WT_ORIENT_LL: // No need to project since all low-pass => nothing to do break; case Subband.WT_ORIENT_HL: acb0x = 0; break; case Subband.WT_ORIENT_LH: acb0y = 0; break; case Subband.WT_ORIENT_HH: acb0x = 0; acb0y = 0; break; default: throw new Error("Internal JJ2000 error"); } if(sb.ulcx-acb0x<0 || sb.ulcy-acb0y<0) { throw new IllegalArgumentException("Invalid code-blocks "+ "partition origin or "+ "image offset in the "+ "reference grid."); } // NOTE: when calculating "floor()" by integer division the // dividend and divisor must be positive, we ensure that by // adding the divisor to the dividend and then substracting 1 // to the result of the division tmp = sb.ulcx-acb0x+sb.nomCBlkW; sb.numCb.x = (tmp+sb.w-1)/sb.nomCBlkW - (tmp/sb.nomCBlkW-1); tmp = sb.ulcy-acb0y+sb.nomCBlkH; sb.numCb.y = (tmp+sb.h-1)/sb.nomCBlkH - (tmp/sb.nomCBlkH-1); } else { sb.numCb.x = sb.numCb.y = 0; } } else { initSubbandsFields(t,c,sb.getLL()); initSubbandsFields(t,c,sb.getHL()); initSubbandsFields(t,c,sb.getLH()); initSubbandsFields(t,c,sb.getHH()); } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -