| /* |
| * 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); |
| } |
| } |