Source Code Cross Referenced for RecyclingTileFactory.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: RecyclingTileFactory.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:18 $
010:         * $State: Exp $
011:         */
012:        package javax.media.jai;
013:
014:        import java.awt.Point;
015:        import java.awt.image.ComponentSampleModel;
016:        import java.awt.image.DataBuffer;
017:        import java.awt.image.DataBufferByte;
018:        import java.awt.image.DataBufferInt;
019:        import java.awt.image.DataBufferShort;
020:        import java.awt.image.DataBufferUShort;
021:        import java.awt.image.MultiPixelPackedSampleModel;
022:        import java.awt.image.Raster;
023:        import java.awt.image.SampleModel;
024:        import java.awt.image.SinglePixelPackedSampleModel;
025:        import java.awt.image.WritableRaster;
026:        import java.lang.ref.SoftReference;
027:        import java.util.ArrayList;
028:        import java.util.Arrays;
029:        import java.util.HashMap;
030:        import java.util.Observable;
031:        import com.sun.media.jai.util.DataBufferUtils;
032:
033:        /**
034:         * A simple implementation of <code>TileFactory</code> wherein the tiles
035:         * returned from <code>createTile()</code> attempt to re-use primitive
036:         * arrays provided by the <code>TileRecycler</code> method
037:         * <code>recycleTile()</code>.
038:         *
039:         * <p>
040:         * A simple example of the use of this class is as follows wherein
041:         * image files are read, each image is filtered, and each output
042:         * written to a file:
043:         * <pre>
044:         * String[] sourceFiles; // source file paths
045:         * KernelJAI kernel; // filtering kernel
046:         *
047:         * // Create a RenderingHints object and set hints.
048:         * RenderingHints rh = new RenderingHints(null);
049:         * RecyclingTileFactory rtf = new RecyclingTileFactory();
050:         * rh.put(JAI.KEY_TILE_RECYCLER, rtf);
051:         * rh.put(JAI.KEY_TILE_FACTORY, rtf);
052:         * rh.put(JAI.KEY_IMAGE_LAYOUT,
053:         *        new ImageLayout().setTileWidth(32).setTileHeight(32));
054:         *
055:         * int counter = 0;
056:         *
057:         * // Read each image, filter it, and save the output to a file.
058:         * for(int i = 0; i < sourceFiles.length; i++) {
059:         *     PlanarImage source = JAI.create("fileload", sourceFiles[i]);
060:         *     ParameterBlock pb =
061:         *         (new ParameterBlock()).addSource(source).add(kernel);
062:         *
063:         *     // The TileFactory hint will cause tiles to be created by 'rtf'.
064:         *     RenderedOp dest = JAI.create("convolve", pb, rh);
065:         *     String fileName = "image_"+(++counter)+".tif";
066:         *     JAI.create("filestore", dest, fileName);
067:         *
068:         *     // The TileRecycler hint will cause arrays to be reused by 'rtf'.
069:         *     dest.dispose();
070:         * }
071:         * </pre>
072:         * In the above code, if the <code>SampleModel</code> of all source
073:         * images is identical, then data arrays should only be created in the
074:         * first iteration.
075:         * </p>
076:         *
077:         * @since JAI 1.1.2
078:         */
079:        public class RecyclingTileFactory extends Observable implements 
080:                TileFactory, TileRecycler {
081:
082:            private static final boolean DEBUG = false;
083:
084:            /* XXX
085:            public static void main(String[] args) throws Throwable {
086:                RecyclingTileFactory rtf = new RecyclingTileFactory();
087:
088:                WritableRaster original =
089:                    Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
090:                                                   1024, 768, 1, null);
091:
092:                rtf.recycleTile(Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
093:                                                               1024, 768, 1, null));
094:                rtf.recycleTile(Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
095:                                                               1024, 768, 1, null));
096:
097:                rtf.createTile(original.getSampleModel(),
098:                               new Point(original.getMinX(),
099:                                         original.getMinY()));
100:                rtf.createTile(original.getSampleModel(),
101:                               new Point(original.getMinX(),
102:                                         original.getMinY()));
103:                rtf.createTile(original.getSampleModel(),
104:                               new Point(original.getMinX(),
105:                                         original.getMinY()));
106:
107:                //System.out.println(original.hashCode()+" "+original);
108:                //System.out.println(recycled.hashCode()+" "+recycled);
109:
110:                System.exit(0);
111:            }
112:             */
113:
114:            /**
115:             * Cache of recycled arrays.  The key in this mapping is a
116:             * <code>Long</code> which is formed for a given two-dimensional
117:             * array as
118:             *
119:             * <pre>
120:             * long type;     // DataBuffer.TYPE_*
121:             * long numBanks; // Number of banks
122:             * long size;     // Size of each bank
123:             * Long key = new Long((type << 56) | (numBanks << 32) | size);
124:             * </pre>
125:             *
126:             * where the value of <code>type</code> is one of the constants
127:             * <code>DataBuffer.TYPE_*</code>.  The value corresponding to each key
128:             * is an <code>ArrayList</code> of <code>SoftReferences</code> to the
129:             * internal data banks of <code>DataBuffer</code>s of tiles wherein the
130:             * data bank array has the type and dimensions implied by the key.
131:             */
132:            private HashMap recycledArrays = new HashMap(32);
133:
134:            /**
135:             * The amount of memory currrently used for array storage.
136:             */
137:            private long memoryUsed = 0L;
138:
139:            // XXX Inline this method or make it public?
140:            private static long getBufferSizeCSM(ComponentSampleModel csm) {
141:                int[] bandOffsets = csm.getBandOffsets();
142:                int maxBandOff = bandOffsets[0];
143:                for (int i = 1; i < bandOffsets.length; i++)
144:                    maxBandOff = Math.max(maxBandOff, bandOffsets[i]);
145:
146:                long size = 0;
147:                if (maxBandOff >= 0)
148:                    size += maxBandOff + 1;
149:                int pixelStride = csm.getPixelStride();
150:                if (pixelStride > 0)
151:                    size += pixelStride * (csm.getWidth() - 1);
152:                int scanlineStride = csm.getScanlineStride();
153:                if (scanlineStride > 0)
154:                    size += scanlineStride * (csm.getHeight() - 1);
155:                return size;
156:            }
157:
158:            // XXX Inline this method or make it public?
159:            private static long getNumBanksCSM(ComponentSampleModel csm) {
160:                int[] bankIndices = csm.getBankIndices();
161:                int maxIndex = bankIndices[0];
162:                for (int i = 1; i < bankIndices.length; i++) {
163:                    int bankIndex = bankIndices[i];
164:                    if (bankIndex > maxIndex) {
165:                        maxIndex = bankIndex;
166:                    }
167:                }
168:                return maxIndex + 1;
169:            }
170:
171:            /**
172:             * Returns a <code>SoftReference</code> to the internal bank
173:             * data of the <code>DataBuffer</code>.
174:             */
175:            private static SoftReference getBankReference(DataBuffer db) {
176:                Object array = null;
177:
178:                switch (db.getDataType()) {
179:                case DataBuffer.TYPE_BYTE:
180:                    array = ((DataBufferByte) db).getBankData();
181:                    break;
182:                case DataBuffer.TYPE_USHORT:
183:                    array = ((DataBufferUShort) db).getBankData();
184:                    break;
185:                case DataBuffer.TYPE_SHORT:
186:                    array = ((DataBufferShort) db).getBankData();
187:                    break;
188:                case DataBuffer.TYPE_INT:
189:                    array = ((DataBufferInt) db).getBankData();
190:                    break;
191:                case DataBuffer.TYPE_FLOAT:
192:                    array = DataBufferUtils.getBankDataFloat(db);
193:                    break;
194:                case DataBuffer.TYPE_DOUBLE:
195:                    array = DataBufferUtils.getBankDataDouble(db);
196:                    break;
197:                default:
198:                    throw new UnsupportedOperationException(JaiI18N
199:                            .getString("Generic3"));
200:
201:                }
202:
203:                return new SoftReference(array);
204:            }
205:
206:            /**
207:             * Returns the amount of memory (in bytes) used by the supplied data
208:             * bank array.
209:             */
210:            private static long getDataBankSize(int dataType, int numBanks,
211:                    int size) {
212:                int bytesPerElement = 0;
213:                switch (dataType) {
214:                case DataBuffer.TYPE_BYTE:
215:                    bytesPerElement = 1;
216:                    break;
217:                case DataBuffer.TYPE_USHORT:
218:                case DataBuffer.TYPE_SHORT:
219:                    bytesPerElement = 2;
220:                    break;
221:                case DataBuffer.TYPE_INT:
222:                case DataBuffer.TYPE_FLOAT:
223:                    bytesPerElement = 4;
224:                    break;
225:                case DataBuffer.TYPE_DOUBLE:
226:                    bytesPerElement = 8;
227:                    break;
228:                default:
229:                    throw new UnsupportedOperationException(JaiI18N
230:                            .getString("Generic3"));
231:
232:                }
233:
234:                return numBanks * size * bytesPerElement;
235:            }
236:
237:            /**
238:             * Constructs a <code>RecyclingTileFactory</code>.
239:             */
240:            public RecyclingTileFactory() {
241:            }
242:
243:            /**
244:             * Returns <code>true</code>.
245:             */
246:            public boolean canReclaimMemory() {
247:                return true;
248:            }
249:
250:            /**
251:             * Returns <code>true</code>.
252:             */
253:            public boolean isMemoryCache() {
254:                return true;
255:            }
256:
257:            public long getMemoryUsed() {
258:                return memoryUsed;
259:            }
260:
261:            public void flush() {
262:                synchronized (recycledArrays) {
263:                    recycledArrays.clear();
264:                    memoryUsed = 0L;
265:                }
266:            }
267:
268:            public WritableRaster createTile(SampleModel sampleModel,
269:                    Point location) {
270:
271:                if (sampleModel == null) {
272:                    throw new IllegalArgumentException("sampleModel == null!");
273:                }
274:
275:                if (location == null) {
276:                    location = new Point(0, 0);
277:                }
278:
279:                DataBuffer db = null;
280:
281:                int type = sampleModel.getTransferType();
282:                long numBanks = 0;
283:                long size = 0;
284:
285:                if (sampleModel instanceof  ComponentSampleModel) {
286:                    ComponentSampleModel csm = (ComponentSampleModel) sampleModel;
287:                    numBanks = getNumBanksCSM(csm);
288:                    size = getBufferSizeCSM(csm);
289:                } else if (sampleModel instanceof  MultiPixelPackedSampleModel) {
290:                    MultiPixelPackedSampleModel mppsm = (MultiPixelPackedSampleModel) sampleModel;
291:                    numBanks = 1;
292:                    int dataTypeSize = DataBuffer.getDataTypeSize(type);
293:                    size = mppsm.getScanlineStride() * mppsm.getHeight()
294:                            + (mppsm.getDataBitOffset() + dataTypeSize - 1)
295:                            / dataTypeSize;
296:                } else if (sampleModel instanceof  SinglePixelPackedSampleModel) {
297:                    SinglePixelPackedSampleModel sppsm = (SinglePixelPackedSampleModel) sampleModel;
298:                    numBanks = 1;
299:                    size = sppsm.getScanlineStride() * (sppsm.getHeight() - 1)
300:                            + sppsm.getWidth();
301:                }
302:
303:                if (size != 0) {
304:                    Object array = getRecycledArray(type, numBanks, size);
305:                    if (array != null) {
306:                        switch (type) {
307:                        case DataBuffer.TYPE_BYTE: {
308:                            byte[][] bankData = (byte[][]) array;
309:                            for (int i = 0; i < numBanks; i++) {
310:                                Arrays.fill(bankData[i], (byte) 0);
311:                            }
312:                            db = new DataBufferByte(bankData, (int) size);
313:                        }
314:                            break;
315:                        case DataBuffer.TYPE_USHORT: {
316:                            short[][] bankData = (short[][]) array;
317:                            for (int i = 0; i < numBanks; i++) {
318:                                Arrays.fill(bankData[i], (short) 0);
319:                            }
320:                            db = new DataBufferUShort(bankData, (int) size);
321:                        }
322:                            break;
323:                        case DataBuffer.TYPE_SHORT: {
324:                            short[][] bankData = (short[][]) array;
325:                            for (int i = 0; i < numBanks; i++) {
326:                                Arrays.fill(bankData[i], (short) 0);
327:                            }
328:                            db = new DataBufferShort(bankData, (int) size);
329:                        }
330:                            break;
331:                        case DataBuffer.TYPE_INT: {
332:                            int[][] bankData = (int[][]) array;
333:                            for (int i = 0; i < numBanks; i++) {
334:                                Arrays.fill(bankData[i], 0);
335:                            }
336:                            db = new DataBufferInt(bankData, (int) size);
337:                        }
338:                            break;
339:                        case DataBuffer.TYPE_FLOAT: {
340:                            float[][] bankData = (float[][]) array;
341:                            for (int i = 0; i < numBanks; i++) {
342:                                Arrays.fill(bankData[i], 0.0F);
343:                            }
344:                            db = DataBufferUtils.createDataBufferFloat(
345:                                    bankData, (int) size);
346:                        }
347:                            break;
348:                        case DataBuffer.TYPE_DOUBLE: {
349:                            double[][] bankData = (double[][]) array;
350:                            for (int i = 0; i < numBanks; i++) {
351:                                Arrays.fill(bankData[i], 0.0);
352:                            }
353:                            db = DataBufferUtils.createDataBufferDouble(
354:                                    bankData, (int) size);
355:                        }
356:                            break;
357:                        default:
358:                            throw new IllegalArgumentException(JaiI18N
359:                                    .getString("Generic3"));
360:                        }
361:
362:                        if (DEBUG) {
363:                            System.out.println(getClass().getName()
364:                                    + " Using a recycled array");// XXX
365:                            //(new Throwable()).printStackTrace(); // XXX
366:                        }
367:                    } else if (DEBUG) {
368:                        System.out.println(getClass().getName() + " No type "
369:                                + type + " array[" + numBanks + "][" + size
370:                                + "] available");
371:                    }
372:                } else if (DEBUG) {
373:                    System.out.println(getClass().getName() + " Size is zero");
374:                }
375:
376:                if (db == null) {
377:                    if (DEBUG) {
378:                        System.out.println(getClass().getName()
379:                                + " Creating new DataBuffer");// XXX
380:                    }
381:                    //(new Throwable()).printStackTrace(); // XXX
382:                    db = sampleModel.createDataBuffer();
383:                }
384:
385:                return Raster.createWritableRaster(sampleModel, db, location);
386:            }
387:
388:            /**
389:             * Recycle the given tile.
390:             */
391:            public void recycleTile(Raster tile) {
392:                DataBuffer db = tile.getDataBuffer();
393:
394:                Long key = new Long(((long) db.getDataType() << 56)
395:                        | ((long) db.getNumBanks() << 32) | (long) db.getSize());
396:
397:                if (DEBUG) {
398:                    System.out.println("Recycling array for: "
399:                            + db.getDataType() + " " + db.getNumBanks() + " "
400:                            + db.getSize());
401:                    //System.out.println("recycleTile(); key = "+key);
402:                }
403:
404:                synchronized (recycledArrays) {
405:                    Object value = recycledArrays.get(key);
406:                    ArrayList arrays = null;
407:                    if (value != null) {
408:                        arrays = (ArrayList) value;
409:                    } else {
410:                        arrays = new ArrayList();
411:                    }
412:
413:                    memoryUsed += getDataBankSize(db.getDataType(), db
414:                            .getNumBanks(), db.getSize());
415:
416:                    arrays.add(getBankReference(db));
417:
418:                    if (value == null) {
419:                        recycledArrays.put(key, arrays);
420:                    }
421:                }
422:            }
423:
424:            /**
425:             * Retrieve an array of the specified type and length.
426:             */
427:            private Object getRecycledArray(int arrayType, long numBanks,
428:                    long arrayLength) {
429:                Long key = new Long(((long) arrayType << 56) | numBanks << 32
430:                        | arrayLength);
431:
432:                if (DEBUG) {
433:                    System.out.println("Attempting to get array for: "
434:                            + arrayType + " " + numBanks + " " + arrayLength);
435:                    //System.out.println("Attempting to get array for key "+key);
436:                }
437:
438:                synchronized (recycledArrays) {
439:                    Object value = recycledArrays.get(key);
440:
441:                    if (value != null) {
442:                        ArrayList arrays = (ArrayList) value;
443:                        for (int idx = arrays.size() - 1; idx >= 0; idx--) {
444:                            SoftReference bankRef = (SoftReference) arrays
445:                                    .remove(idx);
446:                            memoryUsed -= getDataBankSize(arrayType,
447:                                    (int) numBanks, (int) arrayLength);
448:                            if (idx == 0) {
449:                                recycledArrays.remove(key);
450:                            }
451:
452:                            Object array = bankRef.get();
453:                            if (array != null) {
454:                                return array;
455:                            }
456:
457:                            if (DEBUG)
458:                                System.out.println("null reference");
459:                        }
460:                    }
461:                }
462:
463:                //if(DEBUG) System.out.println("getRecycledArray() returning "+array);
464:
465:                return null;
466:            }
467:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.