1 7 8 9 package java.awt.image; 10 11 import java.awt.color.ColorSpace ; 12 import java.awt.geom.Rectangle2D ; 13 import java.awt.Rectangle ; 14 import java.awt.RenderingHints ; 15 import java.awt.geom.Point2D ; 16 import sun.awt.image.ImagingLib; 17 18 59 60 public class LookupOp implements BufferedImageOp , RasterOp { 61 private LookupTable ltable; 62 private int numComponents; 63 RenderingHints hints; 64 65 73 public LookupOp(LookupTable lookup, RenderingHints hints) { 74 this.ltable = lookup; 75 this.hints = hints; 76 numComponents = ltable.getNumComponents(); 77 } 78 79 84 public final LookupTable getTable() { 85 return ltable; 86 } 87 88 108 public final BufferedImage filter(BufferedImage src, BufferedImage dst) { 109 ColorModel srcCM = src.getColorModel(); 110 int numBands = srcCM.getNumColorComponents(); 111 ColorModel dstCM; 112 if (srcCM instanceof IndexColorModel ) { 113 throw new 114 IllegalArgumentException ("LookupOp cannot be "+ 115 "performed on an indexed image"); 116 } 117 int numComponents = ltable.getNumComponents(); 118 if (numComponents != 1 && 119 numComponents != srcCM.getNumComponents() && 120 numComponents != srcCM.getNumColorComponents()) 121 { 122 throw new IllegalArgumentException ("Number of arrays in the "+ 123 " lookup table ("+ 124 numComponents+ 125 " is not compatible with the "+ 126 " src image: "+src); 127 } 128 129 130 boolean needToConvert = false; 131 132 int width = src.getWidth(); 133 int height = src.getHeight(); 134 135 if (dst == null) { 136 dst = createCompatibleDestImage(src, null); 137 dstCM = srcCM; 138 } 139 else { 140 if (width != dst.getWidth()) { 141 throw new 142 IllegalArgumentException ("Src width ("+width+ 143 ") not equal to dst width ("+ 144 dst.getWidth()+")"); 145 } 146 if (height != dst.getHeight()) { 147 throw new 148 IllegalArgumentException ("Src height ("+height+ 149 ") not equal to dst height ("+ 150 dst.getHeight()+")"); 151 } 152 153 dstCM = dst.getColorModel(); 154 if (srcCM.getColorSpace().getType() != 155 dstCM.getColorSpace().getType()) 156 { 157 needToConvert = true; 158 dst = createCompatibleDestImage(src, null); 159 } 160 161 } 162 163 BufferedImage origDst = dst; 164 165 if (ImagingLib.filter(this, src, dst) == null) { 166 WritableRaster srcRaster = src.getRaster(); 168 WritableRaster dstRaster = dst.getRaster(); 169 170 if (srcCM.hasAlpha()) { 171 if (numBands-1 == numComponents || numComponents == 1) { 172 int minx = srcRaster.getMinX(); 173 int miny = srcRaster.getMinY(); 174 int[] bands = new int[numBands-1]; 175 for (int i=0; i < numBands-1; i++) { 176 bands[i] = i; 177 } 178 srcRaster = 179 srcRaster.createWritableChild(minx, miny, 180 srcRaster.getWidth(), 181 srcRaster.getHeight(), 182 minx, miny, 183 bands); 184 } 185 } 186 if (dstCM.hasAlpha()) { 187 int dstNumBands = dstRaster.getNumBands(); 188 if (dstNumBands-1 == numComponents || numComponents == 1) { 189 int minx = dstRaster.getMinX(); 190 int miny = dstRaster.getMinY(); 191 int[] bands = new int[numBands-1]; 192 for (int i=0; i < numBands-1; i++) { 193 bands[i] = i; 194 } 195 dstRaster = 196 dstRaster.createWritableChild(minx, miny, 197 dstRaster.getWidth(), 198 dstRaster.getHeight(), 199 minx, miny, 200 bands); 201 } 202 } 203 204 filter(srcRaster, dstRaster); 205 } 206 207 if (needToConvert) { 208 ColorConvertOp ccop = new ColorConvertOp (hints); 210 ccop.filter(dst, origDst); 211 } 212 213 return origDst; 214 } 215 216 236 public final WritableRaster filter (Raster src, WritableRaster dst) { 237 int numBands = src.getNumBands(); 238 int dstLength = dst.getNumBands(); 239 int height = src.getHeight(); 240 int width = src.getWidth(); 241 int srcPix[] = new int[numBands]; 242 243 245 if (dst == null) { 246 dst = createCompatibleDestRaster(src); 247 } 248 else if (height != dst.getHeight() || width != dst.getWidth()) { 249 throw new 250 IllegalArgumentException ("Width or height of Rasters do not "+ 251 "match"); 252 } 253 dstLength = dst.getNumBands(); 254 255 if (numBands != dstLength) { 256 throw new 257 IllegalArgumentException ("Number of channels in the src (" 258 + numBands + 259 ") does not match number of channels" 260 + " in the destination (" 261 + dstLength + ")"); 262 } 263 int numComponents = ltable.getNumComponents(); 264 if (numComponents != 1 && numComponents != src.getNumBands()) { 265 throw new IllegalArgumentException ("Number of arrays in the "+ 266 " lookup table ("+ 267 numComponents+ 268 " is not compatible with the "+ 269 " src Raster: "+src); 270 } 271 272 273 if (ImagingLib.filter(this, src, dst) != null) { 274 return dst; 275 } 276 277 if (ltable instanceof ByteLookupTable ) { 279 byteFilter ((ByteLookupTable ) ltable, src, dst, 280 width, height, numBands); 281 } 282 else if (ltable instanceof ShortLookupTable ) { 283 shortFilter ((ShortLookupTable ) ltable, src, dst, width, 284 height, numBands); 285 } 286 else { 287 int sminX = src.getMinX(); 289 int sY = src.getMinY(); 290 int dminX = dst.getMinX(); 291 int dY = dst.getMinY(); 292 for (int y=0; y < height; y++, sY++, dY++) { 293 int sX = sminX; 294 int dX = dminX; 295 for (int x=0; x < width; x++, sX++, dX++) { 296 src.getPixel(sX, sY, srcPix); 298 299 ltable.lookupPixel(srcPix, srcPix); 301 302 dst.setPixel(dX, dY, srcPix); 304 } 305 } 306 } 307 308 return dst; 309 } 310 311 318 public final Rectangle2D getBounds2D (BufferedImage src) { 319 return getBounds2D(src.getRaster()); 320 } 321 322 329 public final Rectangle2D getBounds2D (Raster src) { 330 return src.getBounds(); 331 332 } 333 334 343 public BufferedImage createCompatibleDestImage (BufferedImage src, 344 ColorModel destCM) { 345 BufferedImage image; 346 int w = src.getWidth(); 347 int h = src.getHeight(); 348 int transferType = DataBuffer.TYPE_BYTE; 349 if (destCM == null) { 350 ColorModel cm = src.getColorModel(); 351 Raster raster = src.getRaster(); 352 if (cm instanceof ComponentColorModel ) { 353 DataBuffer db = raster.getDataBuffer(); 354 boolean hasAlpha = cm.hasAlpha(); 355 boolean isPre = cm.isAlphaPremultiplied(); 356 int trans = cm.getTransparency(); 357 int[] nbits = null; 358 if (ltable instanceof ByteLookupTable ) { 359 if (db.getDataType() == db.TYPE_USHORT) { 360 if (hasAlpha) { 362 nbits = new int[2]; 363 if (trans == cm.BITMASK) { 364 nbits[1] = 1; 365 } 366 else { 367 nbits[1] = 8; 368 } 369 } 370 else { 371 nbits = new int[1]; 372 } 373 nbits[0] = 8; 374 } 375 } 377 else if (ltable instanceof ShortLookupTable ) { 378 transferType = DataBuffer.TYPE_USHORT; 379 if (db.getDataType() == db.TYPE_BYTE) { 380 if (hasAlpha) { 381 nbits = new int[2]; 382 if (trans == cm.BITMASK) { 383 nbits[1] = 1; 384 } 385 else { 386 nbits[1] = 16; 387 } 388 } 389 else { 390 nbits = new int[1]; 391 } 392 nbits[0] = 16; 393 } 394 } 395 if (nbits != null) { 396 cm = new ComponentColorModel (cm.getColorSpace(), 397 nbits, hasAlpha, isPre, 398 trans, transferType); 399 } 400 } 401 image = new BufferedImage (cm, 402 cm.createCompatibleWritableRaster(w, h), 403 cm.isAlphaPremultiplied(), 404 null); 405 } 406 else { 407 image = new BufferedImage (destCM, 408 destCM.createCompatibleWritableRaster(w, 409 h), 410 destCM.isAlphaPremultiplied(), 411 null); 412 } 413 414 return image; 415 } 416 417 423 public WritableRaster createCompatibleDestRaster (Raster src) { 424 return src.createCompatibleWritableRaster(); 425 } 426 427 440 public final Point2D getPoint2D (Point2D srcPt, Point2D dstPt) { 441 if (dstPt == null) { 442 dstPt = new Point2D.Float (); 443 } 444 dstPt.setLocation(srcPt.getX(), srcPt.getY()); 445 446 return dstPt; 447 } 448 449 454 public final RenderingHints getRenderingHints() { 455 return hints; 456 } 457 458 private final void byteFilter(ByteLookupTable lookup, Raster src, 459 WritableRaster dst, 460 int width, int height, int numBands) { 461 int[] srcPix = null; 462 463 byte[][] table = lookup.getTable(); 465 int offset = lookup.getOffset(); 466 int tidx; 467 int step=1; 468 469 if (table.length == 1) { 471 step=0; 472 } 473 474 int x; 475 int y; 476 int band; 477 int len = table[0].length; 478 479 for ( y=0; y < height; y++) { 481 tidx = 0; 482 for ( band=0; band < numBands; band++, tidx+=step) { 483 srcPix = src.getSamples(0, y, width, 1, band, srcPix); 485 486 for ( x=0; x < width; x++) { 487 int index = srcPix[x]-offset; 488 if (index < 0 || index > len) { 489 throw new 490 IllegalArgumentException ("index ("+index+ 491 "(out of range: "+ 492 " srcPix["+x+ 493 "]="+ srcPix[x]+ 494 " offset="+ offset); 495 } 496 srcPix[x] = table[tidx][index]; 498 } 499 dst.setSamples(0, y, width, 1, band, srcPix); 501 } 502 } 503 } 504 505 private final void shortFilter(ShortLookupTable lookup, Raster src, 506 WritableRaster dst, 507 int width, int height, int numBands) { 508 int band; 509 int[] srcPix = null; 510 511 short[][] table = lookup.getTable(); 513 int offset = lookup.getOffset(); 514 int tidx; 515 int step=1; 516 517 if (table.length == 1) { 519 step=0; 520 } 521 522 int x = 0; 523 int y = 0; 524 int index; 525 int maxShort = (1<<16)-1; 526 for (y=0; y < height; y++) { 528 tidx = 0; 529 for ( band=0; band < numBands; band++, tidx+=step) { 530 srcPix = src.getSamples(0, y, width, 1, band, srcPix); 532 533 for ( x=0; x < width; x++) { 534 index = srcPix[x]-offset; 535 if (index < 0 || index > maxShort) { 536 throw new 537 IllegalArgumentException ("index out of range "+ 538 index+" x is "+x+ 539 "srcPix[x]="+srcPix[x] 540 +" offset="+ offset); 541 } 542 srcPix[x] = table[tidx][index]; 544 } 545 dst.setSamples(0, y, width, 1, band, srcPix); 547 } 548 } 549 } 550 } 551 552 553 | Popular Tags |