Source Code Cross Referenced for GeometricOpImage.java in  » 6.0-JDK-Modules » Java-Advanced-Imaging » javax » media » jai » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » Java Advanced Imaging » javax.media.jai 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $RCSfile: GeometricOpImage.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.2 $
009:         * $Date: 2005/05/10 00:34:12 $
010:         * $State: Exp $
011:         */
012:        package javax.media.jai;
013:
014:        import java.awt.Rectangle;
015:        import java.awt.RenderingHints;
016:        import java.awt.geom.Point2D;
017:        import java.awt.image.DataBuffer;
018:        import java.awt.image.RenderedImage;
019:        import java.awt.image.Raster;
020:        import java.awt.image.WritableRaster;
021:        import java.awt.Point;
022:        import java.util.Map;
023:        import java.util.Vector;
024:        import javax.media.jai.util.CaselessStringKey;
025:        import com.sun.media.jai.util.ImageUtil;
026:
027:        /**
028:         * An abstract base class for image operators that perform a geometric
029:         * transformation of the source image.
030:         *
031:         * <p> The geometric relationship between the source and destination images
032:         * will be determined by the specific behavior of the methods
033:         * <code>backwardMapRect()</code> and <code>forwardMapRect()</code> the
034:         * implementations of which must be provided by a subclass.
035:         *
036:         * <p> The location of the source pixel corresponding to a given destination
037:         * pixel is determined by the aforementioned backward mapping transformation.
038:         * The value of the destination pixel is then calculated by interpolating the
039:         * values of a set of source pixels at locations in the vicinity of the
040:         * backward mapped destination pixel location according to the requirements
041:         * of a specified interpolation algorithm.  In particular, a given
042:         * destination pixel value may be interpolated from the neighborhood of source
043:         * pixels beginning at (sx - leftPadding, sy - topPadding) and extending to
044:         * (sx + rightPadding, sy + bottomPadding), inclusive, where (sx,&nbsp;sy) is
045:         * the truncated backward mapped location of the destination pixel.  The
046:         * actual amount of padding required is determined by a supplied
047:         * <code>Interpolation</code> object.
048:         *
049:         * <p> Since this operator might need a region around each source pixel in
050:         * order to compute the destination pixel value, the border destination pixels
051:         * might not be able to be computed without any source extension mechanism.
052:         * The source extension method can be specified by supplying a
053:         * <code>BorderExtender</code> object that will define the pixel values of the
054:         * source outside the actual source area as a function of the actual source
055:         * pixel values.  If no extension is specified, the destination samples that
056:         * cannot be computed will be written in the destination as the user-specified
057:         * background values.
058:         *
059:         * @see BorderExtender
060:         * @see Interpolation
061:         * @see InterpolationNearest
062:         * @see OpImage
063:         *
064:         * @since JAI 1.1
065:         */
066:        public abstract class GeometricOpImage extends OpImage {
067:            /**
068:             * The <code>Interpolation</code> object describing the subpixel
069:             * interpolation method.  This variable should not be null.
070:             */
071:            protected Interpolation interp;
072:
073:            /**
074:             * The <code>BorderExtender</code> describing the method by which
075:             * source data are extended to provide sufficient context for
076:             * calculation of the pixel values of backward mapped coordinates
077:             * according to the interpolation method specified.  If this
078:             * variable is <code>null</code> no extension will be performed.
079:             */
080:            protected BorderExtender extender = null;
081:
082:            /**
083:             * The computable bounds of this image within which the pixels of the
084:             * image may be computed and set.  This is equal to the bounding box of
085:             * the set of pixels the locations of which backward map to within the
086:             * source image bounds contracted by the padding values required for
087:             * interpolation.
088:             *
089:             * <p> The <code>GeometricOpImage</code> constructor sets the computable
090:             * bounds to the image bounds.  Subclasses should set this value to
091:             * values reasonable for the operation in question.
092:             */
093:            protected Rectangle computableBounds;
094:
095:            /**
096:             * Indicates whether the background values are provided.
097:             */
098:            protected boolean setBackground;
099:
100:            /**
101:             * The user-specified background values.
102:             */
103:            protected double[] backgroundValues;
104:
105:            /**
106:             * The user-specified background values in integer.
107:             */
108:            protected int[] intBackgroundValues;
109:
110:            /**
111:             * Constructs a <code>GeometricOpImage</code>.  The image layout
112:             * (image bounds, tile grid layout, <code>SampleModel</code> and
113:             * <code>ColorModel</code>) of the output are set in the standard
114:             * way by the <code>OpImage</code> constructor.
115:             *
116:             * <p> Additional control over the image bounds, tile grid layout,
117:             * <code>SampleModel</code>, and <code>ColorModel</code> may be
118:             * obtained by specifying an <code>ImageLayout</code> parameter.
119:             * This parameter will be passed to the superclass constructor
120:             * unchanged.
121:             *
122:             * @param layout An <code>ImageLayout</code> containing the source
123:             *        bounds before padding, and optionally containing the
124:             *        tile grid layout, <code>SampleModel</code>, and
125:             *        <code>ColorModel</code>.
126:             * @param sources  The immediate sources of this image.
127:             * @param configuration Configurable attributes of the image including
128:             *        configuration variables indexed by
129:             *        <code>RenderingHints.Key</code>s and image properties indexed
130:             *        by <code>String</code>s or <code>CaselessStringKey</code>s.
131:             *        This is simply forwarded to the superclass constructor.
132:             * @param cobbleSources A <code>boolean</code> indicating whether
133:             *        <code>computeRect()</code> expects contiguous sources.
134:             * @param extender A <code>BorderExtender</code>, or <code>null</code>.
135:             * @param interp an <code>Interpolation</code> object to use for
136:             *        interpolation of the backward mapped pixel values at
137:             *        fractional positions.  If the supplied parameter is
138:             *        <code>null</code> the corresponding instance variable
139:             *        will be initialized to an instance of
140:             *        <code>InterpolationNearest</code>.
141:             *
142:             * @throws IllegalArgumentException if <code>sources</code>
143:             *         is <code>null</code>.
144:             * @throws IllegalArgumentException  If <code>sources</code>
145:             *         is non-<code>null</code> and any object in
146:             *         <code>sources</code> is <code>null</code>.
147:             * @throws IllegalArgumentException if combining the intersected
148:             *         source bounds with the layout parameter results in negative
149:             *         output width or height.
150:             */
151:            public GeometricOpImage(Vector sources, ImageLayout layout,
152:                    Map configuration, boolean cobbleSources,
153:                    BorderExtender extender, Interpolation interp) {
154:                this (sources, layout, configuration, cobbleSources, extender,
155:                        interp, null);
156:            }
157:
158:            private static Map configHelper(Map configuration) {
159:
160:                Map config;
161:
162:                if (configuration == null) {
163:                    config = new RenderingHints(
164:                            JAI.KEY_REPLACE_INDEX_COLOR_MODEL, Boolean.TRUE);
165:                } else {
166:
167:                    config = configuration;
168:
169:                    // If the user specified a value for this hint, we don't
170:                    // want to change that
171:                    if (!config.containsKey(JAI.KEY_REPLACE_INDEX_COLOR_MODEL)) {
172:
173:                        RenderingHints hints = new RenderingHints(null);
174:                        // This is effectively a clone of configuration
175:                        hints.putAll(configuration);
176:                        config = hints;
177:                        config.put(JAI.KEY_REPLACE_INDEX_COLOR_MODEL,
178:                                Boolean.TRUE);
179:                    }
180:                }
181:
182:                return config;
183:            }
184:
185:            /**
186:             * Constructs a <code>GeometricOpImage</code>.  The image layout
187:             * (image bounds, tile grid layout, <code>SampleModel</code> and
188:             * <code>ColorModel</code>) of the output are set in the standard
189:             * way by the <code>OpImage</code> constructor.
190:             *
191:             * <p> Additional control over the image bounds, tile grid layout,
192:             * <code>SampleModel</code>, and <code>ColorModel</code> may be
193:             * obtained by specifying an <code>ImageLayout</code> parameter.
194:             * This parameter will be passed to the superclass constructor
195:             * unchanged.
196:             *
197:             * <p> A <code>RenderingHints</code> for 
198:             * <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code> with the value of
199:             * <code>Boolean.TRUE</code> is automatically added to the given
200:             * <code>configuration</code> and passed up to the superclass constructor
201:             * so that geometric operations are performed on the pixel values instead
202:             * of being performed on the indices into the color map for those
203:             * operations whose source(s) have an <code>IndexColorModel</code>.
204:             * This addition will take place only if a value for the 
205:             * <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code> has not already been
206:             * provided by the user. Note that the <code>configuration</code> Map
207:             * is cloned before the new hint is added to it. Regarding the value
208:             * for the <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code>
209:             * <code>RenderingHints</code>, the operator itself can be smart
210:             * based on the parameters, i.e. while the default value for
211:             * the <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code> is
212:             * <code>Boolean.TRUE</code> for operations that extend this class,
213:             * in some cases the operator could set the default.
214:             *
215:             * @param layout An <code>ImageLayout</code> containing the source
216:             *        bounds before padding, and optionally containing the
217:             *        tile grid layout, <code>SampleModel</code>, and
218:             *        <code>ColorModel</code>.
219:             * @param sources  The immediate sources of this image.
220:             * @param configuration Configurable attributes of the image including
221:             *        configuration variables indexed by
222:             *        <code>RenderingHints.Key</code>s and image properties indexed
223:             *        by <code>String</code>s or <code>CaselessStringKey</code>s.
224:             *        This is simply forwarded to the superclass constructor.
225:             * @param cobbleSources A <code>boolean</code> indicating whether
226:             *        <code>computeRect()</code> expects contiguous sources.
227:             * @param extender A <code>BorderExtender</code>, or <code>null</code>.
228:             * @param interp an <code>Interpolation</code> object to use for
229:             *        interpolation of the backward mapped pixel values at
230:             *        fractional positions.  If the supplied parameter is
231:             *        <code>null</code> the corresponding instance variable
232:             *        will be initialized to an instance of
233:             *        <code>InterpolationNearest</code>.
234:             * @param backgroundValues The user-specified background values.  If the
235:             *        provided array length is smaller than the number of bands, all
236:             *        the bands will be filled with the first element of the array.
237:             *	      If the provided array is null, set it to <code>new double[]{0.0}
238:             *	      </code>.
239:             *
240:             * @throws IllegalArgumentException if <code>sources</code>
241:             *         is <code>null</code>.
242:             * @throws IllegalArgumentException  If <code>sources</code>
243:             *         is non-<code>null</code> and any object in
244:             *         <code>sources</code> is <code>null</code>.
245:             * @throws IllegalArgumentException if combining the intersected
246:             *         source bounds with the layout parameter results in negative
247:             *         output width or height.
248:             * @since JAI 1.1.2
249:             */
250:            public GeometricOpImage(Vector sources, ImageLayout layout,
251:                    Map configuration, boolean cobbleSources,
252:                    BorderExtender extender, Interpolation interp,
253:                    double[] backgroundValues) {
254:                super (sources, layout, configHelper(configuration),
255:                        cobbleSources);
256:
257:                this .extender = extender;
258:                this .interp = interp != null ? interp
259:                        : new InterpolationNearest();
260:
261:                if (backgroundValues == null)
262:                    backgroundValues = new double[] { 0.0 };
263:
264:                this .setBackground = false;
265:                for (int i = 0; i < backgroundValues.length; i++)
266:                    if (backgroundValues[i] != 0.0)
267:                        this .setBackground = true;
268:
269:                this .backgroundValues = backgroundValues;
270:                int numBands = getSampleModel().getNumBands();
271:                if (backgroundValues.length < numBands) {
272:                    this .backgroundValues = new double[numBands];
273:                    for (int i = 0; i < numBands; i++)
274:                        this .backgroundValues[i] = backgroundValues[0];
275:                }
276:
277:                if (sampleModel.getDataType() <= DataBuffer.TYPE_INT) {
278:                    int length = this .backgroundValues.length;
279:                    intBackgroundValues = new int[length];
280:                    for (int i = 0; i < length; i++)
281:                        intBackgroundValues[i] = (int) this .backgroundValues[i];
282:                }
283:
284:                // Initialize computable bounds to the current image bounds.
285:                computableBounds = getBounds();
286:            }
287:
288:            /**
289:             * Retrieve the <code>Interpolation</code> object associated with
290:             * this class instance.  The object is returned by reference.
291:             *
292:             * @return The associated <code>Interpolation</code> object.
293:             */
294:            public Interpolation getInterpolation() {
295:                return interp;
296:            }
297:
298:            /**
299:             * Retrieve the <code>BorderExtender</code> object associated with
300:             * this class instance.  The object is returned by reference.
301:             *
302:             * @return The associated <code>BorderExtender</code> object
303:             *         or <code>null</code>.
304:             */
305:            public BorderExtender getBorderExtender() {
306:                return extender;
307:            }
308:
309:            /**
310:             * Computes the position in the specified source that best
311:             * matches the supplied destination image position. If it
312:             * is not possible to compute the requested position,
313:             * <code>null</code> will be returned.
314:             *
315:             * <p>The implementation in this class returns the value of
316:             * <code>pt</code> in the following code snippet:
317:             *
318:             * <pre>
319:             * Rectangle destRect = new Rectangle((int)destPt.getX(),
320:             *                                    (int)destPt.getY(),
321:             *                                    1, 1);
322:             * Rectangle sourceRect = backwardMapRect(destRect, sourceIndex);
323:             * Point2D pt = (Point2D)destPt.clone();
324:             * pt.setLocation(sourceRect.x + (sourceRect.width - 1.0)/2.0,
325:             *                sourceRect.y + (sourceRect.height - 1.0)/2.0);
326:             * </pre>
327:             *
328:             * Subclasses requiring different behavior should override this
329:             * method.</p>
330:             *
331:             * @param destPt the position in destination image coordinates
332:             * to map to source image coordinates.
333:             * @param sourceIndex the index of the source image.
334:             *
335:             * @return a <code>Point2D</code> of the same class as
336:             * <code>destPt</code> or <code>null</code>.
337:             *
338:             * @throws IllegalArgumentException if <code>destPt</code> is
339:             * <code>null</code>.
340:             * @throws IndexOutOfBoundsException if <code>sourceIndex</code> is
341:             * negative or greater than or equal to the number of sources.
342:             *
343:             * @since JAI 1.1.2
344:             */
345:            public Point2D mapDestPoint(Point2D destPt, int sourceIndex) {
346:                if (destPt == null) {
347:                    throw new IllegalArgumentException(JaiI18N
348:                            .getString("Generic0"));
349:                } else if (sourceIndex < 0 || sourceIndex >= getNumSources()) {
350:                    throw new IndexOutOfBoundsException(JaiI18N
351:                            .getString("Generic1"));
352:                }
353:
354:                Rectangle destRect = new Rectangle((int) destPt.getX(),
355:                        (int) destPt.getY(), 1, 1);
356:
357:                Rectangle sourceRect = backwardMapRect(destRect, sourceIndex);
358:
359:                if (sourceRect == null) {
360:                    return null;
361:                }
362:
363:                Point2D pt = (Point2D) destPt.clone();
364:                pt.setLocation(sourceRect.x + (sourceRect.width - 1.0) / 2.0,
365:                        sourceRect.y + (sourceRect.height - 1.0) / 2.0);
366:
367:                return pt;
368:            }
369:
370:            /**
371:             * Computes the position in the destination that best
372:             * matches the supplied source image position. If it
373:             * is not possible to compute the requested position,
374:             * <code>null</code> will be returned.
375:             *
376:             * <p>The implementation in this class returns the value of
377:             * <code>pt</code> in the following code snippet:
378:             *
379:             * <pre>
380:             * Rectangle sourceRect = new Rectangle((int)sourcePt.getX(),
381:             *                                      (int)sourcePt.getY(),
382:             *                                      1, 1);
383:             * Rectangle destRect = forwardMapRect(sourceRect, sourceIndex);
384:             * Point2D pt = (Point2D)sourcePt.clone();
385:             * pt.setLocation(destRect.x + (destRect.width - 1.0)/2.0,
386:             *                destRect.y + (destRect.height - 1.0)/2.0);
387:             * </pre>
388:             *
389:             * Subclasses requiring different behavior should override this
390:             * method.</p>
391:             *
392:             * @param sourcePt the position in source image coordinates
393:             * to map to destination image coordinates.
394:             * @param sourceIndex the index of the source image.
395:             *
396:             * @return a <code>Point2D</code> of the same class as
397:             * <code>sourcePt</code> or <code>null</code>.
398:             *
399:             * @throws IllegalArgumentException if <code>sourcePt</code> is
400:             * <code>null</code>.
401:             * @throws IndexOutOfBoundsException if <code>sourceIndex</code> is
402:             * negative or greater than or equal to the number of sources.
403:             *
404:             * @since JAI 1.1.2
405:             */
406:            public Point2D mapSourcePoint(Point2D sourcePt, int sourceIndex) {
407:                if (sourcePt == null) {
408:                    throw new IllegalArgumentException(JaiI18N
409:                            .getString("Generic0"));
410:                } else if (sourceIndex < 0 || sourceIndex >= getNumSources()) {
411:                    throw new IndexOutOfBoundsException(JaiI18N
412:                            .getString("Generic1"));
413:                }
414:
415:                Rectangle sourceRect = new Rectangle((int) sourcePt.getX(),
416:                        (int) sourcePt.getY(), 1, 1);
417:                Rectangle destRect = forwardMapRect(sourceRect, sourceIndex);
418:
419:                if (destRect == null) {
420:                    return null;
421:                }
422:
423:                Point2D pt = (Point2D) sourcePt.clone();
424:                pt.setLocation(destRect.x + (destRect.width - 1.0) / 2.0,
425:                        destRect.y + (destRect.height - 1.0) / 2.0);
426:
427:                return pt;
428:            }
429:
430:            /**
431:             * Returns the minimum bounding box of the region of the destination
432:             * to which a particular <code>Rectangle</code> of the specified source
433:             * will be mapped.
434:             *
435:             * <p> The integral source rectangle coordinates should be considered
436:             * pixel indices.  The "energy" of each pixel is defined to be
437:             * concentrated in the continuous plane of pixels at an offset of
438:             * (0.5,&nbsp;0.5) from the index of the pixel.  Forward mappings
439:             * must take this (0.5,&nbsp;0.5) pixel center into account.  Thus
440:             * given integral source pixel indices as input, the fractional
441:             * destination location, as calculated by functions Xf(xSrc,&nbsp;ySrc),
442:             * Yf(xSrc,&nbsp;ySrc), is given by:
443:             * <pre>
444:             *
445:             *     xDst = Xf(xSrc+0.5, ySrc+0.5) - 0.5
446:             *     yDst = Yf(xSrc+0.5, ySrc+0.5) - 0.5
447:             *
448:             * </pre>
449:             *
450:             * @param sourceRect the <code>Rectangle</code> in source coordinates.
451:             * @param sourceIndex the index of the source image.
452:             *
453:             * @return a <code>Rectangle</code> indicating the destination
454:             *         bounding box, or <code>null</code> if the bounding box
455:             *         is unknown.
456:             *
457:             * @throws IllegalArgumentException if <code>sourceIndex</code> is
458:             *         negative or greater than the index of the last source.
459:             * @throws IllegalArgumentException if <code>sourceRect</code> is
460:             *         <code>null</code>.
461:             */
462:            protected abstract Rectangle forwardMapRect(Rectangle sourceRect,
463:                    int sourceIndex);
464:
465:            /**
466:             * Returns the minimum bounding box of the region of the specified
467:             * source to which a particular <code>Rectangle</code> of the
468:             * destination will be mapped.
469:             *
470:             * <p> The integral destination rectangle coordinates should be considered
471:             * pixel indices.  The "energy" of each pixel is defined to be
472:             * concentrated in the continuous plane of pixels at an offset of
473:             * (0.5,&nbsp;0.5) from the index of the pixel.  Backward mappings
474:             * must take this (0.5,&nbsp;0.5) pixel center into account.  Thus
475:             * given integral destination pixel indices as input, the fractional
476:             * source location, as calculated by functions Xb(xDst,&nbsp;yDst),
477:             * Yb(xDst,&nbsp;yDst), is given by:
478:             * <pre>
479:             *
480:             *     xSrc = Xb(xDst+0.5, yDst+0.5) - 0.5
481:             *     ySrc = Yb(xDst+0.5, yDst+0.5) - 0.5
482:             *
483:             * </pre>
484:             *
485:             * @param destRect the <code>Rectangle</code> in destination coordinates.
486:             * @param sourceIndex the index of the source image.
487:             *
488:             * @return a <code>Rectangle</code> indicating the source bounding box,
489:             *         or <code>null</code> if the bounding box is unknown.
490:             *
491:             * @throws IllegalArgumentException if <code>sourceIndex</code> is
492:             *         negative or greater than the index of the last source.
493:             * @throws IllegalArgumentException if <code>destRect</code> is
494:             *         <code>null</code>.
495:             */
496:            protected abstract Rectangle backwardMapRect(Rectangle destRect,
497:                    int sourceIndex);
498:
499:            /**
500:             * Returns a conservative estimate of the destination region that
501:             * can potentially be affected by the pixels of a rectangle of a
502:             * given source.  The supplied <code>Rectangle</code> will first be
503:             * contracted according to the <code>Interpolation</code> object
504:             * characteristics and then forward mapped into destination coordinate
505:             * space using <code>forwardMapRect()</code>. The resulting
506:             * <code>Rectangle</code> is <u>not</u> clipped to the destination
507:             * image bounds.
508:             *
509:             * @param sourceRect the <code>Rectangle</code> in source coordinates.
510:             * @param sourceIndex the index of the source image.
511:             * @return a <code>Rectangle</code> indicating the potentially affected
512:             *         destination region.  This will equal the destination bounds
513:             *         if <code>forwardMapRect()</code> returns null.
514:             *
515:             * @throws IllegalArgumentException if <code>sourceIndex</code> is
516:             *         negative or greater than the index of the last source.
517:             * @throws IllegalArgumentException if <code>sourceRect</code> is
518:             *         <code>null</code>.
519:             */
520:            public Rectangle mapSourceRect(Rectangle sourceRect, int sourceIndex) {
521:
522:                if (sourceRect == null) {
523:                    throw new IllegalArgumentException(JaiI18N
524:                            .getString("Generic0"));
525:                }
526:
527:                if (sourceIndex < 0 || sourceIndex >= getNumSources()) {
528:                    throw new IllegalArgumentException(JaiI18N
529:                            .getString("Generic1"));
530:                }
531:
532:                // Cache left and top padding.
533:                int lpad = interp.getLeftPadding();
534:                int tpad = interp.getTopPadding();
535:
536:                // Shrink the source Rectangle according to the Interpolation.
537:                Rectangle srcRect = (Rectangle) sourceRect.clone();
538:                srcRect.x += lpad;
539:                srcRect.y += tpad;
540:                srcRect.width -= (lpad + interp.getRightPadding());
541:                srcRect.height -= (tpad + interp.getBottomPadding());
542:
543:                // Map the source Rectangle into destination space.
544:                Rectangle destRect = forwardMapRect(srcRect, sourceIndex);
545:
546:                // Return Rectangle or destination bounds.
547:                return destRect == null ? getBounds() : destRect;
548:            }
549:
550:            /**
551:             * Returns a conservative estimate of the region of a specified
552:             * source that is required in order to compute the pixels of a
553:             * given destination rectangle.  The supplied <code>Rectangle</code>
554:             * will first be backward mapped into source coordinate space using
555:             * <code>backwardMapRect()</code> and then the resulting context
556:             * will be modified according to the <code>Interpolation</code>
557:             * object characteristics. The resulting <code>Rectangle</code>
558:             * is <u>not</u> clipped to the source image bounds.
559:             *
560:             * @param destRect the <code>Rectangle</code> in destination coordinates.
561:             * @param sourceIndex the index of the source image.
562:             *
563:             * @return a <code>Rectangle</code> indicating the required source region.
564:             *         This will equal the bounds of the respective source
565:             *         if <code>backwardMapRect()</code> returns null.
566:             *
567:             * @throws IllegalArgumentException if <code>sourceIndex</code> is
568:             *         negative or greater than the index of the last source.
569:             * @throws IllegalArgumentException if <code>destRect</code> is
570:             *         <code>null</code>.
571:             */
572:            public Rectangle mapDestRect(Rectangle destRect, int sourceIndex) {
573:
574:                if (destRect == null) {
575:                    throw new IllegalArgumentException(JaiI18N
576:                            .getString("Generic0"));
577:                }
578:
579:                if (sourceIndex < 0 || sourceIndex >= getNumSources()) {
580:                    throw new IllegalArgumentException(JaiI18N
581:                            .getString("Generic1"));
582:                }
583:
584:                // Map the destination Rectangle into the appropriate source space.
585:                Rectangle sourceRect = backwardMapRect(destRect, sourceIndex);
586:                if (sourceRect == null) {
587:                    return getSource(sourceIndex).getBounds();
588:                }
589:
590:                // Cache left and top padding.
591:                int lpad = interp.getLeftPadding();
592:                int tpad = interp.getTopPadding();
593:
594:                // Return padded Rectangle.
595:                return new Rectangle(sourceRect.x - lpad, sourceRect.y - tpad,
596:                        sourceRect.width + lpad + interp.getRightPadding(),
597:                        sourceRect.height + tpad + interp.getBottomPadding());
598:            }
599:
600:            /**
601:             * Computes a tile.  A new <code>WritableRaster</code> is created to
602:             * represent the requested tile.  Its width and height are equal to this
603:             * image's tile width and tile height respectively.  If the requested
604:             * tile lies outside of the image's boundary, or if the backward mapped
605:             * and padded tile region does not intersect all sources, the created
606:             * raster is returned with all of its pixels set to 0.
607:             *
608:             * <p> Whether or not this method performs source cobbling is determined
609:             * by the <code>cobbleSources</code> variable set at construction time.
610:             * If <code>cobbleSources</code> is <code>true</code>, cobbling is
611:             * performed on the source for areas that intersect multiple tiles,
612:             * and <code>computeRect(Raster[], WritableRaster, Rectangle)</code>
613:             * is called to perform the actual computation.  Otherwise,
614:             * <code>computeRect(PlanarImage[], WritableRaster, Rectangle)</code>
615:             * is called to perform the actual computation.
616:             *
617:             * @param tileX The X index of the tile.
618:             * @param tileY The Y index of the tile.
619:             *
620:             * @return The tile as a <code>Raster</code>.
621:             */
622:            public Raster computeTile(int tileX, int tileY) {
623:                // The origin of the tile.
624:                Point org = new Point(tileXToX(tileX), tileYToY(tileY));
625:
626:                // Create a new WritableRaster to represent this tile.
627:                WritableRaster dest = createWritableRaster(sampleModel, org);
628:
629:                // Find the intersection between this tile and the bounds.
630:                Rectangle destRect = getTileRect(tileX, tileY).intersection(
631:                        getBounds());
632:
633:                if (destRect.isEmpty()) {
634:                    if (setBackground) {
635:                        ImageUtil.fillBackground(dest, destRect,
636:                                backgroundValues);
637:                    }
638:
639:                    return dest; // tile outside of destination bounds
640:                }
641:
642:                int numSources = getNumSources();
643:                if (cobbleSources) {
644:                    Raster[] rasterSources = new Raster[numSources];
645:
646:                    // Cobble areas
647:                    for (int i = 0; i < numSources; i++) {
648:                        PlanarImage source = getSource(i);
649:
650:                        Rectangle srcBounds = source.getBounds();
651:                        Rectangle srcRect = mapDestRect(destRect, i);
652:                        if (srcRect == null) {
653:                            // Set to source bounds.
654:                            srcRect = srcBounds;
655:                        } else {
656:                            if (extender == null
657:                                    && !srcBounds.contains(srcRect)) {
658:                                // Clip to source bounds.
659:                                srcRect = srcBounds.intersection(srcRect);
660:                            }
661:                            if (!srcRect.intersects(srcBounds)) {
662:                                // Outside of source bounds.
663:                                if (setBackground) {
664:                                    ImageUtil.fillBackground(dest, destRect,
665:                                            backgroundValues);
666:                                }
667:                                return dest;
668:                            }
669:                        }
670:
671:                        rasterSources[i] = extender != null ? source
672:                                .getExtendedData(srcRect, extender) : source
673:                                .getData(srcRect);
674:                    }
675:
676:                    computeRect(rasterSources, dest, destRect);
677:
678:                    for (int i = 0; i < numSources; i++) {
679:                        Raster sourceData = rasterSources[i];
680:                        if (sourceData != null) {
681:                            PlanarImage source = getSourceImage(i);
682:
683:                            // Recycle the source tile
684:                            if (source.overlapsMultipleTiles(sourceData
685:                                    .getBounds())) {
686:                                recycleTile(sourceData);
687:                            }
688:                        }
689:                    }
690:                } else {
691:                    PlanarImage[] imageSources = new PlanarImage[numSources];
692:
693:                    for (int i = 0; i < numSources; i++) {
694:                        imageSources[i] = getSource(i);
695:                    }
696:                    computeRect(imageSources, dest, destRect);
697:                }
698:
699:                return dest;
700:            }
701:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.