Question for ICC profile specialistes (and C dev? ;))

Hello community.
As we have announced recently, we have released a beta version of the future Siril.
So far the feedback has been good and we are happy.

Of course, we have some bugs we are trying to fix it. One of them is very annoying for me as my skill in this field are weak.
This new version provide 32-bit floating precision pixels. That’s great, but we have some issues with 32-bit TIFF images (not with 16-bit, I don’t know why), and probably with png.

Here an example of a TIFF image: FileSender

Users told me that opening it with Photoshop (and Lightroom) leads to a corrupted image. For me, with GIMP I have no issue. However, I can reproduce the issue using RT.



This is because RT does not make any assumption of the ICC profile while GIMP do it.

So, my clue is that Photoshop and LR do the same than RT (but I cannot test it): no assumption.

  • Now, what is the best easiest way to embed a ICC profile in TIFF files (and PNG). I would like to avoid, at least in a first time, the use a new lib like littleCMS. I would like to just embed a simple sRGB profile inside the files.
    With libtiff we can use the TIFF_TAG: TIFFTAG_ICCPROFILE but I do not well understand how it works.
    Should I read a sRGB.icc file and include the buffer in
    TIFFSetField(tif, TIFFTAG_ICCPROFILE, buffer_size, buffer); ?

But in this case, what about Windows, MacOS, … Can we find sRGB.icc easily? Must I upload it to the sources? Is my reasoning wrong?

  • Other question, why I only see this issue with 32-bit TIFF images? Not with the 16-bit ones, while I think I have the issue with 16-bit PNG.

Cheers,

The application (PS/RT/GIMP/Whatever) should apply a default profile for the colorspace used in the image if the image does not have an profile, or give a dialog box with a list of usable profiles to apply before usage.

I don’t have access to PS/LR/RT, so I don’t know what they do.

The image looks good in the applications I use.

Yes. The contents of the ICCPROFILE tag are just the contents of the .icc/.icm profile file. (buffer_size would of course be the size of the profile data and not the size of the buffer).

On macOS the sRGB profile is located at “/System/Library/ColorSync/Profiles/sRGB Profile.icc”. But not all sRGB profiles are the same (https://ninedegreesbelow.com/photography/srgb-profile-comparison.html) - you are probably better off embedding an sRGB profile in your distribution to ensure consistent results across platforms.

Not sure. The wrong image is much lighter than the correct one - maybe you are outputting sRGB encoded data and the applications are assuming it is linear for the 32bit case. Embedding the correct ICC profile should fix this.

You may want to consider using a linear RGB encoding for the 32bit float files.

use EXIFtool, which is a cross-platform utility.

Hermann-Josef

You can’t just embed a profile, you need to ensure the image data corresponds to the strictures of that profile, gamut and tone. Mismatching that IMHO is the easiest way to confuse renditions and the behaviors that produce them. So, at export, you need to (in LittleCMS parlance) cmsTransform() the image from whatever profile represented it internally to sRGB. If you do this, it doesn’t matter which sRGB profile you use, as the data will correspond to it.

If you want to package an sRGB profile without actually including a file, you can encode it to a c char[] with xxd -i:

glenn@caliente:~/ImageStuff/elles_icc_profiles/profiles$ xxd -i sRGB-elle-V2-g22.icc |more
unsigned char sRGB_elle_V2_g22_icc[] = {
  0x00, 0x00, 0x05, 0x68, 0x6c, 0x63, 0x6d, 0x73, 0x02, 0x20, 0x00, 0x00,
  0x6d, 0x6e, 0x74, 0x72, 0x52, 0x47, 0x42, 0x20, 0x58, 0x59, 0x5a, 0x20,
...

Edit: Oh if you do this, remember to abide by the license… :slight_smile:
Edit #2: The above hex-encoded binary snipped is copyrighted by Elle Stone, CC-BY-SA 3.0

Regarding the code, for TIFF what you describe for setting the TIFFTAG_ICCPROFILE using TIFFSetField() is correct. libpng has a similar mechanism, png_set_iCCP(), takes a pointer to the buffer and an integer length.

The only difference between 32-bit (which I’ll assume to be float) and 16-bit transforms in LittleCMS is that floating point data allows LittleCMS to not clip at the upper end of the data container.

2 Likes

Thank you all for your messages.

I want to do it programmatically ;).

Yes, of course this is data size. What is the difference between *.icc and *.icm profile file?

OK, how generally software do?

No, I was outputing nothing, you can check with exiftool. Now I tried a small thing by quickly embedding a sRGB profile inside my TIFF pic.
Here the result: FileSender

@ggbutcher : many thanks for your explanation.

Until now we never dealt with ICC profile. So it is difficult for me to say anything about it. I know, that is ashamed for image software, but in fact when we are doing only preprocessing it is not really important. So I don’t really how I can ensure that.

So I need to understand it (outisde LittleCMS parlance :slight_smile: ).

Works like a charm, thx.

My sRGB profile has:

Profile Copyright : no copyright, use freely

Thanks a lot, you helped me a lot even if I have to understand a lot of things…

1 Like

No worries, it felt the same way to me when I tackled it in rawproc.

This missive might be of help:

1 Like

.icc is the official extension, .icm is used by Microsoft. You often get ICC profiles with the icm extension if they are targetting windows.

I opened your example file in Preview (macOS) and it looks correct. If I strip the embedded ICC profile, preview displays the too light version:

The embedded ICC profile doesn’t alter the content of the file in any way - it just describes how the RGB numbers in the file can be converted into XYZ space. You don’t need to use something like LittleCMS (although that can make converting between colour spaces more convenient), you just need to label your existing output with the correct profile so other software can interpret the values correctly.

Without an embedded profile, most colour managed software will guess how the numbers in the file should be interpreted (the usual guess is ‘sRGB’ because this sort of works for random RGB values from a typical 1990’s CRT monitor). In the case of 32bit float data, several applications are obviously using linear sRGB as a guess.

In the siril source code, you have an xyz_to_rgb function (in colors.c) which is definately converting XYZ to sRGB. So I’m guessing that sRGB is the correct profile to tag your ouput files with.

2 Likes

Wow, many thanks !!!

It is my guess too. I’m on the right track then.