001: package it.geosolutions.imageio.plugins.jhdf;
002:
003: import it.geosolutions.imageio.plugins.jhdf.pool.DatasetPool.DatasetCopy;
004: import it.geosolutions.imageio.stream.input.FileImageInputStreamExtImpl;
005:
006: import java.awt.Rectangle;
007: import java.awt.Transparency;
008: import java.awt.color.ColorSpace;
009: import java.awt.image.BandedSampleModel;
010: import java.awt.image.BufferedImage;
011: import java.awt.image.ColorModel;
012: import java.awt.image.ComponentColorModel;
013: import java.awt.image.DataBuffer;
014: import java.awt.image.DataBufferByte;
015: import java.awt.image.DataBufferFloat;
016: import java.awt.image.DataBufferInt;
017: import java.awt.image.DataBufferShort;
018: import java.awt.image.Raster;
019: import java.awt.image.SampleModel;
020: import java.awt.image.WritableRaster;
021: import java.io.File;
022: import java.io.IOException;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.logging.Logger;
026:
027: import javax.imageio.ImageReadParam;
028: import javax.imageio.ImageReader;
029: import javax.imageio.ImageTypeSpecifier;
030: import javax.imageio.metadata.IIOMetadata;
031: import javax.imageio.spi.ImageReaderSpi;
032:
033: import ncsa.hdf.object.Dataset;
034: import ncsa.hdf.object.Datatype;
035:
036: import com.sun.media.imageioimpl.common.ImageUtil;
037: import com.sun.media.jai.codecimpl.util.RasterFactory;
038:
039: /**
040: * WORK IN PROGRESS - NOT YET COMPLETED - ACTUALLY ABANDONED
041: */
042:
043: public class JHDFImageReader extends ImageReader {
044: private static final Logger LOGGER = org.geotools.util.logging.Logging
045: .getLogger("it.geosolutions.imageio.plugins.jhdf.");
046:
047: /** The originating provider. It is used to retrieve the DatasetPoolHandler */
048: protected JHDFImageReaderSpi spi;
049:
050: private boolean isInitialized = false;
051:
052: private File originatingFile = null;
053:
054: private ImageTypeSpecifier imageType;
055:
056: protected JHDFImageReader(ImageReaderSpi originatingProvider) {
057: super (originatingProvider);
058: spi = (JHDFImageReaderSpi) originatingProvider;
059: }
060:
061: public int getWidth(final int imageIndex) throws IOException {
062: if (!isInitialized)
063: initialize();
064: DatasetCopy item = spi.dsPoolManager.getDatasetCopy(imageIndex);
065: final int width = item.getDataset().getWidth();
066: spi.dsPoolManager.getBackDatasetCopy(imageIndex, item
067: .getCopyID(), false);
068: return width;
069:
070: }
071:
072: public int getHeight(final int imageIndex) throws IOException {
073: if (!isInitialized)
074: initialize();
075: DatasetCopy item = spi.dsPoolManager.getDatasetCopy(imageIndex);
076: final int height = item.getDataset().getHeight();
077: spi.dsPoolManager.getBackDatasetCopy(imageIndex, item
078: .getCopyID(), false);
079: return height;
080: }
081:
082: public IIOMetadata getImageMetadata(final int imageIndex)
083: throws IOException {
084: return null;
085: }
086:
087: public int getNumImages(boolean arg0) throws IOException {
088: return 0;
089: }
090:
091: public IIOMetadata getStreamMetadata() throws IOException {
092: return null;
093: }
094:
095: public BufferedImage read(final int imageIndex, ImageReadParam param)
096: throws IOException {
097:
098: BufferedImage bimage = null;
099: // TODO: REMOVE this MESSAGE
100: System.out.print("read->");
101: System.out.print(Integer.toString(param.getSourceRegion().x)
102: + " " + Integer.toString(param.getSourceRegion().y)
103: + "\n");
104: final DatasetCopy dsc = spi.dsPoolManager
105: .getDatasetCopy(imageIndex);
106: final int pooledCopy = dsc.getCopyID();
107:
108: // TODO: REMOVE this MESSAGE
109: System.out.print(Integer.toString(param.getSourceRegion().x)
110: + " " + Integer.toString(param.getSourceRegion().y)
111: + " Obtained copy=" + pooledCopy + "\n");
112: if (dsc != null) {
113: final Dataset dataset = dsc.getDataset();
114: dataset.init();
115:
116: if (!isInitialized)
117: initialize();
118: dataset.init();
119: final int width = dataset.getWidth();
120: final int height = dataset.getHeight();
121:
122: if (param == null)
123: param = getDefaultReadParam();
124:
125: int dstWidth = -1;
126: int dstHeight = -1;
127: int srcRegionWidth = -1;
128: int srcRegionHeight = -1;
129: int srcRegionXOffset = -1;
130: int srcRegionYOffset = -1;
131: int xSubsamplingFactor = -1;
132: int ySubsamplingFactor = -1;
133:
134: // //
135: //
136: // Retrieving Information about Source Region and doing
137: // additional intialization operations.
138: //
139: // //
140: Rectangle srcRegion = param.getSourceRegion();
141: if (srcRegion != null) {
142: srcRegionWidth = (int) srcRegion.getWidth();
143: srcRegionHeight = (int) srcRegion.getHeight();
144: srcRegionXOffset = (int) srcRegion.getX();
145: srcRegionYOffset = (int) srcRegion.getY();
146:
147: // //
148: //
149: // Minimum correction for wrong source regions
150: //
151: // When you do subsampling or source subsetting it might
152: // happen that the given source region in the read param is
153: // uncorrect, which means it can be or a bit larger than the
154: // original file or can begin a bit before original limits.
155: //
156: // We got to be prepared to handle such case in order to avoid
157: // generating ArrayIndexOutOfBoundsException later in the code.
158: //
159: // //
160:
161: if (srcRegionXOffset < 0)
162: srcRegionXOffset = 0;
163: if (srcRegionYOffset < 0)
164: srcRegionYOffset = 0;
165: if ((srcRegionXOffset + srcRegionWidth) > width) {
166: srcRegionWidth = width - srcRegionXOffset;
167: }
168: // initializing destWidth
169: dstWidth = srcRegionWidth;
170:
171: if ((srcRegionYOffset + srcRegionHeight) > height) {
172: srcRegionHeight = height - srcRegionYOffset;
173: }
174: // initializing dstHeight
175: dstHeight = srcRegionHeight;
176:
177: } else {
178: // Source Region not specified.
179: // Assuming Source Region Dimension equal to Source Image
180: // Dimension
181: dstWidth = width;
182: dstHeight = height;
183: srcRegionXOffset = srcRegionYOffset = 0;
184: srcRegionWidth = width;
185: srcRegionHeight = height;
186: }
187:
188: // SubSampling variables initialization
189: xSubsamplingFactor = param.getSourceXSubsampling();
190: ySubsamplingFactor = param.getSourceYSubsampling();
191:
192: // ////
193: //
194: // Updating the destination size in compliance with
195: // the subSampling parameters
196: //
197: // ////
198:
199: dstWidth = ((dstWidth - 1) / xSubsamplingFactor) + 1;
200: dstHeight = ((dstHeight - 1) / ySubsamplingFactor) + 1;
201:
202: final long[] start = dataset.getStartDims();
203: final long[] stride = dataset.getStride();
204: final long[] sizes = dataset.getSelectedDims();
205:
206: start[0] = srcRegionYOffset;
207: start[1] = srcRegionXOffset;
208: sizes[0] = dstHeight;
209: sizes[1] = dstWidth;
210: stride[0] = ySubsamplingFactor;
211: stride[1] = xSubsamplingFactor;
212:
213: final Datatype dt = dataset.getDatatype();
214: final int dataTypeClass = dt.getDatatypeClass();
215: final int dataTypeSize = dt.getDatatypeSize();
216: final boolean isUnsigned = dt.isUnsigned();
217:
218: final int nBands = 1;
219:
220: // bands variables
221: final int[] banks = new int[nBands];
222: final int[] offsets = new int[nBands];
223: for (int band = 0; band < nBands; band++) {
224: /* Bands are not 0-base indexed, so we must add 1 */
225: banks[band] = band;
226: offsets[band] = 0;
227: }
228:
229: // Variable used to specify the data type for the storing samples
230: // of the SampleModel
231: int buffer_type = 0;
232: if (dataTypeClass == Datatype.CLASS_INTEGER) {
233: if (dataTypeSize == 1)
234: buffer_type = DataBuffer.TYPE_BYTE;
235: else if (dataTypeSize == 2) {
236: if (isUnsigned)
237: buffer_type = DataBuffer.TYPE_USHORT;
238: else
239: buffer_type = DataBuffer.TYPE_SHORT;
240: } else if (dataTypeSize == 4)
241: buffer_type = DataBuffer.TYPE_INT;
242: } else if (dataTypeClass == Datatype.CLASS_FLOAT)
243: if (dataTypeSize == 4)
244: buffer_type = DataBuffer.TYPE_FLOAT;
245:
246: SampleModel sm = new BandedSampleModel(buffer_type,
247: dstWidth, dstHeight, dstWidth, banks, offsets);
248: ColorModel cm = null;
249:
250: ColorSpace cs = null;
251: if (nBands > 1) {
252: // Number of Bands > 1.
253: // ImageUtil.createColorModel provides to Creates a
254: // ColorModel that may be used with the specified
255: // SampleModel
256: cm = ImageUtil.createColorModel(sm);
257: if (cm == null)
258: LOGGER.info("There are no ColorModels found");
259:
260: } else if ((buffer_type == DataBuffer.TYPE_BYTE)
261: || (buffer_type == DataBuffer.TYPE_USHORT)
262: || (buffer_type == DataBuffer.TYPE_INT)
263: || (buffer_type == DataBuffer.TYPE_FLOAT)
264: || (buffer_type == DataBuffer.TYPE_DOUBLE)) {
265:
266: // Just one band. Using the built-in Gray Scale Color Space
267: cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
268: cm = RasterFactory.createComponentColorModel(
269: buffer_type, // dataType
270: cs, // color space
271: false, // has alpha
272: false, // is alphaPremultiplied
273: Transparency.OPAQUE); // transparency
274: } else {
275: if (buffer_type == DataBuffer.TYPE_SHORT) {
276: // Just one band. Using the built-in Gray Scale Color
277: // Space
278: cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
279: cm = new ComponentColorModel(cs, false, false,
280: Transparency.OPAQUE, DataBuffer.TYPE_SHORT);
281: }
282: }
283:
284: WritableRaster wr = null;
285: final Object data;
286: try {
287: data = dataset.read();
288: final int size = dstWidth * dstHeight;
289:
290: // DataBuffer db = new
291: // DataBufferInt((int[])data,dstHeight*dstWidth);
292:
293: DataBuffer db = null;
294:
295: switch (buffer_type) {
296: case DataBuffer.TYPE_BYTE:
297: db = new DataBufferByte((byte[]) data, size);
298: break;
299: case DataBuffer.TYPE_SHORT:
300: case DataBuffer.TYPE_USHORT:
301: db = new DataBufferShort((short[]) data, size);
302: break;
303: case DataBuffer.TYPE_INT:
304: db = new DataBufferInt((int[]) data, size);
305: break;
306: case DataBuffer.TYPE_FLOAT:
307: db = new DataBufferFloat((float[]) data, size);
308: break;
309: }
310:
311: wr = Raster.createWritableRaster(sm, db, null);
312: bimage = new BufferedImage(cm, wr, false, null);
313:
314: } catch (OutOfMemoryError e) {
315: // TODO Auto-generated catch block
316: } catch (Exception e) {
317: // TODO Auto-generated catch block
318: }
319: System.out.print("<---read ");
320: System.out.print(Integer
321: .toString(param.getSourceRegion().x)
322: + " "
323: + Integer.toString(param.getSourceRegion().y)
324: + "\n");
325: spi.dsPoolManager.getBackDatasetCopy(imageIndex,
326: pooledCopy, true);
327: }
328:
329: return bimage;
330: }
331:
332: public void setInput(Object input, boolean seekForwardOnly,
333: boolean ignoreMetadata) {
334: this .setInput(input);
335: }
336:
337: public void setInput(Object input, boolean seekForwardOnly) {
338: this .setInput(input, seekForwardOnly);
339: }
340:
341: public void setInput(Object input) {
342:
343: File file = null;
344:
345: // ////////////////////////////////////////////////////////////////////
346: //
347: // Reset the state of this reader
348: //
349: // Prior to set a new input, I need to do a pre-emptive reset in order
350: // to clear any value-object related to the previous input.
351: // ////////////////////////////////////////////////////////////////////
352: if (input instanceof File)
353: file = (File) input;
354:
355: if (input instanceof FileImageInputStreamExtImpl)
356: file = ((FileImageInputStreamExtImpl) input).getFile();
357:
358: // reading information
359: initialize(file);
360:
361: }
362:
363: public Iterator getImageTypes(int imageIndex) throws IOException {
364: // if (!isInitialized)
365: // initialize();
366: // final List l = new java.util.ArrayList(5);
367: // System.out.print("getImagesTypes->");
368: // DatasetCopy item = spi.dsPoolManager.getDatasetCopy(imageIndex);
369: // Dataset dataset = item.getDataset();
370: // dataset.init();
371: //
372: // final Datatype dt = dataset.getDatatype();
373: // final int width = dataset.getWidth();
374: // final int height = dataset.getHeight();
375: // final int dataTypeClass = dt.getDatatypeClass();
376: // final int dataTypeSize = dt.getDatatypeSize();
377: // final boolean isUnsigned = dt.isUnsigned();
378: // ColorModel cm = null;
379: // SampleModel sm = null;
380: // if (dataTypeClass == Datatype.CLASS_INTEGER) {
381: // if (dataTypeSize == 1) {
382: // cm = RasterFactory.createComponentColorModel(
383: // DataBuffer.TYPE_BYTE, ColorSpace
384: // .getInstance(ColorSpace.CS_GRAY), false, false,
385: // Transparency.OPAQUE);
386: // sm = cm.createCompatibleSampleModel(width, height);
387: //
388: // } else if (dataTypeSize == 2 && !isUnsigned) {
389: // // XXX I am forcing to USHORT for testing purposes
390: // cm = new ComponentColorModel(ColorSpace
391: // .getInstance(ColorSpace.CS_GRAY), false, false,
392: // Transparency.OPAQUE, DataBuffer.TYPE_USHORT);
393: // sm = cm.createCompatibleSampleModel(width, height);
394: // } else if (dataTypeSize == 4) {
395: // cm = new ComponentColorModel(ColorSpace
396: // .getInstance(ColorSpace.CS_GRAY), false, false,
397: // Transparency.OPAQUE, DataBuffer.TYPE_INT);
398: // sm = cm.createCompatibleSampleModel(width, height);
399: // }
400: // } else if (dataTypeClass == Datatype.CLASS_FLOAT) {
401: //
402: // cm = RasterFactory.createComponentColorModel(DataBuffer.TYPE_FLOAT,
403: // ColorSpace.getInstance(ColorSpace.CS_GRAY), false, false,
404: // Transparency.OPAQUE);
405: // sm = cm.createCompatibleSampleModel(width, height);
406: //
407: // }
408: //
409: // imageType = new ImageTypeSpecifier(cm, sm);
410: // l.add(imageType);
411: // spi.dsPoolManager.getBackDatasetCopy(imageIndex, item.getCopyID(),
412: // false);
413: // System.out.print("<---getImagesTypes\n");
414: // return l.iterator();
415:
416: final List l = new java.util.ArrayList(5);
417: if (!isInitialized)
418: initialize();
419:
420: DatasetCopy item = spi.dsPoolManager.getDatasetCopy(imageIndex);
421: Dataset dataset = item.getDataset();
422: dataset.init();
423:
424: final Datatype dt = dataset.getDatatype();
425:
426: final int nRank = dataset.getRank();
427: System.out.println(nRank);
428: final int dataTypeClass = dt.getDatatypeClass();
429: final int dataTypeSize = dt.getDatatypeSize();
430: final int width = dataset.getWidth();
431: final int height = dataset.getHeight();
432: final boolean isUnsigned = dt.isUnsigned();
433:
434: final int nBands = 1;
435:
436: // bands variables
437: final int[] banks = new int[nBands];
438: final int[] offsets = new int[nBands];
439: for (int band = 0; band < nBands; band++) {
440: /* Bands are not 0-base indexed, so we must add 1 */
441: banks[band] = band;
442: offsets[band] = 0;
443: }
444:
445: // Variable used to specify the data type for the storing samples
446: // of the SampleModel
447: int buffer_type = 0;
448: if (dataTypeClass == Datatype.CLASS_INTEGER) {
449: if (dataTypeSize == 1)
450: buffer_type = DataBuffer.TYPE_BYTE;
451: else if (dataTypeSize == 2) {
452: if (isUnsigned)
453: buffer_type = DataBuffer.TYPE_USHORT;
454: else
455: buffer_type = DataBuffer.TYPE_SHORT;
456: } else if (dataTypeSize == 4)
457: buffer_type = DataBuffer.TYPE_INT;
458: } else if (dataTypeClass == Datatype.CLASS_FLOAT)
459: if (dataTypeSize == 4)
460: buffer_type = DataBuffer.TYPE_FLOAT;
461:
462: SampleModel sm = new BandedSampleModel(buffer_type, width,
463: height, width, banks, offsets);
464: ColorModel cm = null;
465:
466: ColorSpace cs = null;
467: if (nBands > 1) {
468: // Number of Bands > 1.
469: // ImageUtil.createColorModel provides to Creates a
470: // ColorModel that may be used with the specified
471: // SampleModel
472: cm = ImageUtil.createColorModel(sm);
473: if (cm == null)
474: LOGGER.info("There are no ColorModels found");
475:
476: } else if ((buffer_type == DataBuffer.TYPE_BYTE)
477: || (buffer_type == DataBuffer.TYPE_USHORT)
478: || (buffer_type == DataBuffer.TYPE_INT)
479: || (buffer_type == DataBuffer.TYPE_FLOAT)
480: || (buffer_type == DataBuffer.TYPE_DOUBLE)) {
481:
482: // Just one band. Using the built-in Gray Scale Color Space
483: cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
484: cm = RasterFactory.createComponentColorModel(buffer_type, // dataType
485: cs, // color space
486: false, // has alpha
487: false, // is alphaPremultiplied
488: Transparency.OPAQUE); // transparency
489: } else {
490: if (buffer_type == DataBuffer.TYPE_SHORT) {
491: // Just one band. Using the built-in Gray Scale Color
492: // Space
493: cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
494: cm = new ComponentColorModel(cs, false, false,
495: Transparency.OPAQUE, DataBuffer.TYPE_SHORT);
496: }
497: }
498:
499: spi.dsPoolManager.getBackDatasetCopy(imageIndex, item
500: .getCopyID(), false);
501: imageType = new ImageTypeSpecifier(cm, sm);
502: l.add(imageType);
503: return l.iterator();
504:
505: }
506:
507: private void initialize(File file) {
508: if (!isInitialized) {
509: originatingFile = file;
510: spi.dsPoolManager.setOriginatingFile(originatingFile);
511: isInitialized = true;
512: }
513: }
514:
515: private void initialize() {
516: initialize(originatingFile);
517: }
518:
519: public int getTileHeight(int imageIndex) throws IOException {
520: return 256;
521: }
522:
523: public int getTileWidth(int imageIndex) throws IOException {
524: return 256;
525: }
526:
527: public void dispose() {
528: // TODO: NEED TO BE IMPLEMENTED
529: super .dispose();
530: }
531:
532: public void reset() {
533: // TODO: NEED TO BE IMPLEMENTED
534: super.reset();
535: }
536:
537: }
|