Hi Laurent,

Java2D has color correction code in it, but it is only really hooked up to the specific color correction classes so it pretty much has to be manually invoked. The rendering pipeline usually punts on issues like color space other than if you specify an alternate color space for a BufferedImage then it may classify the image as "Custom" and use a lot of really slow custom rendering pipelines (as in, "I have no idea how colors are stored there so let's make method calls per pixel to read and write them").

By default it assumes that sRGB is a close enough approximation for any screen output device and just does pretty straightforward math on the pixel values and pretends that it is doing it all "in sRGB space". In reality, it is doing it all in "just computing with the color components" space and assuming that since the output is a screen then it is essentially "sort of playing in sRGB space". The assumption works fine for GUI and casual rendering, but more deliberate treatment of color spaces would really be needed for things like pre-press.

In particular, it does no gamma correction except in the LCD text loops - those are so finicky when it comes to getting the AA just right in terms of quality that they really required us to do gamma corrected blending or the results just wouldn't be readable. But, all other AA rendering (and alpha rendering) is done just linearly in the space of the component values.

Note that to do the gamma correction for LCD text in the hw accelerated pipelines we have to read back the screen so that we can convert them into gamma space and back again. This greatly increases the cost of the rendering and if we did the same thing for regular shape rendering then there would be a significant performance hit. I believe that future versions of D3D and OpenGL will eventually support gamma corrected blending natively, but for now the gamma decorrection on the destination has to be implemented with manual computations in a shader. If you combine that with the fact that shaders cannot access the output pixel then there is no way to do that correction without reading back from the screen and providing those pixel values as a secondary input to the shader. Note that you can't simply bind the output surface as an input texture because neither API allows a texture to be bound as both the input and output of the same operation - so a readback has to be done. (Grrr)

Another possibility is to store all pixel values internally in a linear sRGB space and to de/re-gamma them as we copy them to the screen, then we could avoid the readback in most cases at the cost of a single gamma conversion on the final blit, but that would take a serious overhaul to the rendering pipelines to accomplish and we haven't even prototyped something like that. Rendering directly to the screen via "Window.getGraphics()", though, would need to do the readback for every render operation...

                        ...jim

On 8/14/14 3:00 AM, Laurent Bourgès wrote:
Hi,

Here are questions about the java2d pipeline to understand how colors
are handled as pixel values (conversions):
- BufferedImage use by default the sRGB colorspace (non linear) so its
raster data (RGBA) are encoded as int values (sRGB).

What parts of the java2d pipeline handle color blending in linear RGB
(quality issue) ?
AlphaComposite impl (ogl, xr) .... like the SrcOver operator.
Blit ?

The Javadoc explains conversions between premultiplied alpha images...
but nothing about the colorspace of pixels.

Is it supposed to be always sRGB = the java native color space ?

So the complete pipeline should deal with gamma correction at every
color blending stage...

- if I create a BufferedImage with the CS_LINEAR_RGB colorspace (RGBA
values), I expected the image to have better quality but the final PNG
image remains the same.

Conversion into sRGB happened at some stage or the PNG encoder is buggy ?

- Is it possible to implement a custom MaskBlit / MaskFill in java ? Or
I must fix the C implementations dealing with all possible pixel formats
(rgb, rgba, rgb555 ....) in every pipeline (software, opengl, xrender,
direct3d...)

- how could I use an alternative colorspace (cie-lch for example) with
the current pipelines to make color blending in this perfect colorspace
and convert the final image back to sRGB ?

Thanks for your feedback,
Laurent

Reply via email to