/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2011, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.image.io.plugin; import com.sun.media.imageio.stream.RawImageInputStream; import java.awt.Dimension; import java.awt.image.ComponentSampleModel; import java.awt.image.DataBuffer; import java.awt.image.SampleModel; import java.io.IOException; import java.nio.ByteOrder; import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; import javax.imageio.ImageReader; import javax.imageio.spi.IIORegistry; import javax.imageio.spi.ImageReaderSpi; import javax.imageio.stream.ImageInputStream; import org.geotoolkit.internal.image.io.Formats; import org.geotoolkit.nio.IOUtilities; import org.geotoolkit.metadata.bil.HDRAccessor; /** * Reader for the <cite>BIL</cite> format. * * @author Johann Sorel (Geomatys) * @module */ public class BILImageReader extends WorldFileImageReader { public BILImageReader(final Spi provider) throws IOException { super(provider); } @Override protected Object createInput(final String readerID) throws IOException { if(!"main".equals(readerID)){ return super.createInput(readerID); } final ImageInputStream iis = (ImageInputStream) super.createInput(readerID); final Object hdrfile = IOUtilities.changeExtension(input, "hdr"); final Map<String,String> parameters = HDRAccessor.read(hdrfile); final int[] off = new int[]{0}; final int w = Integer.valueOf(parameters.get(HDRAccessor.NCOLS)); final int h = Integer.valueOf(parameters.get(HDRAccessor.NROWS)); final int nbbit = Integer.valueOf(parameters.get(HDRAccessor.NBITS)); final boolean signed = parameters.get(HDRAccessor.PIXELTYPE).contains("SIGNED"); final boolean littleEndian = "I".equalsIgnoreCase(parameters.get(HDRAccessor.BYTEORDER)); iis.setByteOrder((littleEndian)?ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN); final int transferType; if(nbbit <= 8){ transferType = DataBuffer.TYPE_BYTE; }else if(nbbit <= 16){ //todo use the signed value transferType = DataBuffer.TYPE_USHORT; }else{ throw new IOException("Unsupported number of bits : " + nbbit); } final SampleModel sm = new ComponentSampleModel(transferType, w, h, 1, w, off); final long[] offsets = new long[]{0}; final Dimension[] dimension = new Dimension[]{new Dimension(w, h)}; final RawImageInputStream input = new RawImageInputStream(iis, sm, offsets, dimension); return input; } public static class Spi extends WorldFileImageReader.Spi { public Spi() throws IllegalArgumentException { super(Formats.getReaderByFormatName("RAW", Spi.class)); this.suffixes = new String[]{"BIL","bil"}; this.names = new String[]{"BIL","bil"}; } @Override public ImageReader createReaderInstance(final Object extension) throws IOException { return new BILImageReader(this); } @Override public boolean canDecodeInput(final Object source) throws IOException { //check if file has extension .bil and .hdr file is present final String extension = IOUtilities.extension(source); if(!"bil".equalsIgnoreCase(extension)){ return false; } final Object hdrpath = IOUtilities.changeExtension(source, "hdr"); final Object hdrfile = IOUtilities.tryToPath(hdrpath); if(hdrfile instanceof Path){ final Path f = (Path) hdrfile; return Files.exists(f); } return false; } public static void registerDefaults(IIORegistry registry) { if (registry == null) { registry = IIORegistry.getDefaultInstance(); } final Spi provider = new Spi(); registry.registerServiceProvider(provider, ImageReaderSpi.class); registry.setOrdering(ImageReaderSpi.class, provider, provider.main); } public static void unregisterDefaults(IIORegistry registry) { if (registry == null) { registry = IIORegistry.getDefaultInstance(); } final Class<? extends Spi> type = Spi.class; final Spi provider = registry.getServiceProviderByClass(type); if (provider != null) { registry.deregisterServiceProvider(provider, ImageReaderSpi.class); } } } }