package org.geotools.coverage.grid.imageio.geotiff; import java.io.IOException; import java.net.URL; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.metadata.IIOMetadata; import javax.imageio.stream.ImageInputStream; import org.geotools.coverage.grid.io.imageio.FileBasedImageReaderWalker; import org.geotools.coverage.grid.io.imageio.ImageReaderSource; import org.geotools.factory.Hints; import org.geotools.gce.geotiff.GeoTiffUtils; import org.geotools.resources.i18n.ErrorKeys; import org.geotools.resources.i18n.Errors; /** * * * @source $URL$ */ public class GeotiffImageReaderWalker extends FileBasedImageReaderWalker { /** Logger. */ private final static Logger LOGGER = org.geotools.util.logging.Logging .getLogger(GeotiffImageReaderWalker.class); private ImageReader mainImageReader; private ImageReader externalOvrImageReader; private int mainFileNumImages; private int extOvrFileNumImages; private ImageInputStream mainImageInputStream; private ImageInputStream externalOvrImageInputStream; public GeotiffImageReaderWalker(URL sourceURL, Hints hints) throws IOException { super(sourceURL, hints, GeoTiffUtils.TIFFREADERFACTORY); } @Override protected TiffRasterManagerBuilder getRasterManagerBuilder() { return new TiffRasterManagerBuilder(); } @Override protected ImageReader acquireReader(int i) throws IOException { if (mainImageReader == null) throw new IOException(Errors.format(ErrorKeys.DISPOSED_FACTORY)); if (!hasExternalOverviews) return mainImageReader; if (i < mainFileNumImages) return mainImageReader; if (i < mainFileNumImages + extOvrFileNumImages) return externalOvrImageReader; throw new IOException(Errors.format(ErrorKeys.INDEX_OUT_OF_BOUNDS_$1)); } @Override protected void releaseReader(int i) throws IOException { // do nothing } @Override protected void endWalk() throws IOException { dispose(); } @Override protected void prepareElement(int i) throws IOException { // do nothing } @Override protected int getNumElemements() throws IOException { if (mainImageReader == null) return -1; return mainFileNumImages + extOvrFileNumImages; } @Override protected void startWalk() throws IOException { // check if we have ext ovr then open needed readers // MAIN FILE // create a stream mainImageInputStream = this.inStreamSPI.createInputStreamInstance(sourceFile, ImageIO.getUseCache(), ImageIO.getCacheDirectory()); // create the main reader mainImageReader = this.readerSPI.createReaderInstance(); mainImageReader.setInput(mainImageInputStream); // OVERVIEWS FILE // create a stream if (hasExternalOverviews) { externalOvrImageInputStream = this.inStreamSPI.createInputStreamInstance( externalOverviewsFile, ImageIO.getUseCache(), ImageIO.getCacheDirectory()); // create the main reader externalOvrImageReader = GeoTiffUtils.TIFFREADERFACTORY.createReaderInstance(); externalOvrImageReader.setInput(externalOvrImageInputStream); } // now check the num image mainFileNumImages = mainImageReader.getNumImages(true); if (hasExternalOverviews) { extOvrFileNumImages = externalOvrImageReader.getNumImages(true); // TODO if we have ext ovr we should somehow ignore additional pages that might bring // levels themselves } } private void dispose() { mainFileNumImages = -1; extOvrFileNumImages = -1; try { if (mainImageInputStream != null) mainImageInputStream.close(); } catch (Exception e) { // TODO: handle exception } try { if (externalOvrImageInputStream != null) externalOvrImageInputStream.close(); } catch (Exception e) { // TODO: handle exception } try { if (mainImageReader != null) mainImageReader.dispose(); } catch (Exception e) { // TODO: handle exception } finally { mainImageReader = null; } try { if (externalOvrImageReader != null) externalOvrImageReader.dispose(); } catch (Exception e) { // TODO: handle exception } finally { externalOvrImageReader = null; } } @Override protected IIOMetadata getStreamMetadata() throws IOException { if (mainImageReader == null) return null; return mainImageReader.getStreamMetadata(); } @Override protected ImageReaderSource<?> getSource(int imageIndex) throws IOException { if (mainImageReader == null) throw new IOException(Errors.format(ErrorKeys.DISPOSED_FACTORY)); if (!hasExternalOverviews) return super.getSource(imageIndex); if (imageIndex < mainFileNumImages) return super.getSource(imageIndex); if (imageIndex < mainFileNumImages + extOvrFileNumImages) return ImageReaderSource.wrapFile(imageIndex, externalOverviewsFile, super.inStreamSPI, GeoTiffUtils.TIFFREADERFACTORY); throw new IOException(Errors.format(ErrorKeys.INDEX_OUT_OF_BOUNDS_$1)); } }