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 + -
显示快捷键?