/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * 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 com.bc.ceres.jai.operator; import javax.media.jai.ImageLayout; import javax.media.jai.JAI; import javax.media.jai.OperationDescriptorImpl; import javax.media.jai.ParameterBlockJAI; import javax.media.jai.RenderedOp; import javax.media.jai.registry.RenderedRegistryMode; import java.awt.RenderingHints; import java.awt.image.DataBuffer; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; /** * An <code>OperationDescriptor</code> describing the "Reinterpret" * operation. * <p/> * The Reinterpret operation creates a single-banded, tiled rendered * image, where the source samples are rescaled or reformatted. */ public class ReinterpretDescriptor extends OperationDescriptorImpl { public static final String PARAM_NAME_FACTOR = "factor"; public static final String PARAM_NAME_OFFSET = "offset"; public static final String PARAM_NAME_SCALING_TYPE = "scalingType"; public static final String PARAM_NAME_INTERPRETATION_TYPE = "interpretationType"; /** * The default interpretation type: all data types are interpreted as in AWT */ public static final InterpretationType AWT = new InterpretationType("AWT", 0); /** * Interpretation type for interpreting byte data as signed. */ public static final InterpretationType INTERPRET_BYTE_SIGNED = new InterpretationType("INTERPRET_BYTE_SIGNED", 1); /** * Interpretation type for interpreting integer data as unsigned. */ public static final InterpretationType INTERPRET_INT_UNSIGNED = new InterpretationType("INTERPRET_INT_UNSIGNED", 2); /** * The default scaling type: source samples are scaled linearly. */ public static final ScalingType LINEAR = new ScalingType("LINEAR", 0); /** * Exponential scaling type: source samples are scaled linearly * and then raised to the power of 10. */ public static final ScalingType EXPONENTIAL = new ScalingType("EXPONENTIAL", 1); /** * Logarithmic scaling type: source samples are scaled linearly * and then their logarithms to the basis of 10 are computed. */ public static final ScalingType LOGARITHMIC = new ScalingType("LOGARITHMIC", 2); private static final String[][] RESOURCES = { {"GlobalName", "Reinterpret"}, {"LocalName", "Reinterpret"}, {"Vendor", "com.bc.ceres.jai"}, {"Description", "Reinterprets an image by applying a rescaling or reformatting."}, {"DocURL", ""}, {"Version", "1.0"}, {"arg0Desc", "Scaling factor"}, {"arg1Desc", "Scaling offset"}, {"arg2Desc", "Scaling type"}, {"arg3Desc", "Interpretation type"}, }; private static final String[] SUPPORTED_MODES = new String[]{RenderedRegistryMode.MODE_NAME}; private static final String[] PARAM_NAMES = new String[]{PARAM_NAME_FACTOR, PARAM_NAME_OFFSET, PARAM_NAME_SCALING_TYPE, PARAM_NAME_INTERPRETATION_TYPE}; private static final Class[] PARAM_CLASSES = new Class[]{Double.class, Double.class, ScalingType.class, InterpretationType.class}; private static final Object[] PARAM_DEFAULTS = new Object[]{1.0, 0.0, LINEAR, AWT}; /** * Constructs a new instance of this class. */ public ReinterpretDescriptor() { super(RESOURCES, SUPPORTED_MODES, 1, PARAM_NAMES, PARAM_CLASSES, PARAM_DEFAULTS, null); } /** * Reinterprets an image. * <p/> * <p>Creates a <code>ParameterBlockJAI</code> from all supplied arguments (except <code>hints</code>) and * invokes {@link JAI#create(String,java.awt.image.renderable.ParameterBlock,java.awt.RenderingHints)}. * * @param source The <code>RenderedImage</code> source. * @param factor The scaling factor. * @param offset The scaling offset. * @param scalingType The manner of scaling. * @param interpretationType The interpretation type. * @param hints The <code>RenderingHints</code> to use. May be <code>null</code>. * * @return The <code>RenderedOp</code> destination. * * @throws IllegalArgumentException if <code>source</code> is <code>null</code>. * @see javax.media.jai.JAI * @see javax.media.jai.ParameterBlockJAI * @see javax.media.jai.RenderedOp */ public static RenderedOp create(RenderedImage source, double factor, double offset, ScalingType scalingType, InterpretationType interpretationType, RenderingHints hints) { final ParameterBlockJAI pb = new ParameterBlockJAI("Reinterpret", RenderedRegistryMode.MODE_NAME); pb.setSource("source0", source); pb.setParameter(PARAM_NAME_FACTOR, factor); pb.setParameter(PARAM_NAME_OFFSET, offset); pb.setParameter(PARAM_NAME_SCALING_TYPE, scalingType); pb.setParameter(PARAM_NAME_INTERPRETATION_TYPE, interpretationType); return JAI.create("Reinterpret", pb, hints); } /** * Creates the target image layout for a given source and a given target sample model. * * @param source The source. * @param sampleModel The target sample model. * * @return the target image layout. */ public static ImageLayout createTargetImageLayout(RenderedImage source, SampleModel sampleModel) { final ImageLayout imageLayout = new ImageLayout(source); imageLayout.setSampleModel(sampleModel); return imageLayout; } /** * Returns the target data type for a given source data type and reinterpretation properties. * * @param sourceDataType The source data type * @param factor The scaling factor. * @param offset The scaling offset. * @param scalingType The manner of scaling. * @param interpretationType The interpretation type. * * @return the target data type. * * @see java.awt.image.DataBuffer */ public static int getTargetDataType(int sourceDataType, double factor, double offset, ScalingType scalingType, InterpretationType interpretationType) { final boolean rescale = scalingType != LINEAR || factor != 1.0 || offset != 0.0; if (rescale) { switch (sourceDataType) { case DataBuffer.TYPE_BYTE: case DataBuffer.TYPE_USHORT: case DataBuffer.TYPE_SHORT: case DataBuffer.TYPE_FLOAT: return DataBuffer.TYPE_FLOAT; case DataBuffer.TYPE_INT: case DataBuffer.TYPE_DOUBLE: return DataBuffer.TYPE_DOUBLE; default: return DataBuffer.TYPE_UNDEFINED; } } else { switch (sourceDataType) { case DataBuffer.TYPE_BYTE: if (interpretationType == ReinterpretDescriptor.INTERPRET_BYTE_SIGNED) { return DataBuffer.TYPE_SHORT; } case DataBuffer.TYPE_INT: if (interpretationType == ReinterpretDescriptor.INTERPRET_INT_UNSIGNED) { return DataBuffer.TYPE_DOUBLE; } default: return sourceDataType; } } } }