package fr.unistra.pelican.util.remotesensing; import java.io.BufferedInputStream; import java.io.DataInput; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import fr.unistra.pelican.ByteImage; import fr.unistra.pelican.DoubleImage; import fr.unistra.pelican.Image; import fr.unistra.pelican.IntegerImage; /** * Loads an image (in BSQ format) into an Image * @author Clément Hengy, Jonathan Weber */ public final class BSQReader extends BinReader { public BSQReader(HdrReader h, String p){ this.hr = h; this.path = new File(p).getAbsoluteFile(); } public Image getPelicanImage() throws Throwable{ int xi, yi, bi, bytesNumber; File[] subFiles; byte[] tab; File binaryFile = null; String hdrPathRadical; FileInputStream fis; xi = hr.getCols(); yi = hr.getLines(); bi = hr.getBands(); bytesNumber = hr.getBytesNumber(); hdrPathRadical = this.path.getName().substring(0, this.path.getName().length()-4); subFiles = this.path.getParentFile().listFiles(); for(int i = 0; i < subFiles.length && (null == binaryFile); ++i){ String fileName = subFiles[i].getName(); if(fileName.equals(hdrPathRadical) || fileName.equals(hdrPathRadical+".img") || fileName.endsWith(hdrPathRadical+".IMG") || fileName.endsWith(hdrPathRadical+".bsq") || fileName.endsWith(hdrPathRadical+".BSQ")) binaryFile = subFiles[i]; } if(null == binaryFile){ System.err.println("getPelicanImage() : Unable to find the associated binary file"); return null; } try{ fis = new FileInputStream(binaryFile); } catch(FileNotFoundException ex){ System.err.println("getPelicanImage() : Unable to open the associated binary file"); return null; } BufferedInputStream bif = new BufferedInputStream(fis); DataInput bf = null; if(!hr.getByteOrder()) bf = DataInputFactory.createDataInputLittleEndian(fis); else bf = DataInputFactory.createDataInputBigEndian(fis); switch(hr.getDataType()){ case 1: ByteImage imgcase1 = new ByteImage(xi, yi, 1, 1, bi); for(int b = 0; b < bi; ++b){ for(int y = 0; y < yi; ++y){ for(int x = 0; x < xi; ++x){ imgcase1.setPixelXYBByte(x, y, b, bf.readByte()); } } } img=imgcase1; break; case 2: IntegerImage imgcase2 = new IntegerImage(xi, yi, 1, 1, bi); for(int b = 0; b < bi; ++b){ for(int y = 0; y < yi; ++y){ for(int x = 0; x < xi; ++x){ imgcase2.setPixelXYBInt(x, y, b, bf.readShort()); } } } img=imgcase2; break; case 3: IntegerImage imgcase3 = new IntegerImage(xi, yi, 1, 1, bi); for(int b = 0; b < bi; ++b){ for(int y = 0; y < yi; ++y){ for(int x = 0; x < xi; ++x){ imgcase3.setPixelXYBInt(x, y, b, bf.readInt()); } } } img=imgcase3; break; case 4: DoubleImage imgcase4 = new DoubleImage(xi, yi, 1, 1, bi); for(int b = 0; b < bi; ++b){ for(int y = 0; y < yi; ++y){ for(int x = 0; x < xi; ++x){ imgcase4.setPixelXYBDouble(x, y, b, bf.readFloat()); } } } img=imgcase4; break; case 5: DoubleImage imgcase5 = new DoubleImage(xi, yi, 1, 1, bi); for(int b = 0; b < bi; ++b){ for(int y = 0; y < yi; ++y){ for(int x = 0; x < xi; ++x){ imgcase5.setPixelXYBDouble(x, y, b, bf.readDouble()); } } } img=imgcase5; break; case 12: double _2pow11 = 1./Math.pow(2, 11); DoubleImage imgcase12 = new DoubleImage(xi, yi, 1, 1, bi); for(int b = 0; b < bi; ++b){ for(int y = 0; y < yi; ++y){ for(int x = 0; x < xi; ++x){ // case 12 => pixel 16 bits mais seulement 11 bits de codé imgcase12.setPixelXYBDouble(x, y, b, bf.readShort()*_2pow11); } } } img=imgcase12; break; } super.setProperties(); return img; } @Override public Image getPelicanImage(int sx, int sy, int ex, int ey) throws Throwable { int xi, yi, bi, bytesNumber; File[] subFiles; byte[] tab; File binaryFile = null; String hdrPathRadical; FileInputStream fis; xi = hr.getCols(); yi = hr.getLines(); bi = hr.getBands(); bytesNumber = hr.getBytesNumber(); hdrPathRadical = this.path.getName().substring(0, this.path.getName().length()-4); subFiles = this.path.getParentFile().listFiles(); for(int i = 0; i < subFiles.length && (null == binaryFile); ++i){ String fileName = subFiles[i].getName(); if(fileName.equals(hdrPathRadical) || fileName.equals(hdrPathRadical+".img") || fileName.endsWith(hdrPathRadical+".IMG") || fileName.endsWith(hdrPathRadical+".bsq") || fileName.endsWith(hdrPathRadical+".BSQ")) binaryFile = subFiles[i]; } if(null == binaryFile){ System.err.println("getPelicanImage() : Unable to find the associated binary file"); return null; } try{ fis = new FileInputStream(binaryFile); } catch(FileNotFoundException eex){ System.err.println("getPelicanImage() : Unable to open the associated binary file"); return null; } // buffer de 32Mo BufferedInputStream bif = new BufferedInputStream(fis, /*Math.min(bytesNumber,*/32*1024*1024/*)*/); DataInput bf = null; if(!hr.getByteOrder()) bf = DataInputFactory.createDataInputLittleEndian(bif); else bf = DataInputFactory.createDataInputBigEndian(bif); switch(hr.getDataType()){ case 1: ByteImage imgcase1 = new ByteImage(ex-sx+1, ey-sy+1, 1, 1, bi); for(int b = 0; b < bi; ++b){ for(int y = 0; y < yi; ++y){ for(int x = 0; x < xi; ++x){ byte value = bf.readByte(); if(x <= ex && x >= sx && y <= ey && y >= sy) imgcase1.setPixelXYBByte(x, y, b, value); } } } img=imgcase1; break; case 2: IntegerImage imgcase2 = new IntegerImage(ex-sx+1, ey-sy+1, 1, 1, bi); for(int b = 0; b < bi; ++b){ for(int y = 0; y < yi; ++y){ for(int x = 0; x < xi; ++x){ short value = bf.readShort(); if(x <= ex && x >= sx && y <= ey && y >= sy) imgcase2.setPixelXYBInt(x, y, b, value); } } } img=imgcase2; break; case 3: IntegerImage imgcase3 = new IntegerImage(ex-sx+1, ey-sy+1, 1, 1, bi); for(int b = 0; b < bi; ++b){ for(int y = 0; y < yi; ++y){ for(int x = 0; x < xi; ++x){ int value = bf.readInt(); if(x <= ex && x >= sx && y <= ey && y >= sy) imgcase3.setPixelXYBInt(x, y, b, value); } } } img=imgcase3; break; case 4: DoubleImage imgcase4 = new DoubleImage(ex-sx+1, ey-sy+1, 1, 1, bi); for(int b = 0; b < bi; ++b){ for(int y = 0; y < yi; ++y){ for(int x = 0; x < xi; ++x){ float value = bf.readFloat(); if(x <= ex && x >= sx && y <= ey && y >= sy) imgcase4.setPixelXYBDouble(x, y, b, value); } } } img=imgcase4; break; case 5: DoubleImage imgcase5 = new DoubleImage(ex-sx+1, ey-sy+1, 1, 1, bi); for(int b = 0; b < bi; ++b){ for(int y = 0; y < yi; ++y){ for(int x = 0; x < xi; ++x){ double value = bf.readDouble(); if(x <= ex && x >= sx && y <= ey && y >= sy) imgcase5.setPixelXYBDouble(x, y, b, value); } } } img=imgcase5; break; case 12: DoubleImage imgcase12 = new DoubleImage(ex-sx+1, ey-sy+1, 1, 1, bi); for(int b = 0; b < bi; ++b){ for(int y = 0; y < yi; ++y){ for(int x = 0; x < xi; ++x) { short value = bf.readShort(); // case 12 => pixel 16 bits mais seulement 11 bits de codé if(x <= ex && x >= sx && y <= ey && y >= sy) imgcase12.setPixelXYBDouble(x-sx, y-sy, b, value/Math.pow(2, 11)); } } } img=imgcase12; break; } super.setProperties(); return img; } }