/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2009-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.internal; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.ColorModel; import java.awt.image.RenderedImage; import java.awt.image.WritableRaster; import java.io.Serializable; import javax.media.jai.PlanarImage; /** * An implementation of {@link BufferedImageOp} where the result is expected to be an image of * the same size than the input. This class is not public because we rely on JAI when we can. * It is used only when an operation can not be easily described in a single JAI parameter block. * * {@section Serialization} * This class must be serializable because the operation may be sent over the network * for execution on a remote server. * * @author Martin Desruisseaux (Geomatys) * @version 3.01 * * @since 3.00 * @module */ public abstract class SimpleBufferedImageOp implements BufferedImageOp, Serializable { /** * For cross-version compatibility. */ private static final long serialVersionUID = 6973234963094057672L; /** * Creates a new operation. */ protected SimpleBufferedImageOp() { } /** * Applies the operation on the given image. * * @param src The image to be filtered. * @return The result of the filtering operation. */ public abstract RenderedImage filter(final BufferedImage src); /** * Applies the operation on the given image. The default implementation invokes * {@link #filter(BufferedImage)} and convert the result to a {@link BufferedImage}. * * @param src The image to be filtered. * @param dest Where to store the result, or {@code null}. * @return The result of the filtering operation. */ @Override public BufferedImage filter(final BufferedImage src, BufferedImage dest) { final RenderedImage result = filter(src); if (dest != result) { if (dest == null) { if (result instanceof BufferedImage) { return (BufferedImage) result; } if (result instanceof PlanarImage) { return ((PlanarImage) result).getAsBufferedImage(); } dest = createCompatibleDestImage(src, null); } else { final Rectangle2D bounds = getBounds2D(src); if (dest.getWidth() != bounds.getWidth() || dest.getHeight() != bounds.getHeight()) { throw new IllegalArgumentException(); } } ImageUtilities.fill(dest, 0); final Graphics2D gr = dest.createGraphics(); gr.drawRenderedImage(result, new AffineTransform()); gr.dispose(); } return dest; } /** * Creates destination image with the correct size and number of bands. */ @Override public BufferedImage createCompatibleDestImage(final BufferedImage src, ColorModel destCM) { if (destCM == null) { destCM = src.getColorModel(); } final WritableRaster raster = destCM.createCompatibleWritableRaster(src.getWidth(), src.getHeight()); return new BufferedImage(destCM, raster, false, null); } /** * Returns the bounding box of the filtered destination image. * The default implementation returns the same bounds than the source image. */ @Override public Rectangle2D getBounds2D(final BufferedImage src) { return ImageUtilities.getBounds(src); } /** * Returns the location of the corresponding destination point given a point in the source image. * The default implementation returns the same ordinates than the source point. */ @Override public Point2D getPoint2D(final Point2D srcPt, final Point2D dstPt) { if (dstPt == null) { return (Point2D) srcPt.clone(); } dstPt.setLocation(srcPt); return dstPt; } /** * Returns the rendering hints for this operation. * The default implementation returns an empty map. */ @Override public RenderingHints getRenderingHints() { return new RenderingHints(null); } }