📄 roiscaler.java
字号:
w = (new Integer(word)).intValue(); word = stok.nextToken(); h = (new Integer(word)).intValue(); } catch(NumberFormatException e){ throw new IllegalArgumentException("Bad parameter for "+ "'-Rroi R' option : "+ word); } catch(NoSuchElementException f){ throw new IllegalArgumentException("Wrong number of "+ "parameters for "+ "h'-Rroi R' option."); } // If the ROI is component-specific, check which comps. if(roiInComp != null) for(int i=0; i<nc;i++){ if(roiInComp[i]){ roi=new ROI(i,ulx,uly,w,h); roiVector.addElement(roi); } } else{ // Otherwise add ROI for all components for(int i=0; i<nc;i++){ roi=new ROI(i,ulx,uly,w,h); roiVector.addElement(roi); } } break; case 'C': // Circular ROI to be read nrOfROIs++; try{ word = stok.nextToken(); x = (new Integer(word)).intValue(); word = stok.nextToken(); y = (new Integer(word)).intValue(); word = stok.nextToken(); rad = (new Integer(word)).intValue(); } catch(NumberFormatException e){ throw new IllegalArgumentException("Bad parameter for "+ "'-Rroi C' option : "+ word); } catch(NoSuchElementException f){ throw new IllegalArgumentException("Wrong number of "+ "parameters for "+ "'-Rroi C' option."); } // If the ROI is component-specific, check which comps. if(roiInComp != null) for(int i=0; i<nc; i++){ if(roiInComp[i]){ roi = new ROI(i,x,y,rad); roiVector.addElement(roi); } } else{ // Otherwise add ROI for all components for(int i=0; i<nc; i++){ roi = new ROI(i,x,y,rad); roiVector.addElement(roi); } } break; case 'A': // ROI wth arbitrary shape nrOfROIs++; String filename; ImgReaderPGM maskPGM = null; try{ filename = stok.nextToken(); } catch(NoSuchElementException e){ throw new IllegalArgumentException("Wrong number of "+ "parameters for "+ "'-Rroi A' option."); } try { maskPGM = new ImgReaderPGM(filename); } catch(IOException e){ throw new Error("Cannot read PGM file with ROI"); } // If the ROI is component-specific, check which comps. if(roiInComp != null) for(int i=0; i<nc; i++){ if(roiInComp[i]){ roi = new ROI(i,maskPGM); roiVector.addElement(roi); } } else{ // Otherwise add ROI for all components for(int i=0; i<nc; i++){ roi = new ROI(i,maskPGM); roiVector.addElement(roi); } } break; default: throw new Error("Bad parameters for ROI nr "+roiVector.size()); } } return roiVector; } /** * This function gets a datablk from the entropy coder. The sample sin the * block, which consists of the quantized coefficients from the quantizer, * are scaled by the values given for any ROIs specified. * * <P>The function calls on a ROIMaskGenerator to get the mask for * scaling the coefficients in the current block. * * <P>The data returned by this method is a copy of the orignal * data. Therfore 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. See the 'CBlkWTData' class. * * @param n 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 'n', or * null if all code-blocks for the current tile have been returned. * * @see CBlkWTData * */ public CBlkWTData getNextCodeBlock(int n, CBlkWTData cblk) { return getNextInternCodeBlock(n,cblk); } /** * This function gets a datablk from the entropy coder. The sample sin the * block, which consists of the quantized coefficients from the quantizer, * are scaled by the values given for any ROIs specified. * * <P>The function calls on a ROIMaskGenerator to get the mask for * scaling the coefficients in the current block. * * @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 'n', or * null if all code-blocks for the current tile have been returned. * * @see CBlkWTData * */ public CBlkWTData getNextInternCodeBlock(int c, CBlkWTData cblk){ int mi,i,j,k,wrap; int ulx, uly, w, h; DataBlkInt mask = roiMask; // local copy of mask int[] maskData; // local copy of mask data int[] data; // local copy of quantized data int tmp; int bitMask = 0x7FFFFFFF; SubbandAn root,sb; int maxBits = 0; // local copy boolean roiInTile; boolean sbInMask; int nROIcoeff = 0; // Get codeblock's data from quantizer cblk = src.getNextCodeBlock(c,cblk); // If there is no ROI in the image, or if we already got all // code-blocks if (!roi || cblk == null) { return cblk; } data = (int[])cblk.getData(); sb = cblk.sb; ulx = cblk.ulx; uly = cblk.uly; w = cblk.w; h = cblk.h; sbInMask= (sb.resLvl<=useStartLevel); // Check that there is an array for the mask and set it to zero maskData = mask.getDataInt(); // local copy of mask data if(maskData==null || w*h>maskData.length){ maskData = new int[w*h]; mask.setDataInt(maskData); } else{ for(i=w*h-1;i>=0;i--) maskData[i]=0; } mask.ulx = ulx; mask.uly = uly; mask.w = w; mask.h = h; // Get ROI mask from generator root = src.getSubbandTree(tIdx,c); maxBits = maxMagBits[tIdx][c]; roiInTile = mg.getROIMask(mask,root,maxBits,c); // If there is no ROI in this tile, return the code-block untouched if(!roiInTile && (!sbInMask)) { cblk.nROIbp = 0; return cblk; } // Update field containing the number of ROI magnitude bit-planes cblk.nROIbp = cblk.magbits; // If the ROI should adhere to the code-block's boundaries or if the // entire subband belongs to the ROI mask, The code-block is set to // belong entirely to the ROI with the highest scaling value if(blockAligned || sbInMask) { // Scale the wmse so that instead of scaling the coefficients, the // wmse is scaled. cblk.wmseScaling *= (float)(1<<(maxBits<<1)); cblk.nROIcoeff = w*h; return cblk; } // Scale background coefficients bitMask=(((1<<cblk.magbits)-1)<<(31-cblk.magbits)); wrap=cblk.scanw-w; mi=h*w-1; i=cblk.offset+cblk.scanw*(h-1)+w-1; for(j=h;j>0;j--){ for(k=w;k>0;k--,i--,mi--){ tmp=data[i]; if (maskData[mi] != 0) { // ROI coeff. We need to erase fractional bits to ensure // that they do not conflict with BG coeffs. This is only // strictly necessary for ROI coeffs. which non-fractional // magnitude is zero, but much better BG quality can be // achieved if done if reset to zero since coding zeros is // much more efficient (the entropy coder knows nothing // about ROI and cannot avoid coding the ROI fractional // bits, otherwise this would not be necessary). data[i] = (0x80000000 & tmp) | (tmp & bitMask); nROIcoeff++; } else { // BG coeff. it is not necessary to erase fractional bits data[i] = (0x80000000 & tmp) | ((tmp & 0x7FFFFFFF) >> maxBits); } } i-=wrap; } // Modify the number of significant bit-planes in the code-block cblk.magbits += maxBits; // Store the number of ROI coefficients present in the code-block cblk.nROIcoeff = nROIcoeff; return cblk; } /** * This function returns the ROI mask generator. * * @return The roi mask generator */ public ROIMaskGenerator getROIMaskGenerator(){ return mg; } /** * This function returns the blockAligned flag * * @return Flag indicating whether the ROIs were block aligned */ public boolean getBlockAligned(){ return blockAligned; } /** * This function returns the flag indicating if any ROI functionality used * * @return Flag indicating whether there are ROIs in the image */ public boolean useRoi(){ return roi; } /** * Returns the parameters that are used in this class and * implementing classes. It returns a 2D String array. Each of the * 1D arrays is for a different option, and they have 3 * elements. The first element is the option name, the second one * is the synopsis, the third one is a long description of what * the parameter is and the fourth is its default value. The * synopsis or description may be 'null', in which case it is * assumed that there is no synopsis or description of the option, * respectively. Null may be returned if no options are supported. * * @return the options name, their synopsis and their explanation, * or null if no options are supported. * */ public static String[][] getParameterInfo() { return pinfo; } /** * Changes the current tile, given the new indexes. An * IllegalArgumentException is thrown if the indexes do not * correspond to a valid tile. * * @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); if(roi) mg.tileChanged(); } /** * 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). * */ public void nextTile() { super.nextTile(); if(roi) mg.tileChanged(); } /** * Calculates the maximum amount of magnitude bits for each * tile-component, and stores it in the 'maxMagBits' array. This is called * by the constructor * * @param encSpec The encoder specifications for addition of roi specs * */ private void calcMaxMagBits(EncoderSpecs encSpec) { int tmp; MaxShiftSpec rois = encSpec.rois; int nt = src.getNumTiles(); int nc = src.getNumComps(); maxMagBits = new int[nt][nc]; src.setTile(0,0); for (int t=0; t<nt; t++) { for (int c=nc-1; c>=0; c--) { tmp = src.getMaxMagBits(c); maxMagBits[t][c] = tmp; rois.setTileCompVal(t,c,new Integer(tmp)); } if( t<nt-1 ) src.nextTile(); } // Reset to current initial tile position src.setTile(0,0); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -