[OpenJDK 2D-Dev] RFR: 8012229: [lcms] Improve performance of color conversion for images with alpha channel

Sergey Bylokhov serb at openjdk.java.net
Mon Mar 29 23:02:11 UTC 2021


On Mon, 29 Mar 2021 07:36:35 GMT, Sergey Bylokhov <serb at openjdk.org> wrote:

> The lcms 2.8 version added support for the cmsFLAGS_COPY_ALPHA flag:
> https://sourceforge.net/p/lcms/mailman/lcms-user/thread/001c01d1c0f3%2484a7cb30%248df76190%24%40ProDigitalSoftware.com/#msg35143398
> 
> which supports alpha channel transportation
> 
> For our usage, it means we can use TYPE_4BYTE_ABGR and TYPE_INT_ARGB directly as a source and destination.
> 
> Some numbers; converting new BufferedImage(3000, 3000, TYPE_INT_ARGB) from CS_sRGB to CS_CIEXYZ via op.filter(src, dst):
> //before the fix
> //Benchmark                  Mode  Cnt    Score    Error  Units
> //ColorAlphaConv.testFilter  avgt    5  603,392 ± 12,932  ms/op
> 
> //after the fix
> //Benchmark                  Mode  Cnt    Score   Error  Units
> //ColorAlphaConv.testFilter  avgt    5  121,624 ± 0,906  ms/op
> 
> But still slower than kcms
> //kcms jdk8u60
> //Benchmark                  Mode  Cnt   Score   Error  Units
> //ColorAlphaConv.testFilter  avgt    5  13,256 ± 0,169  ms/op

src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java line 167:

> 165:         return dst.getColorModel().hasAlpha() == src.getColorModel().hasAlpha();
> 166:     }
> 167: 

Thoughts about the method above:
 - I have left the first check as-is, so for any opaque destinations we will pass data to the lcms directly, but I am not sure that this is correct for source/destination with premultiplied alpha.
 - Since I am not sure about premultiplied alpha I have excluded it for the current fix if the destination has an alpha channel.

src/java.desktop/share/native/liblcms/LCMS.c line 193:

> 191: 
> 192:     sTrans = cmsCreateMultiprofileTransform(iccArray, j,
> 193:         inFormatter, outFormatter, renderType, cmsFLAGS_COPY_ALPHA);

Does not affect performance if the image does not have alpha.

test/jdk/sun/java2d/cmm/ColorConvertOp/ColCvtAlphaDifferentSrcDst.java line 73:

> 71:         //opaqueDst(TYPE_INT_ARGB_PRE, TYPE_4BYTE_ABGR_PRE);
> 72:         //opaqueDst(TYPE_4BYTE_ABGR_PRE, TYPE_INT_BGR);
> 73:     }

Actually, according to the spec, we should transform pre-alpha to alpha -> then apply ICC transform -> then transform pre-alpha-> alpha.
See class description of the:
https://docs.oracle.com/javase/7/docs/api/java/awt/image/ColorConvertOp.html

But it looks like implementation does something different.

-------------

PR: https://git.openjdk.java.net/jdk/pull/3239


More information about the 2d-dev mailing list