1 /* 2 * $RCSfile: ImageLayout.java,v $ 3 * 4 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 5 * 6 * Use is subject to license terms. 7 * 8 * $Revision: 1.1 $ 9 * $Date: 2005/02/11 04:57:09 $ 10 * $State: Exp $ 11 */ 12 package com.lightcrafts.mediax.jai; 13 import java.awt.image.ColorModel; 14 import java.awt.image.RenderedImage; 15 import java.awt.image.SampleModel; 16 import java.io.IOException; 17 import java.io.ObjectInputStream; 18 import java.io.ObjectOutputStream; 19 import java.io.Serializable; 20 import com.lightcrafts.mediax.jai.remote.SerializableState; 21 import com.lightcrafts.mediax.jai.remote.SerializerFactory; 22 23 /** 24 * A class describing the desired layout of an <code>OpImage</code>. 25 * 26 * <p> The <code>ImageLayout</code> class encapsulates three types of information about 27 * an image: 28 * 29 * <ul> 30 * <li> The image bounds, comprising the min X and Y coordinates, 31 * image width, and image height; 32 * <li> The tile grid layout, comprising the tile grid X and Y offsets, 33 * the tile width, and the tile height; and 34 * <li> The <code>SampleModel</code> and <code>ColorModel</code> of the image. 35 * </ul> 36 * 37 * <p> Each of these parameters may be set individually, or left unset. 38 * An unset parameter will cause the corresponding value of a given 39 * <code>RenderedImage</code> to be used. For example, the code: 40 * 41 * <pre> 42 * ImageLayout layout; 43 * RenderedImage im; 44 * 45 * int width = layout.getTileWidth(im); 46 * </pre> 47 * 48 * will return the tile width of the <code>ImageLayout</code> if it is set, 49 * or the tile width of the image <code>im</code> if it is not. 50 * 51 * <p> <code>ImageLayout</code> objects are primarily intended to be passed as part 52 * of the <code>renderingHints</code> argument of the <code>create()</code> method of 53 * <code>RenderedImageFactory</code>. The <code>create()</code> method may remove parameter 54 * settings that it cannot deal with, prior to passing the 55 * <code>ImageLayout</code> to any <code>OpImage</code> constructors. New <code>OpImage</code> subclasses 56 * are not required to accept an <code>ImageLayout</code> parameter, but most will 57 * at least need to synthesize one to be passed up the constructor 58 * chain. 59 * 60 * <p> Methods that modify the state of an <code>ImageLayout</code> return a reference 61 * to 'this' following the change. This allows multiple modifications to 62 * be made in a single expression. This provides a way of modifying an 63 * <code>ImageLayout</code> within a superclass constructor call. 64 * 65 */ 66 public class ImageLayout extends Object implements Cloneable, Serializable { 67 /** A bitmask to specify the validity of <code>minX</code>. */ 68 public static final int MIN_X_MASK = 0x1; 69 /** A bitmask to specify the validity of <code>minY</code>. */ 70 public static final int MIN_Y_MASK = 0x2; 71 /** A bitmask to specify the validity of <code>width</code>. */ 72 public static final int WIDTH_MASK = 0x4; 73 /** A bitmask to specify the validity of <code>height</code>. */ 74 public static final int HEIGHT_MASK = 0x8; 75 76 /** A bitmask to specify the validity of <code>tileGridXOffset</code>. */ 77 public static final int TILE_GRID_X_OFFSET_MASK = 0x10; 78 /** A bitmask to specify the validity of <code>tileGridYOffset</code>. */ 79 public static final int TILE_GRID_Y_OFFSET_MASK = 0x20; 80 /** A bitmask to specify the validity of <code>tileWidth</code>. */ 81 public static final int TILE_WIDTH_MASK = 0x40; 82 /** A bitmask to specify the validity of <code>tileHeight</code>. */ 83 public static final int TILE_HEIGHT_MASK = 0x80; 84 85 /** A bitmask to specify the validity of <code>sampleModel</code>. */ 86 public static final int SAMPLE_MODEL_MASK = 0x100; 87 88 /** A bitmask to specify the validity of <code>colorModel</code>. */ 89 public static final int COLOR_MODEL_MASK = 0x200; 90 91 /** The image's minimum X coordinate. */ 92 int minX = 0; 93 94 /** The image's minimum Y coordinate. */ 95 int minY = 0; 96 97 /** The image's <code>width</code>. */ 98 int width = 0; 99 100 /** The image's height. */ 101 int height = 0; 102 103 /** The X coordinate of tile (0, 0). */ 104 int tileGridXOffset = 0; 105 106 /** The Y coordinate of tile (0, 0). */ 107 int tileGridYOffset = 0; 108 109 /** The width of a tile. */ 110 int tileWidth = 0; 111 112 /** The height of a tile. */ 113 int tileHeight = 0; 114 115 /** The image's <code>SampleModel</code>. */ 116 transient SampleModel sampleModel = null; 117 118 /** The image's <code>ColorModel</code>. */ 119 transient ColorModel colorModel = null; 120 121 /** The 'or'-ed together valid bitmasks. */ 122 protected int validMask = 0; 123 124 /** Constructs an <code>ImageLayout</code> with no parameters set. */ ImageLayout()125 public ImageLayout() {} 126 127 /** 128 * Constructs an <code>ImageLayout</code> with all its parameters set. 129 * The <code>sampleModel</code> and <code>colorModel</code> parameters are ignored if null. 130 * 131 * @param minX the image's minimum X coordinate. 132 * @param minY the image's minimum Y coordinate. 133 * @param width the image's width. 134 * @param height the image's height. 135 * @param tileGridXOffset the X coordinate of tile (0, 0). 136 * @param tileGridYOffset the Y coordinate of tile (0, 0). 137 * @param tileWidth the width of a tile. 138 * @param tileHeight the height of a tile. 139 * @param sampleModel the image's <code>SampleModel</code>. 140 * @param colorModel the image's <code>ColorModel</code>. 141 */ ImageLayout(int minX, int minY, int width, int height, int tileGridXOffset, int tileGridYOffset, int tileWidth, int tileHeight, SampleModel sampleModel, ColorModel colorModel)142 public ImageLayout(int minX, 143 int minY, 144 int width, 145 int height, 146 int tileGridXOffset, 147 int tileGridYOffset, 148 int tileWidth, 149 int tileHeight, 150 SampleModel sampleModel, 151 ColorModel colorModel) { 152 setMinX(minX); 153 setMinY(minY); 154 setWidth(width); 155 setHeight(height); 156 setTileGridXOffset(tileGridXOffset); 157 setTileGridYOffset(tileGridYOffset); 158 setTileWidth(tileWidth); 159 setTileHeight(tileHeight); 160 if (sampleModel != null) { 161 setSampleModel(sampleModel); 162 } 163 if (colorModel != null) { 164 setColorModel(colorModel); 165 } 166 } 167 168 169 /** 170 * Constructs an <code>ImageLayout</code> with only the image dimension 171 * parameters set. 172 * 173 * @param minX the image's minimum X coordinate. 174 * @param minY the image's minimum Y coordinate. 175 * @param width the image's width. 176 * @param height the image's height. 177 */ ImageLayout(int minX, int minY, int width, int height)178 public ImageLayout(int minX, 179 int minY, 180 int width, 181 int height) { 182 setMinX(minX); 183 setMinY(minY); 184 setWidth(width); 185 setHeight(height); 186 } 187 188 /** 189 * Constructs an <code>ImageLayout</code> with its tile grid layout, 190 * <code>SampleModel</code>, and <code>ColorModel</code> parameters set. 191 * The <code>sampleModel</code> and <code>colorModel</code> parameters are ignored if null. 192 * 193 * @param tileGridXOffset the X coordinate of tile (0, 0). 194 * @param tileGridYOffset the Y coordinate of tile (0, 0). 195 * @param tileWidth the width of a tile. 196 * @param tileHeight the height of a tile. 197 * @param sampleModel the image's <code>SampleModel</code>. 198 * @param colorModel the image's <code>ColorModel</code>. 199 */ ImageLayout(int tileGridXOffset, int tileGridYOffset, int tileWidth, int tileHeight, SampleModel sampleModel, ColorModel colorModel)200 public ImageLayout(int tileGridXOffset, 201 int tileGridYOffset, 202 int tileWidth, 203 int tileHeight, 204 SampleModel sampleModel, 205 ColorModel colorModel) { 206 setTileGridXOffset(tileGridXOffset); 207 setTileGridYOffset(tileGridYOffset); 208 setTileWidth(tileWidth); 209 setTileHeight(tileHeight); 210 if (sampleModel != null) { 211 setSampleModel(sampleModel); 212 } 213 if (colorModel != null) { 214 setColorModel(colorModel); 215 } 216 } 217 218 /** 219 * Constructs an <code>ImageLayout</code> with all its parameters set 220 * to equal those of a given <code>RenderedImage</code>. 221 * 222 * @param im a <code>RenderedImage</code> whose layout will be copied. 223 */ ImageLayout(RenderedImage im)224 public ImageLayout(RenderedImage im) { 225 this(im.getMinX(), 226 im.getMinY(), 227 im.getWidth(), 228 im.getHeight(), 229 im.getTileGridXOffset(), 230 im.getTileGridYOffset(), 231 im.getTileWidth(), 232 im.getTileHeight(), 233 im.getSampleModel(), 234 im.getColorModel()); 235 } 236 237 /** 238 * Returns the 'or'-ed together bitmask indicating parameter validity. 239 * To determine the validity of a particular parameter, say tile width, 240 * test <code>getValidMask() & ImageLayout.TILE_WIDTH_MASK</code> 241 * against <code>0</code>. 242 * 243 * <p> To test a single mask value or set of mask values, the 244 * convenience method isValid() may be used. 245 * 246 * @return an int that is the logical 'or' of the valid mask values, 247 * with a '1' bit representing the setting of a value. 248 */ getValidMask()249 public int getValidMask() { 250 return validMask; 251 } 252 253 /** 254 * Returns <code>true</code> if all the parameters specified by the argument are set. 255 * 256 * @param mask a bitmask. 257 * @return a boolean truth value. 258 */ isValid(int mask)259 public final boolean isValid(int mask) { 260 return (validMask & mask) == mask; 261 } 262 263 /** 264 * Sets selected bits of the valid bitmask. The valid bitmask is 265 * set to the logical 'or' of its prior value and a new value. 266 * 267 * @param mask the new mask value to be 'or'-ed with the prior value. 268 * @return a reference to this <code>ImageLayout</code> following the change. 269 */ setValid(int mask)270 public ImageLayout setValid(int mask) { 271 validMask |= mask; 272 return this; 273 } 274 275 /** 276 * Clears selected bits of the valid bitmask. The valid bitmask 277 * is set to the logical 'and' of its prior value and the negation 278 * of the new mask value. This effectively subtracts from the set of 279 * valid parameters. 280 * 281 * @param mask the new mask value to be negated and 'and'-ed with 282 * the prior value. 283 * @return a reference to this <code>ImageLayout</code> following the change. 284 */ unsetValid(int mask)285 public ImageLayout unsetValid(int mask) { 286 validMask &= ~mask; 287 return this; 288 } 289 290 /** 291 * Marks the parameters dealing with the image bounds 292 * (minX, minY, width, and height) as being invalid. 293 * 294 * @return a reference to this <code>ImageLayout</code> following the change. 295 */ unsetImageBounds()296 public ImageLayout unsetImageBounds() { 297 unsetValid(MIN_X_MASK | 298 MIN_Y_MASK | 299 WIDTH_MASK | 300 HEIGHT_MASK); 301 return this; 302 } 303 304 /** 305 * Marks the parameters dealing with the tile layout (tileGridXOffset, 306 * tileGridYOffset, tileWidth, and tileHeight) as being invalid. 307 * 308 * @return a reference to this <code>ImageLayout</code> following the change. 309 */ unsetTileLayout()310 public ImageLayout unsetTileLayout() { 311 unsetValid(TILE_GRID_X_OFFSET_MASK | 312 TILE_GRID_Y_OFFSET_MASK | 313 TILE_WIDTH_MASK | 314 TILE_HEIGHT_MASK); 315 return this; 316 } 317 318 /** 319 * Returns the value of <code>minX</code> if it is valid, and 320 * otherwise returns the value from the supplied <code>RenderedImage</code>. 321 * If <code>minX</code> is not valid and fallback is null, 0 is returned. 322 * 323 * @param fallback the <code>RenderedImage</code> fallback. 324 * @return the appropriate value of minX. 325 */ getMinX(RenderedImage fallback)326 public int getMinX(RenderedImage fallback) { 327 if (isValid(MIN_X_MASK)) { 328 return minX; 329 } else { 330 if (fallback == null) { 331 return 0; 332 } else { 333 return fallback.getMinX(); 334 } 335 } 336 } 337 338 /** 339 * Sets <code>minX</code> to the supplied value and marks it as valid. 340 * 341 * @param minX the minimum X coordinate of the image, as an int. 342 * @return a reference to this <code>ImageLayout</code> following the change. 343 */ setMinX(int minX)344 public ImageLayout setMinX(int minX) { 345 this.minX = minX; 346 setValid(MIN_X_MASK); 347 return this; 348 } 349 350 /** 351 * Returns the value of <code>minY</code> if it is valid, and 352 * otherwise returns the value from the supplied <code>RenderedImage</code>. 353 * If <code>minY</code> is not valid and fallback is null, 0 is returned. 354 * 355 * @param fallback the <code>RenderedImage</code> fallback. 356 * @return the appropriate value of minY. 357 */ getMinY(RenderedImage fallback)358 public int getMinY(RenderedImage fallback) { 359 if (isValid(MIN_Y_MASK)) { 360 return minY; 361 } else { 362 if (fallback == null) { 363 return 0; 364 } else { 365 return fallback.getMinY(); 366 } 367 } 368 } 369 370 /** 371 * Sets <code>minY</code> to the supplied value and marks it as valid. 372 * 373 * @param minY the minimum Y coordinate of the image, as an int. 374 * @return a reference to this <code>ImageLayout</code> following the change. 375 */ setMinY(int minY)376 public ImageLayout setMinY(int minY) { 377 this.minY = minY; 378 setValid(MIN_Y_MASK); 379 return this; 380 } 381 382 /** 383 * Returns the value of <code>width</code> if it is valid, and 384 * otherwise returns the value from the supplied <code>RenderedImage</code>. 385 * If <code>width</code> is not valid and fallback is null, 0 is returned. 386 * 387 * @param fallback the <code>RenderedImage</code> fallback. 388 * @return the appropriate value of width. 389 */ getWidth(RenderedImage fallback)390 public int getWidth(RenderedImage fallback) { 391 if (isValid(WIDTH_MASK)) { 392 return width; 393 } else { 394 if (fallback == null) { 395 return 0; 396 } else { 397 return fallback.getWidth(); 398 } 399 } 400 } 401 402 /** 403 * Sets <code>width</code> to the supplied value and marks it as valid. 404 * 405 * @param width the width of the image, as an int. 406 * @return a reference to this <code>ImageLayout</code> following the change. 407 * @throws IllegalArgumentException if <code>width</code> is non-positive. 408 */ setWidth(int width)409 public ImageLayout setWidth(int width) { 410 if(width <= 0) { 411 throw new IllegalArgumentException(JaiI18N.getString("ImageLayout0")); 412 } 413 this.width = width; 414 setValid(WIDTH_MASK); 415 return this; 416 } 417 418 /** 419 * Returns the value of height if it is valid, and 420 * otherwise returns the value from the supplied <code>RenderedImage</code>. 421 * If height is not valid and fallback is null, 0 is returned. 422 * 423 * @param fallback the <code>RenderedImage</code> fallback. 424 * @return the appropriate value of height. 425 */ getHeight(RenderedImage fallback)426 public int getHeight(RenderedImage fallback) { 427 if (isValid(HEIGHT_MASK)) { 428 return height; 429 } else { 430 if (fallback == null) { 431 return 0; 432 } else { 433 return fallback.getHeight(); 434 } 435 } 436 } 437 438 /** 439 * Sets height to the supplied value and marks it as valid. 440 * 441 * @param height the height of the image, as an int. 442 * @return a reference to this <code>ImageLayout</code> following the change. 443 * @throws IllegalArgumentException if <code>height</code> is non-positive. 444 */ setHeight(int height)445 public ImageLayout setHeight(int height) { 446 if(height <= 0) { 447 throw new IllegalArgumentException(JaiI18N.getString("ImageLayout0")); 448 } 449 this.height = height; 450 setValid(HEIGHT_MASK); 451 return this; 452 } 453 454 /** 455 * Returns the value of <code>tileGridXOffset</code> if it is valid, and 456 * otherwise returns the value from the supplied <code>RenderedImage</code>. 457 * If <code>tileGridXOffset</code> is not valid and fallback is null, 0 is returned. 458 * 459 * @param fallback the <code>RenderedImage</code> fallback. 460 * @return the appropriate value of tileGridXOffset. 461 */ getTileGridXOffset(RenderedImage fallback)462 public int getTileGridXOffset(RenderedImage fallback) { 463 if (isValid(TILE_GRID_X_OFFSET_MASK)) { 464 return tileGridXOffset; 465 } else { 466 if (fallback == null) { 467 return 0; 468 } else { 469 return fallback.getTileGridXOffset(); 470 } 471 } 472 } 473 474 /** 475 * Sets <code>tileGridXOffset</code> to the supplied value and marks it as valid. 476 * 477 * @param tileGridXOffset the X coordinate of tile (0, 0), as an int. 478 * @return a reference to this <code>ImageLayout</code> following the change. 479 */ setTileGridXOffset(int tileGridXOffset)480 public ImageLayout setTileGridXOffset(int tileGridXOffset) { 481 this.tileGridXOffset = tileGridXOffset; 482 setValid(TILE_GRID_X_OFFSET_MASK); 483 return this; 484 } 485 486 /** 487 * Returns the value of <code>tileGridYOffset</code> if it is valid, and 488 * otherwise returns the value from the supplied <code>RenderedImage</code>. 489 * If <code>tileGridYOffset</code> is not valid and fallback is null, 0 is returned. 490 * 491 * @param fallback the <code>RenderedImage</code> fallback. 492 * @return the appropriate value of tileGridYOffset. 493 */ getTileGridYOffset(RenderedImage fallback)494 public int getTileGridYOffset(RenderedImage fallback) { 495 if (isValid(TILE_GRID_Y_OFFSET_MASK)) { 496 return tileGridYOffset; 497 } else { 498 if (fallback == null) { 499 return 0; 500 } else { 501 return fallback.getTileGridYOffset(); 502 } 503 } 504 } 505 506 /** 507 * Sets <code>tileGridYOffset</code> to the supplied value and marks it as valid. 508 * 509 * @param tileGridYOffset the Y coordinate of tile (0, 0), as an int. 510 * @return a reference to this <code>ImageLayout</code> following the change. 511 */ setTileGridYOffset(int tileGridYOffset)512 public ImageLayout setTileGridYOffset(int tileGridYOffset) { 513 this.tileGridYOffset = tileGridYOffset; 514 setValid(TILE_GRID_Y_OFFSET_MASK); 515 return this; 516 } 517 518 /** 519 * Returns the value of <code>tileWidth</code> if it is valid, and 520 * otherwise returns the value from the supplied <code>RenderedImage</code>. 521 * If <code>tileWidth</code> is not valid and fallback is null, 0 is returned. 522 * 523 * @param fallback the <code>RenderedImage</code> fallback. 524 * @return the appropriate value of tileWidth. 525 */ getTileWidth(RenderedImage fallback)526 public int getTileWidth(RenderedImage fallback) { 527 if (isValid(TILE_WIDTH_MASK)) { 528 return tileWidth; 529 } else { 530 if (fallback == null) { 531 return 0; 532 } else { 533 return fallback.getTileWidth(); 534 } 535 } 536 } 537 538 /** 539 * Sets <code>tileWidth</code> to the supplied value and marks it as valid. 540 * 541 * @param tileWidth the width of a tile, as an int. 542 * @return a reference to this <code>ImageLayout</code> following the change. 543 * @throws IllegalArgumentException if <code>tileWidth</code> is 544 * non-positive. 545 */ setTileWidth(int tileWidth)546 public ImageLayout setTileWidth(int tileWidth) { 547 if(tileWidth <= 0) { 548 throw new IllegalArgumentException(JaiI18N.getString("ImageLayout0")); 549 } 550 this.tileWidth = tileWidth; 551 setValid(TILE_WIDTH_MASK); 552 return this; 553 } 554 555 /** 556 * Returns the value of tileHeight if it is valid, and 557 * otherwise returns the value from the supplied <code>RenderedImage</code>. 558 * If tileHeight is not valid and fallback is null, 0 is returned. 559 * 560 * @param fallback the <code>RenderedImage</code> fallback. 561 * @return the appropriate value of tileHeight. 562 */ getTileHeight(RenderedImage fallback)563 public int getTileHeight(RenderedImage fallback) { 564 if (isValid(TILE_HEIGHT_MASK)) { 565 return tileHeight; 566 } else { 567 if (fallback == null) { 568 return 0; 569 } else { 570 return fallback.getTileHeight(); 571 } 572 } 573 } 574 575 /** 576 * Sets tileHeight to the supplied value and marks it as valid. 577 * 578 * @param tileHeight the height of a tile, as an int. 579 * @return a reference to this <code>ImageLayout</code> following the change. 580 * @throws IllegalArgumentException if <code>tileHeight</code> is 581 * non-positive. 582 */ setTileHeight(int tileHeight)583 public ImageLayout setTileHeight(int tileHeight) { 584 if(tileHeight <= 0) { 585 throw new IllegalArgumentException(JaiI18N.getString("ImageLayout0")); 586 } 587 this.tileHeight = tileHeight; 588 setValid(TILE_HEIGHT_MASK); 589 return this; 590 } 591 592 /** 593 * Returns the value of <code>sampleModel</code> if it is valid, and 594 * otherwise returns the value from the supplied <code>RenderedImage</code>. 595 * If <code>sampleModel</code> is not valid and fallback is null, null is returned. 596 * 597 * @param fallback the <code>RenderedImage</code> fallback. 598 * @return the appropriate value of <code>sampleModel</code>. 599 */ getSampleModel(RenderedImage fallback)600 public SampleModel getSampleModel(RenderedImage fallback) { 601 if (isValid(SAMPLE_MODEL_MASK)) { 602 return sampleModel; 603 } else { 604 if (fallback == null) { 605 return null; 606 } else { 607 return fallback.getSampleModel(); 608 } 609 } 610 } 611 612 /** 613 * Sets <code>sampleModel</code> to the supplied value and marks it as valid. 614 * 615 * @param sampleModel the new <code>SampleModel</code>. 616 * @return a reference to this <code>ImageLayout</code> following the change. 617 */ setSampleModel(SampleModel sampleModel)618 public ImageLayout setSampleModel(SampleModel sampleModel) { 619 this.sampleModel = sampleModel; 620 setValid(SAMPLE_MODEL_MASK); 621 return this; 622 } 623 624 /** 625 * Returns the value of <code>colorModel</code> if it is valid, and 626 * otherwise returns the value from the supplied <code>RenderedImage</code>. 627 * If <code>colorModel</code> is not valid and fallback is null, null is returned. 628 * 629 * @param fallback the <code>RenderedImage</code> fallback. 630 * @return the appropriate value of <code>colorModel</code>. 631 */ getColorModel(RenderedImage fallback)632 public ColorModel getColorModel(RenderedImage fallback) { 633 if (isValid(COLOR_MODEL_MASK)) { 634 return colorModel; 635 } else { 636 if (fallback == null) { 637 return null; 638 } else { 639 return fallback.getColorModel(); 640 } 641 } 642 } 643 644 /** 645 * Sets <code>colorModel</code> to the supplied value and marks it as valid. 646 * 647 * @param colorModel the new <code>ColorModel</code>. 648 * @return a reference to this <code>ImageLayout</code> following the change. 649 */ setColorModel(ColorModel colorModel)650 public ImageLayout setColorModel(ColorModel colorModel) { 651 this.colorModel = colorModel; 652 setValid(COLOR_MODEL_MASK); 653 return this; 654 } 655 656 /** Returns a String containing the values of all valid fields. */ toString()657 public String toString() { 658 String s = "ImageLayout["; 659 boolean first = true; 660 661 if (isValid(MIN_X_MASK)) { 662 s += "MIN_X=" + minX; 663 first = false; 664 } 665 666 if (isValid(MIN_Y_MASK)) { 667 if (!first) { 668 s += ", "; 669 } 670 s += "MIN_Y=" + minY; 671 first = false; 672 } 673 674 if (isValid(WIDTH_MASK)) { 675 if (!first) { 676 s += ", "; 677 } 678 s += "WIDTH=" + width; 679 first = false; 680 } 681 682 if (isValid(HEIGHT_MASK)) { 683 if (!first) { 684 s += ", "; 685 } 686 s += "HEIGHT=" + height; 687 first = false; 688 } 689 690 if (isValid(TILE_GRID_X_OFFSET_MASK)) { 691 if (!first) { 692 s += ", "; 693 } 694 s += "TILE_GRID_X_OFFSET=" + tileGridXOffset; 695 first = false; 696 } 697 698 if (isValid(TILE_GRID_Y_OFFSET_MASK)) { 699 if (!first) { 700 s += ", "; 701 } 702 s += "TILE_GRID_Y_OFFSET=" + tileGridYOffset; 703 first = false; 704 } 705 706 if (isValid(TILE_WIDTH_MASK)) { 707 if (!first) { 708 s += ", "; 709 } 710 s += "TILE_WIDTH=" + tileWidth; 711 first = false; 712 } 713 714 if (isValid(TILE_HEIGHT_MASK)) { 715 if (!first) { 716 s += ", "; 717 } 718 s += "TILE_HEIGHT=" + tileHeight; 719 first = false; 720 } 721 722 if (isValid(SAMPLE_MODEL_MASK)) { 723 if (!first) { 724 s += ", "; 725 } 726 s += "SAMPLE_MODEL=" + sampleModel; 727 first = false; 728 } 729 730 if (isValid(COLOR_MODEL_MASK)) { 731 if (!first) { 732 s += ", "; 733 } 734 s += "COLOR_MODEL=" + colorModel; 735 } 736 737 s += "]"; 738 return s; 739 } 740 741 /** 742 * Returns a clone of the <code>ImageLayout</code> as an Object. 743 */ clone()744 public Object clone() { 745 try { 746 return super.clone(); 747 } catch (CloneNotSupportedException e) { 748 return null; 749 } 750 } 751 752 /** 753 * Serialize the <code>ImageLayout</code>. 754 * @throws IOException 755 */ writeObject(ObjectOutputStream out)756 private void writeObject(ObjectOutputStream out) throws IOException { 757 // Write the non-static and non-transient fields. 758 out.defaultWriteObject(); 759 760 // Create and write a serializable SampleModel. 761 if(isValid(SAMPLE_MODEL_MASK)) { 762 out.writeObject(SerializerFactory.getState(sampleModel, null)); 763 } 764 765 // Create and write a serializable ColorModel. 766 if(isValid(COLOR_MODEL_MASK)) { 767 out.writeObject(SerializerFactory.getState(colorModel, null)); 768 } 769 } 770 771 /** 772 * Deserialize the <code>ImageLayout</code>. 773 * @throws IOException 774 */ readObject(ObjectInputStream in)775 private void readObject(ObjectInputStream in) 776 throws IOException, ClassNotFoundException { 777 // Read the non-static and non-transient fields. 778 in.defaultReadObject(); 779 780 // Read the serializable form of the SampleModel. 781 if(isValid(SAMPLE_MODEL_MASK)) { 782 Object object = in.readObject(); 783 if (!(object instanceof SerializableState)) 784 sampleModel = null; 785 786 SerializableState ss = (SerializableState)object; 787 Class c = ss.getObjectClass(); 788 if (SampleModel.class.isAssignableFrom(c)) 789 sampleModel = (SampleModel)ss.getObject(); 790 else 791 sampleModel = null; 792 } 793 794 // Read the serializable form of the ColorModel. 795 if(isValid(COLOR_MODEL_MASK)) { 796 Object object = in.readObject(); 797 if (!(object instanceof SerializableState)) 798 colorModel = null; 799 800 SerializableState ss = (SerializableState)object; 801 Class c = ss.getObjectClass(); 802 if (ColorModel.class.isAssignableFrom(c)) 803 colorModel = (ColorModel)ss.getObject(); 804 else 805 colorModel = null; 806 } 807 } 808 809 /** 810 * Tests if the specified <code>Object</code> equals this 811 * <code>ImageLayout</code>. 812 * 813 * @param obj the <code>Object</code> to test for equality 814 * 815 * @return <code>true</code> if the specified <code>Object</code> 816 * is an instance of <code>ImageLayout</code> and equals this 817 * <code>ImageLayout</code>; <code>false</code> otherwise. 818 * 819 * @since JAI 1.1 820 */ equals(Object obj)821 public boolean equals(Object obj) { 822 823 if (this == obj) 824 return true; 825 826 if (!(obj instanceof ImageLayout)) 827 return false; 828 829 ImageLayout il = (ImageLayout)obj; 830 831 return (validMask == il.validMask ) && 832 (width == il.width ) && 833 (height == il.height ) && 834 (minX == il.minX ) && 835 (minY == il.minY ) && 836 (tileHeight == il.tileHeight ) && 837 (tileWidth == il.tileWidth ) && 838 (tileGridXOffset == il.tileGridXOffset) && 839 (tileGridYOffset == il.tileGridYOffset) && 840 (sampleModel.equals(il.sampleModel )) && 841 (colorModel.equals(il.colorModel)); 842 } 843 844 /** 845 * Returns the hash code for this <code>ImageLayout</code>. 846 * 847 * @return a hash code for this <code>ImageLayout</code>. 848 * 849 * @since JAI 1.1 850 */ hashCode()851 public int hashCode() { 852 853 int code = 0, i = 1; 854 855 // This implementation is quite arbitrary. 856 // hashCode's NEED not be uniqe for two "different" objects 857 code += (width * i++); 858 code += (height * i++); 859 code += (minX * i++); 860 code += (minY * i++); 861 code += (tileHeight * i++); 862 code += (tileWidth * i++); 863 code += (tileGridXOffset * i++); 864 code += (tileGridYOffset * i++); 865 866 code ^= sampleModel.hashCode(); 867 code ^= validMask; 868 code ^= colorModel.hashCode(); 869 870 return code; 871 } 872 } 873