⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 forwwtfull.java

📁 java 实现的小波压缩库代码,内部包含了分析器
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
                    }
                    if (sb2.gOrient == Subband.WT_ORIENT_LL) {
                        // Only low-pass steps left, no need to continue
                        // checking
                        break;
                    }
                    sb2 = sb2.getParent();
                } while (sb2 != null);
                // There is at least a high-pass step on the vertical
                // decomposition => project to 0
                apoy = 0;
                break;
            case Subband.WT_ORIENT_HH:
                // There is at least a high-pass step on the horiz. and
                // vertical decomposition => project to 0
                apox = 0;
                apoy = 0;
                break;
            default:
                throw new Error("Internal JJ2000 error");
            }
            // 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
            co.x = (sb.ulcx+sb.w-apox+sb.nomCBlkW-1) / 
                sb.nomCBlkW -((sb.ulcx-apox+sb.nomCBlkW)/sb.nomCBlkW-1);
            co.y = (sb.ulcy+sb.h-apoy+sb.nomCBlkH-1) / 
                sb.nomCBlkH -((sb.ulcy-apoy+sb.nomCBlkH)/sb.nomCBlkH-1);
        }
        else {
            co.x = 0;
            co.y = 0;
        }
        return co;
    }
    
    /**
     * Returns the next code-block in the current tile for the specified
     * component. The order in which code-blocks are returned is not
     * specified. However each code-block is returned only once and all
     * code-blocks will be returned if the method is called 'N' times, where
     * 'N' is the number of code-blocks in the tile. After all the code-blocks
     * have been returned for the current tile calls to this method will
     * return 'null'.
     *
     * <p>When changing the current tile (through 'setTile()' or 'nextTile()')
     * this method will always return the first code-block, as if this method
     * was never called before for the new current tile.</p>
     *
     * <p>The data returned by this method is the data in the internal buffer
     * of this object, and thus can not be modified by the caller. The
     * 'offset' and 'scanw' of the returned data have, in general, some
     * non-zero value. The 'magbits' of the returned data is not set by this
     * method and should be ignored. See the 'CBlkWTData' class.</p>
     *
     * <p>The 'ulx' and 'uly' members of the returned 'CBlkWTData' object
     * contain the coordinates of the top-left corner of the block, with
     * respect to the tile, not the subband.</p>
     *
     * @param c The component for which to return the next code-block.
     *
     * @param cblk If non-null this object will be used to return the new
     * code-block. If null a new one will be allocated and returned.
     *
     * @return The next code-block in the current tile for component 'n', or
     * null if all code-blocks for the current tile have been returned.
     *
     * @see CBlkWTData
     * */
    public CBlkWTData getNextInternCodeBlock(int c, CBlkWTData cblk) {
        int cbm,cbn,cn,cm;
        int apox, apoy;
        SubbandAn sb;
	intData = (filters.getWTDataType(tIdx,c)==DataBlk.TYPE_INT);

        //If the source image has not been decomposed 
        if(decomposedComps[c] == null) {
            int k,w,h;
            DataBlk bufblk;
            Object dst_data;
	    
            w = getCompWidth(c);
            h = getCompHeight(c);
	    
            //Get the source image data
            if(intData){
                decomposedComps[c] = new DataBlkInt(0,0,w,h);
                bufblk = new DataBlkInt();
            }
            else {
                decomposedComps[c] = new DataBlkFloat(0,0,w,h);
                bufblk = new DataBlkFloat();
            }
	    
            // Get data from source line by line (this diminishes the memory
            // requirements on the data source)
            dst_data = decomposedComps[c].getData();
            bufblk.ulx = 0;
            bufblk.w = w;
            bufblk.h = 1;
            for (k=0; k<h; k++) {
                bufblk.uly = k;
                bufblk.ulx = 0;
                bufblk = src.getInternCompData(bufblk,c);
                System.arraycopy(bufblk.getData(),bufblk.offset,
                                 dst_data,k*w,w);
            }
                        
            //Decompose source image
            waveletTreeDecomposition(decomposedComps[c],
                                     getSubbandTree(tIdx,c),c); 
	    
            // Make the first subband the current one
            currentSubband[c] = getNextSubband(c);

            lastn[c] = -1;
            lastm[c] = 0;
        }
        
        // Get the next code-block to "send"
        do {
            // Calculate number of code-blocks in current subband
            ncblks = getNumCodeBlocks(currentSubband[c],ncblks);
            // Goto next code-block
            lastn[c]++;
            if (lastn[c] == ncblks.x) { // Got to end of this row of
                // code-blocks
                lastn[c] = 0;
                lastm[c]++;
            }
            if (lastm[c] < ncblks.y) {
                // Not past the last code-block in the subband, we can return
                // this code-block
                break;
            }
            // If we get here we already sent all code-blocks in this subband,
            // goto next subband
            currentSubband[c] = getNextSubband(c);
            lastn[c] = -1;
            lastm[c] = 0;
            if ( currentSubband[c] == null ) {
                // We don't need the transformed data any more (a priori)
                decomposedComps[c] = null;
                // All code-blocks from all subbands in the current
                // tile have been returned so we return a null
                // reference
                return null;
            }
            // Loop to find the next code-block
        } while (true);
        

        // 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.
        apox = pox;
        apoy = poy;
        Subband sb2;
        switch (currentSubband[c].gOrient) {
        case Subband.WT_ORIENT_LL:
            // No need to project since all low-pass => nothing to do
            break;
        case Subband.WT_ORIENT_HL:
            // There is at least a high-pass step on the horizontal
            // decomposition => project to 0
            apox = 0;
            // We need to find out if there has been a high-pass step on the
            // vertical decomposition
            sb2 = currentSubband[c];
            do {
                if (sb2.orientation == Subband.WT_ORIENT_HH ||
                    sb2.orientation == Subband.WT_ORIENT_LH) {
                    // Vertical high-pass step => project to 0 and done
                    apoy = 0;
                    break;
                }
                if (sb2.gOrient == Subband.WT_ORIENT_LL) {
                    // Only low-pass steps left, no need to continue checking
                    break;
                }
                sb2 = sb2.getParent();
            } while (sb2 != null);
            break;
        case Subband.WT_ORIENT_LH:
            // We need to find out if there has been a high-pass step on the
            // horizontal decomposition
            sb2 = currentSubband[c];
            do {
                if (sb2.orientation == Subband.WT_ORIENT_HH ||
                    sb2.orientation == Subband.WT_ORIENT_HL) {
                    // Horizontal high-pass step => project to 0 and done
                    apox = 0;
                    break;
                }
                if (sb2.gOrient == Subband.WT_ORIENT_LL) {
                    // Only low-pass steps left, no need to continue checking
                    break;
                }
                sb2 = sb2.getParent();
            } while (sb2 != null);
            // There is at least a high-pass step on the vertical
            // decomposition => project to 0
            apoy = 0;
            break;
        case Subband.WT_ORIENT_HH:
            // There is at least a high-pass step on the horiz. and vertical
            // decomposition => project to 0
            apox = 0;
            apoy = 0;
            break;
        default:
            throw new Error("Internal JJ2000 error");
        }

        // Initialize output code-block
        if ( cblk==null ) {
            if (intData) {
                cblk = new CBlkWTDataInt();
            }
            else {
                cblk = new CBlkWTDataFloat();
            }
        }
        cbn = lastn[c];
        cbm = lastm[c];
        sb = currentSubband[c];
        cblk.n = cbn;
        cblk.m = cbm;
        cblk.sb = sb;
        // Calculate the indexes of first code-block in subband w/respect to
        // the partitioning origin, to then calculate the position and size
        // 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
        cn = (sb.ulcx-apox+sb.nomCBlkW)/sb.nomCBlkW-1;
        cm = (sb.ulcy-apoy+sb.nomCBlkH)/sb.nomCBlkH-1;
        if (cbn == 0) { // Left-most code-block, starts where subband starts
            cblk.ulx = sb.ulx;
        }
        else {
            // Calculate starting canvas coordinate and convert to subb. coords
            cblk.ulx = (cn+cbn)*sb.nomCBlkW - (sb.ulcx-apox) + sb.ulx;
        }
        if (cbm == 0) { // Bottom-most code-block, starts where subband starts
            cblk.uly = sb.uly;
        }
        else {
            cblk.uly = (cm+cbm)*sb.nomCBlkH - (sb.ulcy-apoy) + sb.uly;
        }
        if (cbn < ncblks.x-1) {
            // Calculate where next code-block starts => width
            cblk.w = (cn+cbn+1)*sb.nomCBlkW - (sb.ulcx-apox) + sb.ulx -
                cblk.ulx;
        }
        else { // Right-most code-block, ends where subband ends
            cblk.w = sb.ulx+sb.w-cblk.ulx;
        }
        if (cbm < ncblks.y-1) {
            // Calculate where next code-block starts => height
            cblk.h = (cm+cbm+1)*sb.nomCBlkH - (sb.ulcy-apoy) + sb.uly -
                cblk.uly;
        }
        else { // Bottom-most code-block, ends where subband ends
            cblk.h = sb.uly+sb.h-cblk.uly;
        }
        cblk.wmseScaling = 1f;
 
        // Since we are in getNextInternCodeBlock() we can return a
        // reference to the internal buffer, no need to copy. Just initialize
        // the 'offset' and 'scanw'
        cblk.offset = cblk.uly*decomposedComps[c].w+cblk.ulx;
        cblk.scanw = decomposedComps[c].w;

        // For the data just put a reference to our buffer
        cblk.setData(decomposedComps[c].getData());
        // Return code-block
        return cblk;
    }
    
    /**
     * Returns the next code-block in the current tile for the specified
     * component, as a copy (see below). The order in which code-blocks are
     * returned is not specified. However each code-block is returned only
     * once and all code-blocks will be returned if the method is called 'N'
     * times, where 'N' is the number of code-blocks in the tile. After all
     * the code-blocks have been returned for the current tile calls to this
     * method will return 'null'.
     *
     * <p>When changing the current tile (through 'setTile()' or 'nextTile()')
     * this method will always return the first code-block, as if this method
     * was never called before for the new current tile.</p>
     *
     * <p>The data returned by this method is always a copy of the internal
     * data of this object, and it can be modified "in place" without
     * any problems after being returned. The 'offset' of the returned data is
     * 0, and the 'scanw' is the same as the code-block width.  The 'magbits'
     * of the returned data is not set by this method and should be
     * ignored. See the 'CBlkWTData' class.</p>
     *
     * <p>The 'ulx' and 'uly' members of the returned 'CBlkWTData' object
     * contain the coordinates of the top-left corner of the block, with
     * respect to the tile, not the subband.</p>
     *
     * @param c The component for which to return the next code-block.
     *
     * @param cblk If non-null this object will be used to return the new
     * code-block. If null a new one will be allocated and returned. If the
     * "data" array of the object is non-null it will be reused, if possible,
     * to return the data.
     *
     * @return The next code-block in the current tile for component 'c', or
     * null if all code-blocks for the current tile have been returned.
     *
     * @see CBlkWTData
     * */
    public CBlkWTData getNextCodeBlock(int c, CBlkWTData cblk) {
        // We can not directly use getNextInternCodeBlock() since that returns
        // a reference to the internal buffer, we have to copy that data

        int j,k;
        int w;
        Object dst_data; // a int[] or float[] object
        int[] dst_data_int;
        float[] dst_data_float;
        Object src_data; // a int[] or float[] object

	intData = (filters.getWTDataType(tIdx,c)==DataBlk.TYPE_INT);

        dst_data = null;

        // Cache the data array, if any
        if (cblk != null) {
            dst_data = cblk.getData();
        }

        // Get the next code-block
        cblk = getNextInternCodeBlock(c,cblk);

        if (cblk == null) {
            return null; // No more code-blocks in current tile for component
            // c
        }

        // Ensure size of output buffer
        if (intData) { // int data
            dst_data_int = (int[]) dst_data;
            if (dst_data_int == null || dst_data_int.length < cblk.w*cblk.h) {
                dst_data = new int[cblk.w*cblk.h];
            }
        }
        else { // float data
            dst_data_float = (float[]) dst_data;
            if (dst_data_float == null ||
                dst_data_float.length < cblk.w*cblk.h) {
                dst_data = new float[cblk.w*cblk.h];
            }
        }
	
        // Copy data line by line
        src_data = cblk.getData();
        w = cblk.w;
        for (j = w*(cblk.h-1), k = cblk.offset+(cblk.h-1)*cblk.scanw;
             j >= 0; j -= w, k -= cblk.scanw) {
            System.arraycopy(src_data,k,dst_data,j,w);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -