/*
* Geotoolkit.org - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2013, 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.processing.image.bandselect;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.RenderedImage;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.util.Hashtable;
import org.geotoolkit.image.iterator.PixelIterator;
import org.geotoolkit.image.iterator.PixelIteratorFactory;
import org.geotoolkit.parameter.Parameters;
import org.geotoolkit.processing.AbstractProcess;
import org.geotoolkit.process.ProcessException;
import org.geotoolkit.processing.image.reformat.ReformatProcess;
import org.opengis.parameter.ParameterValueGroup;
import static org.geotoolkit.processing.image.bandselect.BandSelectDescriptor.*;
import org.apache.sis.util.ArgumentChecks;
import org.geotoolkit.image.internal.ImageUtils;
import org.geotoolkit.image.internal.PhotometricInterpretation;
import org.geotoolkit.image.internal.SampleType;
/**
*
* @author Johann Sorel (Geomatys)
*/
public class BandSelectProcess extends AbstractProcess {
public BandSelectProcess(ParameterValueGroup input) {
super(INSTANCE, input);
}
@Override
protected void execute() throws ProcessException {
ArgumentChecks.ensureNonNull("inputParameter", inputParameters);
final RenderedImage inputImage = (RenderedImage) Parameters.getOrCreate(IN_IMAGE, inputParameters).getValue();
final int[] bands = (int[]) Parameters.getOrCreate(IN_BANDS, inputParameters).getValue();
final SampleModel inputSampleModel = inputImage.getSampleModel();
final int inputNbBand = inputSampleModel.getNumBands();
final int inputType = inputSampleModel.getDataType();
//check band indexes
for(int targetIndex=0;targetIndex<bands.length;targetIndex++){
if(bands[targetIndex] >= inputNbBand){
//wrong index, no band for this index
throw new ProcessException("Invalid band index "+bands[targetIndex]+" , image only have "+inputNbBand+" bands", this, null);
}
}
//create the output image
final int width = inputImage.getWidth();
final int height = inputImage.getHeight();
final int nbBand = bands.length;
final Point upperLeft = new Point(inputImage.getMinX(), inputImage.getMinY());
final WritableRaster raster;
try{
raster = ReformatProcess.createRaster(inputType, width, height, nbBand, upperLeft);
}catch(IllegalArgumentException ex){
throw new ProcessException(ex.getMessage(), this, ex);
}
//-- study Color Model
final SampleType st = SampleType.valueOf(inputImage.getSampleModel().getDataType());
//-- if we choose only one band grayScale else RGB
final PhotometricInterpretation pI = (bands.length == 1) ? PhotometricInterpretation.GRAYSCALE : PhotometricInterpretation.RGB;
final ColorModel outCm = ImageUtils.createColorModel(st, bands.length, pI, null);
final BufferedImage resultImage = new BufferedImage(outCm, raster, false, new Hashtable<>());
//copy datas
final PixelIterator readIte = PixelIteratorFactory.createDefaultIterator(inputImage);
final PixelIterator writeIte = PixelIteratorFactory.createDefaultWriteableIterator(raster, raster);
final double[] pixel = new double[inputNbBand];
int srcBandIdx = 0;
int trgBandIdx = 0;
while (readIte.next() && writeIte.next()) {
srcBandIdx = 0;
trgBandIdx = 0;
//read source pixels
pixel[srcBandIdx] = readIte.getSampleDouble();
while (++srcBandIdx != inputNbBand) {
readIte.next();
pixel[srcBandIdx] = readIte.getSampleDouble();
}
//write target pixels
writeIte.setSampleDouble(pixel[bands[trgBandIdx]]);
while (++trgBandIdx != bands.length) {
writeIte.next();
writeIte.setSampleDouble(pixel[bands[trgBandIdx]]);
}
}
Parameters.getOrCreate(OUT_IMAGE, outputParameters).setValue(resultImage);
}
}