blob: a16f37f1236503c2fa140b9a2733aee2837c2615 [file] [log] [blame]
/*
* Copyright (c) 2007, 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.
*
* 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 java.awt.Color;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DirectColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ImageFactory {
public static int WIDTH = 256;
public static int HEIGHT = 256;
final static int aMask = 0xFF000000;
final static int rMask = 0x00FF0000;
final static int gMask = 0x0000FF00;
final static int bMask = 0x000000FF;
final static int r555Mask = 0x7c00;
final static int g555Mask = 0x3e0;
final static int b555Mask = 0x1f;
final static int r565Mask = 0xf800;
final static int g565Mask = 0x7e0;
final static int b565Mask = 0x1f;
final static int rShift = 16;
final static int gShift = 8;
final static int bShift = 0;
public static BufferedImage createCCMImage(int cs, int dataType)
{
ColorSpace cSpace = ColorSpace.getInstance(cs);
ComponentColorModel ccm = null;
if (dataType == DataBuffer.TYPE_INT)
{
ccm = new ComponentColorModel(cSpace,
((cs == ColorSpace.CS_GRAY)?
new int[] {8}: new int[] {8,8,8}),
false, false, Transparency.OPAQUE, dataType);
} else {
ccm = new ComponentColorModel(
cSpace, false, false, Transparency.OPAQUE, dataType);
}
SampleModel sm = ccm.createCompatibleSampleModel(WIDTH, HEIGHT);
WritableRaster raster = ccm.createCompatibleWritableRaster(WIDTH,
HEIGHT);
DataBuffer data = raster.getDataBuffer();
fillCCM(data, sm, cSpace);
return new BufferedImage(ccm, raster, false, null);
}
public static BufferedImage createDCMImage(int type, int cs) {
if (type == BufferedImage.TYPE_INT_RGB && cs == ColorSpace.CS_sRGB) {
BufferedImage image = new BufferedImage(WIDTH, HEIGHT,
BufferedImage.TYPE_INT_RGB);
DataBuffer data = image.getData().getDataBuffer();
fill(image);
return image;
}
ColorSpace cSpace = ColorSpace.getInstance(cs);
DirectColorModel dcm = null;
switch(type) {
case BufferedImage.TYPE_INT_ARGB:
dcm = new DirectColorModel(cSpace, 32, rMask, gMask,
bMask, aMask, false,
DataBuffer.TYPE_INT);
break;
case BufferedImage.TYPE_INT_RGB:
dcm = new DirectColorModel(cSpace, 24, rMask, gMask,
bMask, 0, false,
DataBuffer.TYPE_INT);
break;
case BufferedImage.TYPE_INT_BGR:
dcm = new DirectColorModel(cSpace, 24, rMask, gMask,
bMask, 0, false,
DataBuffer.TYPE_INT);
break;
case BufferedImage.TYPE_USHORT_555_RGB:
dcm = new DirectColorModel(cSpace, 15, r555Mask, g555Mask,
b555Mask, 0, false,
DataBuffer.TYPE_USHORT);
break;
case BufferedImage.TYPE_USHORT_565_RGB:
dcm = new DirectColorModel(cSpace, 16, r565Mask, g565Mask,
b565Mask, 0, false,
DataBuffer.TYPE_USHORT);
break;
}
SampleModel sm = dcm.createCompatibleSampleModel(WIDTH, HEIGHT);
WritableRaster raster = dcm.createCompatibleWritableRaster(WIDTH,
HEIGHT);
switch(type) {
case BufferedImage.TYPE_INT_ARGB:
fillDCM(raster.getDataBuffer(), sm, cSpace.getType());
break;
case BufferedImage.TYPE_INT_RGB:
fillDCM(raster.getDataBuffer(), sm, cSpace.getType());
break;
case BufferedImage.TYPE_INT_BGR:
fillDCM(raster.getDataBuffer(), sm, cSpace.getType());
break;
case BufferedImage.TYPE_USHORT_555_RGB:
fillDCM(raster.getDataBuffer(), sm, cSpace.getType(), 5, 5, 5);
break;
case BufferedImage.TYPE_USHORT_565_RGB:
fillDCM(raster.getDataBuffer(), sm, cSpace.getType(), 5, 6, 5);
break;
}
return new BufferedImage(dcm, raster, false, null);
}
public static void fill(BufferedImage image) {
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
image.setRGB(i,j,0xFF000000 | (i << 16) | (j << 8) |
((i + j)>>1));
}
}
}
public static void fillCCM(DataBuffer data, SampleModel sm, ColorSpace cs) {
switch (cs.getType()) {
case ColorSpace.TYPE_RGB:
case ColorSpace.TYPE_XYZ:
case ColorSpace.TYPE_3CLR:
if (data.getDataType() == DataBuffer.TYPE_BYTE ||
data.getDataType() == DataBuffer.TYPE_INT)
{
int [] pixel = new int[3];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = i;
pixel[1] = j;
pixel[2] = ((i + j)>>1);
sm.setPixel(i, j, pixel, data);
}
}
} else if (data.getDataType() == DataBuffer.TYPE_SHORT) {
int [] pixel = new int[3];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = (i<<7);
pixel[1] = (j<<7);
pixel[2] = ((i + j)<<6);
sm.setPixel(i, j, pixel, data);
}
}
} else if (data.getDataType() == DataBuffer.TYPE_USHORT) {
int [] pixel = new int[3];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = (i<<8);
pixel[1] = (j<<8);
pixel[2] = ((i + j)<<7);
sm.setPixel(i, j, pixel, data);
}
}
} else if (data.getDataType() == DataBuffer.TYPE_DOUBLE) {
double [] pixel = new double [3];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = (i/255.0)*(cs.getMaxValue(0) -
cs.getMinValue(0)) +
cs.getMinValue(0);
pixel[1] = (j/255.0)*(cs.getMaxValue(1) -
cs.getMinValue(1)) +
cs.getMinValue(1);
pixel[2] = (((i + j)>>1)/255.0)*(cs.getMaxValue(2) -
cs.getMinValue(2))+
cs.getMinValue(2);
sm.setPixel(i, j, pixel, data);
}
}
} else if (data.getDataType() == DataBuffer.TYPE_FLOAT) {
float [] pixel = new float [3];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = (i/255.0f)*(cs.getMaxValue(0) -
cs.getMinValue(0)) +
cs.getMinValue(0);
pixel[1] = (j/255.0f)*(cs.getMaxValue(1) -
cs.getMinValue(1)) +
cs.getMinValue(1);
pixel[2] = (((i + j)>>1)/255.0f)*(cs.getMaxValue(2)-
cs.getMinValue(2))
+ cs.getMinValue(2);
sm.setPixel(i, j, pixel, data);
}
}
} else {
throw new RuntimeException("Unsupported DataBuffer type");
}
break;
case ColorSpace.TYPE_GRAY:
if (data.getDataType() == DataBuffer.TYPE_BYTE ||
data.getDataType() == DataBuffer.TYPE_INT) {
int [] pixel = new int[1];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = i;
sm.setPixel(i, j, pixel, data);
}
}
} else if (data.getDataType() == DataBuffer.TYPE_SHORT) {
int [] pixel = new int[1];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = i << 7;
sm.setPixel(i, j, pixel, data);
}
}
} else if (data.getDataType() == DataBuffer.TYPE_USHORT) {
int [] pixel = new int[1];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = i << 8;
sm.setPixel(i, j, pixel, data);
}
}
} else if (data.getDataType() == DataBuffer.TYPE_DOUBLE) {
double [] pixel = new double[1];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = (i/255.0)*(cs.getMaxValue(0) -
cs.getMinValue(0)) +
cs.getMinValue(0);;
sm.setPixel(i, j, pixel, data);
}
}
} else if (data.getDataType() == DataBuffer.TYPE_FLOAT) {
float [] pixel = new float[1];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = (i/255.0f)*(cs.getMaxValue(0) -
cs.getMinValue(0)) +
cs.getMinValue(0);;
sm.setPixel(i, j, pixel, data);
}
}
} else {
throw new RuntimeException("Unsupported DataBuffer type");
}
break;
}
}
public static void fillDCM(DataBuffer data, SampleModel sm, int csType,
int c1Bits, int c2Bits, int c3Bits)
{
int [] pixel;
pixel = new int[4];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = i >> (8 - c1Bits);
pixel[1] = j >> (8 - c2Bits);
pixel[2] = ((i + j)>>1) >> (8 - c3Bits);
pixel[3] = 0xFF;
sm.setPixel(i, j, pixel, data);
}
}
}
public static void fillDCM(DataBuffer data, SampleModel sm, int csType) {
fillDCM(data, sm, csType, 8, 8, 8);
}
public static BufferedImage createDstImage(int type) {
return new BufferedImage(WIDTH, HEIGHT, type);
}
}