diff --git a/jdk/make/sun/cmm/lcms/Makefile b/jdk/make/sun/cmm/lcms/Makefile index 24fde37fba0..85b02e4960e 100644 --- a/jdk/make/sun/cmm/lcms/Makefile +++ b/jdk/make/sun/cmm/lcms/Makefile @@ -28,6 +28,9 @@ PACKAGE = sun.java2d.cmm.lcms LIBRARY = lcms PRODUCT = sun +# Use highest level of optimization on this library +OPTIMIZATION_LEVEL = HIGHEST + include $(BUILDDIR)/common/Defs.gmk # diff --git a/jdk/make/sun/cmm/lcms/mapfile-vers b/jdk/make/sun/cmm/lcms/mapfile-vers index ac4e7458b37..3d9074f746d 100644 --- a/jdk/make/sun/cmm/lcms/mapfile-vers +++ b/jdk/make/sun/cmm/lcms/mapfile-vers @@ -27,13 +27,12 @@ SUNWprivate_1.1 { global: - Java_sun_java2d_cmm_lcms_LCMS_loadProfile; - Java_sun_java2d_cmm_lcms_LCMS_freeProfile; + Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative; + Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative; Java_sun_java2d_cmm_lcms_LCMS_getProfileSize; Java_sun_java2d_cmm_lcms_LCMS_getProfileData; - Java_sun_java2d_cmm_lcms_LCMS_getTagSize; - Java_sun_java2d_cmm_lcms_LCMS_getTagData; - Java_sun_java2d_cmm_lcms_LCMS_setTagData; + Java_sun_java2d_cmm_lcms_LCMS_getTagNative; + Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative; Java_sun_java2d_cmm_lcms_LCMS_colorConvert; Java_sun_java2d_cmm_lcms_LCMS_getProfileID; Java_sun_java2d_cmm_lcms_LCMS_initLCMS; diff --git a/jdk/makefiles/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk index 01dbc2ba417..46f1778a5fc 100644 --- a/jdk/makefiles/CompileNativeLibraries.gmk +++ b/jdk/makefiles/CompileNativeLibraries.gmk @@ -1218,7 +1218,7 @@ ifdef OPENJDK OUTPUT_DIR:=$(INSTALL_LIBRARIES_HERE),\ SRC:=$(JDK_TOPDIR)/src/share/native/sun/java2d/cmm/lcms,\ LANG:=C,\ - OPTIMIZATION:=LOW, \ + OPTIMIZATION:=HIGHEST, \ CFLAGS:=$(filter-out -xc99=%none,$(CFLAGS_JDKLIB)) \ $(SHARED_LIBRARY_FLAGS) \ -I$(JDK_TOPDIR)/src/share/native/sun/java2d \ diff --git a/jdk/makefiles/mapfiles/liblcms/mapfile-vers b/jdk/makefiles/mapfiles/liblcms/mapfile-vers index 04703dffc5a..024511423d3 100644 --- a/jdk/makefiles/mapfiles/liblcms/mapfile-vers +++ b/jdk/makefiles/mapfiles/liblcms/mapfile-vers @@ -27,13 +27,12 @@ SUNWprivate_1.1 { global: - Java_sun_java2d_cmm_lcms_LCMS_loadProfile; - Java_sun_java2d_cmm_lcms_LCMS_freeProfile; + Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative; + Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative; Java_sun_java2d_cmm_lcms_LCMS_getProfileSize; Java_sun_java2d_cmm_lcms_LCMS_getProfileData; - Java_sun_java2d_cmm_lcms_LCMS_getTagSize; - Java_sun_java2d_cmm_lcms_LCMS_getTagData; - Java_sun_java2d_cmm_lcms_LCMS_setTagData; + Java_sun_java2d_cmm_lcms_LCMS_getTagNative; + Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative; Java_sun_java2d_cmm_lcms_LCMS_colorConvert; Java_sun_java2d_cmm_lcms_LCMS_getProfileID; Java_sun_java2d_cmm_lcms_LCMS_initLCMS; diff --git a/jdk/src/macosx/classes/sun/font/CStrike.java b/jdk/src/macosx/classes/sun/font/CStrike.java index 61fe234cb29..9635b85a1de 100644 --- a/jdk/src/macosx/classes/sun/font/CStrike.java +++ b/jdk/src/macosx/classes/sun/font/CStrike.java @@ -500,7 +500,10 @@ public class CStrike extends FontStrike { final Iterator i = generalCache.values().iterator(); while (i.hasNext()) { final long longValue = i.next().longValue(); - if (longValue != -1 && longValue != 0) StrikeCache.freeLongPointer(longValue); + if (longValue != -1 && longValue != 0) { + removeGlyphInfoFromCache(longValue); + StrikeCache.freeLongPointer(longValue); + } } } @@ -512,7 +515,10 @@ public class CStrike extends FontStrike { private static void disposeLongArray(final long[] longArray) { for (int i = 0; i < longArray.length; i++) { final long ptr = longArray[i]; - if (ptr != 0 && ptr != -1) StrikeCache.freeLongPointer(ptr); // free's the native struct pointer + if (ptr != 0 && ptr != -1) { + removeGlyphInfoFromCache(ptr); + StrikeCache.freeLongPointer(ptr); // free's the native struct pointer + } } } diff --git a/jdk/src/macosx/classes/sun/font/CStrikeDisposer.java b/jdk/src/macosx/classes/sun/font/CStrikeDisposer.java index 7357ea6bd42..661bd6a7b42 100644 --- a/jdk/src/macosx/classes/sun/font/CStrikeDisposer.java +++ b/jdk/src/macosx/classes/sun/font/CStrikeDisposer.java @@ -85,4 +85,6 @@ class CStrikeDisposer extends FontStrikeDisposer { } private native void freeNativeScalerContext(long pContext); + + protected static native void removeGlyphInfoFromCache(long glyphInfo); } diff --git a/jdk/src/macosx/native/sun/font/AWTStrike.m b/jdk/src/macosx/native/sun/font/AWTStrike.m index 261bd34ae57..7f04b530ade 100644 --- a/jdk/src/macosx/native/sun/font/AWTStrike.m +++ b/jdk/src/macosx/native/sun/font/AWTStrike.m @@ -27,11 +27,13 @@ #import "java_awt_geom_PathIterator.h" #import "sun_awt_SunHints.h" #import "sun_font_CStrike.h" +#import "sun_font_CStrikeDisposer.h" #import "CGGlyphImages.h" #import "CGGlyphOutlines.h" #import "AWTStrike.h" #import "CoreTextSupport.h" //#import "jni_util.h" +#include "fontscalerdefs.h" /* Use THIS_FILE when it is available. */ #ifndef THIS_FILE @@ -423,3 +425,19 @@ JNF_COCOA_EXIT(env); return metrics; } + +extern void AccelGlyphCache_RemoveAllInfos(GlyphInfo* glyph); +/* + * Class: sun_font_CStrikeDisposer + * Method: removeGlyphInfoFromCache + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_sun_font_CStrikeDisposer_removeGlyphInfoFromCache +(JNIEnv *env, jclass cls, jlong glyphInfo) +{ + JNF_COCOA_ENTER(env); + + AccelGlyphCache_RemoveAllCellInfos((GlyphInfo*)jlong_to_ptr(glyphInfo)); + + JNF_COCOA_EXIT(env); +} diff --git a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java index 5cfda3cdb74..c6eae65a73a 100644 --- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java +++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java @@ -25,29 +25,91 @@ package sun.java2d.cmm.lcms; -import java.awt.color.ColorSpace; import java.awt.color.ICC_Profile; -import java.awt.color.CMMException; +import java.util.Arrays; +import java.util.HashMap; import sun.java2d.cmm.ColorTransform; import sun.java2d.cmm.PCMM; -import sun.java2d.cmm.lcms.LCMS; -import sun.java2d.cmm.lcms.LCMSTransform; public class LCMS implements PCMM { /* methods invoked from ICC_Profile */ - public native long loadProfile(byte[] data); + @Override + public long loadProfile(byte[] data) { + long id = loadProfileNative(data); - public native void freeProfile(long profileID); + if (id != 0L) { + if (profiles == null) { + profiles = new HashMap<>(); + } + profiles.put(id, new TagCache(id)); + } + return id; + } + + private native long loadProfileNative(byte[] data); + + @Override + public void freeProfile(long profileID) { + TagCache c = profiles.remove(profileID); + if (c != null) { + c.clear(); + } + if (profiles.isEmpty()) { + profiles = null; + } + freeProfileNative(profileID); + } + + private native void freeProfileNative(long profileID); public native synchronized int getProfileSize(long profileID); public native synchronized void getProfileData(long profileID, byte[] data); - public native synchronized int getTagSize(long profileID, int tagSignature); - public native synchronized void getTagData(long profileID, int tagSignature, - byte[] data); - public native synchronized void setTagData(long profileID, int tagSignature, + @Override + public synchronized int getTagSize(long profileID, int tagSignature) { + TagCache cache = profiles.get(profileID); + + if (cache == null) { + cache = new TagCache(profileID); + profiles.put(profileID, cache); + } + + TagData t = cache.getTag(tagSignature); + return t == null ? 0 : t.getSize(); + } + + private static native byte[] getTagNative(long profileID, int signature); + + @Override + public synchronized void getTagData(long profileID, int tagSignature, + byte[] data) + { + TagCache cache = profiles.get(profileID); + + if (cache == null) { + cache = new TagCache(profileID); + profiles.put(profileID, cache); + } + + TagData t = cache.getTag(tagSignature); + if (t != null) { + t.copyDataTo(data); + } + } + + @Override + public synchronized void setTagData(long profileID, int tagSignature, byte[] data) { + TagCache cache = profiles.get(profileID); + + if (cache != null) { + cache.clear(); + } + setTagDataNative(profileID, tagSignature, data); + } + + private native synchronized void setTagDataNative(long profileID, int tagSignature, byte[] data); public static native long getProfileID(ICC_Profile profile); @@ -103,4 +165,59 @@ public class LCMS implements PCMM { initLCMS(LCMSTransform.class, LCMSImageLayout.class, ICC_Profile.class); } + + private 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; + } + } + + private static class TagCache { + private long profileID; + private HashMap tags; + + TagCache(long id) { + profileID = id; + + tags = new HashMap<>(); + } + + TagData getTag(int sig) { + TagData t = tags.get(sig); + if (t == null) { + byte[] tagData = getTagNative(profileID, sig); + if (tagData != null) { + t = new TagData(sig, tagData); + tags.put(sig, t); + } + } + return t; + } + + void clear() { + tags.clear(); + } + } + + private static HashMap profiles; } diff --git a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java index 3695a163211..b53bd9a45d3 100644 --- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java +++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java @@ -22,26 +22,19 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ - package sun.java2d.cmm.lcms; -import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.awt.image.ComponentColorModel; -import java.awt.image.Raster; -import java.awt.image.WritableRaster; -import java.awt.image.SinglePixelPackedSampleModel; import java.awt.image.ComponentSampleModel; import java.awt.image.DataBuffer; -import java.awt.image.DataBufferByte; -import java.awt.image.DataBufferUShort; -import java.awt.image.DataBufferInt; 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) { @@ -49,47 +42,34 @@ class LCMSImageLayout { } public static int EXTRA_SH(int x) { - return x<<7; + return x << 7; } public static int CHANNELS_SH(int x) { - return x<<3; + return x << 3; } - - public static final int SWAPFIRST = 1<<14; - - public static final int DOSWAP = 1<<10; - + 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); - + CHANNELS_SH(3) | BYTES_SH(1); public static final int PT_GRAY_8 = - CHANNELS_SH(1) | BYTES_SH(1); - + CHANNELS_SH(1) | BYTES_SH(1); public static final int PT_GRAY_16 = - CHANNELS_SH(1) | BYTES_SH(2); - + CHANNELS_SH(1) | BYTES_SH(2); public static final int PT_RGBA_8 = - EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1); - + 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; - + EXTRA_SH(1) | CHANNELS_SH(3) | BYTES_SH(1) | SWAPFIRST; public static final int PT_BGR_8 = - DOSWAP | CHANNELS_SH(3) | BYTES_SH(1); - + 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; - - + 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; @@ -98,25 +78,30 @@ class LCMSImageLayout { int nextRowOffset; 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 LCMSImageLayout(int np, int pixelType, int pixelSize) { this.pixelType = pixelType; width = np; height = 1; - nextRowOffset = np*pixelSize; + nextRowOffset = np * pixelSize; offset = 0; } private LCMSImageLayout(int width, int height, int pixelType, - int pixelSize) { + int pixelSize) { this.pixelType = pixelType; this.width = width; this.height = height; - nextRowOffset = width*pixelSize; + nextRowOffset = width * pixelSize; offset = 0; } - public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize) { this(np, pixelType, pixelSize); dataType = DT_BYTE; @@ -135,102 +120,218 @@ class LCMSImageLayout { dataArray = data; } - public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize) - { + public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize) { this(np, pixelType, pixelSize); dataType = DT_DOUBLE; dataArray = data; } - public LCMSImageLayout(BufferedImage image) { - ShortComponentRaster shortRaster; - IntegerComponentRaster intRaster; - ByteComponentRaster byteRaster; + 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) { + LCMSImageLayout l = new LCMSImageLayout(); + switch (image.getType()) { case BufferedImage.TYPE_INT_RGB: - pixelType = PT_ARGB_8; - isIntPacked = true; + l.pixelType = PT_ARGB_8; + l.isIntPacked = true; break; case BufferedImage.TYPE_INT_ARGB: - pixelType = PT_ARGB_8; - isIntPacked = true; + l.pixelType = PT_ARGB_8; + l.isIntPacked = true; break; case BufferedImage.TYPE_INT_BGR: - pixelType = PT_ABGR_8; - isIntPacked = true; + l.pixelType = PT_ABGR_8; + l.isIntPacked = true; break; case BufferedImage.TYPE_3BYTE_BGR: - pixelType = PT_BGR_8; + l.pixelType = PT_BGR_8; break; case BufferedImage.TYPE_4BYTE_ABGR: - pixelType = PT_ABGR_8; + l.pixelType = PT_ABGR_8; break; case BufferedImage.TYPE_BYTE_GRAY: - pixelType = PT_GRAY_8; + l.pixelType = PT_GRAY_8; break; case BufferedImage.TYPE_USHORT_GRAY: - pixelType = PT_GRAY_16; + l.pixelType = PT_GRAY_16; break; default: - // TODO: Add support for some images having - // SinglePixelPackedModel and ComponentSampleModel - throw new IllegalArgumentException( - "CMMImageLayout - bad image type passed to constructor"); + /* 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; } - width = image.getWidth(); - height = image.getHeight(); + 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: - intRaster = (IntegerComponentRaster)image.getRaster(); - nextRowOffset = intRaster.getScanlineStride()*4; - offset = intRaster.getDataOffset(0)*4; - dataArray = intRaster.getDataStorage(); - dataType = DT_INT; + do { + IntegerComponentRaster intRaster = (IntegerComponentRaster) + image.getRaster(); + l.nextRowOffset = intRaster.getScanlineStride() * 4; + l.offset = intRaster.getDataOffset(0) * 4; + l.dataArray = intRaster.getDataStorage(); + 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: - byteRaster = (ByteComponentRaster)image.getRaster(); - nextRowOffset = byteRaster.getScanlineStride(); - int firstBand = image.getSampleModel().getNumBands() - 1; - offset = byteRaster.getDataOffset(firstBand); - dataArray = byteRaster.getDataStorage(); - dataType = DT_BYTE; + do { + ByteComponentRaster byteRaster = (ByteComponentRaster) + image.getRaster(); + l.nextRowOffset = byteRaster.getScanlineStride(); + int firstBand = image.getSampleModel().getNumBands() - 1; + l.offset = byteRaster.getDataOffset(firstBand); + l.dataArray = byteRaster.getDataStorage(); + l.dataType = DT_BYTE; + if (l.nextRowOffset == l.width * byteRaster.getPixelStride()) { + l.imageAtOnce = true; + } + } while (false); break; case BufferedImage.TYPE_BYTE_GRAY: - byteRaster = (ByteComponentRaster)image.getRaster(); - nextRowOffset = byteRaster.getScanlineStride(); - offset = byteRaster.getDataOffset(0); - dataArray = byteRaster.getDataStorage(); - dataType = DT_BYTE; + do { + ByteComponentRaster byteRaster = (ByteComponentRaster) + image.getRaster(); + l.nextRowOffset = byteRaster.getScanlineStride(); + 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: - shortRaster = (ShortComponentRaster)image.getRaster(); - nextRowOffset = shortRaster.getScanlineStride()*2; - offset = shortRaster.getDataOffset(0) * 2; - dataArray = shortRaster.getDataStorage(); - dataType = DT_SHORT; + do { + ShortComponentRaster shortRaster = (ShortComponentRaster) + image.getRaster(); + l.nextRowOffset = shortRaster.getScanlineStride() * 2; + l.offset = shortRaster.getDataOffset(0) * 2; + l.dataArray = shortRaster.getDataStorage(); + l.dataType = DT_SHORT; + + if (l.nextRowOffset == l.width * 2 * shortRaster.getPixelStride()) { + l.imageAtOnce = true; + } + } while (false); break; + default: + return null; + } + 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; } } - public static boolean isSupported(BufferedImage image) { - switch (image.getType()) { - case BufferedImage.TYPE_INT_RGB: - case BufferedImage.TYPE_INT_ARGB: - case BufferedImage.TYPE_INT_BGR: - case BufferedImage.TYPE_3BYTE_BGR: - case BufferedImage.TYPE_4BYTE_ABGR: - case BufferedImage.TYPE_BYTE_GRAY: - case BufferedImage.TYPE_USHORT_GRAY: - return true; + public static LCMSImageLayout createImageLayout(Raster r) { + LCMSImageLayout l = new LCMSImageLayout(); + if (r instanceof ByteComponentRaster) { + 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.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 false; + return null; } } diff --git a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java index aa9d0bf054f..de8a77c75f3 100644 --- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java +++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java @@ -161,13 +161,18 @@ public class LCMSTransform implements ColorTransform { } public void colorConvert(BufferedImage src, BufferedImage dst) { - if (LCMSImageLayout.isSupported(src) && - LCMSImageLayout.isSupported(dst)) - { - doTransform(new LCMSImageLayout(src), new LCMSImageLayout(dst)); - return; - } LCMSImageLayout srcIL, dstIL; + + dstIL = LCMSImageLayout.createImageLayout(dst); + + if (dstIL != null) { + srcIL = LCMSImageLayout.createImageLayout(src); + if (srcIL != null) { + doTransform(srcIL, dstIL); + return; + } + } + Raster srcRas = src.getRaster(); WritableRaster dstRas = dst.getRaster(); ColorModel srcCM = src.getColorModel(); @@ -439,6 +444,14 @@ public class LCMSTransform implements ColorTransform { 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(); diff --git a/jdk/src/share/classes/sun/print/RasterPrinterJob.java b/jdk/src/share/classes/sun/print/RasterPrinterJob.java index 404f66cc26f..24bece595f8 100644 --- a/jdk/src/share/classes/sun/print/RasterPrinterJob.java +++ b/jdk/src/share/classes/sun/print/RasterPrinterJob.java @@ -527,9 +527,92 @@ public abstract class RasterPrinterJob extends PrinterJob { } } + private PageFormat attributeToPageFormat(PrintService service, + PrintRequestAttributeSet attSet) { + PageFormat page = defaultPage(); + + if (service == null) { + return page; + } + + OrientationRequested orient = (OrientationRequested) + attSet.get(OrientationRequested.class); + if (orient == null) { + orient = (OrientationRequested) + service.getDefaultAttributeValue(OrientationRequested.class); + } + if (orient == OrientationRequested.REVERSE_LANDSCAPE) { + page.setOrientation(PageFormat.REVERSE_LANDSCAPE); + } else if (orient == OrientationRequested.LANDSCAPE) { + page.setOrientation(PageFormat.LANDSCAPE); + } else { + page.setOrientation(PageFormat.PORTRAIT); + } + + Media media = (Media)attSet.get(Media.class); + if (media == null) { + media = + (Media)service.getDefaultAttributeValue(Media.class); + } + if (!(media instanceof MediaSizeName)) { + media = MediaSizeName.NA_LETTER; + } + MediaSize size = + MediaSize.getMediaSizeForName((MediaSizeName)media); + if (size == null) { + size = MediaSize.NA.LETTER; + } + Paper paper = new Paper(); + float dim[] = size.getSize(1); //units == 1 to avoid FP error + double w = Math.rint((dim[0]*72.0)/Size2DSyntax.INCH); + double h = Math.rint((dim[1]*72.0)/Size2DSyntax.INCH); + paper.setSize(w, h); + MediaPrintableArea area = + (MediaPrintableArea) + attSet.get(MediaPrintableArea.class); + double ix, iw, iy, ih; + + if (area != null) { + // Should pass in same unit as updatePageAttributes + // to avoid rounding off errors. + ix = Math.rint( + area.getX(MediaPrintableArea.INCH) * DPI); + iy = Math.rint( + area.getY(MediaPrintableArea.INCH) * DPI); + iw = Math.rint( + area.getWidth(MediaPrintableArea.INCH) * DPI); + ih = Math.rint( + area.getHeight(MediaPrintableArea.INCH) * DPI); + } + else { + if (w >= 72.0 * 6.0) { + ix = 72.0; + iw = w - 2 * 72.0; + } else { + ix = w / 6.0; + iw = w * 0.75; + } + if (h >= 72.0 * 6.0) { + iy = 72.0; + ih = h - 2 * 72.0; + } else { + iy = h / 6.0; + ih = h * 0.75; + } + } + paper.setImageableArea(ix, iy, iw, ih); + page.setPaper(paper); + return page; + } protected void updatePageAttributes(PrintService service, PageFormat page) { + updateAttributesWithPageFormat(service, page, this.attributes); + } + + protected void updateAttributesWithPageFormat(PrintService service, + PageFormat page, + PrintRequestAttributeSet attributes) { if (service == null || page == null) { return; } @@ -659,6 +742,18 @@ public abstract class RasterPrinterJob extends PrinterJob { throw new HeadlessException(); } + DialogTypeSelection dlg = + (DialogTypeSelection)attributes.get(DialogTypeSelection.class); + + // Check for native, note that default dialog is COMMON. + if (dlg == DialogTypeSelection.NATIVE) { + PrintService pservice = getPrintService(); + PageFormat page = pageDialog(attributeToPageFormat(pservice, + attributes)); + updateAttributesWithPageFormat(pservice, page, attributes); + return page; + } + final GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment(). getDefaultScreenDevice().getDefaultConfiguration(); @@ -698,77 +793,7 @@ public abstract class RasterPrinterJob extends PrinterJob { attributes.remove(amCategory); } attributes.addAll(newas); - - PageFormat page = defaultPage(); - - OrientationRequested orient = - (OrientationRequested) - attributes.get(OrientationRequested.class); - int pfOrient = PageFormat.PORTRAIT; - if (orient != null) { - if (orient == OrientationRequested.REVERSE_LANDSCAPE) { - pfOrient = PageFormat.REVERSE_LANDSCAPE; - } else if (orient == OrientationRequested.LANDSCAPE) { - pfOrient = PageFormat.LANDSCAPE; - } - } - page.setOrientation(pfOrient); - - Media media = (Media)attributes.get(Media.class); - if (media == null) { - media = - (Media)service.getDefaultAttributeValue(Media.class); - } - if (!(media instanceof MediaSizeName)) { - media = MediaSizeName.NA_LETTER; - } - MediaSize size = - MediaSize.getMediaSizeForName((MediaSizeName)media); - if (size == null) { - size = MediaSize.NA.LETTER; - } - Paper paper = new Paper(); - float dim[] = size.getSize(1); //units == 1 to avoid FP error - double w = Math.rint((dim[0]*72.0)/Size2DSyntax.INCH); - double h = Math.rint((dim[1]*72.0)/Size2DSyntax.INCH); - paper.setSize(w, h); - MediaPrintableArea area = - (MediaPrintableArea) - attributes.get(MediaPrintableArea.class); - double ix, iw, iy, ih; - - if (area != null) { - // Should pass in same unit as updatePageAttributes - // to avoid rounding off errors. - ix = Math.rint( - area.getX(MediaPrintableArea.INCH) * DPI); - iy = Math.rint( - area.getY(MediaPrintableArea.INCH) * DPI); - iw = Math.rint( - area.getWidth(MediaPrintableArea.INCH) * DPI); - ih = Math.rint( - area.getHeight(MediaPrintableArea.INCH) * DPI); - } - else { - if (w >= 72.0 * 6.0) { - ix = 72.0; - iw = w - 2 * 72.0; - } else { - ix = w / 6.0; - iw = w * 0.75; - } - if (h >= 72.0 * 6.0) { - iy = 72.0; - ih = h - 2 * 72.0; - } else { - iy = h / 6.0; - ih = h * 0.75; - } - } - paper.setImageableArea(ix, iy, iw, ih); - page.setPaper(paper); - - return page; + return attributeToPageFormat(service, attributes); } else { return null; } @@ -795,7 +820,6 @@ public abstract class RasterPrinterJob extends PrinterJob { throw new HeadlessException(); } - DialogTypeSelection dlg = (DialogTypeSelection)attributes.get(DialogTypeSelection.class); @@ -816,7 +840,6 @@ public abstract class RasterPrinterJob extends PrinterJob { } - /* A security check has already been performed in the * java.awt.print.printerJob.getPrinterJob method. * So by the time we get here, it is OK for the current thread diff --git a/jdk/src/share/demo/java2d/J2DBench/build.xml b/jdk/src/share/demo/java2d/J2DBench/build.xml index a36aca8cec7..c29611d0f7a 100644 --- a/jdk/src/share/demo/java2d/J2DBench/build.xml +++ b/jdk/src/share/demo/java2d/J2DBench/build.xml @@ -52,7 +52,7 @@ - - + + + + - - diff --git a/jdk/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_large.jpg b/jdk/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_large.jpg new file mode 100644 index 00000000000..6d61c9f120f Binary files /dev/null and b/jdk/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_large.jpg differ diff --git a/jdk/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_medium.jpg b/jdk/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_medium.jpg new file mode 100644 index 00000000000..6b4ef3f38d1 Binary files /dev/null and b/jdk/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_medium.jpg differ diff --git a/jdk/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_small.jpg b/jdk/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_small.jpg new file mode 100644 index 00000000000..41fb2eaccba Binary files /dev/null and b/jdk/src/share/demo/java2d/J2DBench/resources/cmm_images/img_icc_small.jpg differ diff --git a/jdk/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/ColorConversionTests.java b/jdk/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/ColorConversionTests.java index e71b18857f1..4916929c32f 100644 --- a/jdk/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/ColorConversionTests.java +++ b/jdk/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/ColorConversionTests.java @@ -51,6 +51,7 @@ public class ColorConversionTests extends CMMTests { DataConversionTests.init(); ColorConvertOpTests.init(); + EmbeddedProfileTests.init(); } protected ColorConversionTests(Group parent, String nodeName, String description) { diff --git a/jdk/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/EmbeddedProfileTests.java b/jdk/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/EmbeddedProfileTests.java new file mode 100644 index 00000000000..3af6313eff1 --- /dev/null +++ b/jdk/src/share/demo/java2d/J2DBench/src/j2dbench/tests/cmm/EmbeddedProfileTests.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ + +package j2dbench.tests.cmm; + +import j2dbench.Group; +import j2dbench.Option; +import j2dbench.Result; +import j2dbench.TestEnvironment; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.net.URL; +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.stream.ImageInputStream; + +/* This benchmark verifies how changes in cmm library affects image decoding */ +public class EmbeddedProfileTests extends ColorConversionTests { + + protected static Group grpRoot; + protected static Group grpOptionsRoot; + + protected static Option inputImages; + + public static void init() { + grpRoot = new Group(colorConvRoot, "embed", "Embedded Profile Tests"); + + grpOptionsRoot = new Group(grpRoot, "embedOptions", "Options"); + + inputImages = createImageList(); + + new ReadImageTest(); + } + + private static enum IccImageResource { + SMALL("images/img_icc_small.jpg", "512x512", "Small: 512x512"), + MEDIUM("images/img_icc_medium.jpg", "2048x2048", "Medium: 2048x2048"), + LARGE("images/img_icc_large.jpg", "4096x4096", "Large: 4096x4096"); + + private IccImageResource(String file, String name, String description) { + this.url = CMMTests.class.getResource(file); + this.abbrev = name; + this.description = description; + } + + public final URL url; + public final String abbrev; + public final String description; + } + + private static Option createImageList() { + IccImageResource[] images = IccImageResource.values(); + + int num = images.length; + + String[] names = new String[num]; + String[] abbrev = new String[num]; + String[] descr = new String[num]; + + for (int i = 0; i < num; i++) { + names[i] = images[i].toString(); + abbrev[i] = images[i].abbrev; + descr[i] = images[i].description; + } + + Option list = new Option.ObjectList(grpOptionsRoot, + "Images", "Input Images", + names, images, abbrev, descr, 1); + + return list; + } + + public EmbeddedProfileTests(Group parent, String nodeName, String description) { + super(parent, nodeName, description); + addDependencies(grpOptionsRoot, true); + } + + private static class Context { + URL input; + + public Context(TestEnvironment env, Result res) { + + IccImageResource icc_input = (IccImageResource) + env.getModifier(inputImages); + + input = icc_input.url; + } + } + + public Object initTest(TestEnvironment env, Result res) { + return new Context(env, res); + } + + public void cleanupTest(TestEnvironment env, Object o) { + Context ctx = (Context)o; + ctx.input = null; + } + + private static class ReadImageTest extends EmbeddedProfileTests { + public ReadImageTest() { + super(grpRoot, "embd_img_read", "ImageReader.read()"); + } + + public void runTest(Object octx, int numReps) { + final Context ctx = (Context)octx; + final URL url = ctx.input; + ImageInputStream iis = null; + ImageReader reader = null; + + try { + iis = ImageIO.createImageInputStream(url.openStream()); + reader = ImageIO.getImageReaders(iis).next(); + } catch (IOException e) { + throw new RuntimeException("Unable to run the becnhmark", e); + } + + do { + try { + reader.setInput(iis); + BufferedImage img = reader.read(0); + reader.reset(); + + iis = ImageIO.createImageInputStream(url.openStream()); + } catch (Exception e) { + e.printStackTrace(); + } + } while (--numReps >= 0); + } + } +} diff --git a/jdk/src/share/native/sun/font/layout/LookupProcessor.cpp b/jdk/src/share/native/sun/font/layout/LookupProcessor.cpp index 60727aa3f3a..88e9f25ddeb 100644 --- a/jdk/src/share/native/sun/font/layout/LookupProcessor.cpp +++ b/jdk/src/share/native/sun/font/layout/LookupProcessor.cpp @@ -125,6 +125,10 @@ le_uint32 LookupProcessor::applySingleLookup(le_uint16 lookupTableIndex, GlyphIt } const LookupTable *lookupTable = lookupListTable->getLookupTable(lookupTableIndex); + if (lookupTable == NULL) { + success = LE_INTERNAL_ERROR; + return 0; + } le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags); GlyphIterator tempIterator(*glyphIterator, lookupFlags); le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance, success); diff --git a/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c b/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c index 7da0370baad..1340c82a822 100644 --- a/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c @@ -117,6 +117,7 @@ static jfieldID IL_offset_fID; static jfieldID IL_nextRowOffset_fID; static jfieldID IL_width_fID; static jfieldID IL_height_fID; +static jfieldID IL_imageAtOnce_fID; static jfieldID PF_ID_fID; JavaVM *javaVM; @@ -237,7 +238,7 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_createNativeTransform * Method: loadProfile * Signature: ([B)J */ -JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfile +JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative (JNIEnv *env, jobject obj, jbyteArray data) { jbyte* dataArray; @@ -284,7 +285,7 @@ JNIEXPORT jlong JNICALL Java_sun_java2d_cmm_lcms_LCMS_loadProfile * Method: freeProfile * Signature: (J)V */ -JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfile +JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative (JNIEnv *env, jobject obj, jlong id) { storeID_t sProf; @@ -369,48 +370,22 @@ static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize); static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize); static cmsBool _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jbyte *pData, jint size); -/* - * Class: sun_java2d_cmm_lcms_LCMS - * Method: getTagSize - * Signature: (JI)I - */ -JNIEXPORT jint JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagSize - (JNIEnv *env, jobject obj, jlong id, jint tagSig) -{ - storeID_t sProf; - TagSignature_t sig; - jint result = -1; - - sProf.j = id; - sig.j = tagSig; - - if (tagSig == SigHead) { - result = sizeof(cmsICCHeader); - } else { - if (cmsIsTag(sProf.pf, sig.cms)) { - result = cmsReadRawTag(sProf.pf, sig.cms, NULL, 0); - } else { - JNU_ThrowByName(env, "java/awt/color/CMMException", - "ICC profile tag not found"); - } - } - - return result; -} /* * Class: sun_java2d_cmm_lcms_LCMS * Method: getTagData * Signature: (JI[B)V */ -JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagData - (JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data) +JNIEXPORT jbyteArray JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagNative + (JNIEnv *env, jobject obj, jlong id, jint tagSig) { storeID_t sProf; TagSignature_t sig; cmsInt32Number tagSize; - jbyte* dataArray; + jbyte* dataArray = NULL; + jbyteArray data = NULL; + jint bufSize; sProf.j = id; @@ -419,12 +394,14 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagData if (tagSig == SigHead) { cmsBool status; - bufSize =(*env)->GetArrayLength(env, data); + // allocate java array + bufSize = sizeof(cmsICCHeader); + data = (*env)->NewByteArray(env, bufSize); - if (bufSize < sizeof(cmsICCHeader)) { - JNU_ThrowByName(env, "java/awt/color/CMMException", - "Insufficient buffer capacity"); - return; + if (data == NULL) { + JNU_ThrowByName(env, "java/awt/color/CMMException", + "Unable to allocate buffer"); + return NULL; } dataArray = (*env)->GetByteArrayElements (env, data, 0); @@ -432,7 +409,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagData if (dataArray == NULL) { JNU_ThrowByName(env, "java/awt/color/CMMException", "Unable to get buffer"); - return; + return NULL; } status = _getHeaderInfo(sProf.pf, dataArray, bufSize); @@ -442,9 +419,10 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagData if (!status) { JNU_ThrowByName(env, "java/awt/color/CMMException", "ICC Profile header not found"); + return NULL; } - return; + return data; } if (cmsIsTag(sProf.pf, sig.cms)) { @@ -452,16 +430,15 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagData } else { JNU_ThrowByName(env, "java/awt/color/CMMException", "ICC profile tag not found"); - return; + return NULL; } - // verify data buffer capacity - bufSize = (*env)->GetArrayLength(env, data); - - if (tagSize < 0 || 0 > bufSize || tagSize > bufSize) { + // allocate java array + data = (*env)->NewByteArray(env, tagSize); + if (data == NULL) { JNU_ThrowByName(env, "java/awt/color/CMMException", - "Insufficient buffer capacity."); - return; + "Unable to allocate buffer"); + return NULL; } dataArray = (*env)->GetByteArrayElements (env, data, 0); @@ -469,7 +446,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagData if (dataArray == NULL) { JNU_ThrowByName(env, "java/awt/color/CMMException", "Unable to get buffer"); - return; + return NULL; } bufSize = cmsReadRawTag(sProf.pf, sig.cms, dataArray, tagSize); @@ -479,8 +456,9 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagData if (bufSize != tagSize) { JNU_ThrowByName(env, "java/awt/color/CMMException", "Can not get tag data."); + return NULL; } - return; + return data; } /* @@ -488,7 +466,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_getTagData * Method: setTagData * Signature: (JI[B)V */ -JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagData +JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative (JNIEnv *env, jobject obj, jlong id, jint tagSig, jbyteArray data) { storeID_t sProf; @@ -586,6 +564,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert char* inputRow; char* outputRow; jobject srcData, dstData; + jboolean srcAtOnce = JNI_FALSE, dstAtOnce = JNI_FALSE; srcOffset = (*env)->GetIntField (env, src, IL_offset_fID); srcNextRowOffset = (*env)->GetIntField (env, src, IL_nextRowOffset_fID); @@ -594,6 +573,9 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert width = (*env)->GetIntField (env, src, IL_width_fID); height = (*env)->GetIntField (env, src, IL_height_fID); + srcAtOnce = (*env)->GetBooleanField(env, src, IL_imageAtOnce_fID); + dstAtOnce = (*env)->GetBooleanField(env, dst, IL_imageAtOnce_fID); + sTrans.j = (*env)->GetLongField (env, trans, Trans_ID_fID); if (sTrans.xf == NULL) { @@ -625,10 +607,14 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_colorConvert inputRow = (char*)inputBuffer + srcOffset; outputRow = (char*)outputBuffer + dstOffset; - for (i = 0; i < height; i++) { - cmsDoTransform(sTrans.xf, inputRow, outputRow, width); - inputRow += srcNextRowOffset; - outputRow += dstNextRowOffset; + if (srcAtOnce && dstAtOnce) { + cmsDoTransform(sTrans.xf, inputRow, outputRow, width * height); + } else { + for (i = 0; i < height; i++) { + cmsDoTransform(sTrans.xf, inputRow, outputRow, width); + inputRow += srcNextRowOffset; + outputRow += dstNextRowOffset; + } } releaseILData(env, inputBuffer, srcDType, srcData); @@ -670,6 +656,7 @@ JNIEXPORT void JNICALL Java_sun_java2d_cmm_lcms_LCMS_initLCMS IL_width_fID = (*env)->GetFieldID (env, IL, "width", "I"); IL_height_fID = (*env)->GetFieldID (env, IL, "height", "I"); IL_offset_fID = (*env)->GetFieldID (env, IL, "offset", "I"); + IL_imageAtOnce_fID = (*env)->GetFieldID (env, IL, "imageAtOnce", "Z"); IL_nextRowOffset_fID = (*env)->GetFieldID (env, IL, "nextRowOffset", "I"); PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J"); diff --git a/jdk/src/share/native/sun/java2d/loops/AnyByteBinary.h b/jdk/src/share/native/sun/java2d/loops/AnyByteBinary.h index abe7f230bee..3b1fa03b06a 100644 --- a/jdk/src/share/native/sun/java2d/loops/AnyByteBinary.h +++ b/jdk/src/share/native/sun/java2d/loops/AnyByteBinary.h @@ -153,7 +153,10 @@ jint PREFIX ## rgb; #define InitByteBinaryAlphaLoadData(TYPE, PREFIX, pRasInfo) \ - PREFIX ## Lut = (pRasInfo)->lutBase + do { \ + PREFIX ## Lut = (pRasInfo)->lutBase; \ + PREFIX ## rgb = 0; \ + } while (0) #define LoadAlphaFromByteBinaryFor4ByteArgb(TYPE, pRas, PREFIX, COMP_PREFIX) \ do { \ diff --git a/jdk/src/share/native/sun/java2d/loops/ByteIndexed.h b/jdk/src/share/native/sun/java2d/loops/ByteIndexed.h index 3917c238e48..215cfc0e111 100644 --- a/jdk/src/share/native/sun/java2d/loops/ByteIndexed.h +++ b/jdk/src/share/native/sun/java2d/loops/ByteIndexed.h @@ -202,7 +202,10 @@ typedef jubyte ByteIndexedBmDataType; jint PREFIX ## rgb; #define InitByteIndexedAlphaLoadData(PREFIX, pRasInfo) \ - PREFIX ## Lut = (pRasInfo)->lutBase + do { \ + PREFIX ## Lut = (pRasInfo)->lutBase; \ + PREFIX ## rgb = 0; \ + } while (0) #define LoadAlphaFromByteIndexedFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \ do { \ diff --git a/jdk/src/share/native/sun/java2d/loops/IntArgb.h b/jdk/src/share/native/sun/java2d/loops/IntArgb.h index aec63431cb1..f4ec00524cc 100644 --- a/jdk/src/share/native/sun/java2d/loops/IntArgb.h +++ b/jdk/src/share/native/sun/java2d/loops/IntArgb.h @@ -122,7 +122,8 @@ typedef jint IntArgbDataType; #define DeclareIntArgbAlphaLoadData(PREFIX) \ jint PREFIX; -#define InitIntArgbAlphaLoadData(PREFIX, pRasInfo) +#define InitIntArgbAlphaLoadData(PREFIX, pRasInfo) \ + PREFIX = 0 #define LoadAlphaFromIntArgbFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \ do { \ diff --git a/jdk/src/share/native/sun/java2d/loops/IntArgbBm.h b/jdk/src/share/native/sun/java2d/loops/IntArgbBm.h index 81d551820a8..675fba1d228 100644 --- a/jdk/src/share/native/sun/java2d/loops/IntArgbBm.h +++ b/jdk/src/share/native/sun/java2d/loops/IntArgbBm.h @@ -133,7 +133,8 @@ typedef jint IntArgbBmDataType; #define DeclareIntArgbBmAlphaLoadData(PREFIX) \ jint PREFIX; -#define InitIntArgbBmAlphaLoadData(PREFIX, pRasInfo) +#define InitIntArgbBmAlphaLoadData(PREFIX, pRasInfo) \ + PREFIX = 0 #define LoadAlphaFromIntArgbBmFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \ do { \ diff --git a/jdk/src/share/native/sun/java2d/loops/IntArgbPre.h b/jdk/src/share/native/sun/java2d/loops/IntArgbPre.h index 5ffb9dacb0b..c45013d0e00 100644 --- a/jdk/src/share/native/sun/java2d/loops/IntArgbPre.h +++ b/jdk/src/share/native/sun/java2d/loops/IntArgbPre.h @@ -153,7 +153,8 @@ typedef jint IntArgbPreDataType; #define DeclareIntArgbPreAlphaLoadData(PREFIX) \ jint PREFIX; -#define InitIntArgbPreAlphaLoadData(PREFIX, pRasInfo) +#define InitIntArgbPreAlphaLoadData(PREFIX, pRasInfo) \ + PREFIX = 0 #define LoadAlphaFromIntArgbPreFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \ do { \ diff --git a/jdk/src/share/native/sun/java2d/loops/TransformHelper.c b/jdk/src/share/native/sun/java2d/loops/TransformHelper.c index 23bba354756..72334550250 100644 --- a/jdk/src/share/native/sun/java2d/loops/TransformHelper.c +++ b/jdk/src/share/native/sun/java2d/loops/TransformHelper.c @@ -353,6 +353,9 @@ Java_sun_java2d_loops_TransformHelper_Transform pInterpFunc = pBicubicFunc; maxlinepix = LINE_SIZE / 16; break; + default: + // Should not happen, but just in case. + return; } srcInfo.bounds.x1 = sx1; diff --git a/jdk/src/share/native/sun/java2d/loops/Ushort4444Argb.h b/jdk/src/share/native/sun/java2d/loops/Ushort4444Argb.h index 348e03b7df4..aa50d8b0ff3 100644 --- a/jdk/src/share/native/sun/java2d/loops/Ushort4444Argb.h +++ b/jdk/src/share/native/sun/java2d/loops/Ushort4444Argb.h @@ -120,7 +120,8 @@ typedef jushort Ushort4444ArgbDataType; #define DeclareUshort4444ArgbAlphaLoadData(PREFIX) \ jint PREFIX; -#define InitUshort4444ArgbAlphaLoadData(PREFIX, pRasInfo) +#define InitUshort4444ArgbAlphaLoadData(PREFIX, pRasInfo) \ + PREFIX = 0 #define LoadAlphaFromUshort4444ArgbFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \ do { \ diff --git a/jdk/src/share/native/sun/java2d/loops/UshortIndexed.h b/jdk/src/share/native/sun/java2d/loops/UshortIndexed.h index 7786bda3829..6a4b5b13e5d 100644 --- a/jdk/src/share/native/sun/java2d/loops/UshortIndexed.h +++ b/jdk/src/share/native/sun/java2d/loops/UshortIndexed.h @@ -170,7 +170,10 @@ typedef jushort UshortIndexedBmDataType; jint PREFIX ## rgb; #define InitUshortIndexedAlphaLoadData(PREFIX, pRasInfo) \ - PREFIX ## Lut = (pRasInfo)->lutBase + do { \ + PREFIX ## Lut = (pRasInfo)->lutBase; \ + PREFIX ## rgb = 0; \ + } while (0) #define LoadAlphaFromUshortIndexedFor4ByteArgb(pRas, PREFIX, COMP_PREFIX) \ do { \