/*
* Geotoolkit.org - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2007-2012, Open Source Geospatial Foundation (OSGeo)
* (C) 2009-2012, 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;
import javax.media.jai.iterator.RectIter;
/**
* A {@link RectIter} with subsampling.
*
* @author Martin Desruisseaux (Geomatys)
* @version 3.00
*
* @since 2.4
* @module
*/
final class SubsampledRectIter implements RectIter {
/**
* The wrapped iterator.
*/
private final RectIter iterator;
/**
* Index of current band in the {@link #sourceBands} array.
*/
private int bandIndex;
/**
* The source bands.
*/
private final int[] sourceBands;
/**
* The subsampling parameters.
*/
private final int dx, dy;
/**
* Wraps the specified iterator.
*/
public SubsampledRectIter(final RectIter iterator,
final int sourceXSubsampling, final int sourceYSubsampling,
final int[] sourceBands)
{
this.iterator = iterator;
dx = sourceXSubsampling - 1;
dy = sourceYSubsampling - 1;
this.sourceBands = sourceBands;
}
/**
* Sets the iterator to the first line of its bounding rectangle.
*/
@Override
public void startLines() {
iterator.startLines();
}
/**
* Sets the iterator to the next line of the image.
*/
@Override
public void nextLine() {
nextLineDone();
}
/**
* Sets the iterator to the next line in the image.
*/
@Override
public boolean nextLineDone() {
if (iterator.nextLineDone()) {
return true;
}
iterator.jumpLines(dy);
return false;
}
/**
* Jumps downward num lines from the current position.
*/
@Override
public void jumpLines(final int num) {
iterator.jumpLines(num * (dy+1));
}
/**
* Returns true if the bottom row of the bounding rectangle has been passed.
*/
@Override
public boolean finishedLines() {
return iterator.finishedLines();
}
/**
* Sets the iterator to the leftmost pixel of its bounding rectangle.
*/
@Override
public void startPixels() {
iterator.startPixels();
}
/**
* Sets the iterator to the next pixel in image.
*/
@Override
public void nextPixel() {
nextPixelDone();
}
/**
* Sets the iterator to the next pixel in the image.
*/
@Override
public boolean nextPixelDone() {
if (iterator.nextPixelDone()) {
return true;
}
iterator.jumpPixels(dx);
return false;
}
/**
* Jumps rightward num pixels from the current position.
*/
@Override
public void jumpPixels(final int num) {
iterator.jumpPixels(num * (dx+1));
}
/**
* Returns true if the right edge of the bounding rectangle has been passed.
*/
@Override
public boolean finishedPixels() {
return iterator.finishedPixels();
}
/**
* Sets the iterator to the first band of the image.
*/
@Override
public void startBands() {
bandIndex = 0;
iterator.startBands();
for (int skip=sourceBands[0]; --skip>=0;) {
iterator.nextBand();
}
}
/**
* Sets the iterator to the next band in the image.
*/
@Override
public void nextBand() {
nextBandDone();
}
/**
* Sets the iterator to the next band in the image, and returns
* true if the max band has been exceeded.
*/
@Override
public boolean nextBandDone() {
int skip = sourceBands[bandIndex];
if (++bandIndex >= sourceBands.length) {
return true;
}
skip = sourceBands[bandIndex] - skip;
if (skip < 0) {
iterator.startBands();
skip = sourceBands[bandIndex];
}
while (--skip >= 0) {
if (iterator.nextBandDone()) {
return true;
}
}
return false;
}
/**
* Returns true if the max band in the image has been exceeded.
*/
@Override
public boolean finishedBands() {
return iterator.finishedBands();
}
@Override public int getSample () {return iterator.getSample ();}
@Override public int getSample (int b) {return iterator.getSample (sourceBands[b]);}
@Override public float getSampleFloat () {return iterator.getSampleFloat ();}
@Override public float getSampleFloat (int b) {return iterator.getSampleFloat (sourceBands[b]);}
@Override public double getSampleDouble() {return iterator.getSampleDouble();}
@Override public double getSampleDouble(int b) {return iterator.getSampleDouble(sourceBands[b]);}
@Override
public int[] getPixel(int[] a) {
final int length = sourceBands.length;
if (a == null) {
a = new int[length];
}
for (int i=0; i<length; i++) {
a[i] = getSample(i);
}
return a;
}
@Override
public float[] getPixel(float[] a) {
final int length = sourceBands.length;
if (a == null) {
a = new float[length];
}
for (int i=0; i<length; i++) {
a[i] = getSampleFloat(i);
}
return a;
}
@Override
public double[] getPixel(double[] a) {
final int length = sourceBands.length;
if (a == null) {
a = new double[length];
}
for (int i=0; i<length; i++) {
a[i] = getSampleDouble(i);
}
return a;
}
}