Source Code Cross Referenced for BaseHDFImageReader.java in  » GIS » GeoTools-2.4.1 » it » geosolutions » imageio » plugins » jhdf » 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 » GIS » GeoTools 2.4.1 » it.geosolutions.imageio.plugins.jhdf 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package it.geosolutions.imageio.plugins.jhdf;
002:
003:        import it.geosolutions.imageio.plugins.slices2D.SliceImageReader;
004:        import it.geosolutions.imageio.stream.input.FileImageInputStreamExtImpl;
005:
006:        import java.awt.Rectangle;
007:        import java.awt.image.BandedSampleModel;
008:        import java.awt.image.BufferedImage;
009:        import java.awt.image.ColorModel;
010:        import java.awt.image.DataBuffer;
011:        import java.awt.image.DataBufferByte;
012:        import java.awt.image.DataBufferDouble;
013:        import java.awt.image.DataBufferFloat;
014:        import java.awt.image.DataBufferInt;
015:        import java.awt.image.DataBufferShort;
016:        import java.awt.image.Raster;
017:        import java.awt.image.SampleModel;
018:        import java.awt.image.WritableRaster;
019:        import java.io.File;
020:        import java.io.IOException;
021:        import java.util.ArrayList;
022:        import java.util.Iterator;
023:        import java.util.LinkedHashMap;
024:        import java.util.List;
025:        import java.util.Set;
026:
027:        import javax.imageio.ImageReadParam;
028:        import javax.imageio.ImageTypeSpecifier;
029:        import javax.imageio.spi.ImageReaderSpi;
030:
031:        import ncsa.hdf.object.Dataset;
032:        import ncsa.hdf.object.Datatype;
033:        import ncsa.hdf.object.FileFormat;
034:        import ncsa.hdf.object.HObject;
035:
036:        public abstract class BaseHDFImageReader extends SliceImageReader {
037:
038:            /** A <code>LinkedHashMap</code> having all the <code>Dataset</code>s 
039:             * contained within the source */
040:            protected LinkedHashMap subDatasetsMap;
041:
042:            /** A mutex used to synchronize operations */
043:            protected final int[] mutex = new int[] { 0 };
044:
045:            /**
046:             * Returns a subDataset given a subDatasetIndex
047:             * 
048:             * @param subDatasetIndex
049:             *            The index of the required subDataset
050:             * @return the required subDataset
051:             */
052:            protected Dataset retrieveDataset(int subDatasetIndex) {
053:                synchronized (mutex) {
054:                    Set set = subDatasetsMap.keySet();
055:                    Iterator it = set.iterator();
056:                    for (int j = 0; j < subDatasetIndex; j++)
057:                        it.next();
058:                    return (Dataset) subDatasetsMap.get((String) it.next());
059:                }
060:            }
061:
062:            private void checkImageIndex(int imageIndex) {
063:                //TODO: implements this to handle supported indexes
064:            }
065:
066:            // TODO: should be moved in the aboveLayer?
067:
068:            /**
069:             * Class used to store basic source structure properties such as number of
070:             * subdatasets and basic properties of each sub dataset, such as, rank,
071:             * dimensions size, chunk size.
072:             */
073:            protected class SourceStructure {
074:
075:                /** the number of subdatasets contained within the data source */
076:                protected int nSubdatasets;
077:
078:                /** a list of {@link SubDatasetInfo} instances */
079:                protected ArrayList subDatasetInfo;
080:
081:                /**
082:                 * Redundant field. Allows index management without scanning all
083:                 * <code>SubDatasetInfo</code>
084:                 */
085:                protected ArrayList subDatasetSizes;
086:
087:                /**
088:                 * A-priori Constructor. Use this form when you know the exact
089:                 * subdataset number prior to instantiate the
090:                 * <code>SourceStructure</code>
091:                 * 
092:                 * @param subdatasetsNum
093:                 */
094:                public SourceStructure(int subdatasetsNum) {
095:                    nSubdatasets = subdatasetsNum;
096:                    subDatasetInfo = new ArrayList(subdatasetsNum);
097:                    // new SubDatasetInfo[subdatasetsNum];
098:                    subDatasetSizes = new ArrayList(subdatasetsNum);
099:                }
100:
101:                /**
102:                 * Constructor which need to be used when you dont know the exact
103:                 * subdataset number a priori. After all <code>SubDatasetInfo</code>'s
104:                 * has been added, you need to call the <code>init</code> method.
105:                 * 
106:                 */
107:
108:                public SourceStructure() {
109:                    nSubdatasets = 0;
110:                    subDatasetInfo = new ArrayList(10);
111:                    subDatasetSizes = new ArrayList(10);
112:                }
113:
114:                public long getSubDatasetSize(int index) {
115:                    return ((Long) subDatasetSizes.get(index)).longValue();
116:                    // return subDatasetSize[0];
117:                }
118:
119:                public void setSubDatasetSize(int index, long size) {
120:                    subDatasetSizes.add(index, new Long(size));
121:                }
122:
123:                public int getNSubdatasets() {
124:                    return nSubdatasets;
125:                }
126:
127:                public void setNSubdatasets(int subdatasets) {
128:                    nSubdatasets = subdatasets;
129:                }
130:
131:                public long[] getSubDatasetSizes() {
132:                    final Object[] objArray = subDatasetSizes.toArray();
133:                    final int length = objArray.length;
134:                    final long[] array = new long[length];
135:                    for (int i = 0; i < length; i++)
136:                        array[i] = ((Long) (objArray[i])).longValue();
137:                    return array;
138:                }
139:
140:                public void setSubDatasetInfo(int subDatasetIndex,
141:                        SubDatasetInfo dsInfo) {
142:                    // subDatasetInfo[j] = dsInfo;
143:                    subDatasetInfo.add(subDatasetIndex, dsInfo);
144:                }
145:
146:                public void addSubDatasetProperties(SubDatasetInfo dsInfo,
147:                        long subDatasetSize) {
148:                    // subDatasetInfo[j] = dsInfo;
149:                    subDatasetInfo.add(nSubdatasets, dsInfo);
150:                    subDatasetSizes.add(nSubdatasets++,
151:                            new Long(subDatasetSize));
152:                }
153:
154:                public SubDatasetInfo getSubDatasetInfo(int subDatasetIndex) {
155:                    if (subDatasetIndex <= nSubdatasets)
156:                        // return subDatasetInfo[subDatasetIndex];
157:                        return (SubDatasetInfo) subDatasetInfo
158:                                .get(subDatasetIndex);
159:                    else
160:                        return null;
161:                }
162:
163:                public void dispose() {
164:                    nSubdatasets = 0;
165:                    subDatasetInfo.clear();
166:                    subDatasetSizes.clear();
167:                }
168:            }
169:
170:            /**
171:             * 
172:             * @param itemName
173:             *            The name of the product/subDataset to be checked
174:             * @return <code>true</code> if the product/subdataset needs to be taken
175:             *         on account.
176:             */
177:            protected abstract boolean isAcceptedItem(final String itemName);
178:
179:            /**
180:             * Additional initialization for a specific HDF "Profile".
181:             * Depending on the HDF data producer, the originating file has a proper
182:             * data/metadata structure. For this reason, a specific initialization 
183:             * should be implemented for each different HDF "Profile".
184:             * As an instance, the Automated Processing System (APS) produces HDF files
185:             * having a structure which differes from the HDF structure of a file 
186:             * produced by TIROS Operational Vertical Sounder (TOVS).
187:             * 
188:             * @throws Exception
189:             */
190:            protected abstract void initializeProfile() throws Exception;
191:
192:            protected abstract int getBandNumberFromProduct(
193:                    final String productName);
194:
195:            /** The originating FileFormat */
196:            protected FileFormat fileFormat = null;
197:
198:            protected ImageTypeSpecifier imageType = null;
199:
200:            /**
201:             * a <code>SourceStructure</code>'s instance needed to get main
202:             * SubDatasets info and properties.
203:             */
204:            protected SourceStructure sourceStructure;
205:
206:            /** root of the FileFormat related to the provided input source */
207:            protected HObject root;
208:
209:            protected BaseHDFImageReader(ImageReaderSpi originatingProvider) {
210:                super (originatingProvider);
211:            }
212:
213:            /**
214:             * Returns the width in pixels of the given image within the input source.
215:             * 
216:             * @param imageIndex
217:             *            the index of the image to be queried.
218:             * 
219:             * @return the width of the image, as an <code>int</code>.
220:             */
221:            public int getWidth(final int imageIndex) throws IOException {
222:                if (!isInitialized)
223:                    initialize();
224:                return sourceStructure.getSubDatasetInfo(
225:                        retrieveSubDatasetIndex(imageIndex)).getWidth();
226:            }
227:
228:            /**
229:             * Returns the height in pixels of the given image within the input source.
230:             * 
231:             * @param imageIndex
232:             *            the index of the image to be queried.
233:             * 
234:             * @return the height of the image, as an <code>int</code>.
235:             */
236:            public int getHeight(final int imageIndex) throws IOException {
237:                if (!isInitialized)
238:                    initialize();
239:                return sourceStructure.getSubDatasetInfo(
240:                        retrieveSubDatasetIndex(imageIndex)).getHeight();
241:            }
242:
243:            /**
244:             * Reads the image indexed by <code>imageIndex</code> and returns it as a
245:             * <code>BufferedImage</code>, using a supplied <code>ImageReadParam</code>
246:             * 
247:             * @param imageIndex
248:             *            the index of the image to be retrieved.
249:             * @param param
250:             *            an <code>ImageReadParam</code> used to control the reading
251:             *            process, or <code>null</code>.
252:             * 
253:             * @return the desired portion of the image as a <code>BufferedImage</code>.
254:             */
255:            public BufferedImage read(final int imageIndex, ImageReadParam param)
256:                    throws IOException {
257:
258:                // ////////////////////////////////////////////////////////////////////
259:                //
260:                // INITIALIZATIONS
261:                //
262:                // ////////////////////////////////////////////////////////////////////
263:
264:                if (!isInitialized)
265:                    initialize();
266:
267:                //Getting indexing information
268:                final int[] slice2DindexCoordinates = getSlice2DIndexCoordinates(imageIndex);
269:                final int subDatasetIndex = slice2DindexCoordinates[0];
270:                final Dataset dataset = retrieveDataset(subDatasetIndex);
271:
272:                BufferedImage bimage = null;
273:                SubDatasetInfo sdInfo = sourceStructure
274:                        .getSubDatasetInfo(subDatasetIndex);
275:
276:                final int rank = sdInfo.getRank();
277:                final int width = sdInfo.getWidth();
278:                final int height = sdInfo.getHeight();
279:                final Datatype dt = sdInfo.getDatatype();
280:
281:                if (param == null)
282:                    param = getDefaultReadParam();
283:
284:                int dstWidth = -1;
285:                int dstHeight = -1;
286:                int srcRegionWidth = -1;
287:                int srcRegionHeight = -1;
288:                int srcRegionXOffset = -1;
289:                int srcRegionYOffset = -1;
290:                int xSubsamplingFactor = -1;
291:                int ySubsamplingFactor = -1;
292:
293:                // //
294:                //
295:                // Retrieving Information about Source Region and doing
296:                // additional intialization operations.
297:                //
298:                // //
299:                Rectangle srcRegion = param.getSourceRegion();
300:                if (srcRegion != null) {
301:                    srcRegionWidth = (int) srcRegion.getWidth();
302:                    srcRegionHeight = (int) srcRegion.getHeight();
303:                    srcRegionXOffset = (int) srcRegion.getX();
304:                    srcRegionYOffset = (int) srcRegion.getY();
305:
306:                    // //
307:                    //
308:                    // Minimum correction for wrong source regions
309:                    //
310:                    // When you do subsampling or source subsetting it might
311:                    // happen that the given source region in the read param is
312:                    // uncorrect, which means it can be or a bit larger than the
313:                    // original file or can begin a bit before original limits.
314:                    //
315:                    // We got to be prepared to handle such case in order to avoid
316:                    // generating ArrayIndexOutOfBoundsException later in the code.
317:                    //
318:                    // //
319:
320:                    if (srcRegionXOffset < 0)
321:                        srcRegionXOffset = 0;
322:                    if (srcRegionYOffset < 0)
323:                        srcRegionYOffset = 0;
324:                    if ((srcRegionXOffset + srcRegionWidth) > width) {
325:                        srcRegionWidth = width - srcRegionXOffset;
326:                    }
327:                    // initializing destWidth
328:                    dstWidth = srcRegionWidth;
329:
330:                    if ((srcRegionYOffset + srcRegionHeight) > height) {
331:                        srcRegionHeight = height - srcRegionYOffset;
332:                    }
333:                    // initializing dstHeight
334:                    dstHeight = srcRegionHeight;
335:
336:                } else {
337:                    // Source Region not specified.
338:                    // Assuming Source Region Dimension equal to Source Image
339:                    // Dimension
340:                    dstWidth = width;
341:                    dstHeight = height;
342:                    srcRegionXOffset = srcRegionYOffset = 0;
343:                    srcRegionWidth = width;
344:                    srcRegionHeight = height;
345:                }
346:
347:                // SubSampling variables initialization
348:                xSubsamplingFactor = param.getSourceXSubsampling();
349:                ySubsamplingFactor = param.getSourceYSubsampling();
350:
351:                // ////
352:                //
353:                // Updating the destination size in compliance with
354:                // the subSampling parameters
355:                //
356:                // ////
357:
358:                dstWidth = ((dstWidth - 1) / xSubsamplingFactor) + 1;
359:                dstHeight = ((dstHeight - 1) / ySubsamplingFactor) + 1;
360:
361:                // getting dataset properties.
362:                dataset.init();
363:                final long[] start = dataset.getStartDims();
364:                final long[] stride = dataset.getStride();
365:                final long[] sizes = dataset.getSelectedDims();
366:
367:                // Setting variables needed to execute read operation.
368:                start[rank - 2] = srcRegionYOffset;
369:                start[rank - 1] = srcRegionXOffset;
370:                sizes[rank - 2] = dstHeight;
371:                sizes[rank - 1] = dstWidth;
372:                stride[rank - 2] = ySubsamplingFactor;
373:                stride[rank - 1] = xSubsamplingFactor;
374:
375:                if (rank > 2) {
376:                    // Setting indexes of dimensions > 2.
377:                    for (int i = 0; i < rank - 2; i++) {
378:                        // TODO: Need to change indexing logic?
379:                        start[i] = slice2DindexCoordinates[i + 1];
380:                        sizes[i] = 1;
381:                        stride[i] = 1;
382:                    }
383:                }
384:
385:                final int nBands = getBandNumberFromProduct(sdInfo.getName());
386:
387:                // bands variables
388:                final int[] banks = new int[nBands];
389:                final int[] offsets = new int[nBands];
390:                for (int band = 0; band < nBands; band++) {
391:                    banks[band] = band;
392:                    offsets[band] = 0;
393:                }
394:
395:                // Setting SampleModel and ColorModel
396:                final int bufferType = HDFUtilities
397:                        .getBufferTypeFromDataType(dt);
398:                SampleModel sm = new BandedSampleModel(bufferType, dstWidth,
399:                        dstHeight, dstWidth, banks, offsets);
400:                ColorModel cm = retrieveColorModel(sm);
401:
402:                // ////////////////////////////////////////////////////////////////////
403:                //
404:                // DATA READ
405:                //
406:                // ////////////////////////////////////////////////////////////////////
407:
408:                WritableRaster wr = null;
409:                final Object data;
410:                try {
411:                    data = dataset.read();
412:                    final int size = dstWidth * dstHeight;
413:                    DataBuffer dataBuffer = null;
414:
415:                    switch (bufferType) {
416:                    case DataBuffer.TYPE_BYTE:
417:                        dataBuffer = new DataBufferByte((byte[]) data, size);
418:                        break;
419:                    case DataBuffer.TYPE_SHORT:
420:                    case DataBuffer.TYPE_USHORT:
421:                        dataBuffer = new DataBufferShort((short[]) data, size);
422:                        break;
423:                    case DataBuffer.TYPE_INT:
424:                        dataBuffer = new DataBufferInt((int[]) data, size);
425:                        break;
426:                    case DataBuffer.TYPE_FLOAT:
427:                        dataBuffer = new DataBufferFloat((float[]) data, size);
428:                        break;
429:                    case DataBuffer.TYPE_DOUBLE:
430:                        dataBuffer = new DataBufferDouble((double[]) data, size);
431:                        break;
432:                    }
433:
434:                    wr = Raster.createWritableRaster(sm, dataBuffer, null);
435:                    bimage = new BufferedImage(cm, wr, false, null);
436:
437:                } catch (Exception e) {
438:                    RuntimeException rte = new RuntimeException(
439:                            "Exception occurred while data Reading" + e);
440:                    rte.initCause(e);
441:                    throw rte;
442:                }
443:
444:                return bimage;
445:            }
446:
447:            public void setInput(Object input, boolean seekForwardOnly,
448:                    boolean ignoreMetadata) {
449:                this .setInput(input);
450:            }
451:
452:            public void setInput(Object input, boolean seekForwardOnly) {
453:                this .setInput(input, seekForwardOnly);
454:            }
455:
456:            public void setInput(Object input) {
457:                // ////////////////////////////////////////////////////////////////////
458:                //
459:                // Reset the state of this reader
460:                //
461:                // Prior to set a new input, I need to do a pre-emptive reset in order
462:                // to clear any value-object related to the previous input.
463:                // ////////////////////////////////////////////////////////////////////
464:
465:                //TODO: Add URL & String support.
466:                if (originatingFile != null)
467:                    reset(); //TODO: Need to reset also sourceStructure 
468:                if (input instanceof  File) {
469:                    originatingFile = (File) input;
470:                }
471:
472:                if (input instanceof  FileImageInputStreamExtImpl) {
473:                    //retrieving File
474:                    originatingFile = ((FileImageInputStreamExtImpl) input)
475:                            .getFile();
476:                }
477:
478:                try {
479:                    initialize();
480:                } catch (IOException e) {
481:                    new RuntimeException("Not a Valid Input", e);
482:                }
483:            }
484:
485:            /**
486:             * Simple initialization method
487:             */
488:            protected void initialize() throws IOException {
489:                synchronized (mutex) {
490:                    if (originatingFile == null)
491:                        throw new IOException(
492:                                "Unable to Initialize data. Provided Input is not valid");
493:                    final String fileName = originatingFile.getAbsolutePath();
494:                    try {
495:                        fileFormat = FileFormat.getInstance(fileName);
496:                        fileFormat = fileFormat.open(fileName, FileFormat.READ);
497:                        root = fileFormat.get("/");
498:                        if (root != null)
499:                            initializeProfile();
500:
501:                    } catch (Exception e) {
502:                        IOException ioe = new IOException(
503:                                "Unable to Initialize data. Provided Input is not valid"
504:                                        + e);
505:                        ioe.initCause(e);
506:                        throw ioe;
507:                    }
508:                    isInitialized = true;
509:                }
510:            }
511:
512:            /**    
513:             * Returns an <code>Iterator</code> containing possible image
514:             * types to which the given image may be decoded, in the form of
515:             * <code>ImageTypeSpecifiers</code>s. 
516:             *
517:             * @param imageIndex the index of the image to be
518:             * <code>retrieved</code>.
519:             *
520:             * @return an <code>Iterator</code> containing at least one
521:             * <code>ImageTypeSpecifier</code> representing suggested image
522:             * types for decoding the current given image.
523:             *
524:             * @exception IllegalStateException if the input source has not been set.
525:             * @exception IndexOutOfBoundsException if the supplied index is
526:             * out of bounds.
527:             * @exception IOException if an error occurs reading the format
528:             * information from the input source.
529:             */
530:
531:            public Iterator getImageTypes(final int imageIndex)
532:                    throws IOException {
533:                final List l = new java.util.ArrayList(1);
534:                if (!isInitialized)
535:                    initialize();
536:
537:                final SubDatasetInfo sdInfo = sourceStructure
538:                        .getSubDatasetInfo(retrieveSubDatasetIndex(imageIndex));
539:
540:                final Datatype dt = sdInfo.getDatatype();
541:                final int width = sdInfo.getWidth();
542:                final int height = sdInfo.getHeight();
543:                final int nBands = getBandNumberFromProduct(sdInfo.getName());
544:
545:                // bands variables
546:                final int[] banks = new int[nBands];
547:                final int[] offsets = new int[nBands];
548:                for (int band = 0; band < nBands; band++) {
549:                    banks[band] = band;
550:                    offsets[band] = 0;
551:                }
552:
553:                // Variable used to specify the data type for the storing samples
554:                // of the SampleModel
555:                final int bufferType = HDFUtilities
556:                        .getBufferTypeFromDataType(dt);
557:                final SampleModel sm = new BandedSampleModel(bufferType, width,
558:                        height, width, banks, offsets);
559:
560:                final ColorModel cm = retrieveColorModel(sm);
561:
562:                imageType = new ImageTypeSpecifier(cm, sm);
563:                l.add(imageType);
564:                return l.iterator();
565:            }
566:
567:            /**
568:             * Returns the height of a tile in the given image.
569:             * 
570:             * @param imageIndex the index of the image to be queried.
571:             *
572:             * @return the height of a tile.
573:             *
574:             * @exception IOException if an error occurs during reading.
575:             */
576:            public int getTileHeight(final int imageIndex) throws IOException {
577:                if (!isInitialized)
578:                    initialize();
579:                final SubDatasetInfo sdInfo = sourceStructure
580:                        .getSubDatasetInfo(retrieveSubDatasetIndex(imageIndex));
581:                final long[] chunkSize = sdInfo.getChunkSize();
582:
583:                // TODO: Change this behavior
584:                if (chunkSize != null) {
585:                    final int rank = sdInfo.getRank();
586:                    return (int) chunkSize[rank - 1];
587:                } else
588:                    return Math.min(512, sdInfo.getHeight());
589:            }
590:
591:            /**
592:             * Returns the width of a tile in the given image.
593:             * 
594:             * @param imageIndex the index of the image to be queried.
595:             *
596:             * @return the width of a tile.
597:             *
598:             * @exception IOException if an error occurs during reading.
599:             */
600:            public int getTileWidth(final int imageIndex) throws IOException {
601:                if (!isInitialized)
602:                    initialize();
603:                final SubDatasetInfo sdInfo = sourceStructure
604:                        .getSubDatasetInfo(retrieveSubDatasetIndex(imageIndex));
605:                final long[] chunkSize = sdInfo.getChunkSize();
606:
607:                // TODO: Change this behavior
608:                if (chunkSize != null) {
609:                    final int rank = sdInfo.getRank();
610:                    return (int) chunkSize[rank - 2];
611:                } else
612:                    return Math.min(512, sdInfo.getWidth());
613:            }
614:
615:            public void dispose() {
616:                super .dispose();
617:                try {
618:                    fileFormat.close();
619:                    sourceStructure.dispose();
620:                    sourceStructure = null;
621:                } catch (Exception e) {
622:                    // TODO Nothing to do.
623:                }
624:            }
625:
626:            public void reset() {
627:                super .setInput(null, false, false);
628:                root = null;
629:                originatingFile = null;
630:            }
631:
632:            /**
633:             * returns a proper subindex needed to access a specific 2D slice of a
634:             * specified coverage/subdataset.
635:             * 
636:             * @param imageIndex
637:             *            the specified coverage/subDataset
638:             * @param selectedIndexOfEachDim
639:             *            the required index of each dimension
640:             * 
641:             * TODO: Should I use a single long[] input parameter containing also the
642:             * subdataset index?
643:             */
644:            public int retrieveSlice2DIndex(int imageIndex,
645:                    int[] selectedIndexOfEachDim) {
646:                int subIndexOffset = 0;
647:                final SubDatasetInfo sdInfo = sourceStructure
648:                        .getSubDatasetInfo(imageIndex);
649:                for (int i = 0; i < imageIndex; i++)
650:                    subIndexOffset += (sourceStructure.getSubDatasetSize(i));
651:
652:                if (selectedIndexOfEachDim != null) {
653:                    // X and Y dims are not taken in account
654:                    final int selectedDimsLenght = selectedIndexOfEachDim.length;
655:                    final long[] subDatasetDims = sdInfo.getDims();
656:                    final int rank = sdInfo.getRank();
657:
658:                    // supposing specifying all required subDimensions.
659:                    // as an instance, if rank=5, I need to specify 3 dimensions-index
660:                    // TODO: maybe I can assume some default behavior.
661:                    // as an instance, using 0 as dimension-index when not specified.
662:                    if (selectedDimsLenght != (rank - 2)) {
663:                        throw new IndexOutOfBoundsException(
664:                                "The selected dims array can't be"
665:                                        + "greater than the rank of the subDataset");
666:                    }
667:                    for (int i = 0; i < selectedDimsLenght; i++) {
668:                        if (selectedIndexOfEachDim[i] > subDatasetDims[i]) {
669:                            final StringBuffer sb = new StringBuffer();
670:                            sb
671:                                    .append(
672:                                            "At least one of the specified indexes is greater than the max allowed index in that dimension\n")
673:                                    .append("dimension=")
674:                                    .append(i)
675:                                    .append(" index=")
676:                                    .append(selectedIndexOfEachDim[i])
677:                                    .append(
678:                                            " while the maximum index available for this dimension is ")
679:                                    .append(subDatasetDims[i]);
680:                            throw new IndexOutOfBoundsException(sb.toString());
681:                        }
682:                    }
683:                    long displacement = 0;
684:                    if (rank > 2) {
685:                        // The least significant dimension is used as offset
686:                        long finalOffset = selectedIndexOfEachDim[rank - 3];
687:                        if (rank > 3) {
688:                            //TODO: review and test this logic with a 4D dataset.
689:                            final long[] multipliers = new long[rank - 3];
690:                            for (int i = 0; i < rank - 3; i++)
691:                                multipliers[i] = subDatasetDims[i + 2];
692:                            for (int i = 0; i < rank - 3; i++) {
693:                                int factor = 1;
694:                                for (int j = 0; j < rank - 3 - i; j++)
695:                                    factor *= multipliers[j];
696:                                displacement += (factor * selectedIndexOfEachDim[i]);
697:                            }
698:                        }
699:                        displacement += finalOffset;
700:                    }
701:                    subIndexOffset += displacement;
702:                }
703:                return (int) subIndexOffset;
704:            }
705:
706:            /**
707:             * Given a specifiedIndex as an input, returns a <code>long[]</code>
708:             * having the subDataset/coverage index at the first position of the array.
709:             * Then, the indexes (of the other dimensions) needed to retrieve a proper
710:             * 2D Slice.
711:             * 
712:             * As an instance, suppose a HDF source contains a 4D SubDataset with the
713:             * form (X,Y,Z,T). if returnedIndex[]={2,3,1}, the required Slice2D is
714:             * available at the subDataset with index=2, timeIndex=3, zIndex=1.
715:             * 
716:             * TODO: Now, we are supposing order is 5thDim -> T -> Z -> (X,Y)
717:             * 
718:             */
719:            public int[] getSlice2DIndexCoordinates(int requiredSlice2DIndex) {
720:                final int nTotalDataset = sourceStructure.getNSubdatasets();
721:                final long[] subDatasetSizes = sourceStructure
722:                        .getSubDatasetSizes();
723:                int iSubdataset = 0;
724:                for (; iSubdataset < nTotalDataset; iSubdataset++) {
725:                    int subDatasetSize = (int) subDatasetSizes[iSubdataset];
726:                    if (requiredSlice2DIndex >= subDatasetSize)
727:                        requiredSlice2DIndex -= subDatasetSize;
728:                    else
729:                        break;
730:                }
731:
732:                // Getting the SubDatasetInfo related to the specified subDataset.
733:                final SubDatasetInfo sdInfo = sourceStructure
734:                        .getSubDatasetInfo(iSubdataset);
735:                final int rank = sdInfo.getRank();
736:
737:                // index initialization
738:                final int[] slice2DIndexCoordinates = new int[rank - 1];// subDatasetIndex+(rank-2)
739:                for (int i = 0; i < rank - 1; i++)
740:                    slice2DIndexCoordinates[i] = 0;
741:                slice2DIndexCoordinates[0] = iSubdataset;
742:
743:                if (rank > 2) {
744:
745:                    if (rank > 3) {
746:                        //				TODO: review and test this logic with a 4D dataset.
747:                        final long[] subDatasetDims = sdInfo.getDims();
748:                        final long[] multipliers = new long[rank - 3];
749:                        for (int i = 0; i < rank - 3; i++)
750:                            multipliers[i] = subDatasetDims[i];
751:
752:                        for (int i = 0; i < rank - 3; i++) {
753:                            int factor = 1;
754:                            for (int j = 0; j < rank - 3 - i; j++)
755:                                factor *= multipliers[j];
756:                            while (requiredSlice2DIndex >= factor) {
757:                                requiredSlice2DIndex -= factor;
758:                                slice2DIndexCoordinates[i + 1]++;
759:                            }
760:                        }
761:                    }
762:                    slice2DIndexCoordinates[rank - 2] = requiredSlice2DIndex;
763:                }
764:                return slice2DIndexCoordinates;
765:            }
766:
767:            // /**
768:            // * Given a specifiedIndex as an input, returns a <code>long[]</code>
769:            // * having the subDataset/coverage index at the first position of the
770:            // array.
771:            // * Then, the indexes (of the other dimensions) needed to retrieve a proper
772:            // * 2D Slice.
773:            // *
774:            // * As an instance, suppose a HDF source contains a 4D SubDataset with the
775:            // * form (X,Y,Z,T). if returnedIndex[]={2,3,1}, the required Slice2D is
776:            // * available at the subDataset with index=2, timeIndex=3, zIndex=1.
777:            // *
778:            // * TODO: Now, we are supposing order is 5thDim -> T -> Z -> (X,Y)
779:            // *
780:            // */
781:            // public int[] getSlice2DIndexCoordinates(int requiredSlice2DIndex) {
782:            // final int nTotalDataset = sourceStructure.getNSubdatasets();
783:            // final long[] subDatasetSizes = sourceStructure.getSubDatasetSizes();
784:            // int iSubdataset = 0;
785:            // for (; iSubdataset < nTotalDataset; iSubdataset++) {
786:            // int subDatasetSize = (int) subDatasetSizes[iSubdataset];
787:            // if (requiredSlice2DIndex >= subDatasetSize)
788:            // requiredSlice2DIndex -= subDatasetSize;
789:            // else
790:            // break;
791:            // }
792:            //
793:            // // Getting the SubDatasetInfo related to the specified subDataset.
794:            // final SubDatasetInfo sdInfo = sourceStructure
795:            // .getSubDatasetInfo(iSubdataset);
796:            // final int rank = sdInfo.getRank();
797:            //
798:            // // index initialization
799:            // final int[] slice2DIndexCoordinates = new int[rank - 1];//
800:            // subDatasetIndex+(rank-2)
801:            // for (int i = 0; i < rank - 1; i++)
802:            // slice2DIndexCoordinates[i] = 0;
803:            // slice2DIndexCoordinates[0] = iSubdataset;
804:            //
805:            // if (rank > 2) {
806:            // final long[] subDatasetDims = sdInfo.getDims();
807:            // if (rank > 3) {
808:            // final long[] multipliers = new long[rank - 3];
809:            // for (int i = 0; i < rank - 3; i++)
810:            // multipliers[i] = subDatasetDims[i + 2];
811:            //
812:            // for (int i = 0; i < rank - 3; i++) {
813:            // int factor = 1;
814:            // for (int j = 0; j < rank - 3 - i; j++)
815:            // factor *= multipliers[j];
816:            // while (requiredSlice2DIndex >= factor) {
817:            // requiredSlice2DIndex -= factor;
818:            // slice2DIndexCoordinates[i + 1]++;
819:            // }
820:            // }
821:            // }
822:            // slice2DIndexCoordinates[rank - 2] = requiredSlice2DIndex;
823:            // }
824:            // return slice2DIndexCoordinates;
825:            // }
826:
827:            /**
828:             * Given the index of a 2D image, retrieve the index of the subDataset
829:             * containing that image.
830:             * 
831:             * @param imageIndex
832:             *            the index of a 2D image
833:             * @return the index of the subDataset containing that image.
834:             */
835:            protected int retrieveSubDatasetIndex(int imageIndex) {
836:                checkImageIndex(imageIndex);
837:                final int nTotalDataset = sourceStructure.getNSubdatasets();
838:                final long[] subDatasetSizes = sourceStructure
839:                        .getSubDatasetSizes();
840:                int iSubdataset = 0;
841:                for (; iSubdataset < nTotalDataset; iSubdataset++) {
842:                    int subDatasetSize = (int) subDatasetSizes[iSubdataset];
843:                    if (imageIndex >= subDatasetSize)
844:                        imageIndex -= subDatasetSize;
845:                    else
846:                        break;
847:                }
848:                return iSubdataset;
849:            }
850:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.