I've spent some time examining what pdfbox is passing to ColorConvertOp
It is called about 10 or 11 times in this test with images typically
1-2K in each dimension.
The input image is a Custom BufferedImage which uses an ICC_ColorSpace
constructed
from a color profile file that is embedded in pdfbox which is an open
source equivalent
of what Acrobat uses. It has a 4 component raster and is opaque
This is filtered into a 3 component standard INT_RGB ColorModel.
I've distilled this down into a small program which has an copy of the
method
that is defined in pdfbox and is invoking the supposedly slow
ColorConvertOp.
So I believe this is all exactly what is happening in pdfbox.
What I find is that it is actually much faster on JDK11 than JDK 8.
prrubuntu:~$ ~/jdk-11/bin/java CConv
4881
prrubuntu:~$ ~/jdk8u181/bin/java CConv
12529
I can't say why that would be but the results are clear.
So I am left to suppose that pdfbox really is doing something different
in 8 vs 11.
Or that this not the real problem. What do others see ?
I've attached the program. The 1Mb color profile file can be got from
the pdfbox sources.
-phil.
On 10/2/18, 9:35 AM, Laurent Bourgès wrote:
Hi Daniel,
Let's not compare apples and oranges. What I can see it takes the
same route and behave similarly.
I agree, I did not take enough time to get accurate profiles, sorry.
If you look at
http://uhash.com/java_reg/Call_Tree_java_8.html
http://uhash.com/java_reg/Call_Tree_java_11.html
You can see that ConvertOp.filter takes 1.5s longer on Java 11.
I confirm: 1.8s vs 300ms.
Philip, do you know what could have change in this 2d area ?
I imagine ColorConvertOp delegates to native code so color profile
(ICC) or hidpi support may have an impact here (or just compiler
options may be different) ...
If needed, I could profile native code using oprofile / perf.
Laurent
import java.io.*;
import java.awt.*;
import java.awt.color.*;
import java.awt.image.*;
public class CConv {
static BufferedImage toRGBImageAWT(WritableRaster raster, ColorSpace colorSpace) {
ColorModel colorModel = new ComponentColorModel(colorSpace,
false, false, Transparency.OPAQUE, raster.getDataBuffer().getDataType());
BufferedImage src = new BufferedImage(colorModel, raster, false, null);
BufferedImage dest = new BufferedImage(raster.getWidth(), raster.getHeight(),
BufferedImage.TYPE_INT_RGB);
ColorConvertOp op = new ColorConvertOp(null);
//System.out.println("src="+src);
//System.out.println("dst="+dest);
op.filter(src, dest);
return dest;
}
public static void main(String args[]) throws Exception {
int width = 2577;
int height = 1540;
int numComponents = 4;
WritableRaster raster =
Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height,
numComponents, new Point(0, 0));
//System.out.println(raster);
ICC_Profile profile = ICC_Profile.getInstance("ISOcoated_v2_300_bas.icc");
ICC_ColorSpace colorSpace = new ICC_ColorSpace(profile);
long t0 = System.currentTimeMillis();
for (int i=0;i<50;i++) {
toRGBImageAWT(raster, colorSpace);
}
long t1 = System.currentTimeMillis();
System.out.println((t1-t0));
}
}