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