feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
221
jdkSrc/jdk8/sun/java2d/cmm/lcms/LCMS.java
Normal file
221
jdkSrc/jdk8/sun/java2d/cmm/lcms/LCMS.java
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2013, 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 sun.java2d.cmm.lcms;
|
||||
|
||||
import java.awt.color.CMMException;
|
||||
import java.awt.color.ICC_Profile;
|
||||
import sun.java2d.cmm.ColorTransform;
|
||||
import sun.java2d.cmm.PCMM;
|
||||
import sun.java2d.cmm.Profile;
|
||||
import sun.java2d.cmm.lcms.LCMSProfile.TagData;
|
||||
|
||||
public class LCMS implements PCMM {
|
||||
|
||||
/* methods invoked from ICC_Profile */
|
||||
@Override
|
||||
public Profile loadProfile(byte[] data) {
|
||||
final Object disposerRef = new Object();
|
||||
|
||||
final long ptr = loadProfileNative(data, disposerRef);
|
||||
|
||||
if (ptr != 0L) {
|
||||
return new LCMSProfile(ptr, disposerRef);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private native long loadProfileNative(byte[] data, Object ref);
|
||||
|
||||
private LCMSProfile getLcmsProfile(Profile p) {
|
||||
if (p instanceof LCMSProfile) {
|
||||
return (LCMSProfile)p;
|
||||
}
|
||||
throw new CMMException("Invalid profile: " + p);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void freeProfile(Profile p) {
|
||||
// we use disposer, so this method does nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProfileSize(final Profile p) {
|
||||
synchronized (p) {
|
||||
return getProfileSizeNative(getLcmsProfile(p).getLcmsPtr());
|
||||
}
|
||||
}
|
||||
|
||||
private native int getProfileSizeNative(long ptr);
|
||||
|
||||
@Override
|
||||
public void getProfileData(final Profile p, byte[] data) {
|
||||
synchronized (p) {
|
||||
getProfileDataNative(getLcmsProfile(p).getLcmsPtr(), data);
|
||||
}
|
||||
}
|
||||
|
||||
private native void getProfileDataNative(long ptr, byte[] data);
|
||||
|
||||
@Override
|
||||
public int getTagSize(Profile p, int tagSignature) {
|
||||
final LCMSProfile profile = getLcmsProfile(p);
|
||||
|
||||
synchronized (profile) {
|
||||
TagData t = profile.getTag(tagSignature);
|
||||
return t == null ? 0 : t.getSize();
|
||||
}
|
||||
}
|
||||
|
||||
static native byte[] getTagNative(long profileID, int signature);
|
||||
|
||||
@Override
|
||||
public void getTagData(Profile p, int tagSignature, byte[] data)
|
||||
{
|
||||
final LCMSProfile profile = getLcmsProfile(p);
|
||||
|
||||
synchronized (profile) {
|
||||
TagData t = profile.getTag(tagSignature);
|
||||
if (t != null) {
|
||||
t.copyDataTo(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setTagData(Profile p, int tagSignature, byte[] data) {
|
||||
final LCMSProfile profile = getLcmsProfile(p);
|
||||
|
||||
synchronized (profile) {
|
||||
profile.clearTagCache();
|
||||
|
||||
// Now we are going to update the profile with new tag data
|
||||
// In some cases, we may change the pointer to the native
|
||||
// profile.
|
||||
//
|
||||
// If we fail to write tag data for any reason, the old pointer
|
||||
// should be used.
|
||||
setTagDataNative(profile.getLcmsPtr(),
|
||||
tagSignature, data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes supplied data as a tag into the profile.
|
||||
* Destroys old profile, if new one was successfully
|
||||
* created.
|
||||
*
|
||||
* Returns valid pointer to new profile.
|
||||
*
|
||||
* Throws CMMException if operation fails, preserve old profile from
|
||||
* destruction.
|
||||
*/
|
||||
private native void setTagDataNative(long ptr, int tagSignature,
|
||||
byte[] data);
|
||||
|
||||
public synchronized static native LCMSProfile getProfileID(ICC_Profile profile);
|
||||
|
||||
/* Helper method used from LCMSColorTransfrom */
|
||||
static long createTransform(
|
||||
LCMSProfile[] profiles, int renderType,
|
||||
int inFormatter, boolean isInIntPacked,
|
||||
int outFormatter, boolean isOutIntPacked,
|
||||
Object disposerRef)
|
||||
{
|
||||
long[] ptrs = new long[profiles.length];
|
||||
|
||||
for (int i = 0; i < profiles.length; i++) {
|
||||
if (profiles[i] == null) throw new CMMException("Unknown profile ID");
|
||||
|
||||
ptrs[i] = profiles[i].getLcmsPtr();
|
||||
}
|
||||
|
||||
return createNativeTransform(ptrs, renderType, inFormatter,
|
||||
isInIntPacked, outFormatter, isOutIntPacked, disposerRef);
|
||||
}
|
||||
|
||||
private static native long createNativeTransform(
|
||||
long[] profileIDs, int renderType,
|
||||
int inFormatter, boolean isInIntPacked,
|
||||
int outFormatter, boolean isOutIntPacked,
|
||||
Object disposerRef);
|
||||
|
||||
/**
|
||||
* Constructs ColorTransform object corresponding to an ICC_profile
|
||||
*/
|
||||
public ColorTransform createTransform(ICC_Profile profile,
|
||||
int renderType,
|
||||
int transformType)
|
||||
{
|
||||
return new LCMSTransform(profile, renderType, renderType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an ColorTransform object from a list of ColorTransform
|
||||
* objects
|
||||
*/
|
||||
public synchronized ColorTransform createTransform(
|
||||
ColorTransform[] transforms)
|
||||
{
|
||||
return new LCMSTransform(transforms);
|
||||
}
|
||||
|
||||
/* methods invoked from LCMSTransform */
|
||||
public static native void colorConvert(LCMSTransform trans,
|
||||
LCMSImageLayout src,
|
||||
LCMSImageLayout dest);
|
||||
public static native void freeTransform(long ID);
|
||||
|
||||
public static native void initLCMS(Class Trans, Class IL, Class Pf);
|
||||
|
||||
private LCMS() {};
|
||||
|
||||
private static LCMS theLcms = null;
|
||||
|
||||
static synchronized PCMM getModule() {
|
||||
if (theLcms != null) {
|
||||
return theLcms;
|
||||
}
|
||||
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public Object run() {
|
||||
/* We need to load awt here because of usage trace and
|
||||
* disposer frameworks
|
||||
*/
|
||||
System.loadLibrary("awt");
|
||||
System.loadLibrary("lcms");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
initLCMS(LCMSTransform.class, LCMSImageLayout.class, ICC_Profile.class);
|
||||
|
||||
theLcms = new LCMS();
|
||||
|
||||
return theLcms;
|
||||
}
|
||||
}
|
||||
449
jdkSrc/jdk8/sun/java2d/cmm/lcms/LCMSImageLayout.java
Normal file
449
jdkSrc/jdk8/sun/java2d/cmm/lcms/LCMSImageLayout.java
Normal file
@@ -0,0 +1,449 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2013, 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 sun.java2d.cmm.lcms;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.ComponentSampleModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.SampleModel;
|
||||
import sun.awt.image.ByteComponentRaster;
|
||||
import sun.awt.image.ShortComponentRaster;
|
||||
import sun.awt.image.IntegerComponentRaster;
|
||||
|
||||
class LCMSImageLayout {
|
||||
|
||||
public static int BYTES_SH(int x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
public static int EXTRA_SH(int x) {
|
||||
return x << 7;
|
||||
}
|
||||
|
||||
public static int CHANNELS_SH(int x) {
|
||||
return x << 3;
|
||||
}
|
||||
public static final int SWAPFIRST = 1 << 14;
|
||||
public static final int DOSWAP = 1 << 10;
|
||||
public static final int PT_RGB_8 =
|
||||
CHANNELS_SH(3) | BYTES_SH(1);
|
||||
public static final int PT_GRAY_8 =
|
||||
CHANNELS_SH(1) | BYTES_SH(1);
|
||||
public static final int PT_GRAY_16 =
|
||||
CHANNELS_SH(1) | BYTES_SH(2);
|
||||
public static final int PT_RGBA_8 =
|
||||
EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1);
|
||||
public static final int PT_ARGB_8 =
|
||||
EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1) | SWAPFIRST;
|
||||
public static final int PT_BGR_8 =
|
||||
DOSWAP | CHANNELS_SH(3) | BYTES_SH(1);
|
||||
public static final int PT_ABGR_8 =
|
||||
DOSWAP | EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1);
|
||||
public static final int PT_BGRA_8 = EXTRA_SH(1) | CHANNELS_SH(3)
|
||||
| BYTES_SH(1) | DOSWAP | SWAPFIRST;
|
||||
public static final int DT_BYTE = 0;
|
||||
public static final int DT_SHORT = 1;
|
||||
public static final int DT_INT = 2;
|
||||
public static final int DT_DOUBLE = 3;
|
||||
boolean isIntPacked = false;
|
||||
int pixelType;
|
||||
int dataType;
|
||||
int width;
|
||||
int height;
|
||||
int nextRowOffset;
|
||||
private int nextPixelOffset;
|
||||
int offset;
|
||||
|
||||
/* This flag indicates whether the image can be processed
|
||||
* at once by doTransfrom() native call. Otherwise, the
|
||||
* image is processed scan by scan.
|
||||
*/
|
||||
private boolean imageAtOnce = false;
|
||||
Object dataArray;
|
||||
|
||||
private int dataArrayLength; /* in bytes */
|
||||
|
||||
private LCMSImageLayout(int np, int pixelType, int pixelSize)
|
||||
throws ImageLayoutException
|
||||
{
|
||||
this.pixelType = pixelType;
|
||||
width = np;
|
||||
height = 1;
|
||||
nextPixelOffset = pixelSize;
|
||||
nextRowOffset = safeMult(pixelSize, np);
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
private LCMSImageLayout(int width, int height, int pixelType,
|
||||
int pixelSize)
|
||||
throws ImageLayoutException
|
||||
{
|
||||
this.pixelType = pixelType;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
nextPixelOffset = pixelSize;
|
||||
nextRowOffset = safeMult(pixelSize, width);
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
|
||||
public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize)
|
||||
throws ImageLayoutException
|
||||
{
|
||||
this(np, pixelType, pixelSize);
|
||||
dataType = DT_BYTE;
|
||||
dataArray = data;
|
||||
dataArrayLength = data.length;
|
||||
|
||||
verify();
|
||||
}
|
||||
|
||||
public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize)
|
||||
throws ImageLayoutException
|
||||
{
|
||||
this(np, pixelType, pixelSize);
|
||||
dataType = DT_SHORT;
|
||||
dataArray = data;
|
||||
dataArrayLength = 2 * data.length;
|
||||
|
||||
verify();
|
||||
}
|
||||
|
||||
public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize)
|
||||
throws ImageLayoutException
|
||||
{
|
||||
this(np, pixelType, pixelSize);
|
||||
dataType = DT_INT;
|
||||
dataArray = data;
|
||||
dataArrayLength = 4 * data.length;
|
||||
|
||||
verify();
|
||||
}
|
||||
|
||||
public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize)
|
||||
throws ImageLayoutException
|
||||
{
|
||||
this(np, pixelType, pixelSize);
|
||||
dataType = DT_DOUBLE;
|
||||
dataArray = data;
|
||||
dataArrayLength = 8 * data.length;
|
||||
|
||||
verify();
|
||||
}
|
||||
|
||||
private LCMSImageLayout() {
|
||||
}
|
||||
|
||||
/* This method creates a layout object for given image.
|
||||
* Returns null if the image is not supported by current implementation.
|
||||
*/
|
||||
public static LCMSImageLayout createImageLayout(BufferedImage image) throws ImageLayoutException {
|
||||
LCMSImageLayout l = new LCMSImageLayout();
|
||||
|
||||
switch (image.getType()) {
|
||||
case BufferedImage.TYPE_INT_RGB:
|
||||
l.pixelType = PT_ARGB_8;
|
||||
l.isIntPacked = true;
|
||||
break;
|
||||
case BufferedImage.TYPE_INT_ARGB:
|
||||
l.pixelType = PT_ARGB_8;
|
||||
l.isIntPacked = true;
|
||||
break;
|
||||
case BufferedImage.TYPE_INT_BGR:
|
||||
l.pixelType = PT_ABGR_8;
|
||||
l.isIntPacked = true;
|
||||
break;
|
||||
case BufferedImage.TYPE_3BYTE_BGR:
|
||||
l.pixelType = PT_BGR_8;
|
||||
break;
|
||||
case BufferedImage.TYPE_4BYTE_ABGR:
|
||||
l.pixelType = PT_ABGR_8;
|
||||
break;
|
||||
case BufferedImage.TYPE_BYTE_GRAY:
|
||||
l.pixelType = PT_GRAY_8;
|
||||
break;
|
||||
case BufferedImage.TYPE_USHORT_GRAY:
|
||||
l.pixelType = PT_GRAY_16;
|
||||
break;
|
||||
default:
|
||||
/* ColorConvertOp creates component images as
|
||||
* default destination, so this kind of images
|
||||
* has to be supported.
|
||||
*/
|
||||
ColorModel cm = image.getColorModel();
|
||||
if (cm instanceof ComponentColorModel) {
|
||||
ComponentColorModel ccm = (ComponentColorModel) cm;
|
||||
|
||||
// verify whether the component size is fine
|
||||
int[] cs = ccm.getComponentSize();
|
||||
for (int s : cs) {
|
||||
if (s != 8) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return createImageLayout(image.getRaster());
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
l.width = image.getWidth();
|
||||
l.height = image.getHeight();
|
||||
|
||||
switch (image.getType()) {
|
||||
case BufferedImage.TYPE_INT_RGB:
|
||||
case BufferedImage.TYPE_INT_ARGB:
|
||||
case BufferedImage.TYPE_INT_BGR:
|
||||
do {
|
||||
IntegerComponentRaster intRaster = (IntegerComponentRaster)
|
||||
image.getRaster();
|
||||
l.nextRowOffset = safeMult(4, intRaster.getScanlineStride());
|
||||
l.nextPixelOffset = safeMult(4, intRaster.getPixelStride());
|
||||
l.offset = safeMult(4, intRaster.getDataOffset(0));
|
||||
l.dataArray = intRaster.getDataStorage();
|
||||
l.dataArrayLength = 4 * intRaster.getDataStorage().length;
|
||||
l.dataType = DT_INT;
|
||||
|
||||
if (l.nextRowOffset == l.width * 4 * intRaster.getPixelStride()) {
|
||||
l.imageAtOnce = true;
|
||||
}
|
||||
} while (false);
|
||||
break;
|
||||
|
||||
case BufferedImage.TYPE_3BYTE_BGR:
|
||||
case BufferedImage.TYPE_4BYTE_ABGR:
|
||||
do {
|
||||
ByteComponentRaster byteRaster = (ByteComponentRaster)
|
||||
image.getRaster();
|
||||
l.nextRowOffset = byteRaster.getScanlineStride();
|
||||
l.nextPixelOffset = byteRaster.getPixelStride();
|
||||
|
||||
int firstBand = image.getSampleModel().getNumBands() - 1;
|
||||
l.offset = byteRaster.getDataOffset(firstBand);
|
||||
l.dataArray = byteRaster.getDataStorage();
|
||||
l.dataArrayLength = byteRaster.getDataStorage().length;
|
||||
l.dataType = DT_BYTE;
|
||||
if (l.nextRowOffset == l.width * byteRaster.getPixelStride()) {
|
||||
l.imageAtOnce = true;
|
||||
}
|
||||
} while (false);
|
||||
break;
|
||||
|
||||
case BufferedImage.TYPE_BYTE_GRAY:
|
||||
do {
|
||||
ByteComponentRaster byteRaster = (ByteComponentRaster)
|
||||
image.getRaster();
|
||||
l.nextRowOffset = byteRaster.getScanlineStride();
|
||||
l.nextPixelOffset = byteRaster.getPixelStride();
|
||||
|
||||
l.dataArrayLength = byteRaster.getDataStorage().length;
|
||||
l.offset = byteRaster.getDataOffset(0);
|
||||
l.dataArray = byteRaster.getDataStorage();
|
||||
l.dataType = DT_BYTE;
|
||||
|
||||
if (l.nextRowOffset == l.width * byteRaster.getPixelStride()) {
|
||||
l.imageAtOnce = true;
|
||||
}
|
||||
} while (false);
|
||||
break;
|
||||
|
||||
case BufferedImage.TYPE_USHORT_GRAY:
|
||||
do {
|
||||
ShortComponentRaster shortRaster = (ShortComponentRaster)
|
||||
image.getRaster();
|
||||
l.nextRowOffset = safeMult(2, shortRaster.getScanlineStride());
|
||||
l.nextPixelOffset = safeMult(2, shortRaster.getPixelStride());
|
||||
|
||||
l.offset = safeMult(2, shortRaster.getDataOffset(0));
|
||||
l.dataArray = shortRaster.getDataStorage();
|
||||
l.dataArrayLength = 2 * shortRaster.getDataStorage().length;
|
||||
l.dataType = DT_SHORT;
|
||||
|
||||
if (l.nextRowOffset == l.width * 2 * shortRaster.getPixelStride()) {
|
||||
l.imageAtOnce = true;
|
||||
}
|
||||
} while (false);
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
l.verify();
|
||||
return l;
|
||||
}
|
||||
|
||||
private static enum BandOrder {
|
||||
DIRECT,
|
||||
INVERTED,
|
||||
ARBITRARY,
|
||||
UNKNOWN;
|
||||
|
||||
public static BandOrder getBandOrder(int[] bandOffsets) {
|
||||
BandOrder order = UNKNOWN;
|
||||
|
||||
int numBands = bandOffsets.length;
|
||||
|
||||
for (int i = 0; (order != ARBITRARY) && (i < bandOffsets.length); i++) {
|
||||
switch (order) {
|
||||
case UNKNOWN:
|
||||
if (bandOffsets[i] == i) {
|
||||
order = DIRECT;
|
||||
} else if (bandOffsets[i] == (numBands - 1 - i)) {
|
||||
order = INVERTED;
|
||||
} else {
|
||||
order = ARBITRARY;
|
||||
}
|
||||
break;
|
||||
case DIRECT:
|
||||
if (bandOffsets[i] != i) {
|
||||
order = ARBITRARY;
|
||||
}
|
||||
break;
|
||||
case INVERTED:
|
||||
if (bandOffsets[i] != (numBands - 1 - i)) {
|
||||
order = ARBITRARY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return order;
|
||||
}
|
||||
}
|
||||
|
||||
private void verify() throws ImageLayoutException {
|
||||
|
||||
if (offset < 0 || offset >= dataArrayLength) {
|
||||
throw new ImageLayoutException("Invalid image layout");
|
||||
}
|
||||
|
||||
if (nextPixelOffset != getBytesPerPixel(pixelType)) {
|
||||
throw new ImageLayoutException("Invalid image layout");
|
||||
}
|
||||
|
||||
int lastScanOffset = safeMult(nextRowOffset, (height - 1));
|
||||
|
||||
int lastPixelOffset = safeMult(nextPixelOffset, (width -1 ));
|
||||
|
||||
lastPixelOffset = safeAdd(lastPixelOffset, lastScanOffset);
|
||||
|
||||
int off = safeAdd(offset, lastPixelOffset);
|
||||
|
||||
if (off < 0 || off >= dataArrayLength) {
|
||||
throw new ImageLayoutException("Invalid image layout");
|
||||
}
|
||||
}
|
||||
|
||||
static int safeAdd(int a, int b) throws ImageLayoutException {
|
||||
long res = a;
|
||||
res += b;
|
||||
if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) {
|
||||
throw new ImageLayoutException("Invalid image layout");
|
||||
}
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
static int safeMult(int a, int b) throws ImageLayoutException {
|
||||
long res = a;
|
||||
res *= b;
|
||||
if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) {
|
||||
throw new ImageLayoutException("Invalid image layout");
|
||||
}
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
public static class ImageLayoutException extends Exception {
|
||||
public ImageLayoutException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
public static LCMSImageLayout createImageLayout(Raster r) {
|
||||
LCMSImageLayout l = new LCMSImageLayout();
|
||||
if (r instanceof ByteComponentRaster &&
|
||||
r.getSampleModel() instanceof ComponentSampleModel) {
|
||||
ByteComponentRaster br = (ByteComponentRaster)r;
|
||||
|
||||
ComponentSampleModel csm = (ComponentSampleModel)r.getSampleModel();
|
||||
|
||||
l.pixelType = CHANNELS_SH(br.getNumBands()) | BYTES_SH(1);
|
||||
|
||||
int[] bandOffsets = csm.getBandOffsets();
|
||||
BandOrder order = BandOrder.getBandOrder(bandOffsets);
|
||||
|
||||
int firstBand = 0;
|
||||
switch (order) {
|
||||
case INVERTED:
|
||||
l.pixelType |= DOSWAP;
|
||||
firstBand = csm.getNumBands() - 1;
|
||||
break;
|
||||
case DIRECT:
|
||||
// do nothing
|
||||
break;
|
||||
default:
|
||||
// unable to create the image layout;
|
||||
return null;
|
||||
}
|
||||
|
||||
l.nextRowOffset = br.getScanlineStride();
|
||||
l.nextPixelOffset = br.getPixelStride();
|
||||
|
||||
l.offset = br.getDataOffset(firstBand);
|
||||
l.dataArray = br.getDataStorage();
|
||||
l.dataType = DT_BYTE;
|
||||
|
||||
l.width = br.getWidth();
|
||||
l.height = br.getHeight();
|
||||
|
||||
if (l.nextRowOffset == l.width * br.getPixelStride()) {
|
||||
l.imageAtOnce = true;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives number of bytes per pixel from the pixel format.
|
||||
* Following bit fields are used here:
|
||||
* [0..2] - bytes per sample
|
||||
* [3..6] - number of color samples per pixel
|
||||
* [7..9] - number of non-color samples per pixel
|
||||
*
|
||||
* A complete description of the pixel format can be found
|
||||
* here: lcms2.h, lines 651 - 667.
|
||||
*
|
||||
* @param pixelType pixel format in lcms2 notation.
|
||||
* @return number of bytes per pixel for given pixel format.
|
||||
*/
|
||||
private static int getBytesPerPixel(int pixelType) {
|
||||
int bytesPerSample = (0x7 & pixelType);
|
||||
int colorSamplesPerPixel = 0xF & (pixelType >> 3);
|
||||
int extraSamplesPerPixel = 0x7 & (pixelType >> 7);
|
||||
|
||||
return bytesPerSample * (colorSamplesPerPixel + extraSamplesPerPixel);
|
||||
}
|
||||
}
|
||||
109
jdkSrc/jdk8/sun/java2d/cmm/lcms/LCMSProfile.java
Normal file
109
jdkSrc/jdk8/sun/java2d/cmm/lcms/LCMSProfile.java
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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 sun.java2d.cmm.lcms;
|
||||
|
||||
import java.awt.color.CMMException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import sun.java2d.cmm.Profile;
|
||||
|
||||
final class LCMSProfile extends Profile {
|
||||
private final TagCache tagCache;
|
||||
|
||||
private final Object disposerReferent;
|
||||
|
||||
LCMSProfile(long ptr, Object ref) {
|
||||
super(ptr);
|
||||
|
||||
disposerReferent = ref;
|
||||
|
||||
tagCache = new TagCache(this);
|
||||
}
|
||||
|
||||
final long getLcmsPtr() {
|
||||
return this.getNativePtr();
|
||||
}
|
||||
|
||||
TagData getTag(int sig) {
|
||||
return tagCache.getTag(sig);
|
||||
}
|
||||
|
||||
void clearTagCache() {
|
||||
tagCache.clear();
|
||||
}
|
||||
|
||||
static class TagCache {
|
||||
final LCMSProfile profile;
|
||||
private HashMap<Integer, TagData> tags;
|
||||
|
||||
TagCache(LCMSProfile p) {
|
||||
profile = p;
|
||||
tags = new HashMap<>();
|
||||
}
|
||||
|
||||
TagData getTag(int sig) {
|
||||
TagData t = tags.get(sig);
|
||||
if (t == null) {
|
||||
byte[] tagData = LCMS.getTagNative(profile.getNativePtr(), sig);
|
||||
if (tagData != null) {
|
||||
t = new TagData(sig, tagData);
|
||||
tags.put(sig, t);
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
tags.clear();
|
||||
}
|
||||
}
|
||||
|
||||
static class TagData {
|
||||
private int signature;
|
||||
private byte[] data;
|
||||
|
||||
TagData(int sig, byte[] data) {
|
||||
this.signature = sig;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
int getSize() {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
byte[] getData() {
|
||||
return Arrays.copyOf(data, data.length);
|
||||
}
|
||||
|
||||
void copyDataTo(byte[] dst) {
|
||||
System.arraycopy(data, 0, dst, 0, data.length);
|
||||
}
|
||||
|
||||
int getSignature() {
|
||||
return signature;
|
||||
}
|
||||
}
|
||||
}
|
||||
660
jdkSrc/jdk8/sun/java2d/cmm/lcms/LCMSTransform.java
Normal file
660
jdkSrc/jdk8/sun/java2d/cmm/lcms/LCMSTransform.java
Normal file
@@ -0,0 +1,660 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2013, 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.
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package sun.java2d.cmm.lcms;
|
||||
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.awt.color.ProfileDataException;
|
||||
import java.awt.color.CMMException;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.SinglePixelPackedSampleModel;
|
||||
import java.awt.image.ComponentSampleModel;
|
||||
import sun.java2d.cmm.*;
|
||||
import sun.java2d.cmm.lcms.*;
|
||||
import static sun.java2d.cmm.lcms.LCMSImageLayout.ImageLayoutException;
|
||||
|
||||
|
||||
public class LCMSTransform implements ColorTransform {
|
||||
long ID;
|
||||
private int inFormatter = 0;
|
||||
private boolean isInIntPacked = false;
|
||||
private int outFormatter = 0;
|
||||
private boolean isOutIntPacked = false;
|
||||
|
||||
ICC_Profile[] profiles;
|
||||
LCMSProfile[] lcmsProfiles;
|
||||
int renderType;
|
||||
int transformType;
|
||||
|
||||
private int numInComponents = -1;
|
||||
private int numOutComponents = -1;
|
||||
|
||||
private Object disposerReferent = new Object();
|
||||
|
||||
/* the class initializer */
|
||||
static {
|
||||
if (ProfileDeferralMgr.deferring) {
|
||||
ProfileDeferralMgr.activateProfiles();
|
||||
}
|
||||
}
|
||||
|
||||
public LCMSTransform(ICC_Profile profile, int renderType,
|
||||
int transformType)
|
||||
{
|
||||
/* Actually, it is not a complete transform but just part of it */
|
||||
profiles = new ICC_Profile[1];
|
||||
profiles[0] = profile;
|
||||
lcmsProfiles = new LCMSProfile[1];
|
||||
lcmsProfiles[0] = LCMS.getProfileID(profile);
|
||||
this.renderType = (renderType == ColorTransform.Any)?
|
||||
ICC_Profile.icPerceptual : renderType;
|
||||
this.transformType = transformType;
|
||||
|
||||
/* Note that ICC_Profile.getNumComponents() is quite expensive
|
||||
* (it may results in a reading of the profile header).
|
||||
* So, here we cache the number of components of input and
|
||||
* output profiles for further usage.
|
||||
*/
|
||||
numInComponents = profiles[0].getNumComponents();
|
||||
numOutComponents = profiles[profiles.length - 1].getNumComponents();
|
||||
}
|
||||
|
||||
public LCMSTransform (ColorTransform[] transforms) {
|
||||
int size = 0;
|
||||
for (int i=0; i < transforms.length; i++) {
|
||||
size+=((LCMSTransform)transforms[i]).profiles.length;
|
||||
}
|
||||
profiles = new ICC_Profile[size];
|
||||
lcmsProfiles = new LCMSProfile[size];
|
||||
int j = 0;
|
||||
for (int i=0; i < transforms.length; i++) {
|
||||
LCMSTransform curTrans = (LCMSTransform)transforms[i];
|
||||
System.arraycopy(curTrans.profiles, 0, profiles, j,
|
||||
curTrans.profiles.length);
|
||||
System.arraycopy(curTrans.lcmsProfiles, 0, lcmsProfiles, j,
|
||||
curTrans.lcmsProfiles.length);
|
||||
j += curTrans.profiles.length;
|
||||
}
|
||||
renderType = ((LCMSTransform)transforms[0]).renderType;
|
||||
|
||||
/* Note that ICC_Profile.getNumComponents() is quite expensive
|
||||
* (it may results in a reading of the profile header).
|
||||
* So, here we cache the number of components of input and
|
||||
* output profiles for further usage.
|
||||
*/
|
||||
numInComponents = profiles[0].getNumComponents();
|
||||
numOutComponents = profiles[profiles.length - 1].getNumComponents();
|
||||
}
|
||||
|
||||
public int getNumInComponents() {
|
||||
return numInComponents;
|
||||
}
|
||||
|
||||
public int getNumOutComponents() {
|
||||
return numOutComponents;
|
||||
}
|
||||
|
||||
private synchronized void doTransform(LCMSImageLayout in,
|
||||
LCMSImageLayout out) {
|
||||
// update native transfrom if needed
|
||||
if (ID == 0L ||
|
||||
inFormatter != in.pixelType || isInIntPacked != in.isIntPacked ||
|
||||
outFormatter != out.pixelType || isOutIntPacked != out.isIntPacked)
|
||||
{
|
||||
|
||||
if (ID != 0L) {
|
||||
// Disposer will destroy forgotten transform
|
||||
disposerReferent = new Object();
|
||||
}
|
||||
inFormatter = in.pixelType;
|
||||
isInIntPacked = in.isIntPacked;
|
||||
|
||||
outFormatter = out.pixelType;
|
||||
isOutIntPacked = out.isIntPacked;
|
||||
|
||||
ID = LCMS.createTransform(lcmsProfiles, renderType,
|
||||
inFormatter, isInIntPacked,
|
||||
outFormatter, isOutIntPacked,
|
||||
disposerReferent);
|
||||
}
|
||||
|
||||
LCMS.colorConvert(this, in, out);
|
||||
}
|
||||
|
||||
public void colorConvert(BufferedImage src, BufferedImage dst) {
|
||||
LCMSImageLayout srcIL, dstIL;
|
||||
try {
|
||||
if (!dst.getColorModel().hasAlpha()) {
|
||||
dstIL = LCMSImageLayout.createImageLayout(dst);
|
||||
|
||||
if (dstIL != null) {
|
||||
srcIL = LCMSImageLayout.createImageLayout(src);
|
||||
if (srcIL != null) {
|
||||
doTransform(srcIL, dstIL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ImageLayoutException e) {
|
||||
throw new CMMException("Unable to convert images");
|
||||
}
|
||||
|
||||
Raster srcRas = src.getRaster();
|
||||
WritableRaster dstRas = dst.getRaster();
|
||||
ColorModel srcCM = src.getColorModel();
|
||||
ColorModel dstCM = dst.getColorModel();
|
||||
int w = src.getWidth();
|
||||
int h = src.getHeight();
|
||||
int srcNumComp = srcCM.getNumColorComponents();
|
||||
int dstNumComp = dstCM.getNumColorComponents();
|
||||
int precision = 8;
|
||||
float maxNum = 255.0f;
|
||||
for (int i = 0; i < srcNumComp; i++) {
|
||||
if (srcCM.getComponentSize(i) > 8) {
|
||||
precision = 16;
|
||||
maxNum = 65535.0f;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < dstNumComp; i++) {
|
||||
if (dstCM.getComponentSize(i) > 8) {
|
||||
precision = 16;
|
||||
maxNum = 65535.0f;
|
||||
}
|
||||
}
|
||||
float[] srcMinVal = new float[srcNumComp];
|
||||
float[] srcInvDiffMinMax = new float[srcNumComp];
|
||||
ColorSpace cs = srcCM.getColorSpace();
|
||||
for (int i = 0; i < srcNumComp; i++) {
|
||||
srcMinVal[i] = cs.getMinValue(i);
|
||||
srcInvDiffMinMax[i] = maxNum / (cs.getMaxValue(i) - srcMinVal[i]);
|
||||
}
|
||||
cs = dstCM.getColorSpace();
|
||||
float[] dstMinVal = new float[dstNumComp];
|
||||
float[] dstDiffMinMax = new float[dstNumComp];
|
||||
for (int i = 0; i < dstNumComp; i++) {
|
||||
dstMinVal[i] = cs.getMinValue(i);
|
||||
dstDiffMinMax[i] = (cs.getMaxValue(i) - dstMinVal[i]) / maxNum;
|
||||
}
|
||||
boolean dstHasAlpha = dstCM.hasAlpha();
|
||||
boolean needSrcAlpha = srcCM.hasAlpha() && dstHasAlpha;
|
||||
float[] dstColor;
|
||||
if (dstHasAlpha) {
|
||||
dstColor = new float[dstNumComp + 1];
|
||||
} else {
|
||||
dstColor = new float[dstNumComp];
|
||||
}
|
||||
if (precision == 8) {
|
||||
byte[] srcLine = new byte[w * srcNumComp];
|
||||
byte[] dstLine = new byte[w * dstNumComp];
|
||||
Object pixel;
|
||||
float[] color;
|
||||
float[] alpha = null;
|
||||
if (needSrcAlpha) {
|
||||
alpha = new float[w];
|
||||
}
|
||||
int idx;
|
||||
// TODO check for src npixels = dst npixels
|
||||
try {
|
||||
srcIL = new LCMSImageLayout(
|
||||
srcLine, srcLine.length/getNumInComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(1), getNumInComponents());
|
||||
dstIL = new LCMSImageLayout(
|
||||
dstLine, dstLine.length/getNumOutComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
|
||||
} catch (ImageLayoutException e) {
|
||||
throw new CMMException("Unable to convert images");
|
||||
}
|
||||
// process each scanline
|
||||
for (int y = 0; y < h; y++) {
|
||||
// convert src scanline
|
||||
pixel = null;
|
||||
color = null;
|
||||
idx = 0;
|
||||
for (int x = 0; x < w; x++) {
|
||||
pixel = srcRas.getDataElements(x, y, pixel);
|
||||
color = srcCM.getNormalizedComponents(pixel, color, 0);
|
||||
for (int i = 0; i < srcNumComp; i++) {
|
||||
srcLine[idx++] = (byte)
|
||||
((color[i] - srcMinVal[i]) * srcInvDiffMinMax[i] +
|
||||
0.5f);
|
||||
}
|
||||
if (needSrcAlpha) {
|
||||
alpha[x] = color[srcNumComp];
|
||||
}
|
||||
}
|
||||
// color convert srcLine to dstLine
|
||||
doTransform(srcIL, dstIL);
|
||||
|
||||
// convert dst scanline
|
||||
pixel = null;
|
||||
idx = 0;
|
||||
for (int x = 0; x < w; x++) {
|
||||
for (int i = 0; i < dstNumComp; i++) {
|
||||
dstColor[i] = ((float) (dstLine[idx++] & 0xff)) *
|
||||
dstDiffMinMax[i] + dstMinVal[i];
|
||||
}
|
||||
if (needSrcAlpha) {
|
||||
dstColor[dstNumComp] = alpha[x];
|
||||
} else if (dstHasAlpha) {
|
||||
dstColor[dstNumComp] = 1.0f;
|
||||
}
|
||||
pixel = dstCM.getDataElements(dstColor, 0, pixel);
|
||||
dstRas.setDataElements(x, y, pixel);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
short[] srcLine = new short[w * srcNumComp];
|
||||
short[] dstLine = new short[w * dstNumComp];
|
||||
Object pixel;
|
||||
float[] color;
|
||||
float[] alpha = null;
|
||||
if (needSrcAlpha) {
|
||||
alpha = new float[w];
|
||||
}
|
||||
int idx;
|
||||
try {
|
||||
srcIL = new LCMSImageLayout(
|
||||
srcLine, srcLine.length/getNumInComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
|
||||
|
||||
dstIL = new LCMSImageLayout(
|
||||
dstLine, dstLine.length/getNumOutComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
|
||||
} catch (ImageLayoutException e) {
|
||||
throw new CMMException("Unable to convert images");
|
||||
}
|
||||
// process each scanline
|
||||
for (int y = 0; y < h; y++) {
|
||||
// convert src scanline
|
||||
pixel = null;
|
||||
color = null;
|
||||
idx = 0;
|
||||
for (int x = 0; x < w; x++) {
|
||||
pixel = srcRas.getDataElements(x, y, pixel);
|
||||
color = srcCM.getNormalizedComponents(pixel, color, 0);
|
||||
for (int i = 0; i < srcNumComp; i++) {
|
||||
srcLine[idx++] = (short)
|
||||
((color[i] - srcMinVal[i]) * srcInvDiffMinMax[i] +
|
||||
0.5f);
|
||||
}
|
||||
if (needSrcAlpha) {
|
||||
alpha[x] = color[srcNumComp];
|
||||
}
|
||||
}
|
||||
// color convert srcLine to dstLine
|
||||
doTransform(srcIL, dstIL);
|
||||
|
||||
// convert dst scanline
|
||||
pixel = null;
|
||||
idx = 0;
|
||||
for (int x = 0; x < w; x++) {
|
||||
for (int i = 0; i < dstNumComp; i++) {
|
||||
dstColor[i] = ((float) (dstLine[idx++] & 0xffff)) *
|
||||
dstDiffMinMax[i] + dstMinVal[i];
|
||||
}
|
||||
if (needSrcAlpha) {
|
||||
dstColor[dstNumComp] = alpha[x];
|
||||
} else if (dstHasAlpha) {
|
||||
dstColor[dstNumComp] = 1.0f;
|
||||
}
|
||||
pixel = dstCM.getDataElements(dstColor, 0, pixel);
|
||||
dstRas.setDataElements(x, y, pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void colorConvert(Raster src, WritableRaster dst,
|
||||
float[] srcMinVal, float[]srcMaxVal,
|
||||
float[] dstMinVal, float[]dstMaxVal) {
|
||||
LCMSImageLayout srcIL, dstIL;
|
||||
|
||||
// Can't pass src and dst directly to CMM, so process per scanline
|
||||
SampleModel srcSM = src.getSampleModel();
|
||||
SampleModel dstSM = dst.getSampleModel();
|
||||
int srcTransferType = src.getTransferType();
|
||||
int dstTransferType = dst.getTransferType();
|
||||
boolean srcIsFloat, dstIsFloat;
|
||||
if ((srcTransferType == DataBuffer.TYPE_FLOAT) ||
|
||||
(srcTransferType == DataBuffer.TYPE_DOUBLE)) {
|
||||
srcIsFloat = true;
|
||||
} else {
|
||||
srcIsFloat = false;
|
||||
}
|
||||
if ((dstTransferType == DataBuffer.TYPE_FLOAT) ||
|
||||
(dstTransferType == DataBuffer.TYPE_DOUBLE)) {
|
||||
dstIsFloat = true;
|
||||
} else {
|
||||
dstIsFloat = false;
|
||||
}
|
||||
int w = src.getWidth();
|
||||
int h = src.getHeight();
|
||||
int srcNumBands = src.getNumBands();
|
||||
int dstNumBands = dst.getNumBands();
|
||||
float[] srcScaleFactor = new float[srcNumBands];
|
||||
float[] dstScaleFactor = new float[dstNumBands];
|
||||
float[] srcUseMinVal = new float[srcNumBands];
|
||||
float[] dstUseMinVal = new float[dstNumBands];
|
||||
for (int i = 0; i < srcNumBands; i++) {
|
||||
if (srcIsFloat) {
|
||||
srcScaleFactor[i] = 65535.0f / (srcMaxVal[i] - srcMinVal[i]);
|
||||
srcUseMinVal[i] = srcMinVal[i];
|
||||
} else {
|
||||
if (srcTransferType == DataBuffer.TYPE_SHORT) {
|
||||
srcScaleFactor[i] = 65535.0f / 32767.0f;
|
||||
} else {
|
||||
srcScaleFactor[i] = 65535.0f /
|
||||
((float) ((1 << srcSM.getSampleSize(i)) - 1));
|
||||
}
|
||||
srcUseMinVal[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < dstNumBands; i++) {
|
||||
if (dstIsFloat) {
|
||||
dstScaleFactor[i] = (dstMaxVal[i] - dstMinVal[i]) / 65535.0f;
|
||||
dstUseMinVal[i] = dstMinVal[i];
|
||||
} else {
|
||||
if (dstTransferType == DataBuffer.TYPE_SHORT) {
|
||||
dstScaleFactor[i] = 32767.0f / 65535.0f;
|
||||
} else {
|
||||
dstScaleFactor[i] =
|
||||
((float) ((1 << dstSM.getSampleSize(i)) - 1)) /
|
||||
65535.0f;
|
||||
}
|
||||
dstUseMinVal[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
int ys = src.getMinY();
|
||||
int yd = dst.getMinY();
|
||||
int xs, xd;
|
||||
float sample;
|
||||
short[] srcLine = new short[w * srcNumBands];
|
||||
short[] dstLine = new short[w * dstNumBands];
|
||||
int idx;
|
||||
try {
|
||||
srcIL = new LCMSImageLayout(
|
||||
srcLine, srcLine.length/getNumInComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
|
||||
|
||||
dstIL = new LCMSImageLayout(
|
||||
dstLine, dstLine.length/getNumOutComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
|
||||
} catch (ImageLayoutException e) {
|
||||
throw new CMMException("Unable to convert rasters");
|
||||
}
|
||||
// process each scanline
|
||||
for (int y = 0; y < h; y++, ys++, yd++) {
|
||||
// get src scanline
|
||||
xs = src.getMinX();
|
||||
idx = 0;
|
||||
for (int x = 0; x < w; x++, xs++) {
|
||||
for (int i = 0; i < srcNumBands; i++) {
|
||||
sample = src.getSampleFloat(xs, ys, i);
|
||||
srcLine[idx++] = (short)
|
||||
((sample - srcUseMinVal[i]) * srcScaleFactor[i] + 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
// color convert srcLine to dstLine
|
||||
doTransform(srcIL, dstIL);
|
||||
|
||||
// store dst scanline
|
||||
xd = dst.getMinX();
|
||||
idx = 0;
|
||||
for (int x = 0; x < w; x++, xd++) {
|
||||
for (int i = 0; i < dstNumBands; i++) {
|
||||
sample = ((dstLine[idx++] & 0xffff) * dstScaleFactor[i]) +
|
||||
dstUseMinVal[i];
|
||||
dst.setSample(xd, yd, i, sample);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void colorConvert(Raster src, WritableRaster dst) {
|
||||
|
||||
LCMSImageLayout srcIL, dstIL;
|
||||
dstIL = LCMSImageLayout.createImageLayout(dst);
|
||||
if (dstIL != null) {
|
||||
srcIL = LCMSImageLayout.createImageLayout(src);
|
||||
if (srcIL != null) {
|
||||
doTransform(srcIL, dstIL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Can't pass src and dst directly to CMM, so process per scanline
|
||||
SampleModel srcSM = src.getSampleModel();
|
||||
SampleModel dstSM = dst.getSampleModel();
|
||||
int srcTransferType = src.getTransferType();
|
||||
int dstTransferType = dst.getTransferType();
|
||||
int w = src.getWidth();
|
||||
int h = src.getHeight();
|
||||
int srcNumBands = src.getNumBands();
|
||||
int dstNumBands = dst.getNumBands();
|
||||
int precision = 8;
|
||||
float maxNum = 255.0f;
|
||||
for (int i = 0; i < srcNumBands; i++) {
|
||||
if (srcSM.getSampleSize(i) > 8) {
|
||||
precision = 16;
|
||||
maxNum = 65535.0f;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < dstNumBands; i++) {
|
||||
if (dstSM.getSampleSize(i) > 8) {
|
||||
precision = 16;
|
||||
maxNum = 65535.0f;
|
||||
}
|
||||
}
|
||||
float[] srcScaleFactor = new float[srcNumBands];
|
||||
float[] dstScaleFactor = new float[dstNumBands];
|
||||
for (int i = 0; i < srcNumBands; i++) {
|
||||
if (srcTransferType == DataBuffer.TYPE_SHORT) {
|
||||
srcScaleFactor[i] = maxNum / 32767.0f;
|
||||
} else {
|
||||
srcScaleFactor[i] = maxNum /
|
||||
((float) ((1 << srcSM.getSampleSize(i)) - 1));
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < dstNumBands; i++) {
|
||||
if (dstTransferType == DataBuffer.TYPE_SHORT) {
|
||||
dstScaleFactor[i] = 32767.0f / maxNum;
|
||||
} else {
|
||||
dstScaleFactor[i] =
|
||||
((float) ((1 << dstSM.getSampleSize(i)) - 1)) / maxNum;
|
||||
}
|
||||
}
|
||||
int ys = src.getMinY();
|
||||
int yd = dst.getMinY();
|
||||
int xs, xd;
|
||||
int sample;
|
||||
if (precision == 8) {
|
||||
byte[] srcLine = new byte[w * srcNumBands];
|
||||
byte[] dstLine = new byte[w * dstNumBands];
|
||||
int idx;
|
||||
// TODO check for src npixels = dst npixels
|
||||
try {
|
||||
srcIL = new LCMSImageLayout(
|
||||
srcLine, srcLine.length/getNumInComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(1), getNumInComponents());
|
||||
dstIL = new LCMSImageLayout(
|
||||
dstLine, dstLine.length/getNumOutComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
|
||||
} catch (ImageLayoutException e) {
|
||||
throw new CMMException("Unable to convert rasters");
|
||||
}
|
||||
// process each scanline
|
||||
for (int y = 0; y < h; y++, ys++, yd++) {
|
||||
// get src scanline
|
||||
xs = src.getMinX();
|
||||
idx = 0;
|
||||
for (int x = 0; x < w; x++, xs++) {
|
||||
for (int i = 0; i < srcNumBands; i++) {
|
||||
sample = src.getSample(xs, ys, i);
|
||||
srcLine[idx++] = (byte)
|
||||
((sample * srcScaleFactor[i]) + 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
// color convert srcLine to dstLine
|
||||
doTransform(srcIL, dstIL);
|
||||
|
||||
// store dst scanline
|
||||
xd = dst.getMinX();
|
||||
idx = 0;
|
||||
for (int x = 0; x < w; x++, xd++) {
|
||||
for (int i = 0; i < dstNumBands; i++) {
|
||||
sample = (int) (((dstLine[idx++] & 0xff) *
|
||||
dstScaleFactor[i]) + 0.5f);
|
||||
dst.setSample(xd, yd, i, sample);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
short[] srcLine = new short[w * srcNumBands];
|
||||
short[] dstLine = new short[w * dstNumBands];
|
||||
int idx;
|
||||
|
||||
try {
|
||||
srcIL = new LCMSImageLayout(
|
||||
srcLine, srcLine.length/getNumInComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
|
||||
|
||||
dstIL = new LCMSImageLayout(
|
||||
dstLine, dstLine.length/getNumOutComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
|
||||
} catch (ImageLayoutException e) {
|
||||
throw new CMMException("Unable to convert rasters");
|
||||
}
|
||||
// process each scanline
|
||||
for (int y = 0; y < h; y++, ys++, yd++) {
|
||||
// get src scanline
|
||||
xs = src.getMinX();
|
||||
idx = 0;
|
||||
for (int x = 0; x < w; x++, xs++) {
|
||||
for (int i = 0; i < srcNumBands; i++) {
|
||||
sample = src.getSample(xs, ys, i);
|
||||
srcLine[idx++] = (short)
|
||||
((sample * srcScaleFactor[i]) + 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
// color convert srcLine to dstLine
|
||||
doTransform(srcIL, dstIL);
|
||||
|
||||
// store dst scanline
|
||||
xd = dst.getMinX();
|
||||
idx = 0;
|
||||
for (int x = 0; x < w; x++, xd++) {
|
||||
for (int i = 0; i < dstNumBands; i++) {
|
||||
sample = (int) (((dstLine[idx++] & 0xffff) *
|
||||
dstScaleFactor[i]) + 0.5f);
|
||||
dst.setSample(xd, yd, i, sample);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* convert an array of colors in short format */
|
||||
/* each color is a contiguous set of array elements */
|
||||
/* the number of colors is (size of the array) / (number of input/output
|
||||
components */
|
||||
public short[] colorConvert(short[] src, short[] dst) {
|
||||
|
||||
if (dst == null) {
|
||||
dst = new short [(src.length/getNumInComponents())*getNumOutComponents()];
|
||||
}
|
||||
|
||||
try {
|
||||
LCMSImageLayout srcIL = new LCMSImageLayout(
|
||||
src, src.length/getNumInComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
|
||||
|
||||
LCMSImageLayout dstIL = new LCMSImageLayout(
|
||||
dst, dst.length/getNumOutComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
|
||||
|
||||
doTransform(srcIL, dstIL);
|
||||
|
||||
return dst;
|
||||
} catch (ImageLayoutException e) {
|
||||
throw new CMMException("Unable to convert data");
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] colorConvert(byte[] src, byte[] dst) {
|
||||
if (dst == null) {
|
||||
dst = new byte [(src.length/getNumInComponents())*getNumOutComponents()];
|
||||
}
|
||||
|
||||
try {
|
||||
LCMSImageLayout srcIL = new LCMSImageLayout(
|
||||
src, src.length/getNumInComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(1), getNumInComponents());
|
||||
|
||||
LCMSImageLayout dstIL = new LCMSImageLayout(
|
||||
dst, dst.length/getNumOutComponents(),
|
||||
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
|
||||
LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
|
||||
|
||||
doTransform(srcIL, dstIL);
|
||||
|
||||
return dst;
|
||||
} catch (ImageLayoutException e) {
|
||||
throw new CMMException("Unable to convert data");
|
||||
}
|
||||
}
|
||||
}
|
||||
36
jdkSrc/jdk8/sun/java2d/cmm/lcms/LcmsServiceProvider.java
Normal file
36
jdkSrc/jdk8/sun/java2d/cmm/lcms/LcmsServiceProvider.java
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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 sun.java2d.cmm.lcms;
|
||||
|
||||
import sun.java2d.cmm.CMMServiceProvider;
|
||||
import sun.java2d.cmm.PCMM;
|
||||
|
||||
public final class LcmsServiceProvider extends CMMServiceProvider {
|
||||
@Override
|
||||
protected PCMM getModule() {
|
||||
return LCMS.getModule();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user