/*
 * Copyright (c) 2000, 2003, 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 javax.imageio;

import java.awt.Point;
import java.awt.Transparency;
import java.awt.image.BandedSampleModel;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.color.ColorSpace;
import java.awt.image.IndexColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DirectColorModel;
import java.awt.image.MultiPixelPackedSampleModel;
import java.awt.image.PixelInterleavedSampleModel;
import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.util.Hashtable;

A class that allows the format of an image (in particular, its SampleModel and ColorModel) to be specified in a convenient manner.
/** * A class that allows the format of an image (in particular, its * <code>SampleModel</code> and <code>ColorModel</code>) to be * specified in a convenient manner. * */
public class ImageTypeSpecifier {
The ColorModel to be used as a prototype.
/** * The <code>ColorModel</code> to be used as a prototype. */
protected ColorModel colorModel;
A SampleModel to be used as a prototype.
/** * A <code>SampleModel</code> to be used as a prototype. */
protected SampleModel sampleModel;
Cached specifiers for all of the standard BufferedImage types.
/** * Cached specifiers for all of the standard * <code>BufferedImage</code> types. */
private static ImageTypeSpecifier[] BISpecifier; private static ColorSpace sRGB; // Initialize the standard specifiers static { sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB); BISpecifier = new ImageTypeSpecifier[BufferedImage.TYPE_BYTE_INDEXED + 1]; }
A constructor to be used by inner subclasses only.
/** * A constructor to be used by inner subclasses only. */
private ImageTypeSpecifier() {}
Constructs an ImageTypeSpecifier directly from a ColorModel and a SampleModel. It is the caller's responsibility to supply compatible parameters.
Params:
  • colorModel – a ColorModel.
  • sampleModel – a SampleModel.
Throws:
/** * Constructs an <code>ImageTypeSpecifier</code> directly * from a <code>ColorModel</code> and a <code>SampleModel</code>. * It is the caller's responsibility to supply compatible * parameters. * * @param colorModel a <code>ColorModel</code>. * @param sampleModel a <code>SampleModel</code>. * * @exception IllegalArgumentException if either parameter is * <code>null</code>. * @exception IllegalArgumentException if <code>sampleModel</code> * is not compatible with <code>colorModel</code>. */
public ImageTypeSpecifier(ColorModel colorModel, SampleModel sampleModel) { if (colorModel == null) { throw new IllegalArgumentException("colorModel == null!"); } if (sampleModel == null) { throw new IllegalArgumentException("sampleModel == null!"); } if (!colorModel.isCompatibleSampleModel(sampleModel)) { throw new IllegalArgumentException ("sampleModel is incompatible with colorModel!"); } this.colorModel = colorModel; this.sampleModel = sampleModel; }
Constructs an ImageTypeSpecifier from a RenderedImage. If a BufferedImage is being used, one of the factory methods createFromRenderedImage or createFromBufferedImageType should be used instead in order to get a more accurate result.
Params:
  • image – a RenderedImage.
Throws:
/** * Constructs an <code>ImageTypeSpecifier</code> from a * <code>RenderedImage</code>. If a <code>BufferedImage</code> is * being used, one of the factory methods * <code>createFromRenderedImage</code> or * <code>createFromBufferedImageType</code> should be used instead in * order to get a more accurate result. * * @param image a <code>RenderedImage</code>. * * @exception IllegalArgumentException if the argument is * <code>null</code>. */
public ImageTypeSpecifier(RenderedImage image) { if (image == null) { throw new IllegalArgumentException("image == null!"); } colorModel = image.getColorModel(); sampleModel = image.getSampleModel(); } // Packed static class Packed extends ImageTypeSpecifier { ColorSpace colorSpace; int redMask; int greenMask; int blueMask; int alphaMask; int transferType; boolean isAlphaPremultiplied; public Packed(ColorSpace colorSpace, int redMask, int greenMask, int blueMask, int alphaMask, // 0 if no alpha int transferType, boolean isAlphaPremultiplied) { if (colorSpace == null) { throw new IllegalArgumentException("colorSpace == null!"); } if (colorSpace.getType() != ColorSpace.TYPE_RGB) { throw new IllegalArgumentException ("colorSpace is not of type TYPE_RGB!"); } if (transferType != DataBuffer.TYPE_BYTE && transferType != DataBuffer.TYPE_USHORT && transferType != DataBuffer.TYPE_INT) { throw new IllegalArgumentException ("Bad value for transferType!"); } if (redMask == 0 && greenMask == 0 && blueMask == 0 && alphaMask == 0) { throw new IllegalArgumentException ("No mask has at least 1 bit set!"); } this.colorSpace = colorSpace; this.redMask = redMask; this.greenMask = greenMask; this.blueMask = blueMask; this.alphaMask = alphaMask; this.transferType = transferType; this.isAlphaPremultiplied = isAlphaPremultiplied; int bits = 32; this.colorModel = new DirectColorModel(colorSpace, bits, redMask, greenMask, blueMask, alphaMask, isAlphaPremultiplied, transferType); this.sampleModel = colorModel.createCompatibleSampleModel(1, 1); } }
Returns a specifier for a packed image format that will use a DirectColorModel and a packed SampleModel to store each pixel packed into in a single byte, short, or int.
Params:
  • colorSpace – the desired ColorSpace.
  • redMask – a contiguous mask indicated the position of the red channel.
  • greenMask – a contiguous mask indicated the position of the green channel.
  • blueMask – a contiguous mask indicated the position of the blue channel.
  • alphaMask – a contiguous mask indicated the position of the alpha channel.
  • transferType – the desired SampleModel transfer type.
  • isAlphaPremultiplied – true if the color channels will be premultipled by the alpha channel.
Throws:
Returns:an ImageTypeSpecifier with the desired characteristics.
/** * Returns a specifier for a packed image format that will use a * <code>DirectColorModel</code> and a packed * <code>SampleModel</code> to store each pixel packed into in a * single byte, short, or int. * * @param colorSpace the desired <code>ColorSpace</code>. * @param redMask a contiguous mask indicated the position of the * red channel. * @param greenMask a contiguous mask indicated the position of the * green channel. * @param blueMask a contiguous mask indicated the position of the * blue channel. * @param alphaMask a contiguous mask indicated the position of the * alpha channel. * @param transferType the desired <code>SampleModel</code> transfer type. * @param isAlphaPremultiplied <code>true</code> if the color channels * will be premultipled by the alpha channel. * * @return an <code>ImageTypeSpecifier</code> with the desired * characteristics. * * @exception IllegalArgumentException if <code>colorSpace</code> * is <code>null</code>. * @exception IllegalArgumentException if <code>colorSpace</code> * is not of type <code>TYPE_RGB</code>. * @exception IllegalArgumentException if no mask has at least 1 * bit set. * @exception IllegalArgumentException if * <code>transferType</code> if not one of * <code>DataBuffer.TYPE_BYTE</code>, * <code>DataBuffer.TYPE_USHORT</code>, or * <code>DataBuffer.TYPE_INT</code>. */
public static ImageTypeSpecifier createPacked(ColorSpace colorSpace, int redMask, int greenMask, int blueMask, int alphaMask, // 0 if no alpha int transferType, boolean isAlphaPremultiplied) { return new ImageTypeSpecifier.Packed(colorSpace, redMask, greenMask, blueMask, alphaMask, // 0 if no alpha transferType, isAlphaPremultiplied); } static ColorModel createComponentCM(ColorSpace colorSpace, int numBands, int dataType, boolean hasAlpha, boolean isAlphaPremultiplied) { int transparency = hasAlpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE; int[] numBits = new int[numBands]; int bits = DataBuffer.getDataTypeSize(dataType); for (int i = 0; i < numBands; i++) { numBits[i] = bits; } return new ComponentColorModel(colorSpace, numBits, hasAlpha, isAlphaPremultiplied, transparency, dataType); } // Interleaved static class Interleaved extends ImageTypeSpecifier { ColorSpace colorSpace; int[] bandOffsets; int dataType; boolean hasAlpha; boolean isAlphaPremultiplied; public Interleaved(ColorSpace colorSpace, int[] bandOffsets, int dataType, boolean hasAlpha, boolean isAlphaPremultiplied) { if (colorSpace == null) { throw new IllegalArgumentException("colorSpace == null!"); } if (bandOffsets == null) { throw new IllegalArgumentException("bandOffsets == null!"); } int numBands = colorSpace.getNumComponents() + (hasAlpha ? 1 : 0); if (bandOffsets.length != numBands) { throw new IllegalArgumentException ("bandOffsets.length is wrong!"); } if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_SHORT && dataType != DataBuffer.TYPE_USHORT && dataType != DataBuffer.TYPE_INT && dataType != DataBuffer.TYPE_FLOAT && dataType != DataBuffer.TYPE_DOUBLE) { throw new IllegalArgumentException ("Bad value for dataType!"); } this.colorSpace = colorSpace; this.bandOffsets = (int[])bandOffsets.clone(); this.dataType = dataType; this.hasAlpha = hasAlpha; this.isAlphaPremultiplied = isAlphaPremultiplied; this.colorModel = ImageTypeSpecifier.createComponentCM(colorSpace, bandOffsets.length, dataType, hasAlpha, isAlphaPremultiplied); int minBandOffset = bandOffsets[0]; int maxBandOffset = minBandOffset; for (int i = 0; i < bandOffsets.length; i++) { int offset = bandOffsets[i]; minBandOffset = Math.min(offset, minBandOffset); maxBandOffset = Math.max(offset, maxBandOffset); } int pixelStride = maxBandOffset - minBandOffset + 1; int w = 1; int h = 1; this.sampleModel = new PixelInterleavedSampleModel(dataType, w, h, pixelStride, w*pixelStride, bandOffsets); } public boolean equals(Object o) { if ((o == null) || !(o instanceof ImageTypeSpecifier.Interleaved)) { return false; } ImageTypeSpecifier.Interleaved that = (ImageTypeSpecifier.Interleaved)o; if ((!(this.colorSpace.equals(that.colorSpace))) || (this.dataType != that.dataType) || (this.hasAlpha != that.hasAlpha) || (this.isAlphaPremultiplied != that.isAlphaPremultiplied) || (this.bandOffsets.length != that.bandOffsets.length)) { return false; } for (int i = 0; i < bandOffsets.length; i++) { if (this.bandOffsets[i] != that.bandOffsets[i]) { return false; } } return true; } public int hashCode() { return (super.hashCode() + (4 * bandOffsets.length) + (25 * dataType) + (hasAlpha ? 17 : 18)); } }
Returns a specifier for an interleaved image format that will use a ComponentColorModel and a PixelInterleavedSampleModel to store each pixel component in a separate byte, short, or int.
Params:
  • colorSpace – the desired ColorSpace.
  • bandOffsets – an array of ints indicating the offsets for each band.
  • dataType – the desired data type, as one of the enumerations from the DataBuffer class.
  • hasAlpha – true if an alpha channel is desired.
  • isAlphaPremultiplied – true if the color channels will be premultipled by the alpha channel.
Throws:
Returns:an ImageTypeSpecifier with the desired characteristics.
/** * Returns a specifier for an interleaved image format that will * use a <code>ComponentColorModel</code> and a * <code>PixelInterleavedSampleModel</code> to store each pixel * component in a separate byte, short, or int. * * @param colorSpace the desired <code>ColorSpace</code>. * @param bandOffsets an array of <code>int</code>s indicating the * offsets for each band. * @param dataType the desired data type, as one of the enumerations * from the <code>DataBuffer</code> class. * @param hasAlpha <code>true</code> if an alpha channel is desired. * @param isAlphaPremultiplied <code>true</code> if the color channels * will be premultipled by the alpha channel. * * @return an <code>ImageTypeSpecifier</code> with the desired * characteristics. * * @exception IllegalArgumentException if <code>colorSpace</code> * is <code>null</code>. * @exception IllegalArgumentException if <code>bandOffsets</code> * is <code>null</code>. * @exception IllegalArgumentException if <code>dataType</code> is * not one of the legal <code>DataBuffer.TYPE_*</code> constants. * @exception IllegalArgumentException if * <code>bandOffsets.length</code> does not equal the number of * color space components, plus 1 if <code>hasAlpha</code> is * <code>true</code>. */
public static ImageTypeSpecifier createInterleaved(ColorSpace colorSpace, int[] bandOffsets, int dataType, boolean hasAlpha, boolean isAlphaPremultiplied) { return new ImageTypeSpecifier.Interleaved(colorSpace, bandOffsets, dataType, hasAlpha, isAlphaPremultiplied); } // Banded static class Banded extends ImageTypeSpecifier { ColorSpace colorSpace; int[] bankIndices; int[] bandOffsets; int dataType; boolean hasAlpha; boolean isAlphaPremultiplied; public Banded(ColorSpace colorSpace, int[] bankIndices, int[] bandOffsets, int dataType, boolean hasAlpha, boolean isAlphaPremultiplied) { if (colorSpace == null) { throw new IllegalArgumentException("colorSpace == null!"); } if (bankIndices == null) { throw new IllegalArgumentException("bankIndices == null!"); } if (bandOffsets == null) { throw new IllegalArgumentException("bandOffsets == null!"); } if (bankIndices.length != bandOffsets.length) { throw new IllegalArgumentException ("bankIndices.length != bandOffsets.length!"); } if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_SHORT && dataType != DataBuffer.TYPE_USHORT && dataType != DataBuffer.TYPE_INT && dataType != DataBuffer.TYPE_FLOAT && dataType != DataBuffer.TYPE_DOUBLE) { throw new IllegalArgumentException ("Bad value for dataType!"); } int numBands = colorSpace.getNumComponents() + (hasAlpha ? 1 : 0); if (bandOffsets.length != numBands) { throw new IllegalArgumentException ("bandOffsets.length is wrong!"); } this.colorSpace = colorSpace; this.bankIndices = (int[])bankIndices.clone(); this.bandOffsets = (int[])bandOffsets.clone(); this.dataType = dataType; this.hasAlpha = hasAlpha; this.isAlphaPremultiplied = isAlphaPremultiplied; this.colorModel = ImageTypeSpecifier.createComponentCM(colorSpace, bankIndices.length, dataType, hasAlpha, isAlphaPremultiplied); int w = 1; int h = 1; this.sampleModel = new BandedSampleModel(dataType, w, h, w, bankIndices, bandOffsets); } public boolean equals(Object o) { if ((o == null) || !(o instanceof ImageTypeSpecifier.Banded)) { return false; } ImageTypeSpecifier.Banded that = (ImageTypeSpecifier.Banded)o; if ((!(this.colorSpace.equals(that.colorSpace))) || (this.dataType != that.dataType) || (this.hasAlpha != that.hasAlpha) || (this.isAlphaPremultiplied != that.isAlphaPremultiplied) || (this.bankIndices.length != that.bankIndices.length) || (this.bandOffsets.length != that.bandOffsets.length)) { return false; } for (int i = 0; i < bankIndices.length; i++) { if (this.bankIndices[i] != that.bankIndices[i]) { return false; } } for (int i = 0; i < bandOffsets.length; i++) { if (this.bandOffsets[i] != that.bandOffsets[i]) { return false; } } return true; } public int hashCode() { return (super.hashCode() + (3 * bandOffsets.length) + (7 * bankIndices.length) + (21 * dataType) + (hasAlpha ? 19 : 29)); } }
Returns a specifier for a banded image format that will use a ComponentColorModel and a BandedSampleModel to store each channel in a separate array.
Params:
  • colorSpace – the desired ColorSpace.
  • bankIndices – an array of ints indicating the bank in which each band will be stored.
  • bandOffsets – an array of ints indicating the starting offset of each band within its bank.
  • dataType – the desired data type, as one of the enumerations from the DataBuffer class.
  • hasAlpha – true if an alpha channel is desired.
  • isAlphaPremultiplied – true if the color channels will be premultipled by the alpha channel.
Throws:
Returns:an ImageTypeSpecifier with the desired characteristics.
/** * Returns a specifier for a banded image format that will use a * <code>ComponentColorModel</code> and a * <code>BandedSampleModel</code> to store each channel in a * separate array. * * @param colorSpace the desired <code>ColorSpace</code>. * @param bankIndices an array of <code>int</code>s indicating the * bank in which each band will be stored. * @param bandOffsets an array of <code>int</code>s indicating the * starting offset of each band within its bank. * @param dataType the desired data type, as one of the enumerations * from the <code>DataBuffer</code> class. * @param hasAlpha <code>true</code> if an alpha channel is desired. * @param isAlphaPremultiplied <code>true</code> if the color channels * will be premultipled by the alpha channel. * * @return an <code>ImageTypeSpecifier</code> with the desired * characteristics. * * @exception IllegalArgumentException if <code>colorSpace</code> * is <code>null</code>. * @exception IllegalArgumentException if <code>bankIndices</code> * is <code>null</code>. * @exception IllegalArgumentException if <code>bandOffsets</code> * is <code>null</code>. * @exception IllegalArgumentException if the lengths of * <code>bankIndices</code> and <code>bandOffsets</code> differ. * @exception IllegalArgumentException if * <code>bandOffsets.length</code> does not equal the number of * color space components, plus 1 if <code>hasAlpha</code> is * <code>true</code>. * @exception IllegalArgumentException if <code>dataType</code> is * not one of the legal <code>DataBuffer.TYPE_*</code> constants. */
public static ImageTypeSpecifier createBanded(ColorSpace colorSpace, int[] bankIndices, int[] bandOffsets, int dataType, boolean hasAlpha, boolean isAlphaPremultiplied) { return new ImageTypeSpecifier.Banded(colorSpace, bankIndices, bandOffsets, dataType, hasAlpha, isAlphaPremultiplied); } // Grayscale static class Grayscale extends ImageTypeSpecifier { int bits; int dataType; boolean isSigned; boolean hasAlpha; boolean isAlphaPremultiplied; public Grayscale(int bits, int dataType, boolean isSigned, boolean hasAlpha, boolean isAlphaPremultiplied) { if (bits != 1 && bits != 2 && bits != 4 && bits != 8 && bits != 16) { throw new IllegalArgumentException("Bad value for bits!"); } if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_SHORT && dataType != DataBuffer.TYPE_USHORT) { throw new IllegalArgumentException ("Bad value for dataType!"); } if (bits > 8 && dataType == DataBuffer.TYPE_BYTE) { throw new IllegalArgumentException ("Too many bits for dataType!"); } this.bits = bits; this.dataType = dataType; this.isSigned = isSigned; this.hasAlpha = hasAlpha; this.isAlphaPremultiplied = isAlphaPremultiplied; ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY); if ((bits == 8 && dataType == DataBuffer.TYPE_BYTE) || (bits == 16 && (dataType == DataBuffer.TYPE_SHORT || dataType == DataBuffer.TYPE_USHORT))) { // Use component color model & sample model int numBands = hasAlpha ? 2 : 1; int transparency = hasAlpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE; int[] nBits = new int[numBands]; nBits[0] = bits; if (numBands == 2) { nBits[1] = bits; } this.colorModel = new ComponentColorModel(colorSpace, nBits, hasAlpha, isAlphaPremultiplied, transparency, dataType); int[] bandOffsets = new int[numBands]; bandOffsets[0] = 0; if (numBands == 2) { bandOffsets[1] = 1; } int w = 1; int h = 1; this.sampleModel = new PixelInterleavedSampleModel(dataType, w, h, numBands, w*numBands, bandOffsets); } else { int numEntries = 1 << bits; byte[] arr = new byte[numEntries]; for (int i = 0; i < numEntries; i++) { arr[i] = (byte)(i*255/(numEntries - 1)); } this.colorModel = new IndexColorModel(bits, numEntries, arr, arr, arr); this.sampleModel = new MultiPixelPackedSampleModel(dataType, 1, 1, bits); } } }
Returns a specifier for a grayscale image format that will pack pixels of the given bit depth into array elements of the specified data type.
Params:
  • bits – the number of bits per gray value (1, 2, 4, 8, or 16).
  • dataType – the desired data type, as one of the enumerations from the DataBuffer class.
  • isSigned – true if negative values are to be represented.
Throws:
Returns:an ImageTypeSpecifier with the desired characteristics.
/** * Returns a specifier for a grayscale image format that will pack * pixels of the given bit depth into array elements of * the specified data type. * * @param bits the number of bits per gray value (1, 2, 4, 8, or 16). * @param dataType the desired data type, as one of the enumerations * from the <code>DataBuffer</code> class. * @param isSigned <code>true</code> if negative values are to * be represented. * * @return an <code>ImageTypeSpecifier</code> with the desired * characteristics. * * @exception IllegalArgumentException if <code>bits</code> is * not one of 1, 2, 4, 8, or 16. * @exception IllegalArgumentException if <code>dataType</code> is * not one of <code>DataBuffer.TYPE_BYTE</code>, * <code>DataBuffer.TYPE_SHORT</code>, or * <code>DataBuffer.TYPE_USHORT</code>. * @exception IllegalArgumentException if <code>bits</code> is * larger than the bit size of the given <code>dataType</code>. */
public static ImageTypeSpecifier createGrayscale(int bits, int dataType, boolean isSigned) { return new ImageTypeSpecifier.Grayscale(bits, dataType, isSigned, false, false); }
Returns a specifier for a grayscale plus alpha image format that will pack pixels of the given bit depth into array elements of the specified data type.
Params:
  • bits – the number of bits per gray value (1, 2, 4, 8, or 16).
  • dataType – the desired data type, as one of the enumerations from the DataBuffer class.
  • isSigned – true if negative values are to be represented.
  • isAlphaPremultiplied – true if the luminance channel will be premultipled by the alpha channel.
Throws:
Returns:an ImageTypeSpecifier with the desired characteristics.
/** * Returns a specifier for a grayscale plus alpha image format * that will pack pixels of the given bit depth into array * elements of the specified data type. * * @param bits the number of bits per gray value (1, 2, 4, 8, or 16). * @param dataType the desired data type, as one of the enumerations * from the <code>DataBuffer</code> class. * @param isSigned <code>true</code> if negative values are to * be represented. * @param isAlphaPremultiplied <code>true</code> if the luminance channel * will be premultipled by the alpha channel. * * @return an <code>ImageTypeSpecifier</code> with the desired * characteristics. * * @exception IllegalArgumentException if <code>bits</code> is * not one of 1, 2, 4, 8, or 16. * @exception IllegalArgumentException if <code>dataType</code> is * not one of <code>DataBuffer.TYPE_BYTE</code>, * <code>DataBuffer.TYPE_SHORT</code>, or * <code>DataBuffer.TYPE_USHORT</code>. * @exception IllegalArgumentException if <code>bits</code> is * larger than the bit size of the given <code>dataType</code>. */
public static ImageTypeSpecifier createGrayscale(int bits, int dataType, boolean isSigned, boolean isAlphaPremultiplied) { return new ImageTypeSpecifier.Grayscale(bits, dataType, isSigned, true, isAlphaPremultiplied); } // Indexed static class Indexed extends ImageTypeSpecifier { byte[] redLUT; byte[] greenLUT; byte[] blueLUT; byte[] alphaLUT = null; int bits; int dataType; public Indexed(byte[] redLUT, byte[] greenLUT, byte[] blueLUT, byte[] alphaLUT, int bits, int dataType) { if (redLUT == null || greenLUT == null || blueLUT == null) { throw new IllegalArgumentException("LUT is null!"); } if (bits != 1 && bits != 2 && bits != 4 && bits != 8 && bits != 16) { throw new IllegalArgumentException("Bad value for bits!"); } if (dataType != DataBuffer.TYPE_BYTE && dataType != DataBuffer.TYPE_SHORT && dataType != DataBuffer.TYPE_USHORT && dataType != DataBuffer.TYPE_INT) { throw new IllegalArgumentException ("Bad value for dataType!"); } if ((bits > 8 && dataType == DataBuffer.TYPE_BYTE) || (bits > 16 && dataType != DataBuffer.TYPE_INT)) { throw new IllegalArgumentException ("Too many bits for dataType!"); } int len = 1 << bits; if (redLUT.length != len || greenLUT.length != len || blueLUT.length != len || (alphaLUT != null && alphaLUT.length != len)) { throw new IllegalArgumentException("LUT has improper length!"); } this.redLUT = (byte[])redLUT.clone(); this.greenLUT = (byte[])greenLUT.clone(); this.blueLUT = (byte[])blueLUT.clone(); if (alphaLUT != null) { this.alphaLUT = (byte[])alphaLUT.clone(); } this.bits = bits; this.dataType = dataType; if (alphaLUT == null) { this.colorModel = new IndexColorModel(bits, redLUT.length, redLUT, greenLUT, blueLUT); } else { this.colorModel = new IndexColorModel(bits, redLUT.length, redLUT, greenLUT, blueLUT, alphaLUT); } if ((bits == 8 && dataType == DataBuffer.TYPE_BYTE) || (bits == 16 && (dataType == DataBuffer.TYPE_SHORT || dataType == DataBuffer.TYPE_USHORT))) { int[] bandOffsets = { 0 }; this.sampleModel = new PixelInterleavedSampleModel(dataType, 1, 1, 1, 1, bandOffsets); } else { this.sampleModel = new MultiPixelPackedSampleModel(dataType, 1, 1, bits); } } }
Returns a specifier for an indexed-color image format that will pack index values of the given bit depth into array elements of the specified data type.
Params:
  • redLUT – an array of bytes containing the red values for each index.
  • greenLUT – an array of bytes containing * the green values for each index.
  • blueLUT – an array of bytes containing the blue values for each index.
  • alphaLUT – an array of bytes containing the alpha values for each index, or null to create a fully opaque LUT.
  • bits – the number of bits in each index.
  • dataType – the desired output type, as one of the enumerations from the DataBuffer class.
Throws:
Returns:an ImageTypeSpecifier with the desired characteristics.
/** * Returns a specifier for an indexed-color image format that will pack * index values of the given bit depth into array elements of * the specified data type. * * @param redLUT an array of <code>byte</code>s containing * the red values for each index. * @param greenLUT an array of <code>byte</code>s containing * the * green values for each index. * @param blueLUT an array of <code>byte</code>s containing the * blue values for each index. * @param alphaLUT an array of <code>byte</code>s containing the * alpha values for each index, or <code>null</code> to create a * fully opaque LUT. * @param bits the number of bits in each index. * @param dataType the desired output type, as one of the enumerations * from the <code>DataBuffer</code> class. * * @return an <code>ImageTypeSpecifier</code> with the desired * characteristics. * * @exception IllegalArgumentException if <code>redLUT</code> is * <code>null</code>. * @exception IllegalArgumentException if <code>greenLUT</code> is * <code>null</code>. * @exception IllegalArgumentException if <code>blueLUT</code> is * <code>null</code>. * @exception IllegalArgumentException if <code>bits</code> is * not one of 1, 2, 4, 8, or 16. * @exception IllegalArgumentException if the * non-<code>null</code> LUT parameters do not have lengths of * exactly <code>1 << bits</code>. * @exception IllegalArgumentException if <code>dataType</code> is * not one of <code>DataBuffer.TYPE_BYTE</code>, * <code>DataBuffer.TYPE_SHORT</code>, * <code>DataBuffer.TYPE_USHORT</code>, * or <code>DataBuffer.TYPE_INT</code>. * @exception IllegalArgumentException if <code>bits</code> is * larger than the bit size of the given <code>dataType</code>. */
public static ImageTypeSpecifier createIndexed(byte[] redLUT, byte[] greenLUT, byte[] blueLUT, byte[] alphaLUT, int bits, int dataType) { return new ImageTypeSpecifier.Indexed(redLUT, greenLUT, blueLUT, alphaLUT, bits, dataType); }
Returns an ImageTypeSpecifier that encodes one of the standard BufferedImage types (other than TYPE_CUSTOM).
Params:
  • bufferedImageType – an int representing one of the standard BufferedImage types.
Throws:
See Also:
Returns:an ImageTypeSpecifier with the desired characteristics.
/** * Returns an <code>ImageTypeSpecifier</code> that encodes * one of the standard <code>BufferedImage</code> types * (other than <code>TYPE_CUSTOM</code>). * * @param bufferedImageType an int representing one of the standard * <code>BufferedImage</code> types. * * @return an <code>ImageTypeSpecifier</code> with the desired * characteristics. * * @exception IllegalArgumentException if * <code>bufferedImageType</code> is not one of the standard * types, or is equal to <code>TYPE_CUSTOM</code>. * * @see java.awt.image.BufferedImage * @see java.awt.image.BufferedImage#TYPE_INT_RGB * @see java.awt.image.BufferedImage#TYPE_INT_ARGB * @see java.awt.image.BufferedImage#TYPE_INT_ARGB_PRE * @see java.awt.image.BufferedImage#TYPE_INT_BGR * @see java.awt.image.BufferedImage#TYPE_3BYTE_BGR * @see java.awt.image.BufferedImage#TYPE_4BYTE_ABGR * @see java.awt.image.BufferedImage#TYPE_4BYTE_ABGR_PRE * @see java.awt.image.BufferedImage#TYPE_USHORT_565_RGB * @see java.awt.image.BufferedImage#TYPE_USHORT_555_RGB * @see java.awt.image.BufferedImage#TYPE_BYTE_GRAY * @see java.awt.image.BufferedImage#TYPE_USHORT_GRAY * @see java.awt.image.BufferedImage#TYPE_BYTE_BINARY * @see java.awt.image.BufferedImage#TYPE_BYTE_INDEXED */
public static ImageTypeSpecifier createFromBufferedImageType(int bufferedImageType) { if (bufferedImageType >= BufferedImage.TYPE_INT_RGB && bufferedImageType <= BufferedImage.TYPE_BYTE_INDEXED) { return getSpecifier(bufferedImageType); } else if (bufferedImageType == BufferedImage.TYPE_CUSTOM) { throw new IllegalArgumentException("Cannot create from TYPE_CUSTOM!"); } else { throw new IllegalArgumentException("Invalid BufferedImage type!"); } }
Returns an ImageTypeSpecifier that encodes the layout of a RenderedImage (which may be a BufferedImage).
Params:
  • image – a RenderedImage.
Throws:
Returns:an ImageTypeSpecifier with the desired characteristics.
/** * Returns an <code>ImageTypeSpecifier</code> that encodes the * layout of a <code>RenderedImage</code> (which may be a * <code>BufferedImage</code>). * * @param image a <code>RenderedImage</code>. * * @return an <code>ImageTypeSpecifier</code> with the desired * characteristics. * * @exception IllegalArgumentException if <code>image</code> is * <code>null</code>. */
public static ImageTypeSpecifier createFromRenderedImage(RenderedImage image) { if (image == null) { throw new IllegalArgumentException("image == null!"); } if (image instanceof BufferedImage) { int bufferedImageType = ((BufferedImage)image).getType(); if (bufferedImageType != BufferedImage.TYPE_CUSTOM) { return getSpecifier(bufferedImageType); } } return new ImageTypeSpecifier(image); }
Returns an int containing one of the enumerated constant values describing image formats from BufferedImage.
See Also:
Returns:an int representing a BufferedImage type.
/** * Returns an int containing one of the enumerated constant values * describing image formats from <code>BufferedImage</code>. * * @return an <code>int</code> representing a * <code>BufferedImage</code> type. * * @see java.awt.image.BufferedImage * @see java.awt.image.BufferedImage#TYPE_CUSTOM * @see java.awt.image.BufferedImage#TYPE_INT_RGB * @see java.awt.image.BufferedImage#TYPE_INT_ARGB * @see java.awt.image.BufferedImage#TYPE_INT_ARGB_PRE * @see java.awt.image.BufferedImage#TYPE_INT_BGR * @see java.awt.image.BufferedImage#TYPE_3BYTE_BGR * @see java.awt.image.BufferedImage#TYPE_4BYTE_ABGR * @see java.awt.image.BufferedImage#TYPE_4BYTE_ABGR_PRE * @see java.awt.image.BufferedImage#TYPE_USHORT_565_RGB * @see java.awt.image.BufferedImage#TYPE_USHORT_555_RGB * @see java.awt.image.BufferedImage#TYPE_BYTE_GRAY * @see java.awt.image.BufferedImage#TYPE_USHORT_GRAY * @see java.awt.image.BufferedImage#TYPE_BYTE_BINARY * @see java.awt.image.BufferedImage#TYPE_BYTE_INDEXED */
public int getBufferedImageType() { BufferedImage bi = createBufferedImage(1, 1); return bi.getType(); }
Return the number of color components specified by this object. This is the same value as returned by ColorModel.getNumComponents
Returns:the number of components in the image.
/** * Return the number of color components * specified by this object. This is the same value as returned by * <code>ColorModel.getNumComponents</code> * * @return the number of components in the image. */
public int getNumComponents() { return colorModel.getNumComponents(); }
Return the number of bands specified by this object. This is the same value as returned by SampleModel.getNumBands
Returns:the number of bands in the image.
/** * Return the number of bands * specified by this object. This is the same value as returned by * <code>SampleModel.getNumBands</code> * * @return the number of bands in the image. */
public int getNumBands() { return sampleModel.getNumBands(); }
Return the number of bits used to represent samples of the given band.
Params:
  • band – the index of the band to be queried, as an int.
Throws:
Returns:an int specifying a number of bits.
/** * Return the number of bits used to represent samples of the given band. * * @param band the index of the band to be queried, as an * int. * * @return an int specifying a number of bits. * * @exception IllegalArgumentException if <code>band</code> is * negative or greater than the largest band index. */
public int getBitsPerBand(int band) { if (band < 0 | band >= getNumBands()) { throw new IllegalArgumentException("band out of range!"); } return sampleModel.getSampleSize(band); }
Returns a SampleModel based on the settings encapsulated within this object. The width and height of the SampleModel will be set to arbitrary values.
Returns:a SampleModel with arbitrary dimensions.
/** * Returns a <code>SampleModel</code> based on the settings * encapsulated within this object. The width and height of the * <code>SampleModel</code> will be set to arbitrary values. * * @return a <code>SampleModel</code> with arbitrary dimensions. */
public SampleModel getSampleModel() { return sampleModel; }
Returns a SampleModel based on the settings encapsulated within this object. The width and height of the SampleModel will be set to the supplied values.
Params:
  • width – the desired width of the returned SampleModel.
  • height – the desired height of the returned SampleModel.
Throws:
Returns:a SampleModel with the given dimensions.
/** * Returns a <code>SampleModel</code> based on the settings * encapsulated within this object. The width and height of the * <code>SampleModel</code> will be set to the supplied values. * * @param width the desired width of the returned <code>SampleModel</code>. * @param height the desired height of the returned * <code>SampleModel</code>. * * @return a <code>SampleModel</code> with the given dimensions. * * @exception IllegalArgumentException if either <code>width</code> or * <code>height</code> are negative or zero. * @exception IllegalArgumentException if the product of * <code>width</code> and <code>height</code> is greater than * <code>Integer.MAX_VALUE</code> */
public SampleModel getSampleModel(int width, int height) { if ((long)width*height > Integer.MAX_VALUE) { throw new IllegalArgumentException ("width*height > Integer.MAX_VALUE!"); } return sampleModel.createCompatibleSampleModel(width, height); }
Returns the ColorModel specified by this object.
Returns:a ColorModel.
/** * Returns the <code>ColorModel</code> specified by this object. * * @return a <code>ColorModel</code>. */
public ColorModel getColorModel() { return colorModel; }
Creates a BufferedImage with a given width and height according to the specification embodied in this object.
Params:
  • width – the desired width of the returned BufferedImage.
  • height – the desired height of the returned BufferedImage.
Throws:
  • IllegalArgumentException – if either width or height are negative or zero.
  • IllegalArgumentException – if the product of width and height is greater than Integer.MAX_VALUE, or if the number of array elements needed to store the image is greater than Integer.MAX_VALUE.
Returns:a new BufferedImage
/** * Creates a <code>BufferedImage</code> with a given width and * height according to the specification embodied in this object. * * @param width the desired width of the returned * <code>BufferedImage</code>. * @param height the desired height of the returned * <code>BufferedImage</code>. * * @return a new <code>BufferedImage</code> * * @exception IllegalArgumentException if either <code>width</code> or * <code>height</code> are negative or zero. * @exception IllegalArgumentException if the product of * <code>width</code> and <code>height</code> is greater than * <code>Integer.MAX_VALUE</code>, or if the number of array * elements needed to store the image is greater than * <code>Integer.MAX_VALUE</code>. */
public BufferedImage createBufferedImage(int width, int height) { try { SampleModel sampleModel = getSampleModel(width, height); WritableRaster raster = Raster.createWritableRaster(sampleModel, new Point(0, 0)); return new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), new Hashtable()); } catch (NegativeArraySizeException e) { // Exception most likely thrown from a DataBuffer constructor throw new IllegalArgumentException ("Array size > Integer.MAX_VALUE!"); } }
Returns true if the given Object is an ImageTypeSpecifier and has a SampleModel and ColorModel that are equal to those of this object.
Params:
  • o – the Object to be compared for equality.
Returns:true if the given object is an equivalent ImageTypeSpecifier.
/** * Returns <code>true</code> if the given <code>Object</code> is * an <code>ImageTypeSpecifier</code> and has a * <code>SampleModel</code> and <code>ColorModel</code> that are * equal to those of this object. * * @param o the <code>Object</code> to be compared for equality. * * @return <code>true</code> if the given object is an equivalent * <code>ImageTypeSpecifier</code>. */
public boolean equals(Object o) { if ((o == null) || !(o instanceof ImageTypeSpecifier)) { return false; } ImageTypeSpecifier that = (ImageTypeSpecifier)o; return (colorModel.equals(that.colorModel)) && (sampleModel.equals(that.sampleModel)); }
Returns the hash code for this ImageTypeSpecifier.
Returns:a hash code for this ImageTypeSpecifier
/** * Returns the hash code for this ImageTypeSpecifier. * * @return a hash code for this ImageTypeSpecifier */
public int hashCode() { return (9 * colorModel.hashCode()) + (14 * sampleModel.hashCode()); } private static ImageTypeSpecifier getSpecifier(int type) { if (BISpecifier[type] == null) { BISpecifier[type] = createSpecifier(type); } return BISpecifier[type]; } private static ImageTypeSpecifier createSpecifier(int type) { switch(type) { case BufferedImage.TYPE_INT_RGB: return createPacked(sRGB, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x0, DataBuffer.TYPE_INT, false); case BufferedImage.TYPE_INT_ARGB: return createPacked(sRGB, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000, DataBuffer.TYPE_INT, false); case BufferedImage.TYPE_INT_ARGB_PRE: return createPacked(sRGB, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000, DataBuffer.TYPE_INT, true); case BufferedImage.TYPE_INT_BGR: return createPacked(sRGB, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x0, DataBuffer.TYPE_INT, false); case BufferedImage.TYPE_3BYTE_BGR: return createInterleaved(sRGB, new int[] { 2, 1, 0 }, DataBuffer.TYPE_BYTE, false, false); case BufferedImage.TYPE_4BYTE_ABGR: return createInterleaved(sRGB, new int[] { 3, 2, 1, 0 }, DataBuffer.TYPE_BYTE, true, false); case BufferedImage.TYPE_4BYTE_ABGR_PRE: return createInterleaved(sRGB, new int[] { 3, 2, 1, 0 }, DataBuffer.TYPE_BYTE, true, true); case BufferedImage.TYPE_USHORT_565_RGB: return createPacked(sRGB, 0xF800, 0x07E0, 0x001F, 0x0, DataBuffer.TYPE_USHORT, false); case BufferedImage.TYPE_USHORT_555_RGB: return createPacked(sRGB, 0x7C00, 0x03E0, 0x001F, 0x0, DataBuffer.TYPE_USHORT, false); case BufferedImage.TYPE_BYTE_GRAY: return createGrayscale(8, DataBuffer.TYPE_BYTE, false); case BufferedImage.TYPE_USHORT_GRAY: return createGrayscale(16, DataBuffer.TYPE_USHORT, false); case BufferedImage.TYPE_BYTE_BINARY: return createGrayscale(1, DataBuffer.TYPE_BYTE, false); case BufferedImage.TYPE_BYTE_INDEXED: { BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_INDEXED); IndexColorModel icm = (IndexColorModel)bi.getColorModel(); int mapSize = icm.getMapSize(); byte[] redLUT = new byte[mapSize]; byte[] greenLUT = new byte[mapSize]; byte[] blueLUT = new byte[mapSize]; byte[] alphaLUT = new byte[mapSize]; icm.getReds(redLUT); icm.getGreens(greenLUT); icm.getBlues(blueLUT); icm.getAlphas(alphaLUT); return createIndexed(redLUT, greenLUT, blueLUT, alphaLUT, 8, DataBuffer.TYPE_BYTE); } default: throw new IllegalArgumentException("Invalid BufferedImage type!"); } } }