/* * Copyright (C) 2016 by Array Systems Computing Inc. http://www.array.ca * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * This program 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 General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see http://www.gnu.org/licenses/ */ package org.esa.s1tbx.io.TAXI; import com.bc.ceres.core.ProgressMonitor; import org.esa.snap.core.dataio.ProductReaderPlugIn; import org.esa.snap.core.datamodel.Band; import org.esa.snap.core.datamodel.Product; import org.esa.snap.core.datamodel.ProductData; import org.esa.snap.dataio.envi.EnviConstants; import org.esa.snap.dataio.envi.EnviProductReader; import org.esa.snap.dataio.envi.Header; import org.esa.snap.engine_utilities.gpf.ReaderUtils; import javax.imageio.stream.FileImageInputStream; import javax.imageio.stream.ImageInputStream; import java.io.BufferedReader; import java.io.File; import java.io.IOException; /** * Created by lveci on 17/12/2014. */ public class RATReader extends EnviProductReader { private Header header; private boolean isComplex = false; private ImageInputStream inStream; public RATReader(ProductReaderPlugIn readerPlugIn) { super(readerPlugIn); } protected Product readProductNodesImpl() throws IOException { final File inputFile = ReaderUtils.getFileFromInput(getInput()); final BufferedReader headerReader = getHeaderReader(inputFile); try { header = new Header(headerReader); } finally { if (headerReader != null) { headerReader.close(); } } final int dataType = header.getDataType(); if (dataType == EnviConstants.TYPE_ID_COMPLEXFLOAT32) { return createComplexProduct(inputFile, header, ProductData.TYPE_FLOAT32); } else if (dataType == EnviConstants.TYPE_ID_COMPLEXFLOAT64) { return createComplexProduct(inputFile, header, ProductData.TYPE_FLOAT64); } else { return super.readProductNodesImpl(); } } private Product createComplexProduct(final File inputFile, final Header header, final int bandType) throws IOException { final int width = header.getNumSamples(); final int height = header.getNumLines(); final Product product = new Product(inputFile.getName(), "RAT", width, height); product.setProductReader(this); product.setFileLocation(inputFile); product.setDescription(header.getDescription()); product.getMetadataRoot().addElement(header.getAsMetadata()); initGeoCoding(product, header); applyBeamProperties(product, header.getBeamProperties()); final Band tgtBandI = new Band("i_band", bandType, width, height); tgtBandI.setUnit("real"); product.addBand(tgtBandI); final Band tgtBandQ = new Band("q_band", bandType, width, height); tgtBandQ.setUnit("imaginary"); product.addBand(tgtBandQ); ReaderUtils.createVirtualIntensityBand(product, tgtBandI, tgtBandQ, "_band"); isComplex = true; String ratFilePath = inputFile.getPath().substring(0, inputFile.getPath().length()-4); inStream = new FileImageInputStream(new File(ratFilePath)); inStream.setByteOrder(header.getJavaByteOrder()); return product; } protected void readBandRasterDataImpl(int sourceOffsetX, int sourceOffsetY, int sourceWidth, int sourceHeight, int sourceStepX, int sourceStepY, Band destBand, int destOffsetX, int destOffsetY, int destWidth, int destHeight, ProductData destBuffer, ProgressMonitor pm) throws IOException { if (isComplex) { final int sourceMaxY = sourceOffsetY + sourceHeight - 1; Product product = destBand.getProduct(); final int elemSize = destBuffer.getElemSize(); final int headerOffset = header.getHeaderOffset(); final int bandIndex = product.getBandIndex(destBand.getName()); // band interleaved by pixel int numBands = 2; final long lineSizeInBytes = header.getNumSamples() * numBands * elemSize; ProductData lineData = ProductData.createInstance(destBuffer.getType(), sourceWidth * numBands); pm.beginTask("Reading band '" + destBand.getName() + "'...", sourceMaxY - sourceOffsetY); try { int destPos = 0; for (int sourceY = sourceOffsetY; sourceY <= sourceMaxY; sourceY += sourceStepY) { if (pm.isCanceled()) { break; } synchronized (inStream) { long lineStartPos = headerOffset + sourceY * lineSizeInBytes; inStream.seek(lineStartPos + elemSize * sourceOffsetX * numBands); lineData.readFrom(0, sourceWidth * numBands, inStream); } for (int x = 0; x < sourceWidth; x++) { destBuffer.setElemDoubleAt(destPos++, lineData.getElemDoubleAt(x * numBands + bandIndex)); } pm.worked(1); } } finally { pm.done(); } } else { super.readBandRasterDataImpl(sourceOffsetX, sourceOffsetY, sourceWidth, sourceHeight, sourceStepX, sourceStepY, destBand, destOffsetX, destOffsetY, destWidth, destHeight, destBuffer, pm); } } @Override public void close() throws IOException { if (inStream != null) { inStream.close(); } super.close(); } }