High bit-depth tiff compatability issues

Hello – I’ve been posting around (gimp-user-list, gimp-developer-list, hugin forum) in hopes of helping get to the bottom of interoperability issues relating to high bit-depth tiffs.

I understand that g’mic outputs 32bit float (and that ,ushort can be used to force 16bit integer) and that many programs don’t support this, and that isn’t g’mic’s fault. :slight_smile: But I’m wondering if it would be possible to bring some of the free software world in line with itself. If this is not something useful for g’mic folks to look at, then please ignore. I just don’t know which part of the pipeline needs adjusting, so I’m casting a wider net. :slight_smile:

Here is a zip file of small demo images: http://caseyconnor.org/pub/image/smallexample2.zip

The only editor/viewer that seems to open everything as expected is Luminance HDR. Gimp, hugin, etc, all have issues. I read here that g’mic uses a legacy standard in it’s 32bit format, so maybe this is moot for g’mic, but I post this in the faint hope that it might be useful.

Files in the zip:

original.tif – 16bit integer image exported from Canon Digital Photo Professional
original2.tif – a copy of original.tif used for processing
aligned000?.tif - the result of "align_image_stack --gpu -C -a aligned original*.tif
aligned_then_gmic.tif – the result of gmic -median_files aligned*.tif -o aligned_then_gmic.tif
hugin_output.tif – the result of running a simple rectilinear stitch on aligned_then_gmic.tif
aligned_then_gmic.pto – the pto used to do that
other_example.tif – another strangely-behaving .tif file in case it’s useful (hugin can’t open this one, maybe? But Luminance HDR can.)

…none of the processed .tif files open properly in GIMP, but some of them can be recovered by changing to an integer precision. hugin_output.tif can not be recovered (though again, Luminance HDR opens it fine, and so does hugin).

Let me know if more examples would be useful.

My test setup: Kubuntu 16.10, otto-kesselgulasch gimp 2944dbd688. (Also happens with pixls.us gimps. Happens on linux and windows.) G’MIC 2.0.0. pre-release #013117. align_image_stack version 2016.3.0.85fedd083c55

Here is a response from the hugin developer who suggests that the G’MIC output might be unusual, in case it helps at all:

“I think the format GMIC write is at least unusual. It write float values, but does not adapt the range. The 16 bit integer format goes from 0…65536 for red, green and blue. GMIC write the float values also in this range, but normally the TIFF image are linear when using float (and cover therefore another range). That’s the main reason of the problem.”

So if GIMP et al. are expecting 0-x but G’MIC is generating 0-65535, that would explain a few things… ?

Just for information:

RawTherapee can read aligned0000.tif, aligned0001.tif, original.tif, original2.tif and other_example.tif

Dragging and dropping into GIMP-CCE, only aligned_then_gmic.tif, hugin_output.tif and other_example.tif are white. The rest are okay.

  • Stretch contrast brings hugin_output.tif and other_example.tif into range.
  • aligned_then_gmic.tif probably needs some tone mapping.
  • hugin_output.tif's range is 0…66048, which might be why RT cannot open it.

PS Also, for some reason, the alpha layer introduced during the align_image_stack/Enblend/Enfuse process may confuse the heck out certain apps.

Thanks afre – I see the same results with the CCE AppImages. I shared your observation on the gimp devel list.

It’s odd that hugin_output is > 65535, since the hugin devel said that it writes its output in the same range as the input… do you know the range of aligned_then_gmic.tif?

May I ask how you are determining the range of the tif? Then I can check myself without bothering others. :slight_smile:

Re: alpha channel – I have in my standard processing flow “change precision to 16bit integer and remove alpha channel” and it was for just that kind of reason, but I can’t now recall exactly what the problem was. But yeah, I’ve had issues with that as well.

Thanks,
-c

No problem. I have no idea why the output is like that, but you can easily rectify that by normalizing or clipping prior to opening it in an app that cannot handle out of range values. I think that the small stuff we do is a small price to pay for the world of power that some of these apps give us. :slight_smile:

gmic

gmic hugin_output.tif -p

ImageMagick

magick -format "%f: max = %[fx:maxima] min = %[fx:minima]" hugin_output.tif info:

(Change magick to convert if you have an older version.)

Certainly!

So yes, we can suspect those program assuming that float-valued tiff files must have pixel values in range [0,1].
If the values are higher, they are clamped to [0,1], thus making them appear as pure white images.

If so, just ensure yourself you output tiff files with value range [0,1].
Normalization using -n 0,1 is probably not the best solution, as you will always stretch your initial dynamic.
Depending on your original image values, I rather propose something like this :

$ gmic input_8bits -process_image -/ 255 -o output_float.tiff

or

$ gmic input_16bits -process_image -/ 65535 -o output_float.tiff

Anyway, as someone said in the gimpuser list, TIFF is a container for mage data, and assuming that float-valued TIFF images must be encoded in range [0,1] is a strong assumption that should not be done in general, IMHO. For instance, any float value, like -1, NaN or ±inf are valid in float-valued tiffs, and that’s pretty useful (to have a code for defining unknown pixels for instance).
At least for G’MIC, which is able to process images with any kind of value range, there are no interest to force clamping of image values before saving into a float-valued tiff file (in case you ask :slight_smile: ).

Thanks, David! Now that I understand the issue things are working great. And good tip on the -/ method, thanks.

I understand the reasoning behind the chosen range, and now that I know how to use gmic properly for my workflow, it looks like things will work fine.

-c

1 Like

