/*******************************************************************************
* Copyright (c) 2016 Weasis Team and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nicolas Roduit - initial API and implementation
*******************************************************************************/
package org.weasis.core.api.image.op;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.util.List;
import javax.media.jai.PlanarImage;
import javax.media.jai.RasterAccessor;
import javax.media.jai.RasterFormatTag;
import org.weasis.core.api.Messages;
import org.weasis.core.api.gui.task.TaskInterruptionException;
import org.weasis.core.api.gui.task.TaskMonitor;
import org.weasis.core.api.gui.util.GuiExecutor;
import org.weasis.core.api.image.util.LayoutUtil;
import org.weasis.core.api.media.data.ImageElement;
import org.weasis.core.api.util.StringUtil;
public class MeanCollectionZprojection {
private final List<ImageElement> sources;
private final TaskMonitor taskMonitor;
public MeanCollectionZprojection(List<ImageElement> sources, TaskMonitor taskMonitor) {
if (sources == null) {
throw new IllegalArgumentException("Sources cannot be null!"); //$NON-NLS-1$
}
this.sources = sources;
this.taskMonitor = taskMonitor;
}
private void incrementProgressBar(final int progress) {
if (taskMonitor == null) {
return;
}
if (taskMonitor.isCanceled()) {
throw new TaskInterruptionException("Operation from " + this.getClass().getName() + " has been canceled"); //$NON-NLS-1$ //$NON-NLS-2$
}
if (taskMonitor.isShowProgression()) {
GuiExecutor.instance().execute(new Runnable() {
@Override
public void run() {
taskMonitor.setProgress(progress);
StringBuilder buf = new StringBuilder(Messages.getString("MeanCollectionZprojection.operation")); //$NON-NLS-1$
buf.append(StringUtil.COLON_AND_SPACE);
buf.append(progress);
buf.append("/"); //$NON-NLS-1$
buf.append(taskMonitor.getMaximum());
taskMonitor.setNote(buf.toString());
}
});
}
}
public PlanarImage computeMeanCollectionOpImage() {
if (sources.size() > 1) {
ImageElement firstImg = sources.get(0);
PlanarImage img = firstImg.getImage(null, false);
if (img == null) {
return null;
}
Rectangle region = img.getBounds();
WritableRaster raster = LayoutUtil.createCompatibleRaster(img, region);
SampleModel[] sampleModels = { img.getSampleModel() };
int tagID = RasterAccessor.findCompatibleTag(sampleModels, raster.getSampleModel());
RasterFormatTag dstTag = new RasterFormatTag(raster.getSampleModel(), tagID);
RasterAccessor dst = new RasterAccessor(raster, region, dstTag, null);
switch (dst.getDataType()) {
case DataBuffer.TYPE_BYTE:
computeRectByte(dst, region, tagID);
break;
case DataBuffer.TYPE_USHORT:
computeRectUShort(dst, region, tagID);
break;
case DataBuffer.TYPE_SHORT:
computeRectShort(dst, region, tagID);
break;
case DataBuffer.TYPE_INT:
computeRectInt(dst, region, tagID);
break;
case DataBuffer.TYPE_FLOAT:
computeRectFloat(dst, region, tagID);
break;
case DataBuffer.TYPE_DOUBLE:
computeRectDouble(dst, region, tagID);
break;
}
dst.copyDataToRaster();
BufferedImage buffer = new BufferedImage(img.getColorModel(), raster, false, null);
return PlanarImage.wrapRenderedImage(buffer);
}
return null;
}
private void computeRectByte(RasterAccessor dst, Rectangle region, int tagID) {
int dstWidth = dst.getWidth();
int dstHeight = dst.getHeight();
int dstBands = dst.getNumBands();
int dstLineStride = dst.getScanlineStride();
int dstPixelStride = dst.getPixelStride();
int[] dstBandOffsets = dst.getBandOffsets();
byte[][] dstData = dst.getByteDataArrays();
int[][] accu = new int[dstBands][dstWidth * dstHeight];
int numbSrc = sources.size();
for (int i = 0; i < numbSrc; i++) {
ImageElement imgElement = sources.get(i);
PlanarImage img = imgElement.getImage(null, false);
RasterFormatTag srcTag = new RasterFormatTag(img.getSampleModel(), tagID);
RasterAccessor src = new RasterAccessor(img.getData(), region, srcTag, img.getColorModel());
int srcLineStride = src.getScanlineStride();
int srcPixelStride = src.getPixelStride();
int[] srcBandOffsets = src.getBandOffsets();
byte[][] srcData = src.getByteDataArrays();
for (int b = 0; b < dstBands; b++) {
int srcLineOffset = srcBandOffsets[b];
byte[] s = srcData[b];
int[] a = accu[b];
for (int h = 0; h < dstHeight; h++) {
int srcPixelOffset = srcLineOffset;
srcLineOffset += srcLineStride;
for (int w = 0; w < dstWidth; w++) {
a[h * dstWidth + w] += (s[srcPixelOffset] & 0xff);
srcPixelOffset += srcPixelStride;
}
}
}
incrementProgressBar(i);
}
for (int b = 0; b < dstBands; b++) {
int dstLineOffset = dstBandOffsets[b];
byte[] d = dstData[b];
int[] a = accu[b];
for (int h = 0; h < dstHeight; h++) {
int dstPixelOffset = dstLineOffset;
dstLineOffset += dstLineStride;
for (int w = 0; w < dstWidth; w++) {
d[dstPixelOffset] = (byte) (a[h * dstWidth + w] / (double) numbSrc + 0.5);
dstPixelOffset += dstPixelStride;
}
}
}
}
private void computeRectUShort(RasterAccessor dst, Rectangle region, int tagID) {
int dstWidth = dst.getWidth();
int dstHeight = dst.getHeight();
int dstBands = dst.getNumBands();
int dstLineStride = dst.getScanlineStride();
int dstPixelStride = dst.getPixelStride();
int[] dstBandOffsets = dst.getBandOffsets();
short[][] dstData = dst.getShortDataArrays();
float[][] accu = new float[dstBands][dstWidth * dstHeight];
int numbSrc = sources.size();
for (int i = 0; i < numbSrc; i++) {
ImageElement imgElement = sources.get(i);
PlanarImage img = imgElement.getImage(null, false);
RasterFormatTag srcTag = new RasterFormatTag(img.getSampleModel(), tagID);
RasterAccessor src = new RasterAccessor(img.getData(), region, srcTag, img.getColorModel());
int srcLineStride = src.getScanlineStride();
int srcPixelStride = src.getPixelStride();
int[] srcBandOffsets = src.getBandOffsets();
short[][] srcData = src.getShortDataArrays();
for (int b = 0; b < dstBands; b++) {
int srcLineOffset = srcBandOffsets[b];
short[] s = srcData[b];
float[] a = accu[b];
for (int h = 0; h < dstHeight; h++) {
int srcPixelOffset = srcLineOffset;
srcLineOffset += srcLineStride;
for (int w = 0; w < dstWidth; w++) {
a[h * dstWidth + w] += (s[srcPixelOffset] & 0xffff);
srcPixelOffset += srcPixelStride;
}
}
}
incrementProgressBar(i);
}
for (int b = 0; b < dstBands; b++) {
int dstLineOffset = dstBandOffsets[b];
short[] d = dstData[b];
float[] a = accu[b];
for (int h = 0; h < dstHeight; h++) {
int dstPixelOffset = dstLineOffset;
dstLineOffset += dstLineStride;
for (int w = 0; w < dstWidth; w++) {
d[dstPixelOffset] = (short) (a[h * dstWidth + w] / numbSrc + 0.5F);
dstPixelOffset += dstPixelStride;
}
}
}
}
private void computeRectShort(RasterAccessor dst, Rectangle region, int tagID) {
int dstWidth = dst.getWidth();
int dstHeight = dst.getHeight();
int dstBands = dst.getNumBands();
int dstLineStride = dst.getScanlineStride();
int dstPixelStride = dst.getPixelStride();
int[] dstBandOffsets = dst.getBandOffsets();
short[][] dstData = dst.getShortDataArrays();
float[][] accu = new float[dstBands][dstWidth * dstHeight];
int numbSrc = sources.size();
for (int i = 0; i < numbSrc; i++) {
ImageElement imgElement = sources.get(i);
PlanarImage img = imgElement.getImage(null, false);
RasterFormatTag srcTag = new RasterFormatTag(img.getSampleModel(), tagID);
RasterAccessor src = new RasterAccessor(img.getData(), region, srcTag, img.getColorModel());
int srcLineStride = src.getScanlineStride();
int srcPixelStride = src.getPixelStride();
int[] srcBandOffsets = src.getBandOffsets();
short[][] srcData = src.getShortDataArrays();
for (int b = 0; b < dstBands; b++) {
int srcLineOffset = srcBandOffsets[b];
short[] s = srcData[b];
float[] a = accu[b];
for (int h = 0; h < dstHeight; h++) {
int srcPixelOffset = srcLineOffset;
srcLineOffset += srcLineStride;
for (int w = 0; w < dstWidth; w++) {
a[h * dstWidth + w] += s[srcPixelOffset];
srcPixelOffset += srcPixelStride;
}
}
}
incrementProgressBar(i);
}
for (int b = 0; b < dstBands; b++) {
int dstLineOffset = dstBandOffsets[b];
short[] d = dstData[b];
float[] a = accu[b];
for (int h = 0; h < dstHeight; h++) {
int dstPixelOffset = dstLineOffset;
dstLineOffset += dstLineStride;
for (int w = 0; w < dstWidth; w++) {
d[dstPixelOffset] = (short) (a[h * dstWidth + w] / numbSrc + 0.5F);
dstPixelOffset += dstPixelStride;
}
}
}
}
private void computeRectInt(RasterAccessor dst, Rectangle region, int tagID) {
int dstWidth = dst.getWidth();
int dstHeight = dst.getHeight();
int dstBands = dst.getNumBands();
int dstLineStride = dst.getScanlineStride();
int dstPixelStride = dst.getPixelStride();
int[] dstBandOffsets = dst.getBandOffsets();
int[][] dstData = dst.getIntDataArrays();
double[][] accu = new double[dstBands][dstWidth * dstHeight];
int numbSrc = sources.size();
for (int i = 0; i < numbSrc; i++) {
ImageElement imgElement = sources.get(i);
PlanarImage img = imgElement.getImage(null, false);
RasterFormatTag srcTag = new RasterFormatTag(img.getSampleModel(), tagID);
RasterAccessor src = new RasterAccessor(img.getData(), region, srcTag, img.getColorModel());
int srcLineStride = src.getScanlineStride();
int srcPixelStride = src.getPixelStride();
int[] srcBandOffsets = src.getBandOffsets();
int[][] srcData = src.getIntDataArrays();
for (int b = 0; b < dstBands; b++) {
int srcLineOffset = srcBandOffsets[b];
int[] s = srcData[b];
double[] a = accu[b];
for (int h = 0; h < dstHeight; h++) {
int srcPixelOffset = srcLineOffset;
srcLineOffset += srcLineStride;
for (int w = 0; w < dstWidth; w++) {
a[h * dstWidth + w] += s[srcPixelOffset];
srcPixelOffset += srcPixelStride;
}
}
}
incrementProgressBar(i);
}
for (int b = 0; b < dstBands; b++) {
int dstLineOffset = dstBandOffsets[b];
int[] d = dstData[b];
double[] a = accu[b];
for (int h = 0; h < dstHeight; h++) {
int dstPixelOffset = dstLineOffset;
dstLineOffset += dstLineStride;
for (int w = 0; w < dstWidth; w++) {
d[dstPixelOffset] = (int) (a[h * dstWidth + w] / numbSrc + 0.5);
dstPixelOffset += dstPixelStride;
}
}
}
}
private void computeRectFloat(RasterAccessor dst, Rectangle region, int tagID) {
int dstWidth = dst.getWidth();
int dstHeight = dst.getHeight();
int dstBands = dst.getNumBands();
int dstLineStride = dst.getScanlineStride();
int dstPixelStride = dst.getPixelStride();
int[] dstBandOffsets = dst.getBandOffsets();
float[][] dstData = dst.getFloatDataArrays();
double[][] accu = new double[dstBands][dstWidth * dstHeight];
int numbSrc = sources.size();
for (int i = 0; i < numbSrc; i++) {
ImageElement imgElement = sources.get(i);
PlanarImage img = imgElement.getImage(null, false);
RasterFormatTag srcTag = new RasterFormatTag(img.getSampleModel(), tagID);
RasterAccessor src = new RasterAccessor(img.getData(), region, srcTag, img.getColorModel());
int srcLineStride = src.getScanlineStride();
int srcPixelStride = src.getPixelStride();
int[] srcBandOffsets = src.getBandOffsets();
float[][] srcData = src.getFloatDataArrays();
for (int b = 0; b < dstBands; b++) {
int srcLineOffset = srcBandOffsets[b];
float[] s = srcData[b];
double[] a = accu[b];
for (int h = 0; h < dstHeight; h++) {
int srcPixelOffset = srcLineOffset;
srcLineOffset += srcLineStride;
for (int w = 0; w < dstWidth; w++) {
a[h * dstWidth + w] += s[srcPixelOffset];
srcPixelOffset += srcPixelStride;
}
}
}
incrementProgressBar(i);
}
for (int b = 0; b < dstBands; b++) {
int dstLineOffset = dstBandOffsets[b];
float[] d = dstData[b];
double[] a = accu[b];
for (int h = 0; h < dstHeight; h++) {
int dstPixelOffset = dstLineOffset;
dstLineOffset += dstLineStride;
for (int w = 0; w < dstWidth; w++) {
d[dstPixelOffset] = (float) (a[h * dstWidth + w] / numbSrc + 0.5);
dstPixelOffset += dstPixelStride;
}
}
}
}
private void computeRectDouble(RasterAccessor dst, Rectangle region, int tagID) {
int dstWidth = dst.getWidth();
int dstHeight = dst.getHeight();
int dstBands = dst.getNumBands();
int dstLineStride = dst.getScanlineStride();
int dstPixelStride = dst.getPixelStride();
int[] dstBandOffsets = dst.getBandOffsets();
double[][] dstData = dst.getDoubleDataArrays();
double[][] accu = new double[dstBands][dstWidth * dstHeight];
int numbSrc = sources.size();
for (int i = 0; i < numbSrc; i++) {
ImageElement imgElement = sources.get(i);
PlanarImage img = imgElement.getImage(null, false);
RasterFormatTag srcTag = new RasterFormatTag(img.getSampleModel(), tagID);
RasterAccessor src = new RasterAccessor(img.getData(), region, srcTag, img.getColorModel());
int srcLineStride = src.getScanlineStride();
int srcPixelStride = src.getPixelStride();
int[] srcBandOffsets = src.getBandOffsets();
double[][] srcData = src.getDoubleDataArrays();
for (int b = 0; b < dstBands; b++) {
int srcLineOffset = srcBandOffsets[b];
double[] s = srcData[b];
double[] a = accu[b];
for (int h = 0; h < dstHeight; h++) {
int srcPixelOffset = srcLineOffset;
srcLineOffset += srcLineStride;
for (int w = 0; w < dstWidth; w++) {
a[h * dstWidth + w] += s[srcPixelOffset];
srcPixelOffset += srcPixelStride;
}
}
}
incrementProgressBar(i);
}
for (int b = 0; b < dstBands; b++) {
int dstLineOffset = dstBandOffsets[b];
double[] d = dstData[b];
double[] a = accu[b];
for (int h = 0; h < dstHeight; h++) {
int dstPixelOffset = dstLineOffset;
dstLineOffset += dstLineStride;
for (int w = 0; w < dstWidth; w++) {
d[dstPixelOffset] = a[h * dstWidth + w] / numbSrc + 0.5;
dstPixelOffset += dstPixelStride;
}
}
}
}
}