Source Code Cross Referenced for AreaOpImage.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: AreaOpImage.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:03 $
010:         * $State: Exp $
011:         */
012:        package javax.media.jai;
013:
014:        import java.awt.Rectangle;
015:        import java.awt.RenderingHints;
016:        import java.awt.image.RenderedImage;
017:        import java.awt.image.renderable.ParameterBlock;
018:        import java.awt.image.Raster;
019:        import java.awt.image.WritableRaster;
020:        import java.awt.Point;
021:        import java.util.Map;
022:        import java.util.Vector;
023:        import javax.media.jai.util.CaselessStringKey;
024:
025:        /**
026:         * An abstract base class for image operators that require only a
027:         * fixed rectangular source region around a source pixel in order to
028:         * compute each destination pixel.  
029:         *
030:         * <p> The source and the destination images will occupy the same
031:         * region of the plane.  A given destination pixel (x, y) may be
032:         * computed from the neighborhood of source pixels beginning at (x -
033:         * leftPadding, y - topPadding) and extending to (x + rightPadding, y
034:         * + bottomPadding) inclusive.
035:         * 
036:         * <p> Since this operator needs a region around the source pixel in
037:         * order to compute the destination pixel, the border destination pixels 
038:         * cannot be computed without any source extension. The source extension 
039:         * can be specified by supplying a BorderExtender that will define the
040:         * pixel values of the source outside the actual source area. 
041:         *
042:         * <p> If no extension is specified, the destination samples that
043:         * cannot be computed will be written in the destination as zero.  If
044:         * the source image begins at pixel (minX, minY) and has width w and
045:         * height h, the result of performing an area operation will be an
046:         * image beginning at minX, minY, and having a width of w and a height
047:         * of h, with the area being computed and written starting at (minX +
048:         * leftPadding, minY + topPadding) and having width Math.max(w -
049:         * leftPadding - rightPadding, 0) and height Math.max(h - topPadding
050:         * - bottomPadding, 0).
051:         *
052:         * <p> A <code>RenderingHints</code> for
053:         * <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code> with the value of
054:         * <code>Boolean.TRUE</code> will automatically be added to the given
055:         * <code>configuration</code> and passed up to the superclass constructor
056:         * so that area operations are performed on the pixel values instead
057:         * of being performed on the indices into the color map for those
058:         * operations whose source(s) have an <code>IndexColorModel</code>.
059:         * This addition will only take place if a value for the 
060:         * <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code> has not already been
061:         * provided by the user. Note that the <code>configuration</code> Map
062:         * is cloned before the new hint is added to it. Regarding the value
063:         * for the <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code>
064:         * <code>RenderingHints</code>, the operator itself can be smart
065:         * based on the parameters, i.e. while the default value for
066:         * the <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code> is
067:         * <code>Boolean.TRUE</code> for operations that extend this class,
068:         * in some cases the operator could set the default.
069:         *
070:         * @see BorderExtender
071:         */
072:        public abstract class AreaOpImage extends OpImage {
073:            /**
074:             * The number of source pixels needed to the left of the central pixel.
075:             */
076:            protected int leftPadding;
077:
078:            /** 
079:             * The number of source pixels needed to the right of the central pixel.
080:             */
081:            protected int rightPadding;
082:
083:            /** The number of source pixels needed above the central pixel. */
084:            protected int topPadding;
085:
086:            /** The number of source pixels needed below the central pixel. */
087:            protected int bottomPadding;
088:
089:            /** The BorderExtender, may be null. */
090:            protected BorderExtender extender = null;
091:
092:            private Rectangle theDest;
093:
094:            /** Verify that a specified bounds overlaps that of the source image. */
095:            private static ImageLayout layoutHelper(ImageLayout layout,
096:                    RenderedImage source) {
097:                // If at least one of the bounds variables is set then
098:                // check the overlap with the source image.
099:                if (layout != null
100:                        && source != null
101:                        && (layout.getValidMask() & (ImageLayout.MIN_X_MASK
102:                                | ImageLayout.MIN_Y_MASK
103:                                | ImageLayout.WIDTH_MASK | ImageLayout.HEIGHT_MASK)) != 0) {
104:                    // Get the source bounds.
105:                    Rectangle sourceRect = new Rectangle(source.getMinX(),
106:                            source.getMinY(), source.getWidth(), source
107:                                    .getHeight());
108:
109:                    // Create destination bounds defaulting un-set variables to
110:                    // their respective source values as is done in the superclass
111:                    // OpImage constructor.
112:                    Rectangle dstRect = new Rectangle(layout.getMinX(source),
113:                            layout.getMinY(source), layout.getWidth(source),
114:                            layout.getHeight(source));
115:
116:                    // Check for empty intersection.
117:                    if (dstRect.intersection(sourceRect).isEmpty()) {
118:                        throw new IllegalArgumentException(JaiI18N
119:                                .getString("AreaOpImage0"));
120:                    }
121:                }
122:
123:                return layout;
124:            }
125:
126:            private static Map configHelper(Map configuration) {
127:
128:                Map config;
129:
130:                if (configuration == null) {
131:                    config = new RenderingHints(
132:                            JAI.KEY_REPLACE_INDEX_COLOR_MODEL, Boolean.TRUE);
133:                } else {
134:
135:                    config = configuration;
136:
137:                    // If the user specified a value for this hint, we don't
138:                    // want to change that
139:                    if (!config.containsKey(JAI.KEY_REPLACE_INDEX_COLOR_MODEL)) {
140:                        RenderingHints hints = new RenderingHints(null);
141:                        // This is effectively a clone of configuration
142:                        hints.putAll(configuration);
143:                        config = hints;
144:                        config.put(JAI.KEY_REPLACE_INDEX_COLOR_MODEL,
145:                                Boolean.TRUE);
146:                    }
147:                }
148:
149:                return config;
150:            }
151:
152:            /**
153:             * Constructs an <code>AreaOpImage</code>.  The layout variables
154:             * are set in the standard way by the <code>OpImage</code> constructor.
155:             * 
156:             * <p> Additional control over the image bounds, tile grid layout,
157:             * <code>SampleModel</code>, and <code>ColorModel</code> may be
158:             * obtained by specifying an <code>ImageLayout</code> parameter.
159:             * If the image bounds are specified but do not overlap the source
160:             * bounds then an <code>IllegalArgumentException</code> will be thrown.
161:             * This parameter will be passed to the superclass constructor
162:             * unchanged.
163:             *
164:             * <p> A <code>RenderingHints</code> for
165:             * <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code> with the value of
166:             * <code>Boolean.TRUE</code> will automatically be added to the given
167:             * <code>configuration</code> and passed up to the superclass constructor
168:             * so that area operations are performed on the pixel values instead
169:             * of being performed on the indices into the color map for those
170:             * operations whose source(s) have an <code>IndexColorModel</code>.
171:             * This addition will only take place if a value for the 
172:             * <code>JAI.KEY_REPLACE_INDEX_COLOR_MODEL</code> has not already been
173:             * provided by the user. Note that the <code>configuration</code> Map
174:             * is cloned before the new hint is added to it.
175:             *
176:             * @param source A <code>RenderedImage</code>.
177:             * @param layout An <code>ImageLayout</code> containing the source
178:             *        dimensions before padding, and optionally containing the
179:             *        tile grid layout, <code>SampleModel</code>, and
180:             *        <code>ColorModel</code>.
181:             * @param configuration Configurable attributes of the image including
182:             *        configuration variables indexed by
183:             *        <code>RenderingHints.Key</code>s and image properties indexed
184:             *        by <code>String</code>s or <code>CaselessStringKey</code>s.
185:             *        This is simply forwarded to the superclass constructor.
186:             * @param cobbleSources A <code>boolean</code> indicating whether
187:             *        <code>computeRect()</code> expects contiguous sources.
188:             * @param extender A BorderExtender, or null.
189:             * @param leftPadding The desired left padding.
190:             * @param rightPadding The desired right padding.
191:             * @param topPadding The desired top padding.
192:             * @param bottomPadding The desired bottom padding.
193:             *
194:             * @throws IllegalArgumentException if <code>source</code>
195:             *         is <code>null</code>.
196:             * @throws IllegalArgumentException if the user-specified bounds do
197:             *         intersect the source bounds.
198:             *
199:             * @since JAI 1.1
200:             */
201:            public AreaOpImage(RenderedImage source, ImageLayout layout,
202:                    Map configuration, boolean cobbleSources,
203:                    BorderExtender extender, int leftPadding, int rightPadding,
204:                    int topPadding, int bottomPadding) {
205:                super (
206:                        vectorize(source), // vectorize() checks for null source.
207:                        layoutHelper(layout, source),
208:                        configHelper(configuration), cobbleSources);
209:
210:                this .extender = extender;
211:                this .leftPadding = leftPadding;
212:                this .rightPadding = rightPadding;
213:                this .topPadding = topPadding;
214:                this .bottomPadding = bottomPadding;
215:
216:                if (extender == null) {
217:
218:                    int d_x0 = getMinX() + leftPadding;
219:                    int d_y0 = getMinY() + topPadding;
220:
221:                    int d_w = getWidth() - leftPadding - rightPadding;
222:                    d_w = Math.max(d_w, 0);
223:
224:                    int d_h = getHeight() - topPadding - bottomPadding;
225:                    d_h = Math.max(d_h, 0);
226:
227:                    theDest = new Rectangle(d_x0, d_y0, d_w, d_h);
228:                } else {
229:                    theDest = getBounds();
230:                }
231:            }
232:
233:            /**
234:             * Returns the number of pixels needed to the left of the central pixel.
235:             *
236:             * @return The left padding factor.
237:             */
238:            public int getLeftPadding() {
239:                return leftPadding;
240:            }
241:
242:            /**
243:             * Returns the number of pixels needed to the right of the central pixel.
244:             *
245:             * @return The right padding factor.
246:             */
247:            public int getRightPadding() {
248:                return rightPadding;
249:            }
250:
251:            /** Returns the number of pixels needed above the central pixel.
252:             *
253:             * @return The top padding factor.
254:             */
255:            public int getTopPadding() {
256:                return topPadding;
257:            }
258:
259:            /** Returns the number of pixels needed below the central pixel.
260:             *
261:             * @return The bottom padding factor.
262:             */
263:            public int getBottomPadding() {
264:                return bottomPadding;
265:            }
266:
267:            /**
268:             * Retrieve the <code>BorderExtender</code> object associated with
269:             * this class instance.  The object is returned by reference.
270:             *
271:             * @return The associated <code>BorderExtender</code> object
272:             *         or <code>null</code>.
273:             *
274:             * @since JAI 1.1
275:             */
276:            public BorderExtender getBorderExtender() {
277:                return extender;
278:            }
279:
280:            /**
281:             * Returns a conservative estimate of the destination region that
282:             * can potentially be affected by the pixels of a rectangle of a
283:             * given source. The resulting <code>Rectangle</code> is <u>not</u>
284:             * clipped to the destination image bounds.
285:             *
286:             * @param sourceRect the <code>Rectangle</code> in source coordinates.
287:             * @param sourceIndex the index of the source image.
288:             * @return a <code>Rectangle</code> indicating the potentially affected
289:             *         destination region, or <code>null</code> if the region is
290:             *         unknown.
291:             *
292:             * @throws IllegalArgumentException if <code>sourceIndex</code> is
293:             *         negative or greater than the index of the last source.
294:             * @throws IllegalArgumentException if <code>sourceRect</code> is
295:             *         <code>null</code>.
296:             */
297:            public Rectangle mapSourceRect(Rectangle sourceRect, int sourceIndex) {
298:
299:                if (sourceRect == null) {
300:                    throw new IllegalArgumentException(JaiI18N
301:                            .getString("Generic0"));
302:                }
303:
304:                if (sourceIndex < 0 || sourceIndex >= getNumSources()) {
305:                    throw new IllegalArgumentException(JaiI18N
306:                            .getString("Generic1"));
307:                }
308:
309:                int lpad = getLeftPadding();
310:                int rpad = getRightPadding();
311:                int tpad = getTopPadding();
312:                int bpad = getBottomPadding();
313:
314:                return new Rectangle(sourceRect.x + lpad, sourceRect.y + tpad,
315:                        sourceRect.width - lpad - rpad, sourceRect.height
316:                                - tpad - bpad);
317:            }
318:
319:            /**
320:             * Returns a conservative estimate of the region of a specified
321:             * source that is required in order to compute the pixels of a
322:             * given destination rectangle. The resulting <code>Rectangle</code>
323:             * is <u>not</u> clipped to the source image bounds.
324:             *
325:             * @param destRect the <code>Rectangle</code> in destination coordinates.
326:             * @param sourceIndex the index of the source image.
327:             *
328:             * @return a <code>Rectangle</code> indicating the required source region.
329:             *
330:             * @throws IllegalArgumentException if <code>sourceIndex</code> is
331:             *         negative or greater than the index of the last source.
332:             * @throws IllegalArgumentException if <code>destRect</code> is
333:             *         <code>null</code>.
334:             */
335:            public Rectangle mapDestRect(Rectangle destRect, int sourceIndex) {
336:                if (destRect == null) {
337:                    throw new IllegalArgumentException(JaiI18N
338:                            .getString("Generic0"));
339:                }
340:
341:                if (sourceIndex < 0 || sourceIndex >= getNumSources()) {
342:                    throw new IllegalArgumentException(JaiI18N
343:                            .getString("Generic1"));
344:                }
345:
346:                int lpad = getLeftPadding();
347:                int rpad = getRightPadding();
348:                int tpad = getTopPadding();
349:                int bpad = getBottomPadding();
350:
351:                return new Rectangle(destRect.x - lpad, destRect.y - tpad,
352:                        destRect.width + lpad + rpad, destRect.height + tpad
353:                                + bpad);
354:            }
355:
356:            /**
357:             * Computes a tile.  If source cobbling was requested at
358:             * construction time, the source tile boundaries are overlayed
359:             * onto the destination, cobbling is performed for areas that
360:             * intersect multiple source tiles, and
361:             * <code>computeRect(Raster[], WritableRaster, Rectangle)</code>
362:             * is called for each of the resulting regions.  Otherwise,
363:             * <code>computeRect(PlanarImage[], WritableRaster,
364:             * Rectangle)</code> is called once to compute the entire active
365:             * area of the tile.
366:             *
367:             * <p> The image bounds may be larger than the bounds of the
368:             * source image.  In this case, samples for which there are no
369:             * no corresponding sources are set to zero.
370:             *
371:             * @param tileX The X index of the tile.
372:             * @param tileY The Y index of the tile.
373:             *
374:             * @return The tile as a <code>Raster</code>.
375:             */
376:            public Raster computeTile(int tileX, int tileY) {
377:                if (!cobbleSources) {
378:                    return super .computeTile(tileX, tileY);
379:                }
380:
381:                /* Create a new WritableRaster to represent this tile. */
382:                Point org = new Point(tileXToX(tileX), tileYToY(tileY));
383:                WritableRaster dest = createWritableRaster(sampleModel, org);
384:
385:                /* Clip output rectangle to image bounds. */
386:                Rectangle rect = new Rectangle(org.x, org.y, sampleModel
387:                        .getWidth(), sampleModel.getHeight());
388:
389:                Rectangle destRect = rect.intersection(theDest);
390:                if ((destRect.width <= 0) || (destRect.height <= 0)) {
391:                    return dest;
392:                }
393:
394:                /* account for padding in srcRectangle */
395:                PlanarImage s = getSource(0);
396:                // Fix 4639755: Area operations throw exception for 
397:                // destination extending beyond source bounds
398:                // The default dest image area is the same as the source
399:                // image area.  However, when an ImageLayout hint is set,
400:                // this might be not true.  So the destRect should be the 
401:                // intersection of the provided rectangle, the destination
402:                // bounds and the source bounds.
403:                destRect = destRect.intersection(s.getBounds());
404:                Rectangle srcRect = new Rectangle(destRect);
405:                srcRect.x -= getLeftPadding();
406:                srcRect.width += getLeftPadding() + getRightPadding();
407:                srcRect.y -= getTopPadding();
408:                srcRect.height += getTopPadding() + getBottomPadding();
409:
410:                /*
411:                 * The tileWidth and tileHeight of the source image
412:                 * may differ from this tileWidth and tileHeight.
413:                 */
414:                IntegerSequence srcXSplits = new IntegerSequence();
415:                IntegerSequence srcYSplits = new IntegerSequence();
416:
417:                // there is only one source for an AreaOpImage
418:                s.getSplits(srcXSplits, srcYSplits, srcRect);
419:
420:                // Initialize new sequences of X splits.
421:                IntegerSequence xSplits = new IntegerSequence(destRect.x,
422:                        destRect.x + destRect.width);
423:
424:                xSplits.insert(destRect.x);
425:                xSplits.insert(destRect.x + destRect.width);
426:
427:                srcXSplits.startEnumeration();
428:                while (srcXSplits.hasMoreElements()) {
429:                    int xsplit = srcXSplits.nextElement();
430:                    int lsplit = xsplit - getLeftPadding();
431:                    int rsplit = xsplit + getRightPadding();
432:                    xSplits.insert(lsplit);
433:                    xSplits.insert(rsplit);
434:                }
435:
436:                // Initialize new sequences of Y splits.
437:                IntegerSequence ySplits = new IntegerSequence(destRect.y,
438:                        destRect.y + destRect.height);
439:
440:                ySplits.insert(destRect.y);
441:                ySplits.insert(destRect.y + destRect.height);
442:
443:                srcYSplits.startEnumeration();
444:                while (srcYSplits.hasMoreElements()) {
445:                    int ysplit = srcYSplits.nextElement();
446:                    int tsplit = ysplit - getBottomPadding();
447:                    int bsplit = ysplit + getTopPadding();
448:                    ySplits.insert(tsplit);
449:                    ySplits.insert(bsplit);
450:                }
451:
452:                /*
453:                 * Divide destRect into sub rectangles based on the source splits,
454:                 * and compute each sub rectangle separately.
455:                 */
456:                int x1, x2, y1, y2;
457:                Raster[] sources = new Raster[1];
458:
459:                ySplits.startEnumeration();
460:                for (y1 = ySplits.nextElement(); ySplits.hasMoreElements(); y1 = y2) {
461:                    y2 = ySplits.nextElement();
462:
463:                    int h = y2 - y1;
464:                    int py1 = y1 - getTopPadding();
465:                    int py2 = y2 + getBottomPadding();
466:                    int ph = py2 - py1;
467:
468:                    xSplits.startEnumeration();
469:                    for (x1 = xSplits.nextElement(); xSplits.hasMoreElements(); x1 = x2) {
470:                        x2 = xSplits.nextElement();
471:
472:                        int w = x2 - x1;
473:                        int px1 = x1 - getLeftPadding();
474:                        int px2 = x2 + getRightPadding();
475:                        int pw = px2 - px1;
476:
477:                        // Fetch the padded src rectangle
478:                        Rectangle srcSubRect = new Rectangle(px1, py1, pw, ph);
479:                        sources[0] = (extender != null) ? s.getExtendedData(
480:                                srcSubRect, extender) : s.getData(srcSubRect);
481:
482:                        // Make a destRectangle
483:                        Rectangle dstSubRect = new Rectangle(x1, y1, w, h);
484:                        computeRect(sources, dest, dstSubRect);
485:
486:                        // Recycle the source tile
487:                        if (s.overlapsMultipleTiles(srcSubRect)) {
488:                            recycleTile(sources[0]);
489:                        }
490:                    }
491:                }
492:                return dest;
493:            }
494:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.