stdentropycoder.java

来自「jpeg2000编解码」· Java 代码 · 共 1,566 行 · 第 1/5 页

JAVA
1,566
字号
        }        // If we do timing create necessary structures        if (DO_TIMING) {            time = new long[src.getNumComps()];            // If we are timing make sure that 'finalize' gets called.            System.runFinalizersOnExit(true);        }        // If using multithreaded implementation get necessasry objects        if (nt > 0) {            FacilityManager.getMsgLogger().                printmsg(MsgLogger.INFO,                         "Using multithreaded entropy coder "+                         "with "+nt+" compressor threads.");            tsl = nt;            tPool = new ThreadPool(nt,Thread.currentThread().getPriority()+                                   THREADS_PRIORITY_INC,"StdEntropyCoder");	    idleComps = new Stack();            completedComps = new Stack[src.getNumComps()];            nBusyComps = new int[src.getNumComps()];            finishedTileComponent = new boolean[src.getNumComps()];            for (i=src.getNumComps()-1; i>=0; i--) {                completedComps[i] = new Stack();            }	    for (i=0; i<nt; i++) {		idleComps.push(new StdEntropyCoder.Compressor(i));	    }        } else {            tsl = 1;            tPool = null;	    idleComps = null;            completedComps = null;            nBusyComps = null;            finishedTileComponent = null;        }        // Allocate data structures        outT = new ByteOutputBuffer[tsl];        mqT = new MQCoder[tsl];        boutT = new BitToByteOutput[tsl];        stateT = new int[tsl][(maxCBlkWidth+2)*((maxCBlkHeight+1)/2+2)];        symbufT = new int[tsl][maxCBlkWidth*(STRIPE_HEIGHT*2+2)];        ctxtbufT =  new int[tsl][maxCBlkWidth*(STRIPE_HEIGHT*2+2)];        distbufT = new double[tsl][32*NUM_PASSES];        ratebufT = new int[tsl][32*NUM_PASSES];        istermbufT = new boolean[tsl][32*NUM_PASSES];        srcblkT = new CBlkWTData[tsl];        for (i=0; i<tsl; i++) {            outT[i] = new ByteOutputBuffer();            mqT[i] = new MQCoder(outT[i],NUM_CTXTS,MQ_INIT);        }        precinctPartition = new boolean [src.getNumComps()][src.getNumTiles()];                // Create the subband description for each component and each tile        Subband sb = null;        Coord numTiles = null;        int nc = getNumComps();        numTiles = src.getNumTiles(numTiles);        initTileComp(getNumTiles(),nc);                for (int c=0; c<nc; c++) {            for (int tY=0; tY<numTiles.y; tY++) {                for (int tX=0; tX<numTiles.x; tX++) {                     precinctPartition[c][tIdx] = false;                }            }        }    }    /**     * Prints the timing information, if collected, and calls 'finalize' on     * the super class.     * */    public void finalize() throws Throwable {        if (DO_TIMING) {            int c;            StringBuffer sb;            if (tPool == null) { // Single threaded implementation                sb = new StringBuffer("StdEntropyCoder compression wall "+                                      "clock time:");                for (c=0; c<time.length; c++) {                    sb.append("\n  component ");                    sb.append(c);                    sb.append(": ");                    sb.append(time[c]);                    sb.append(" ms");                }                FacilityManager.getMsgLogger().                    printmsg(MsgLogger.INFO,sb.toString());            } else { // Multithreaded implementation                Compressor compr;                MsgLogger msglog = FacilityManager.getMsgLogger();                sb = new StringBuffer("StdEntropyCoder manager thread "+                                      "wall clock time:");                for (c=0; c<time.length; c++) {                    sb.append("\n  component ");                    sb.append(c);                    sb.append(": ");                    sb.append(time[c]);                    sb.append(" ms");                }                Enumeration enum = idleComps.elements();                sb.append("\nStdEntropyCoder compressor threads wall clock "+                          "time:");                while (enum.hasMoreElements()) {                    compr = (Compressor)(enum.nextElement());                    for (c=0; c<time.length; c++) {                        sb.append("\n  compressor ");                        sb.append(compr.getIdx());                        sb.append(", component ");                        sb.append(c);                        sb.append(": ");                        sb.append(compr.getTiming(c));                        sb.append(" ms");                    }                }                FacilityManager.getMsgLogger().                    printmsg(MsgLogger.INFO,sb.toString());            }        }        super.finalize();    }    /**     * Returns the code-block width for the specified tile and component.     *     * @param t The tile index     *      * @param c the component index     *     * @return The code-block width for the specified tile and component     * */    public int getCBlkWidth(int t, int c) {        return cblks.getCBlkWidth(ModuleSpec.SPEC_TILE_COMP,t,c);    }    /**     * Returns the code-block height for the specified tile and component.     *     * @param t The tile index     *     * @param c The component index     *     * @return The code-block height for the specified tile and component.     * */    public int getCBlkHeight(int t,int c) {        return cblks.getCBlkHeight(ModuleSpec.SPEC_TILE_COMP,t,c);    }    /**     * Returns the next coded 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, if any, and it can be modified "in place" without     * any problems after being returned.</p>     *     * @param c The component for which to return the next code-block.     *     * @param ccb If non-null this object might be used in returning the coded     * code-block in this or any subsequent call to this method. If null a new     * one is created and returned. If the 'data' array of 'cbb' is not null     * it may be reused to return the compressed data.     *     * @return The next coded code-block in the current tile for component     * 'n', or null if all code-blocks for the current tile have been     * returned.     *     * @see CBlkRateDistStats     * */    public CBlkRateDistStats getNextCodeBlock(int c, CBlkRateDistStats ccb) {        long stime = 0L;     // Start time for timed sections        if (tPool == null) { // Use single threaded implementation            // Get code-block data from source            srcblkT[0] = src.getNextInternCodeBlock(c,srcblkT[0]);            if (DO_TIMING) stime = System.currentTimeMillis();            if (srcblkT[0] == null) { // We got all code-blocks                return null;            }            // Initialize thread local variables            if((opts[tIdx][c]&OPT_BYPASS) != 0 && boutT[0] == null) {                boutT[0] = new BitToByteOutput(outT[0]);            }            // Initialize output code-block            if (ccb == null) { ccb = new CBlkRateDistStats(); }            // Compress code-block            compressCodeBlock(c,ccb,srcblkT[0],mqT[0],boutT[0],outT[0],                              stateT[0],distbufT[0],ratebufT[0],                              istermbufT[0],symbufT[0],ctxtbufT[0],                              opts[tIdx][c],isReversible(tIdx,c),                              lenCalc[tIdx][c],tType[tIdx][c]);            if (DO_TIMING) time[c] += System.currentTimeMillis()-stime;            // Return result            return ccb;        } else { // Use multiple threaded implementation            int cIdx;           // Compressor idx            Compressor compr;   // Compressor            if (DO_TIMING) stime = System.currentTimeMillis();            // Give data to all free compressors, using the current component            while (!finishedTileComponent[c] && !idleComps.empty()) {                // Get an idle compressor                compr = (Compressor) idleComps.pop();                cIdx = compr.getIdx();                // Get data for the compressor and wake it up                if (DO_TIMING) time[c] += System.currentTimeMillis()-stime;                srcblkT[cIdx] = src.getNextInternCodeBlock(c,srcblkT[cIdx]);                if (DO_TIMING) stime = System.currentTimeMillis();                if (srcblkT[cIdx] != null) {                    // Initialize thread local variables                    if((opts[tIdx][c]&OPT_BYPASS) != 0 && boutT[cIdx] == null){                        boutT[cIdx] = new BitToByteOutput(outT[cIdx]);                    }                    // Initialize output code-block and compressor thread                    if (ccb == null) ccb = new CBlkRateDistStats();                    compr.ccb = ccb;                    compr.c = c;                    compr.options = opts[tIdx][c];                    compr.rev = isReversible(tIdx,c);                    compr.lcType = lenCalc[tIdx][c];                    compr.tType = tType[tIdx][c];                    nBusyComps[c]++;                    ccb = null;                    // Send compressor to execution in thread pool		    tPool.runTarget(compr,completedComps[c]);                } else {                    // We finished with all the code-blocks in the current                    // tile component                    idleComps.push(compr);                    finishedTileComponent[c] = true;                }            }            // If there are threads for this component which result has not            // been returned yet, get it            if (nBusyComps[c] > 0) {                synchronized (completedComps[c]) {                    // If no compressor is done, wait until one is                    if (completedComps[c].empty()) {                        try {                            if (DO_TIMING) {                                time[c] += System.currentTimeMillis()-stime;                            }                            completedComps[c].wait();                            if (DO_TIMING) {                                stime = System.currentTimeMillis();                            }                        } catch (InterruptedException e) {                        }                    }                    // Remove the thread from the completed queue and put it                    // on the idle queue                    compr = (Compressor) completedComps[c].pop();                    cIdx = compr.getIdx();                    nBusyComps[c]--;                    idleComps.push(compr);                    // Check targets error condition                    tPool.checkTargetErrors();                    // Get the result of compression and return that.                    if (DO_TIMING) time[c] += System.currentTimeMillis()-stime;                    return compr.ccb;                }            } else {                // Check targets error condition                tPool.checkTargetErrors();                // Printing timing info if necessary                if (DO_TIMING) time[c] += System.currentTimeMillis()-stime;                // Nothing is running => no more code-blocks                return null;            }        }    }    /**     * Changes the current tile, given the new indexes. An     * IllegalArgumentException is thrown if the indexes do not correspond to     * a valid tile.     *     * <p>This default implementation just changes the tile in the source.</p>     *     * @param x The horizontal index of the tile.     *     * @param y The vertical index of the new tile.     * */    public void setTile(int x, int y) {        super.setTile(x,y);        // Reset the tile specific variables        if (finishedTileComponent != null) {            for (int c=src.getNumComps()-1; c>=0; c--) {                finishedTileComponent[c] = false;            }        }    }    /**     * 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 default implementation just advances to the next tile in the     * source.</p>     * */

⌨️ 快捷键说明

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