Hi again David – I reported a GIMP bug here… M. Natterer responded that G’MIC should probably be setting TIFFTAG_SMIN,MAXSAMPLEVALUE if it is generating values outside of [0,1].

His full comment is #5, here.

Any thoughts on that?

Thanks,
-c

I don’t agree with Mitch, when he writes :

Assuming that a “default” range of float (16, 32 of 64) bits is “normally”
0.0…1.0, G’MIC should really scale things to that range, or alternatively
set

There are not things like a “normal default range” for float-valued image data. If I’m not wrong, float-valued TIFF files have been primarily created to store medical image data, not photographs. With such data, the absolute value of a pixel may have a real physical meaning (like number of photons measured by the sensor) and I don’t see why the range should be stretched in [0,1] in this case. I have met some float-valued volumetric TIFF files from MRI datasets, and I can ensure the value range was not [0,1] ! And it was not “broken” files !

G’MIC write TIFF files with the image values you provide, it doesn’t write “broken” tiff files. If you think the loading of such generic tiff files will be broken in another software that makes strong assumption about how the value range should “normally” be, then you have to please the constrained software (which is not generic enough :slight_smile: ), and feed it with .tiff files with value range [0,1].

As you have noticed, this can be done easily in G’MIC.

I could of course try to add the metadata suggested by Mitch, as an additional information.
But this is not mandatory fields, so this won’t make the tiff files more valid (and it requires we compute the min/max of the image values, which can takes some time for big images, so I’m not sure that is the way to go).

What I can propose right now is this : Add SMin/SMax Sample Value TIFF tags when writing TIFF files. · dtschump/CImg@3c7123f · GitHub

It just adds the additional tags suggested by Mitch in the TIFF files.
Not sure it will really help, but at least we can try.

Thanks! – from the spec I got the impression that you’d set the tags to [0,65535] or whatever was appropriate for the source data, as opposed to min/max? (The spec says the default for those values is the min/max values of the data type…) Of course if the source data is floating-point (without tags) I guess that still leaves an ambiguity…

(I wonder what g’mic assumes if it’s operating on a floating point file and doing contrast or gamma adjustment or something – it must assume some range of values?)

Some Thoughts

Try to look at the problem differently. Different software tackle different problems.

GIMP is about visualizing data and getting visual feedback from the manipulation we do. It is natural for software with that paradigm to want to assign a certain range for each datatype. In contrast, based on my short experience with G’MIC, it just takes in data as they are and doesn’t make many assumptions. Obviously, certain commands require certain criteria to work properly. So, in terms of compatibility, G’MIC is okay with anything, as long as the file type is recognized and successfully decoded.

Float as [0,1] is just a convention, though a common one. It could be any range really, as long as the operations and results are float and no precision is lost. It only matters when we have to decide to visualize the data. Then we would have to determine how we want to do that. Is 0 and 1 just black and white? Or do we want to view values using false colors? etc.

Takeaway

You need to know what you are trying to accomplish. If you are querying MRI or remote sensing datasets where values mean something, then you would probably not be using GIMP; but if you are using GIMP, then appeasing it with what it wants as input via normalization to [0,1] isn’t a big deal. Adding a tag might help but then we would have to generate lots of them to make the TIFFs “compatible”. It is only a bug or feature report where the software is doing something unexpected or lacks a capability that makes sense for it to have.

And then we have Photoshop, which guts the tags/data it doesn’t like and attaches its own. :dizzy_face:

No, I use

 double valm, valM = max_min(valm);
      TIFFSetField(tif,TIFFTAG_SMINSAMPLEVALUE,valm);
      TIFFSetField(tif,TIFFTAG_SMAXSAMPLEVALUE,valM);

which retrieve the min/max values in the instance image, so that’s the info we are interested in.

Filters in G’MIC generally assume that an usual RGB image has values in [0,255]. This is the G’MIC “convention” for color images. So if you plan to process a 16bits .png with G’MIC filters, it is often a good idea to divide the input values by 257 before processing it, then multiply the result by 257 when saving. It’s not mandatory though, but it helps filters having a coherent behavior.

At least as common as [0,255] in my experience :slight_smile:[quote=“afre, post:14, topic:3725”]
You need to know what you are trying to accomplish
[/quote]

That’s the essential point. It is written in the G’MIC help I think : the user has to know what kind of data he process.
G’MIC is somewhat blind about that, it doesn’t care your image is RGB or something else.
This means that any image with 3 channels can be used for doing RGB to HSV conversion for instance, even if this doesn’t have sense. I assume the user knows generally better what to do than the software.
Flexibility is the master word here.

No, I use

double valm, valM = max_min(valm);
TIFFSetField(tif,TIFFTAG_SMINSAMPLEVALUE,valm);
TIFFSetField(tif,TIFFTAG_SMAXSAMPLEVALUE,valM);

Yeah, I saw that in the code – what I was trying to say was that the spec seemed to me to say that the semantics of SMin/MaxSampleValue was that they indicate the range given the data type, not the min/max of the data. But the more I dig in to the spec the less sense it makes (I guess it’s famous for this). And the GIMP folks seem to agree with you that those tags are not intended to indicate range. I don’t pretend to know much about all this.

Anyway, it sounds like g’mic is comfortable with how it works, and the GIMP developers aren’t eager to use the tags, so perhaps things are best left as they were. Thanks for examining the issue.

I don’t know either. But in any case, once an image has been loaded, G’MIC just takes it as a buffer of float values, and it has no idea about what could be the min/max range to consider. So that information cannot be put in the output tiff file in any case :slight_smile: