/*
 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package java.awt.image;

import java.util.Hashtable;
import java.awt.image.ImageConsumer;
import java.awt.image.ImageFilter;

The BufferedImageFilter class subclasses an ImageFilter to provide a simple means of using a single-source/single-destination image operator (BufferedImageOp) to filter a BufferedImage in the Image Producer/Consumer/Observer paradigm. Examples of these image operators are: ConvolveOp, AffineTransformOp and LookupOp.
See Also:
/** * The {@code BufferedImageFilter} class subclasses an * {@code ImageFilter} to provide a simple means of * using a single-source/single-destination image operator * ({@link BufferedImageOp}) to filter a {@code BufferedImage} * in the Image Producer/Consumer/Observer * paradigm. Examples of these image operators are: {@link ConvolveOp}, * {@link AffineTransformOp} and {@link LookupOp}. * * @see ImageFilter * @see BufferedImage * @see BufferedImageOp */
public class BufferedImageFilter extends ImageFilter implements Cloneable { BufferedImageOp bufferedImageOp; ColorModel model; int width; int height; byte[] bytePixels; int[] intPixels;
Constructs a BufferedImageFilter with the specified single-source/single-destination operator.
Params:
  • op – the specified BufferedImageOp to use to filter a BufferedImage
Throws:
/** * Constructs a {@code BufferedImageFilter} with the * specified single-source/single-destination operator. * @param op the specified {@code BufferedImageOp} to * use to filter a {@code BufferedImage} * @throws NullPointerException if op is null */
public BufferedImageFilter (BufferedImageOp op) { super(); if (op == null) { throw new NullPointerException("Operation cannot be null"); } bufferedImageOp = op; }
Returns the BufferedImageOp.
Returns:the operator of this BufferedImageFilter.
/** * Returns the {@code BufferedImageOp}. * @return the operator of this {@code BufferedImageFilter}. */
public BufferedImageOp getBufferedImageOp() { return bufferedImageOp; }
Filters the information provided in the setDimensions method of the ImageConsumer interface.

Note: This method is intended to be called by the ImageProducer of the Image whose pixels are being filtered. Developers using this class to retrieve pixels from an image should avoid calling this method directly since that operation could result in problems with retrieving the requested pixels.

Params:
  • width – the width to which to set the width of this BufferedImageFilter
  • height – the height to which to set the height of this BufferedImageFilter
See Also:
/** * Filters the information provided in the * {@link ImageConsumer#setDimensions(int, int) setDimensions } method * of the {@link ImageConsumer} interface. * <p> * Note: This method is intended to be called by the * {@link ImageProducer} of the {@code Image} whose pixels are * being filtered. Developers using this class to retrieve pixels from * an image should avoid calling this method directly since that * operation could result in problems with retrieving the requested * pixels. * * @param width the width to which to set the width of this * {@code BufferedImageFilter} * @param height the height to which to set the height of this * {@code BufferedImageFilter} * @see ImageConsumer#setDimensions */
public void setDimensions(int width, int height) { if (width <= 0 || height <= 0) { imageComplete(STATICIMAGEDONE); return; } this.width = width; this.height = height; }
Filters the information provided in the setColorModel method of the ImageConsumer interface.

If model is null, this method clears the current ColorModel of this BufferedImageFilter.

Note: This method is intended to be called by the ImageProducer of the Image whose pixels are being filtered. Developers using this class to retrieve pixels from an image should avoid calling this method directly since that operation could result in problems with retrieving the requested pixels.

Params:
  • model – the ColorModel to which to set the ColorModel of this BufferedImageFilter
See Also:
/** * Filters the information provided in the * {@link ImageConsumer#setColorModel(ColorModel) setColorModel} method * of the {@code ImageConsumer} interface. * <p> * If {@code model} is {@code null}, this * method clears the current {@code ColorModel} of this * {@code BufferedImageFilter}. * <p> * Note: This method is intended to be called by the * {@code ImageProducer} of the {@code Image} * whose pixels are being filtered. Developers using this * class to retrieve pixels from an image * should avoid calling this method directly since that * operation could result in problems with retrieving the * requested pixels. * @param model the {@link ColorModel} to which to set the * {@code ColorModel} of this {@code BufferedImageFilter} * @see ImageConsumer#setColorModel */
public void setColorModel(ColorModel model) { this.model = model; } private void convertToRGB() { int size = width * height; int newpixels[] = new int[size]; if (bytePixels != null) { for (int i = 0; i < size; i++) { newpixels[i] = this.model.getRGB(bytePixels[i] & 0xff); } } else if (intPixels != null) { for (int i = 0; i < size; i++) { newpixels[i] = this.model.getRGB(intPixels[i]); } } bytePixels = null; intPixels = newpixels; this.model = ColorModel.getRGBdefault(); }
Filters the information provided in the setPixels method of the ImageConsumer interface which takes an array of bytes.

Note: This method is intended to be called by the ImageProducer of the Image whose pixels are being filtered. Developers using this class to retrieve pixels from an image should avoid calling this method directly since that operation could result in problems with retrieving the requested pixels.

Throws:
See Also:
/** * Filters the information provided in the {@code setPixels} * method of the {@code ImageConsumer} interface which takes * an array of bytes. * <p> * Note: This method is intended to be called by the * {@code ImageProducer} of the {@code Image} whose pixels * are being filtered. Developers using * this class to retrieve pixels from an image should avoid calling * this method directly since that operation could result in problems * with retrieving the requested pixels. * @throws IllegalArgumentException if width or height are less than * zero. * @see ImageConsumer#setPixels(int, int, int, int, ColorModel, byte[], int, int) */
public void setPixels(int x, int y, int w, int h, ColorModel model, byte pixels[], int off, int scansize) { // Fix 4184230 if (w < 0 || h < 0) { throw new IllegalArgumentException("Width ("+w+ ") and height ("+h+ ") must be > 0"); } // Nothing to do if (w == 0 || h == 0) { return; } if (y < 0) { int diff = -y; if (diff >= h) { return; } off += scansize * diff; y += diff; h -= diff; } if (y + h > height) { h = height - y; if (h <= 0) { return; } } if (x < 0) { int diff = -x; if (diff >= w) { return; } off += diff; x += diff; w -= diff; } if (x + w > width) { w = width - x; if (w <= 0) { return; } } int dstPtr = y*width + x; if (intPixels == null) { if (bytePixels == null) { bytePixels = new byte[width*height]; this.model = model; } else if (this.model != model) { convertToRGB(); } if (bytePixels != null) { for (int sh = h; sh > 0; sh--) { System.arraycopy(pixels, off, bytePixels, dstPtr, w); off += scansize; dstPtr += width; } } } if (intPixels != null) { int dstRem = width - w; int srcRem = scansize - w; for (int sh = h; sh > 0; sh--) { for (int sw = w; sw > 0; sw--) { intPixels[dstPtr++] = model.getRGB(pixels[off++]&0xff); } off += srcRem; dstPtr += dstRem; } } }
Filters the information provided in the setPixels method of the ImageConsumer interface which takes an array of integers.

Note: This method is intended to be called by the ImageProducer of the Image whose pixels are being filtered. Developers using this class to retrieve pixels from an image should avoid calling this method directly since that operation could result in problems with retrieving the requested pixels.

Throws:
See Also:
/** * Filters the information provided in the {@code setPixels} * method of the {@code ImageConsumer} interface which takes * an array of integers. * <p> * Note: This method is intended to be called by the * {@code ImageProducer} of the {@code Image} whose * pixels are being filtered. Developers using this class to * retrieve pixels from an image should avoid calling this method * directly since that operation could result in problems * with retrieving the requested pixels. * @throws IllegalArgumentException if width or height are less than * zero. * @see ImageConsumer#setPixels(int, int, int, int, ColorModel, int[], int, int) */
public void setPixels(int x, int y, int w, int h, ColorModel model, int pixels[], int off, int scansize) { // Fix 4184230 if (w < 0 || h < 0) { throw new IllegalArgumentException("Width ("+w+ ") and height ("+h+ ") must be > 0"); } // Nothing to do if (w == 0 || h == 0) { return; } if (y < 0) { int diff = -y; if (diff >= h) { return; } off += scansize * diff; y += diff; h -= diff; } if (y + h > height) { h = height - y; if (h <= 0) { return; } } if (x < 0) { int diff = -x; if (diff >= w) { return; } off += diff; x += diff; w -= diff; } if (x + w > width) { w = width - x; if (w <= 0) { return; } } if (intPixels == null) { if (bytePixels == null) { intPixels = new int[width * height]; this.model = model; } else { convertToRGB(); } } int dstPtr = y*width + x; if (this.model == model) { for (int sh = h; sh > 0; sh--) { System.arraycopy(pixels, off, intPixels, dstPtr, w); off += scansize; dstPtr += width; } } else { if (this.model != ColorModel.getRGBdefault()) { convertToRGB(); } int dstRem = width - w; int srcRem = scansize - w; for (int sh = h; sh > 0; sh--) { for (int sw = w; sw > 0; sw--) { intPixels[dstPtr++] = model.getRGB(pixels[off++]); } off += srcRem; dstPtr += dstRem; } } }
Filters the information provided in the imageComplete method of the ImageConsumer interface.

Note: This method is intended to be called by the ImageProducer of the Image whose pixels are being filtered. Developers using this class to retrieve pixels from an image should avoid calling this method directly since that operation could result in problems with retrieving the requested pixels.

Params:
  • status – the status of image loading
Throws:
  • ImagingOpException – if there was a problem calling the filter method of the BufferedImageOp associated with this instance.
See Also:
/** * Filters the information provided in the {@code imageComplete} * method of the {@code ImageConsumer} interface. * <p> * Note: This method is intended to be called by the * {@code ImageProducer} of the {@code Image} whose pixels * are being filtered. Developers using * this class to retrieve pixels from an image should avoid calling * this method directly since that operation could result in problems * with retrieving the requested pixels. * @param status the status of image loading * @throws ImagingOpException if there was a problem calling the filter * method of the {@code BufferedImageOp} associated with this * instance. * @see ImageConsumer#imageComplete */
public void imageComplete(int status) { WritableRaster wr; switch(status) { case IMAGEERROR: case IMAGEABORTED: // reinitialize the params model = null; width = -1; height = -1; intPixels = null; bytePixels = null; break; case SINGLEFRAMEDONE: case STATICIMAGEDONE: if (width <= 0 || height <= 0) break; if (model instanceof DirectColorModel) { if (intPixels == null) break; wr = createDCMraster(); } else if (model instanceof IndexColorModel) { int[] bandOffsets = {0}; if (bytePixels == null) break; DataBufferByte db = new DataBufferByte(bytePixels, width*height); wr = Raster.createInterleavedRaster(db, width, height, width, 1, bandOffsets, null); } else { convertToRGB(); if (intPixels == null) break; wr = createDCMraster(); } BufferedImage bi = new BufferedImage(model, wr, model.isAlphaPremultiplied(), null); bi = bufferedImageOp.filter(bi, null); WritableRaster r = bi.getRaster(); ColorModel cm = bi.getColorModel(); int w = r.getWidth(); int h = r.getHeight(); consumer.setDimensions(w, h); consumer.setColorModel(cm); if (cm instanceof DirectColorModel) { DataBufferInt db = (DataBufferInt) r.getDataBuffer(); consumer.setPixels(0, 0, w, h, cm, db.getData(), 0, w); } else if (cm instanceof IndexColorModel) { DataBufferByte db = (DataBufferByte) r.getDataBuffer(); consumer.setPixels(0, 0, w, h, cm, db.getData(), 0, w); } else { throw new InternalError("Unknown color model "+cm); } break; } consumer.imageComplete(status); } private WritableRaster createDCMraster() { WritableRaster wr; DirectColorModel dcm = (DirectColorModel) model; boolean hasAlpha = model.hasAlpha(); int[] bandMasks = new int[3+(hasAlpha ? 1 : 0)]; bandMasks[0] = dcm.getRedMask(); bandMasks[1] = dcm.getGreenMask(); bandMasks[2] = dcm.getBlueMask(); if (hasAlpha) { bandMasks[3] = dcm.getAlphaMask(); } DataBufferInt db = new DataBufferInt(intPixels, width*height); wr = Raster.createPackedRaster(db, width, height, width, bandMasks, null); return wr; } }