diff --git a/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java b/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java index d2da59617f1..816031d73bc 100644 --- a/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java +++ b/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java @@ -31,6 +31,7 @@ import java.awt.image.ColorModel; import java.awt.image.ComponentColorModel; import java.awt.image.ComponentSampleModel; import java.awt.image.Raster; +import java.lang.annotation.Native; import java.nio.ByteOrder; import sun.awt.image.ByteComponentRaster; @@ -70,10 +71,12 @@ final class LCMSImageLayout { // private static final int PT_BGRA_8 = PT_ABGR_8 | SWAPFIRST; private static final int SWAP_ENDIAN = ByteOrder.nativeOrder() == LITTLE_ENDIAN ? DOSWAP : 0; + @Native private static final int DT_BYTE = 0; + @Native private static final int DT_SHORT = 1; + @Native private static final int DT_INT = 2; - private static final int DT_DOUBLE = 3; int pixelType; int dataType; int width; @@ -86,59 +89,33 @@ final class LCMSImageLayout { private int dataArrayLength; /* in bytes */ - private LCMSImageLayout(int np, int pixelType, int pixelSize) { - this.pixelType = pixelType; - width = np; + /** + * Creates a layout object for given parameters. + * + * @param data the storage of pixels: {@code byte[], short[] or int[]} + * @param length the length of the data array + * @param nc the number of color components + * @param dt the type of data array: DT_BYTE, DT_SHORT or DT_INT + * @param size the size of one color component in bytes + */ + private LCMSImageLayout(Object data, int length, int nc, int dt, int size) { + dataArray = data; + dataType = dt; + dataArrayLength = length * size; + pixelType = CHANNELS_SH(nc) | BYTES_SH(size); + width = length / nc; height = 1; - nextPixelOffset = pixelSize; - nextRowOffset = safeMult(pixelSize, np); - offset = 0; - } - - private LCMSImageLayout(int width, int height, int pixelType, int pixelSize) - { - this.pixelType = pixelType; - this.width = width; - this.height = height; - nextPixelOffset = pixelSize; - nextRowOffset = safeMult(pixelSize, width); - offset = 0; - } - - LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize) { - this(np, pixelType, pixelSize); - dataType = DT_BYTE; - dataArray = data; - dataArrayLength = data.length; - + nextPixelOffset = nc * size; + nextRowOffset = dataArrayLength; // outside of data since height is 1 verify(); } - LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize) { - this(np, pixelType, pixelSize); - dataType = DT_SHORT; - dataArray = data; - dataArrayLength = 2 * data.length; - - verify(); + LCMSImageLayout(byte[] data, int nc) { + this(data, data.length, nc, DT_BYTE, Byte.BYTES); } - LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize) { - this(np, pixelType, pixelSize); - dataType = DT_INT; - dataArray = data; - dataArrayLength = 4 * data.length; - - verify(); - } - - LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize) { - this(np, pixelType, pixelSize); - dataType = DT_DOUBLE; - dataArray = data; - dataArrayLength = 8 * data.length; - - verify(); + LCMSImageLayout(short[] data, int nc) { + this(data, data.length, nc, DT_SHORT, Short.BYTES); } private LCMSImageLayout() { @@ -151,15 +128,12 @@ final class LCMSImageLayout { LCMSImageLayout l = new LCMSImageLayout(); switch (image.getType()) { - case BufferedImage.TYPE_INT_RGB: + case BufferedImage.TYPE_INT_RGB, BufferedImage.TYPE_INT_ARGB: l.pixelType = PT_ARGB_8 ^ SWAP_ENDIAN; break; case BufferedImage.TYPE_INT_ARGB_PRE: l.pixelType = PT_ARGB_8_PREMUL ^ SWAP_ENDIAN; break; - case BufferedImage.TYPE_INT_ARGB: - l.pixelType = PT_ARGB_8 ^ SWAP_ENDIAN; - break; case BufferedImage.TYPE_INT_BGR: l.pixelType = PT_ABGR_8 ^ SWAP_ENDIAN; break; @@ -201,74 +175,56 @@ final class LCMSImageLayout { l.height = image.getHeight(); switch (image.getType()) { - case BufferedImage.TYPE_INT_RGB: - case BufferedImage.TYPE_INT_ARGB: - case BufferedImage.TYPE_INT_ARGB_PRE: - 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; - } while (false); - break; - - case BufferedImage.TYPE_3BYTE_BGR: - case BufferedImage.TYPE_4BYTE_ABGR: - case BufferedImage.TYPE_4BYTE_ABGR_PRE: - do { - ByteComponentRaster byteRaster = (ByteComponentRaster) - image.getRaster(); - l.nextRowOffset = byteRaster.getScanlineStride(); - l.nextPixelOffset = byteRaster.getPixelStride(); - - int firstBand = byteRaster.getSampleModel().getNumBands() - 1; - l.offset = byteRaster.getDataOffset(firstBand); - l.dataArray = byteRaster.getDataStorage(); - l.dataArrayLength = byteRaster.getDataStorage().length; - l.dataType = DT_BYTE; - } 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; - } 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; - } while (false); - break; - default: + case BufferedImage.TYPE_INT_RGB, BufferedImage.TYPE_INT_ARGB, + BufferedImage.TYPE_INT_ARGB_PRE, BufferedImage.TYPE_INT_BGR -> + { + var 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; + } + case BufferedImage.TYPE_3BYTE_BGR, BufferedImage.TYPE_4BYTE_ABGR, + BufferedImage.TYPE_4BYTE_ABGR_PRE -> + { + var byteRaster = (ByteComponentRaster) image.getRaster(); + l.nextRowOffset = byteRaster.getScanlineStride(); + l.nextPixelOffset = byteRaster.getPixelStride(); + int firstBand = byteRaster.getSampleModel().getNumBands() - 1; + l.offset = byteRaster.getDataOffset(firstBand); + l.dataArray = byteRaster.getDataStorage(); + l.dataArrayLength = byteRaster.getDataStorage().length; + l.dataType = DT_BYTE; + } + case BufferedImage.TYPE_BYTE_GRAY -> { + var byteRaster = (ByteComponentRaster) image.getRaster(); + l.nextRowOffset = byteRaster.getScanlineStride(); + l.nextPixelOffset = byteRaster.getPixelStride(); + l.offset = byteRaster.getDataOffset(0); + l.dataArray = byteRaster.getDataStorage(); + l.dataArrayLength = byteRaster.getDataStorage().length; + l.dataType = DT_BYTE; + } + case BufferedImage.TYPE_USHORT_GRAY -> { + var 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; + } + default -> { return null; + } } l.verify(); return l; } - private static enum BandOrder { + private enum BandOrder { DIRECT, INVERTED, ARBITRARY, @@ -333,12 +289,9 @@ final class LCMSImageLayout { static LCMSImageLayout createImageLayout(Raster r, ColorModel cm) { LCMSImageLayout l = new LCMSImageLayout(); - if (r instanceof ByteComponentRaster && - r.getSampleModel() instanceof ComponentSampleModel) { - ByteComponentRaster br = (ByteComponentRaster)r; - - ComponentSampleModel csm = (ComponentSampleModel)r.getSampleModel(); - + if (r instanceof ByteComponentRaster br && + r.getSampleModel() instanceof ComponentSampleModel csm) + { int numBands = br.getNumBands(); boolean hasAlpha = cm != null && cm.hasAlpha(); l.pixelType = (hasAlpha ? CHANNELS_SH(numBands - 1) | EXTRA_SH(1) diff --git a/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java b/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java index 077b940d4ca..59f023a9aa2 100644 --- a/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java +++ b/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java @@ -206,14 +206,8 @@ final class LCMSTransform implements ColorTransform { } int idx; // TODO check for src npixels = dst npixels - 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()); + srcIL = new LCMSImageLayout(srcLine, getNumInComponents()); + dstIL = new LCMSImageLayout(dstLine, getNumOutComponents()); // process each scanline for (int y = 0; y < h; y++) { // convert src scanline @@ -262,15 +256,8 @@ final class LCMSTransform implements ColorTransform { alpha = new float[w]; } int idx; - 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); + srcIL = new LCMSImageLayout(srcLine, getNumInComponents()); + dstIL = new LCMSImageLayout(dstLine, getNumOutComponents()); // process each scanline for (int y = 0; y < h; y++) { // convert src scanline @@ -379,15 +366,8 @@ final class LCMSTransform implements ColorTransform { short[] srcLine = new short[w * srcNumBands]; short[] dstLine = new short[w * dstNumBands]; int idx; - 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); + srcIL = new LCMSImageLayout(srcLine, getNumInComponents()); + dstIL = new LCMSImageLayout(dstLine, getNumOutComponents()); // process each scanline for (int y = 0; y < h; y++, ys++, yd++) { // get src scanline @@ -478,14 +458,8 @@ final class LCMSTransform implements ColorTransform { byte[] dstLine = new byte[w * dstNumBands]; int idx; // TODO check for src npixels = dst npixels - 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()); + srcIL = new LCMSImageLayout(srcLine, getNumInComponents()); + dstIL = new LCMSImageLayout(dstLine, getNumOutComponents()); // process each scanline for (int y = 0; y < h; y++, ys++, yd++) { // get src scanline @@ -517,15 +491,8 @@ final class LCMSTransform implements ColorTransform { short[] srcLine = new short[w * srcNumBands]; short[] dstLine = new short[w * dstNumBands]; int idx; - 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); + srcIL = new LCMSImageLayout(srcLine, getNumInComponents()); + dstIL = new LCMSImageLayout(dstLine, getNumOutComponents()); // process each scanline for (int y = 0; y < h; y++, ys++, yd++) { // get src scanline @@ -561,40 +528,20 @@ final class LCMSTransform implements ColorTransform { /* 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()]; + dst = new short[(src.length / numInComponents) * numOutComponents]; } - 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); - + doTransform(new LCMSImageLayout(src, numInComponents), + new LCMSImageLayout(dst, numOutComponents)); return dst; } public byte[] colorConvert(byte[] src, byte[] dst) { if (dst == null) { - dst = new byte [(src.length/getNumInComponents())*getNumOutComponents()]; + dst = new byte[(src.length / numInComponents) * numOutComponents]; } - 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); + doTransform(new LCMSImageLayout(src, numInComponents), + new LCMSImageLayout(dst, numOutComponents)); return dst; } diff --git a/src/java.desktop/share/native/liblcms/LCMS.c b/src/java.desktop/share/native/liblcms/LCMS.c index 2041db2b6e9..0d779ede511 100644 --- a/src/java.desktop/share/native/liblcms/LCMS.c +++ b/src/java.desktop/share/native/liblcms/LCMS.c @@ -27,6 +27,7 @@ #include #include #include "sun_java2d_cmm_lcms_LCMS.h" +#include "sun_java2d_cmm_lcms_LCMSImageLayout.h" #include "jni_util.h" #include "Trace.h" #include "Disposer.h" @@ -45,10 +46,9 @@ #define SigHead TagIdConst('h','e','a','d') -#define DT_BYTE 0 -#define DT_SHORT 1 -#define DT_INT 2 -#define DT_DOUBLE 3 +#define DT_BYTE sun_java2d_cmm_lcms_LCMSImageLayout_DT_BYTE +#define DT_SHORT sun_java2d_cmm_lcms_LCMSImageLayout_DT_SHORT +#define DT_INT sun_java2d_cmm_lcms_LCMSImageLayout_DT_INT /* Default temp profile list size */ #define DF_ICC_BUF_SIZE 32 @@ -478,8 +478,6 @@ static void *getILData(JNIEnv *env, jobject data, jint type) { return (*env)->GetShortArrayElements(env, data, 0); case DT_INT: return (*env)->GetIntArrayElements(env, data, 0); - case DT_DOUBLE: - return (*env)->GetDoubleArrayElements(env, data, 0); default: return NULL; } @@ -497,9 +495,6 @@ static void releaseILData(JNIEnv *env, void *pData, jint type, jobject data, case DT_INT: (*env)->ReleaseIntArrayElements(env, data, (jint *) pData, mode); break; - case DT_DOUBLE: - (*env)->ReleaseDoubleArrayElements(env, data, (jdouble *) pData, mode); - break; } }