Opened 16 months ago

Last modified 13 months ago

#166 new enhancement

Display colour correction with lookup table (or ICC profile)

Reported by: wyattfward@… Owned by: pulkomandy
Priority: minor Milestone:
Component: GrafX2 Version: 2.9WIP
Keywords: color management Cc:

Description

This is just a wishlist item as much as anything, but I'd like it if (for the ports where it is viable) there was a way to use either a 3D lookup table image or an ICC profile with a library like LittleCMS to perform color correction for screens. My laptop, for instance, has a display which only covers about 60% of the sRGB colour gamut, and many colours on it look quite different without correction than they do on an sRGB CRT or LCD panel.

Not all colour correction can currently be done in GPU hardware on most operating systems; they typically only support a one dimensional lookup table that can be used to correct white point and gamma. To get something closer to how an image would look on an ideal display, colour managed software utilizes a three dimensional lookup table to transform colours just before displaying.

Since Grafx2 uses an indexed 256 colour palette, it could likely just achieve this by taking the image's palette, feeding it as a raster image into LittleCMS, and using the resulting image to translate each colour from its raw actual value into a displayed one.

To accomplish this a dialogue would have to be added to either select an ICC profile, or to load a manually created lookup table. If you want to experiment with them, I have written a Python program that uses LittleCMS, and can apply transformations on image files. This could be used to generate palette colour translation tables if needed.
My repository also contains a couple colour profiles from my machines: my Dell u2412M, which only needs minimal corrections, and my Thinkpad X201 Tablet, which needs major corrections (and thus transformations on it yield more dramatic results).

https://gitlab.com/wyatt8740/icc-burn

The colour-corrected image is on the right; what grafx2 shows is on the left (on my Thinkpad; on the Dell the two images would be virtually indistinguishable between each other):
https://i.imgur.com/vj7ohg4g.jpg
Full resolution https://i.imgur.com/vj7ohg4.jpg

Change History (3)

comment:1 by Thomas Bernard, 14 months ago

Isn't color profiles managed at the OS level ?
Which version of GrafX2 have you tried ? The results could be a bit different depending on which "API" is used (SDL 1.2, SDL 2, Win32 GDI or X11)

comment:2 by yrizoud@…, 14 months ago

As I understand it, the goal would be to edit an image on a platform, but simulate the rendering that you would get if the image was dispayed on another platform.

For example if you had the exact ICC profile of a Nintendo DS, and you converted your drawing environmnent to it, the sprites that you draw for a homebrew would transfer more faithfully. No more surprises of "oh these dark shades are too similar when viewed on the real screen".

comment:3 by wyattfward@…, 13 months ago

This is exactly the interpretation I was going for.

Also, no, color profiles are not managed at the OS level. That's the difference between "calibration" and "correction." Under Linux, you can at least configure the RAMDAC (hardware gamma ramps on digital video cards), but that's a one dimensional correction that is mostly just good for fixing gamma and color temperature errors. But further (3-D lookup) corrections need to be done on top of that for something more accurate. Under Windows, the RAMDAC is also configurable, but full color management has to be done at the application level. I think Mac OS might do 3D lookups in its compositor with a GPU shader, but I cannot confirm this.

I have used X11, SDL 1.2, and SDL2 frontends.

In my case, my laptop/tablet (thinkpad x201 tablet) screen does not cover the full sRGB gamut, and many colours look desaturated; additionally, some colors are just wrong; some violets actually look blue on my screen. With a 3D lookup table (either contained in an ICC profile, or in a shader texture/cube file/some other format), the colors can be made to render at least more correctly than they otherwise would. It certainly results in far fewer surprises when I move from my tablet to my desktop (which has an sRGB monitor) or my Amiga (which is using an RGB CRT with EBU phosphors).

It basically makes it easier to know what color I'm actually working with.

Thoughts on some implementation strategies:
Most 3D LUT's I see are 64x64x64 or smaller (32x32x32, or even 16x16x16), so they aren't 1:1 with the full range of possible RGB colours. Therefore, interpolation is used. There's a document that does an okay job explaining the design and use of a 3D lookup table with interpolation, should there be any desire to write one from scratch. I don't really recommend this. It's still useful to understanding the concepts, though.
https://spie.org/samples/PM159.pdf

There are libraries that exist to handle this sort of thing. Little CMS among them. The documentation is thorough, but in my opinion not particularly friendly to people getting started. There are sample programs included in the repository, though.
https://www.littlecms.com/LittleCMS2.12%20tutorial.pdf
https://www.littlecms.com/LittleCMS2.12%20API.pdf

Most lookup tables in ICC profiles translate from the (linear) L*A*B colorspace to some other color space, but it would greatly simplify things and increase performance at run-time if you required users to generate a LUT that goes from sRGB to their desired space directly and provide that. Argyll can do this (specifically, the 'collink' utility), as can DisplayCAL which acts as a wrapper around collink for this purpose.

IRIDAS/Adobe Cube files have a public specification and are a plaintext format; other options include parsing an ICC profile, although not all ICC profiles contain three dimensional XYZ lookup tables. They can be generated by 'collink' from Argyll.
https://wwwimages2.adobe.com/content/dam/acom/en/products/speedgrade/cc/pdfs/cube-lut-specification-1.0.pdf

Last edited 13 months ago by wyattfward@… (previous) (diff)
Note: See TracTickets for help on using tickets.