/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
//import javax.imageio.ImageTypeSpecifier;
public class ImageUtil {
/* XXX testing only
public static void main(String[] args) {
ImageTypeSpecifier bilevel =
ImageTypeSpecifier.createIndexed(new byte[] {(byte)0, (byte)255},
new byte[] {(byte)0, (byte)255},
new byte[] {(byte)0, (byte)255},
null, 1,
DataBuffer.TYPE_BYTE);
ImageTypeSpecifier gray =
ImageTypeSpecifier.createGrayscale(8, DataBuffer.TYPE_BYTE, false);
ImageTypeSpecifier grayAlpha =
ImageTypeSpecifier.createGrayscale(8, DataBuffer.TYPE_BYTE, false,
false);
ImageTypeSpecifier rgb =
ImageTypeSpecifier.createInterleaved(ColorSpace.getInstance(ColorSpace.CS_sRGB),
new int[] {0, 1, 2},
DataBuffer.TYPE_BYTE,
false,
false);
ImageTypeSpecifier rgba =
ImageTypeSpecifier.createInterleaved(ColorSpace.getInstance(ColorSpace.CS_sRGB),
new int[] {0, 1, 2, 3},
DataBuffer.TYPE_BYTE,
true,
false);
ImageTypeSpecifier packed =
ImageTypeSpecifier.createPacked(ColorSpace.getInstance(ColorSpace.CS_sRGB),
0xff000000,
0x00ff0000,
0x0000ff00,
0x000000ff,
DataBuffer.TYPE_BYTE,
false);
SampleModel bandedSM =
new java.awt.image.BandedSampleModel(DataBuffer.TYPE_BYTE,
1, 1, 15);
System.out.println(createColorModel(bilevel.getSampleModel()));
System.out.println(createColorModel(gray.getSampleModel()));
System.out.println(createColorModel(grayAlpha.getSampleModel()));
System.out.println(createColorModel(rgb.getSampleModel()));
System.out.println(createColorModel(rgba.getSampleModel()));
System.out.println(createColorModel(packed.getSampleModel()));
System.out.println(createColorModel(bandedSM));
}
*/
/**
* Creates a <code>ColorModel</code> that may be used with the
* specified <code>SampleModel</code>. If a suitable
* <code>ColorModel</code> cannot be found, this method returns
* <code>null</code>.
*
* <p> Suitable <code>ColorModel</code>s are guaranteed to exist
* for all instances of <code>ComponentSampleModel</code>.
* For 1- and 3- banded <code>SampleModel</code>s, the returned
* <code>ColorModel</code> will be opaque. For 2- and 4-banded
* <code>SampleModel</code>s, the output will use alpha transparency
* which is not premultiplied. 1- and 2-banded data will use a
* grayscale <code>ColorSpace</code>, and 3- and 4-banded data a sRGB
* <code>ColorSpace</code>. Data with 5 or more bands will have a
* <code>BogusColorSpace</code>.</p>
*
* <p>An instance of <code>DirectColorModel</code> will be created for
* instances of <code>SinglePixelPackedSampleModel</code> with no more
* than 4 bands.</p>
*
* <p>An instance of <code>IndexColorModel</code> will be created for
* instances of <code>MultiPixelPackedSampleModel</code>. The colormap
* will be a grayscale ramp with <code>1 << numberOfBits</code>
* entries ranging from zero to at most 255.</p>
*
* @return An instance of <code>ColorModel</code> that is suitable for
* the supplied <code>SampleModel</code>, or <code>null</code>.
*
* @throws IllegalArgumentException If <code>sampleModel</code> is
* <code>null</code>.
*/
// Check the parameter.
if(sampleModel == null) {
throw new IllegalArgumentException("sampleModel == null!");
}
// Get the data type.
// Check the data type
switch(dataType) {
case DataBuffer.TYPE_BYTE:
case DataBuffer.TYPE_USHORT:
case DataBuffer.TYPE_SHORT:
case DataBuffer.TYPE_INT:
case DataBuffer.TYPE_FLOAT:
case DataBuffer.TYPE_DOUBLE:
break;
default:
// Return null for other types.
return null;
}
// The return variable.
// Get the sample size.
// Create a Component ColorModel.
if(sampleModel instanceof ComponentSampleModel) {
// Get the number of bands.
// Determine the color space.
if(numBands <= 2) {
} else if(numBands <= 4) {
} else {
}
boolean isAlphaPremultiplied = false;
int transparency = hasAlpha ?
dataType);
sampleModel instanceof SinglePixelPackedSampleModel) {
int rmask = 0;
int gmask = 0;
int bmask = 0;
int amask = 0;
if (numBands <= 2) {
if (numBands == 2) {
}
} else {
if (numBands == 4) {
}
}
int bits = 0;
bits += sampleSize[i];
}
} else if(sampleModel instanceof MultiPixelPackedSampleModel) {
// Load the colormap with a ramp.
byte[] map = new byte[numEntries];
for (int i = 0; i < numEntries; i++) {
}
}
return colorModel;
}
/**
* For the case of binary data (<code>isBinary()</code> returns
* <code>true</code>), return the binary data as a packed byte array.
* The data will be packed as eight bits per byte with no bit offset,
* i.e., the first bit in each image line will be the left-most of the
* first byte of the line. The line stride in bytes will be
* <code>(int)((getWidth()+7)/8)</code>. The length of the returned
* array will be the line stride multiplied by <code>getHeight()</code>
*
* @return the binary data as a packed array of bytes with zero offset
* of <code>null</code> if the data are not binary.
* @throws IllegalArgumentException if <code>isBinary()</code> returns
* <code>false</code> with the <code>SampleModel</code> of the
* supplied <code>Raster</code> as argument.
*/
}
if(dataBuffer instanceof DataBufferByte &&
numBytesPerRow == lineStride &&
}
int b = 0;
if(bitOffset == 0) {
if(dataBuffer instanceof DataBufferByte) {
int stride = numBytesPerRow;
int offset = 0;
for(int y = 0; y < rectHeight; y++) {
stride);
eltOffset += lineStride;
}
} else if(dataBuffer instanceof DataBufferShort ||
dataBuffer instanceof DataBufferUShort) {
for(int y = 0; y < rectHeight; y++) {
int xRemaining = rectWidth;
int i = eltOffset;
while(xRemaining > 8) {
xRemaining -= 16;
}
if(xRemaining > 0) {
}
eltOffset += lineStride;
}
} else if(dataBuffer instanceof DataBufferInt) {
for(int y = 0; y < rectHeight; y++) {
int xRemaining = rectWidth;
int i = eltOffset;
while(xRemaining > 24) {
xRemaining -= 32;
}
int shift = 24;
while(xRemaining > 0) {
binaryDataArray[b++] =
shift -= 8;
xRemaining -= 8;
}
eltOffset += lineStride;
}
}
} else { // bitOffset != 0
if(dataBuffer instanceof DataBufferByte) {
int stride = numBytesPerRow;
int offset = 0;
for(int y = 0; y < rectHeight; y++) {
stride);
eltOffset += lineStride;
}
} else { // bitOffset % 8 != 0
for(int y = 0; y < rectHeight; y++) {
int i = eltOffset;
int xRemaining = rectWidth;
while(xRemaining > 0) {
if(xRemaining > rightShift) {
binaryDataArray[b++] =
} else {
binaryDataArray[b++] =
}
xRemaining -= 8;
}
eltOffset += lineStride;
}
}
} else if(dataBuffer instanceof DataBufferShort ||
dataBuffer instanceof DataBufferUShort) {
for(int y = 0; y < rectHeight; y++) {
if(mod <= 8) {
} else {
binaryDataArray[b++] =
}
}
eltOffset += lineStride;
}
} else if(dataBuffer instanceof DataBufferInt) {
for(int y = 0; y < rectHeight; y++) {
if(mod <= 24) {
binaryDataArray[b++] =
} else {
binaryDataArray[b++] =
}
}
eltOffset += lineStride;
}
}
}
return binaryDataArray;
}
/**
* Returns the binary data unpacked into an array of bytes.
* The line stride will be the width of the <code>Raster</code>.
*
* @throws IllegalArgumentException if <code>isBinary()</code> returns
* <code>false</code> with the <code>SampleModel</code> of the
* supplied <code>Raster</code> as argument.
*/
}
int k = 0;
if(dataBuffer instanceof DataBufferByte) {
bdata[k++] =
bOffset++;
}
eltOffset += lineStride;
}
} else if(dataBuffer instanceof DataBufferShort ||
dataBuffer instanceof DataBufferUShort) {
bdata[k++] =
0x0000001);
bOffset++;
}
eltOffset += lineStride;
}
} else if(dataBuffer instanceof DataBufferInt) {
bdata[k++] =
0x0000001);
bOffset++;
}
eltOffset += lineStride;
}
}
return bdata;
}
/**
* Sets the supplied <code>Raster</code>'s data from an array
* of packed binary data of the form returned by
* <code>getPackedBinaryData()</code>.
*
* @throws IllegalArgumentException if <code>isBinary()</code> returns
* <code>false</code> with the <code>SampleModel</code> of the
* supplied <code>Raster</code> as argument.
*/
}
int b = 0;
if(bitOffset == 0) {
if(dataBuffer instanceof DataBufferByte) {
if(data == binaryDataArray) {
// Optimal case: simply return.
return;
}
int offset = 0;
for(int y = 0; y < rectHeight; y++) {
stride);
eltOffset += lineStride;
}
} else if(dataBuffer instanceof DataBufferShort ||
dataBuffer instanceof DataBufferUShort) {
for(int y = 0; y < rectHeight; y++) {
int xRemaining = rectWidth;
int i = eltOffset;
while(xRemaining > 8) {
data[i++] =
(binaryDataArray[b++] & 0xFF));
xRemaining -= 16;
}
if(xRemaining > 0) {
data[i++] =
}
eltOffset += lineStride;
}
} else if(dataBuffer instanceof DataBufferInt) {
for(int y = 0; y < rectHeight; y++) {
int xRemaining = rectWidth;
int i = eltOffset;
while(xRemaining > 24) {
data[i++] =
(binaryDataArray[b++] & 0xFF));
xRemaining -= 32;
}
int shift = 24;
while(xRemaining > 0) {
data[i] |=
shift -= 8;
xRemaining -= 8;
}
eltOffset += lineStride;
}
}
} else { // bitOffset != 0
int offset = 0;
if(dataBuffer instanceof DataBufferByte) {
for(int y = 0; y < rectHeight; y++) {
stride);
eltOffset += lineStride;
}
} else { // bitOffset % 8 != 0
for(int y = 0; y < rectHeight; y++) {
int i = eltOffset;
int xRemaining = rectWidth;
while(xRemaining > 0) {
byte datum = binaryDataArray[b++];
if (xRemaining > leftShift8) {
// when all the bits in this BYTE will be set
// into the data buffer.
} else if (xRemaining > leftShift) {
// All the "leftShift" high bits will be set
// into the data buffer. But not all the
// "rightShift" low bits will be set.
i++;
data[i] =
}
else {
// Less than "leftShift" high bits will be set.
data[i] =
}
xRemaining -= 8;
}
eltOffset += lineStride;
}
}
} else if(dataBuffer instanceof DataBufferShort ||
dataBuffer instanceof DataBufferUShort) {
for(int y = 0; y < rectHeight; y++) {
int xRemaining = rectWidth;
for(int x = 0; x < rectWidth;
if(mod <= 8) {
// This BYTE is set into one SHORT
if (xRemaining < 8) {
// Mask the bits to be set.
}
} else if (xRemaining > leftShift16) {
// This BYTE will be set into two SHORTs
data[++i] =
} else if (xRemaining > leftShift) {
// This BYTE will be set into two SHORTs;
// But not all the low bits will be set into SHORT
i++;
data[i] =
} else {
// Only some of the high bits will be set into
// SHORTs
}
}
eltOffset += lineStride;
}
} else if(dataBuffer instanceof DataBufferInt) {
for(int y = 0; y < rectHeight; y++) {
int xRemaining = rectWidth;
for(int x = 0; x < rectWidth;
if(mod <= 24) {
// This BYTE is set into one INT
if (xRemaining < 8) {
// Mask the bits to be set.
}
} else if (xRemaining > leftShift32) {
// All the bits of this BYTE will be set into two INTs
} else if (xRemaining > leftShift) {
// This BYTE will be set into two INTs;
// But not all the low bits will be set into INT
i++;
} else {
// Only some of the high bits will be set into INT
}
}
eltOffset += lineStride;
}
}
}
}
/**
* Copies data into the packed array of the <code>Raster</code>
* from an array of unpacked data of the form returned by
* <code>getUnpackedBinaryData()</code>.
*
* <p> If the data are binary, then the target bit will be set if
* and only if the corresponding byte is non-zero.
*
* @throws IllegalArgumentException if <code>isBinary()</code> returns
* <code>false</code> with the <code>SampleModel</code> of the
* supplied <code>Raster</code> as argument.
*/
}
int k = 0;
if(dataBuffer instanceof DataBufferByte) {
for(int y = 0; y < rectHeight; y++) {
for(int x = 0; x < rectWidth; x++) {
if(bdata[k++] != (byte)0) {
}
bOffset++;
}
eltOffset += lineStride;
}
} else if(dataBuffer instanceof DataBufferShort ||
dataBuffer instanceof DataBufferUShort) {
for(int y = 0; y < rectHeight; y++) {
for(int x = 0; x < rectWidth; x++) {
if(bdata[k++] != (byte)0) {
(short)(0x00000001 <<
}
bOffset++;
}
eltOffset += lineStride;
}
} else if(dataBuffer instanceof DataBufferInt) {
for(int y = 0; y < rectHeight; y++) {
for(int x = 0; x < rectWidth; x++) {
if(bdata[k++] != (byte)0) {
(int)(0x00000001 <<
}
bOffset++;
}
eltOffset += lineStride;
}
}
}
return sm instanceof MultiPixelPackedSampleModel &&
}
if(sampleModel == null) {
}
return null;
}
if (sampleModel instanceof ComponentSampleModel) {
//dataType == DataBuffer.TYPE_SHORT ||
return null;
}
if (colorSpace == null)
numBands <= 2 ?
int transparency = useAlpha ?
boolean premultiplied = false;
for (int i = 0; i < numBands; i++) {
bits[i] = dataTypeSize;
}
bits,
dataType);
} else if (sampleModel instanceof SinglePixelPackedSampleModel) {
int rmask = 0;
int gmask = 0;
int bmask = 0;
int amask = 0;
if (numBands <= 2) {
if (numBands == 2) {
}
} else {
if (numBands == 4) {
}
}
int bits = 0;
bits += sampleSize[i];
}
if (colorSpace == null)
false,
} else if (sampleModel instanceof MultiPixelPackedSampleModel) {
int bits =
for (int i = 0; i < size; i++)
}
return colorModel;
}
if (sm instanceof MultiPixelPackedSampleModel) {
} else if (sm instanceof ComponentSampleModel) {
} else if (sm instanceof SinglePixelPackedSampleModel) {
return elementSize;
}
}
if (sm instanceof MultiPixelPackedSampleModel) {
} else if (sm instanceof ComponentSampleModel) {
long size = 0;
if (maxBandOff >= 0)
if (pixelStride > 0)
if (scanlineStride > 0)
} else if (sm instanceof SinglePixelPackedSampleModel) {
}
return 0;
}
if (sm instanceof ComponentSampleModel) {
if (pixelStride > 0)
if (scanlineStride > 0)
} else
return getTileSize(sm);
}
/**
* Tests whether the color indices represent a gray-scale image.
*
* @param r The red channel color indices.
* @param g The green channel color indices.
* @param b The blue channel color indices.
* @return If all the indices have 256 entries, and are identical mappings,
* return <code>true</code>; otherwise, return <code>false</code>.
*/
public static boolean isIndicesForGrayscale(byte[] r, byte[] g, byte[] b) {
return false;
if (size != 256)
return false;
for (int i = 0; i < size; i++) {
byte temp = (byte) i;
return false;
}
return true;
}
/** Converts the provided object to <code>String</code> */
return "";
String s = "";
if (obj instanceof byte[]) {
s += bArray[i] + " ";
return s;
}
if (obj instanceof int[]) {
s += iArray[i] + " " ;
return s;
}
if (obj instanceof short[]) {
s += sArray[i] + " " ;
return s;
}
}
/** Checks that the provided <code>ImageWriter</code> can encode
* the provided <code>ImageTypeSpecifier</code> or not. If not, an
* <code>IIOException</code> will be thrown.
* @param writer The provided <code>ImageWriter</code>.
* @param type The image to be tested.
* @throws IIOException If the writer cannot encoded the provided image.
*/
throws IIOException {
}
}
/** Checks that the provided <code>ImageWriter</code> can encode
* the provided <code>ColorModel</code> and <code>SampleModel</code>.
* If not, an <code>IIOException</code> will be thrown.
* @param writer The provided <code>ImageWriter</code>.
* @param colorModel The provided <code>ColorModel</code>.
* @param sampleModel The provided <code>SampleModel</code>.
* @throws IIOException If the writer cannot encoded the provided image.
*/
throws IIOException {
}
/**
* Returns whether the image has contiguous data across rows.
*/
if(image instanceof BufferedImage) {
} else {
}
if (sm instanceof ComponentSampleModel) {
// Ensure image rows samples are stored contiguously
// in a single bank.
return false;
}
if (bandOffsets[i] != i) {
return false;
}
}
if (bankIndices[i] != 0) {
return false;
}
}
return true;
}
// Otherwise true if and only if it's a bilevel image with
// a MultiPixelPackedSampleModel, 1 bit per pixel, and 1 bit
// pixel stride.
}
}