/* JAI-Ext - OpenSource Java Advanced Image Extensions Library
* http://www.geo-solutions.it/
* Copyright 2014 GeoSolutions
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package it.geosolutions.jaiext.format;
import java.awt.RenderingHints;
import java.awt.image.ColorModel;
import java.awt.image.RenderedImage;
import java.awt.image.SampleModel;
import java.awt.image.renderable.ParameterBlock;
import java.util.Map;
import javax.media.jai.CRIFImpl;
import javax.media.jai.ImageLayout;
import javax.media.jai.JAI;
import javax.media.jai.NullOpImage;
import javax.media.jai.OpImage;
import javax.media.jai.RasterFactory;
import javax.media.jai.RenderedOp;
import com.sun.media.jai.opimage.CopyOpImage;
import com.sun.media.jai.opimage.RIFUtil;
import com.sun.media.jai.util.JDKWorkarounds;
public class FormatCRIF extends CRIFImpl {
/** Constructor. */
public FormatCRIF() {
super("format");
}
/**
* Creates a new {@link RenderedOp} with a new format
*
* @param pb The source image and data type
* @param renderingHints Contains destination image layout.
*/
public RenderedImage create(ParameterBlock pb, RenderingHints renderingHints) {
// Get the source image and the data type parameter.
RenderedImage src = pb.getRenderedSource(0);
Integer datatype = (Integer) pb.getObjectParameter(0);
int type = datatype.intValue();
// Get ImageLayout from renderHints if any.
ImageLayout layout = RIFUtil.getImageLayoutHint(renderingHints);
// If there is no change return the source image directly.
if (layout == null && type == src.getSampleModel().getDataType()) {
return src;
}
// Create or clone the ImageLayout.
if (layout == null) {
layout = new ImageLayout(src);
} else {
layout = (ImageLayout) layout.clone();
}
boolean isDataTypeChange = false;
// Get prospective destination SampleModel.
SampleModel sampleModel = layout.getSampleModel(src);
// Create a new SampleModel if the type is not as desired.
if (sampleModel.getDataType() != type) {
int tileWidth = layout.getTileWidth(src);
int tileHeight = layout.getTileHeight(src);
int numBands = src.getSampleModel().getNumBands();
SampleModel csm = RasterFactory.createComponentSampleModel(sampleModel, type,
tileWidth, tileHeight, numBands);
layout.setSampleModel(csm);
isDataTypeChange = true;
}
// Check ColorModel.
ColorModel colorModel = layout.getColorModel(null);
if (colorModel != null
&& !JDKWorkarounds.areCompatibleDataModels(layout.getSampleModel(src), colorModel)) {
// Clear the mask bit if incompatible.
layout.unsetValid(ImageLayout.COLOR_MODEL_MASK);
}
// Check whether anything but the ColorModel is changing.
if (layout.getSampleModel(src) == src.getSampleModel()
&& layout.getMinX(src) == src.getMinX() && layout.getMinY(src) == src.getMinY()
&& layout.getWidth(src) == src.getWidth()
&& layout.getHeight(src) == src.getHeight()
&& layout.getTileWidth(src) == src.getTileWidth()
&& layout.getTileHeight(src) == src.getTileHeight()
&& layout.getTileGridXOffset(src) == src.getTileGridXOffset()
&& layout.getTileGridYOffset(src) == src.getTileGridYOffset()) {
if (layout.getColorModel(src) == src.getColorModel()) {
// Nothing changed: return the source directly.
return src;
} else {
// Remove TileCache hint from RenderingHints if present.
RenderingHints hints = renderingHints;
if (hints != null && hints.containsKey(JAI.KEY_TILE_CACHE)) {
hints = new RenderingHints((Map) renderingHints);
hints.remove(JAI.KEY_TILE_CACHE);
}
// Only the ColorModel is changing.
return new NullOpImage(src, layout, hints, OpImage.OP_IO_BOUND);
}
}
if (isDataTypeChange == true) {
// Add JAI.KEY_REPLACE_INDEX_COLOR_MODEL hint to renderHints
if (renderingHints == null) {
renderingHints = new RenderingHints(JAI.KEY_REPLACE_INDEX_COLOR_MODEL, Boolean.TRUE);
} else if (!renderingHints.containsKey(JAI.KEY_REPLACE_INDEX_COLOR_MODEL)) {
// If the user specified a value for this hint, we don't
// want to change that
renderingHints.put(JAI.KEY_REPLACE_INDEX_COLOR_MODEL, Boolean.TRUE);
}
}
return new CopyOpImage(src, renderingHints, layout);
}
}