1 18 package org.apache.batik.ext.awt.image.rendered; 19 20 import java.awt.Point ; 21 import java.awt.Rectangle ; 22 import java.awt.Shape ; 23 import java.awt.Transparency ; 24 import java.awt.color.ColorSpace ; 25 import java.awt.image.ColorModel ; 26 import java.awt.image.ComponentColorModel ; 27 import java.awt.image.DataBuffer ; 28 import java.awt.image.Raster ; 29 import java.awt.image.RenderedImage ; 30 import java.awt.image.SampleModel ; 31 import java.awt.image.WritableRaster ; 32 import java.util.HashMap ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 import java.util.Map ; 36 import java.util.Set ; 37 import java.util.Vector ; 38 39 import org.apache.batik.ext.awt.image.GraphicsUtil; 40 41 42 46 47 56 public abstract class AbstractRed implements CachableRed { 57 58 protected Rectangle bounds; 59 protected Vector srcs; 60 protected Map props; 61 protected SampleModel sm; 62 protected ColorModel cm; 63 protected int tileGridXOff, tileGridYOff; 64 protected int tileWidth, tileHeight; 65 protected int minTileX, minTileY; 66 protected int numXTiles, numYTiles; 67 68 74 protected AbstractRed() { 75 } 76 77 78 85 protected AbstractRed(Rectangle bounds, Map props) { 86 init((CachableRed)null, bounds, null, null, 87 bounds.x, bounds.y, props); 88 } 89 90 97 protected AbstractRed(CachableRed src, Map props) { 98 init(src, src.getBounds(), src.getColorModel(), src.getSampleModel(), 99 (src==null)?0:src.getTileGridXOffset(), 100 (src==null)?0:src.getTileGridYOffset(), 101 props); 102 } 103 104 112 protected AbstractRed(CachableRed src, Rectangle bounds, Map props) { 113 init(src, bounds, src.getColorModel(), src.getSampleModel(), 114 (src==null)?0:src.getTileGridXOffset(), 115 (src==null)?0:src.getTileGridYOffset(), 116 props); 117 } 118 119 132 protected AbstractRed(CachableRed src, Rectangle bounds, 133 ColorModel cm, SampleModel sm, 134 Map props) { 135 init(src, bounds, cm, sm, 136 (src==null)?0:src.getTileGridXOffset(), 137 (src==null)?0:src.getTileGridYOffset(), 138 props); 139 } 140 141 158 protected AbstractRed(CachableRed src, Rectangle bounds, 159 ColorModel cm, SampleModel sm, 160 int tileGridXOff, int tileGridYOff, 161 Map props) { 162 init(src, bounds, cm, sm, tileGridXOff, tileGridYOff, props); 163 } 164 165 185 protected void init(CachableRed src, Rectangle bounds, 186 ColorModel cm, SampleModel sm, 187 int tileGridXOff, int tileGridYOff, 188 Map props) { 189 this.srcs = new Vector (1); 190 if (src != null) { 191 this.srcs.add(src); 192 if (bounds == null) bounds = src.getBounds(); 193 if (cm == null) cm = src.getColorModel(); 194 if (sm == null) sm = src.getSampleModel(); 195 } 196 197 this.bounds = bounds; 198 this.tileGridXOff = tileGridXOff; 199 this.tileGridYOff = tileGridYOff; 200 201 this.props = new HashMap (); 202 if(props != null){ 203 this.props.putAll(props); 204 } 205 206 if (cm == null) 207 cm = new ComponentColorModel 208 (ColorSpace.getInstance(ColorSpace.CS_GRAY), 209 new int [] { 8 }, false, false, Transparency.OPAQUE, 210 DataBuffer.TYPE_BYTE); 211 212 this.cm = cm; 213 214 if (sm == null) 215 sm = cm.createCompatibleSampleModel(bounds.width, bounds.height); 216 this.sm = sm; 217 218 updateTileGridInfo(); 220 } 221 222 231 protected AbstractRed(List srcs, Rectangle bounds, Map props) { 232 init(srcs, bounds, null, null, bounds.x, bounds.y, props); 233 } 234 235 250 protected AbstractRed(List srcs, Rectangle bounds, 251 ColorModel cm, SampleModel sm, 252 Map props) { 253 init(srcs, bounds, cm, sm, bounds.x, bounds.y, props); 254 } 255 256 275 protected AbstractRed(List srcs, Rectangle bounds, 276 ColorModel cm, SampleModel sm, 277 int tileGridXOff, int tileGridYOff, 278 Map props) { 279 init(srcs, bounds, cm, sm, tileGridXOff, tileGridYOff, props); 280 } 281 282 300 protected void init(List srcs, Rectangle bounds, 301 ColorModel cm, SampleModel sm, 302 int tileGridXOff, int tileGridYOff, 303 Map props) { 304 this.srcs = new Vector (); 305 if(srcs != null){ 306 this.srcs.addAll(srcs); 307 } 308 309 if (srcs.size() != 0) { 310 CachableRed src = (CachableRed)srcs.get(0); 311 if (bounds == null) bounds = src.getBounds(); 312 if (cm == null) cm = src.getColorModel(); 313 if (sm == null) sm = src.getSampleModel(); 314 } 315 316 this.bounds = bounds; 317 this.tileGridXOff = tileGridXOff; 318 this.tileGridYOff = tileGridYOff; 319 this.props = new HashMap (); 320 if(props != null){ 321 this.props.putAll(props); 322 } 323 324 if (cm == null) 325 cm = new ComponentColorModel 326 (ColorSpace.getInstance(ColorSpace.CS_GRAY), 327 new int [] { 8 }, false, false, Transparency.OPAQUE, 328 DataBuffer.TYPE_BYTE); 329 330 this.cm = cm; 331 332 if (sm == null) 333 sm = cm.createCompatibleSampleModel(bounds.width, bounds.height); 334 this.sm = sm; 335 336 updateTileGridInfo(); 338 } 339 340 346 protected void updateTileGridInfo() { 347 this.tileWidth = sm.getWidth(); 348 this.tileHeight = sm.getHeight(); 349 350 int x1, y1, maxTileX, maxTileY; 351 352 minTileX = getXTile(bounds.x); 355 minTileY = getYTile(bounds.y); 356 357 x1 = bounds.x + bounds.width-1; maxTileX = getXTile(x1); 359 numXTiles = maxTileX-minTileX+1; 360 361 y1 = bounds.y + bounds.height-1; maxTileY = getYTile(y1); 363 numYTiles = maxTileY-minTileY+1; 364 } 365 366 367 public Rectangle getBounds() { 368 return new Rectangle (getMinX(), 369 getMinY(), 370 getWidth(), 371 getHeight()); 372 } 373 374 public Vector getSources() { 375 return srcs; 376 } 377 378 public ColorModel getColorModel() { 379 return cm; 380 } 381 382 public SampleModel getSampleModel() { 383 return sm; 384 } 385 386 public int getMinX() { 387 return bounds.x; 388 } 389 public int getMinY() { 390 return bounds.y; 391 } 392 393 public int getWidth() { 394 return bounds.width; 395 } 396 397 public int getHeight() { 398 return bounds.height; 399 } 400 401 public int getTileWidth() { 402 return tileWidth; 403 } 404 405 public int getTileHeight() { 406 return tileHeight; 407 } 408 409 public int getTileGridXOffset() { 410 return tileGridXOff; 411 } 412 413 public int getTileGridYOffset() { 414 return tileGridYOff; 415 } 416 417 public int getMinTileX() { 418 return minTileX; 419 } 420 421 public int getMinTileY() { 422 return minTileY; 423 } 424 425 public int getNumXTiles() { 426 return numXTiles; 427 } 428 429 public int getNumYTiles() { 430 return numYTiles; 431 } 432 433 public Object getProperty(String name) { 434 Object ret = props.get(name); 435 if (ret != null) return ret; 436 Iterator i = srcs.iterator(); 437 while (i.hasNext()) { 438 RenderedImage ri = (RenderedImage )i.next(); 439 ret = ri.getProperty(name); 440 if (ret != null) return ret; 441 } 442 return null; 443 } 444 445 public String [] getPropertyNames() { 446 Set keys = props.keySet(); 447 Iterator iter = keys.iterator(); 448 String [] ret = new String [keys.size()]; 449 int i=0; 450 while (iter.hasNext()) { 451 ret[i++] = (String )iter.next(); 452 } 453 454 iter = srcs.iterator(); 455 while (iter.hasNext()) { 456 RenderedImage ri = (RenderedImage )iter.next(); 457 String [] srcProps = ri.getPropertyNames(); 458 if (srcProps.length != 0) { 459 String [] tmp = new String [ret.length+srcProps.length]; 460 System.arraycopy(tmp,0,tmp,0,ret.length); 461 System.arraycopy(tmp,ret.length,srcProps,0,srcProps.length); 462 ret = tmp; 463 } 464 } 465 466 return ret; 467 } 468 469 public Shape getDependencyRegion(int srcIndex, Rectangle outputRgn) { 470 if ((srcIndex < 0) || (srcIndex > srcs.size())) 471 throw new IndexOutOfBoundsException 472 ("Nonexistant source requested."); 473 474 if (outputRgn.intersects(bounds) == false) 476 return new Rectangle (); 477 478 return outputRgn.intersection(bounds); 481 } 482 483 public Shape getDirtyRegion(int srcIndex, Rectangle inputRgn) { 484 if (srcIndex != 0) 485 throw new IndexOutOfBoundsException 486 ("Nonexistant source requested."); 487 488 if (inputRgn.intersects(bounds) == false) 490 return new Rectangle (); 491 492 return inputRgn.intersection(bounds); 495 } 496 497 498 505 public Raster getTile(int tileX, int tileY) { 506 WritableRaster wr = makeTile(tileX, tileY); 507 return copyData(wr); 508 } 509 510 public Raster getData() { 511 return getData(bounds); 512 } 513 514 public Raster getData(Rectangle rect) { 515 SampleModel smRet = sm.createCompatibleSampleModel 516 (rect.width, rect.height); 517 518 Point pt = new Point (rect.x, rect.y); 519 WritableRaster wr = Raster.createWritableRaster(smRet, pt); 520 521 return copyData(wr); 523 } 524 525 530 public final int getXTile(int xloc) { 531 int tgx = xloc-tileGridXOff; 532 if (tgx>=0) 534 return tgx/tileWidth; 535 else 536 return (tgx-tileWidth+1)/tileWidth; 537 } 538 539 544 public final int getYTile(int yloc) { 545 int tgy = yloc-tileGridYOff; 546 if (tgy>=0) 548 return tgy/tileHeight; 549 else 550 return (tgy-tileHeight+1)/tileHeight; 551 } 552 553 559 public void copyToRaster(WritableRaster wr) { 560 int tx0 = getXTile(wr.getMinX()); 561 int ty0 = getYTile(wr.getMinY()); 562 int tx1 = getXTile(wr.getMinX()+wr.getWidth() -1); 563 int ty1 = getYTile(wr.getMinY()+wr.getHeight()-1); 564 565 if (tx0 < minTileX) tx0 = minTileX; 566 if (ty0 < minTileY) ty0 = minTileY; 567 568 if (tx1 >= minTileX+numXTiles) tx1 = minTileX+numXTiles-1; 569 if (ty1 >= minTileY+numYTiles) ty1 = minTileY+numYTiles-1; 570 571 final boolean is_INT_PACK = 572 GraphicsUtil.is_INT_PACK_Data(getSampleModel(), false); 573 574 for (int y=ty0; y<=ty1; y++) 575 for (int x=tx0; x<=tx1; x++) { 576 Raster r = getTile(x, y); 577 if (is_INT_PACK) 578 GraphicsUtil.copyData_INT_PACK(r, wr); 579 else 580 GraphicsUtil.copyData_FALLBACK(r, wr); 581 } 582 } 583 584 585 587 597 public WritableRaster makeTile(int tileX, int tileY) { 598 if ((tileX < minTileX) || (tileX >= minTileX+numXTiles) || 599 (tileY < minTileY) || (tileY >= minTileY+numYTiles)) 600 throw new IndexOutOfBoundsException 601 ("Requested Tile (" + tileX + "," + tileY + 602 ") lies outside the bounds of image"); 603 604 Point pt = new Point (tileGridXOff+tileX*tileWidth, 605 tileGridYOff+tileY*tileHeight); 606 607 WritableRaster wr; 608 wr = Raster.createWritableRaster(sm, pt); 609 625 627 int x0 = wr.getMinX(); 628 int y0 = wr.getMinY(); 629 int x1 = x0+wr.getWidth() -1; 630 int y1 = y0+wr.getHeight()-1; 631 632 if ((x0 < bounds.x) || (x1 >= (bounds.x+bounds.width)) || 633 (y0 < bounds.y) || (y1 >= (bounds.y+bounds.height))) { 634 if (x0 < bounds.x) x0 = bounds.x; 637 if (y0 < bounds.y) y0 = bounds.y; 638 if (x1 >= (bounds.x+bounds.width)) x1 = bounds.x+bounds.width-1; 639 if (y1 >= (bounds.y+bounds.height)) y1 = bounds.y+bounds.height-1; 640 641 wr = wr.createWritableChild(x0, y0, x1-x0+1, y1-y0+1, 642 x0, y0, null); 643 } 644 return wr; 645 } 646 647 public static void copyBand(Raster src, int srcBand, 648 WritableRaster dst, int dstBand) { 649 Rectangle srcR = new Rectangle (src.getMinX(), src.getMinY(), 650 src.getWidth(), src.getHeight()); 651 Rectangle dstR = new Rectangle (dst.getMinX(), dst.getMinY(), 652 dst.getWidth(), dst.getHeight()); 653 654 Rectangle cpR = srcR.intersection(dstR); 655 656 int [] samples = null; 657 for (int y=cpR.y; y< cpR.y+cpR.height; y++) { 658 samples = src.getSamples(cpR.x, y, cpR.width, 1, srcBand, samples); 659 dst.setSamples(cpR.x, y, cpR.width, 1, dstBand, samples); 660 } 661 } 662 } 663 664 | Popular Tags |