001/* 002 * $RCSfile: RectROIMaskGenerator.java,v $ 003 * $Revision: 1.1 $ 004 * $Date: 2005/02/11 05:02:23 $ 005 * $State: Exp $ 006 * 007 * Class: RectROIMaskGenerator 008 * 009 * Description: Generates masks when only rectangular ROIs exist 010 * 011 * 012 * 013 * COPYRIGHT: 014 * 015 * This software module was originally developed by Raphaël Grosbois and 016 * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel 017 * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David 018 * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research 019 * Centre France S.A) in the course of development of the JPEG2000 020 * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This 021 * software module is an implementation of a part of the JPEG 2000 022 * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio 023 * Systems AB and Canon Research Centre France S.A (collectively JJ2000 024 * Partners) agree not to assert against ISO/IEC and users of the JPEG 025 * 2000 Standard (Users) any of their rights under the copyright, not 026 * including other intellectual property rights, for this software module 027 * with respect to the usage by ISO/IEC and Users of this software module 028 * or modifications thereof for use in hardware or software products 029 * claiming conformance to the JPEG 2000 Standard. Those intending to use 030 * this software module in hardware or software products are advised that 031 * their use may infringe existing patents. The original developers of 032 * this software module, JJ2000 Partners and ISO/IEC assume no liability 033 * for use of this software module or modifications thereof. No license 034 * or right to this software module is granted for non JPEG 2000 Standard 035 * conforming products. JJ2000 Partners have full right to use this 036 * software module for his/her own purpose, assign or donate this 037 * software module to any third party and to inhibit third parties from 038 * using this software module for non JPEG 2000 Standard conforming 039 * products. This copyright notice must be included in all copies or 040 * derivative works of this software module. 041 * 042 * Copyright (c) 1999/2000 JJ2000 Partners. 043 * */ 044package jj2000.j2k.roi.encoder; 045 046import jj2000.j2k.image.DataBlkInt; 047import jj2000.j2k.wavelet.Subband; 048 049/** 050 * This class generates the ROI masks when there are only rectangular ROIs in 051 * the image. The ROI mask generation can then be simplified by only 052 * calculating the boundaries of the ROI mask in the particular subbands 053 * 054 * <P>The values are calculated from the scaling factors of the ROIs. The 055 * values with which to scale are equal to u-umin where umin is the lowest 056 * scaling factor within the block. The umin value is sent to the entropy 057 * coder to be used for scaling the distortion values. 058 * 059 * <P> To generate and to store the boundaries of the ROIs, the class 060 * SubbandRectROIMask is used. There is one tree of SubbandMasks for each 061 * component. 062 * 063 * @see SubbandRectROIMask 064 * 065 * @see ROIMaskGenerator 066 * 067 * @see ArbROIMaskGenerator 068 * */ 069public class RectROIMaskGenerator extends ROIMaskGenerator{ 070 071 /** The upper left xs of the ROIs*/ 072 private int[] ulxs; 073 074 /** The upper left ys of the ROIs*/ 075 private int[] ulys; 076 077 /** The lower right xs of the ROIs*/ 078 private int[] lrxs; 079 080 /** The lower right ys of the ROIs*/ 081 private int[] lrys; 082 083 /** Number of ROIs */ 084 private int nrROIs[]; 085 086 /** The tree of subbandmask. One for each component */ 087 private SubbandRectROIMask[] sMasks; 088 089 090 /** 091 * The constructor of the mask generator. The constructor is called with 092 * the ROI data. This data is stored in arrays that are used to generate 093 * the SubbandRectROIMask trees for each component. 094 * 095 * @param ROIs The ROI info. 096 * 097 * @param maxShift The flag indicating use of Maxshift method. 098 * 099 * @param nrc number of components. 100 * */ 101 public RectROIMaskGenerator(ROI[] ROIs, int nrc){ 102 super(ROIs, nrc); 103 int nr=ROIs.length; 104 int r,c; 105 nrROIs=new int[nrc]; 106 sMasks=new SubbandRectROIMask[nrc]; 107 108 // Count number of ROIs per component 109 for(r=nr-1;r>=0;r--){ 110 nrROIs[ROIs[r].comp]++; 111 } 112 } 113 114 115 /** 116 * This functions gets a DataBlk the size of the current code-block and 117 * fills this block with the ROI mask. 118 * 119 * <P> In order to get the mask for a particular Subband, the subband tree 120 * is traversed and at each decomposition, the ROI masks are computed. The 121 * roi bondaries for each subband are stored in the SubbandRectROIMask 122 * tree. 123 * 124 * @param db The data block that is to be filled with the mask 125 * 126 * @param sb The root of the subband tree to which db belongs 127 * 128 * @param magbits The max number of magnitude bits in any code-block 129 * 130 * @param c The component for which to get the mask 131 * 132 * @return Whether or not a mask was needed for this tile 133 * */ 134 public boolean getROIMask(DataBlkInt db, Subband sb, int magbits, int c){ 135 int x = db.ulx; 136 int y = db.uly; 137 int w = db.w; 138 int h = db.h; 139 int[] mask = db.getDataInt(); 140 int i,j,k,r,mink,minj,maxk,maxj; 141 int ulx=0,uly=0,lrx=0,lry=0; 142 int wrap; 143 int maxROI; 144 int[] culxs; 145 int[] culys; 146 int[] clrxs; 147 int[] clrys; 148 SubbandRectROIMask srm; 149 150 // If the ROI bounds have not been calculated for this tile and 151 // component, do so now. 152 if(!tileMaskMade[c]){ 153 makeMask(sb,magbits,c); 154 tileMaskMade[c] = true; 155 } 156 157 if(!roiInTile) { 158 return false; 159 } 160 161 // Find relevant subband mask and get ROI bounds 162 srm = (SubbandRectROIMask)sMasks[c].getSubbandRectROIMask(x,y); 163 culxs = srm.ulxs; 164 culys = srm.ulys; 165 clrxs = srm.lrxs; 166 clrys = srm.lrys; 167 maxROI = culxs.length-1; 168 // Make sure that only parts of ROIs within the code-block are used 169 // and make the bounds local to this block the LR bounds are counted 170 // as the distance from the lower right corner of the block 171 x -= srm.ulx; 172 y -= srm.uly; 173 for(r=maxROI; r>=0; r--){ 174 ulx = culxs[r]-x; 175 if(ulx<0) { 176 ulx = 0; 177 } else if(ulx>=w) { 178 ulx = w; 179 } 180 181 uly = culys[r]-y; 182 if(uly<0) { 183 uly = 0; 184 } else if(uly>=h) { 185 uly = h; 186 } 187 188 lrx = clrxs[r]-x; 189 if(lrx<0) { 190 lrx = -1; 191 } else if(lrx>=w) { 192 lrx = w-1; 193 } 194 195 lry = clrys[r]-y; 196 if(lry<0) { 197 lry = -1; 198 } else if(lry>=h) { 199 lry = h-1; 200 } 201 202 // Add the masks of the ROI 203 i = w*lry+lrx; 204 maxj = (lrx-ulx); 205 wrap = w-maxj-1; 206 maxk = lry-uly; 207 208 for(k=maxk; k>=0; k--){ 209 for(j=maxj;j>=0;j--,i--) 210 mask[i] = magbits; 211 i-=wrap; 212 } 213 } 214 return true; 215 } 216 217 /** 218 * This function returns the relevant data of the mask generator 219 * */ 220 public String toString(){ 221 return("Fast rectangular ROI mask generator"); 222 } 223 224 /** 225 * This function generates the ROI mask for the entire tile. The mask is 226 * generated for one component. This method is called once for each tile 227 * and component. 228 * 229 * @param sb The root of the subband tree used in the decomposition 230 * 231 * @param n component number 232 * */ 233 public void makeMask(Subband sb, int magbits, int n){ 234 int nr = nrROIs[n]; 235 int r; 236 int ulx,uly,lrx,lry; 237 int tileulx = sb.ulcx; 238 int tileuly = sb.ulcy; 239 int tilew = sb.w; 240 int tileh = sb.h; 241 ROI[] ROIs=rois; // local copy 242 243 ulxs = new int[nr]; 244 ulys = new int[nr]; 245 lrxs = new int[nr]; 246 lrys = new int[nr]; 247 248 nr=0; 249 250 for(r=ROIs.length-1;r>=0;r--){ 251 if(ROIs[r].comp==n){ 252 ulx = ROIs[r].ulx; 253 uly = ROIs[r].uly; 254 lrx = ROIs[r].w+ulx-1; 255 lry = ROIs[r].h+uly-1; 256 257 if( ulx > (tileulx + tilew -1 ) || 258 uly > (tileuly + tileh -1 ) || 259 lrx < tileulx || lry < tileuly ) // no part of ROI in tile 260 continue; 261 262 // Check bounds 263 ulx -= tileulx; 264 lrx -= tileulx; 265 uly -= tileuly; 266 lry -= tileuly; 267 268 ulx = (ulx<0) ? 0 : ulx; 269 uly = (uly<0) ? 0 : uly; 270 lrx = (lrx > (tilew-1)) ? tilew-1 : lrx; 271 lry = (lry > (tileh-1)) ? tileh-1 : lry; 272 273 ulxs[nr] = ulx; 274 ulys[nr] = uly; 275 lrxs[nr] = lrx; 276 lrys[nr] = lry; 277 nr++; 278 } 279 } 280 if(nr==0) { 281 roiInTile=false; 282 } 283 else { 284 roiInTile=true; 285 } 286 sMasks[n]=new SubbandRectROIMask(sb,ulxs,ulys,lrxs,lrys,nr); 287 } 288} 289 290 291 292 293