Giter VIP home page Giter VIP logo

Comments (4)

to-mas-kral avatar to-mas-kral commented on August 16, 2024

I tried figuring out how libtiff does this, but this is the only relevant code I found:

/*
 * Construct a mapping table to convert from the range
 * of the data samples to [0,255] --for display.  This
 * process also handles inverting B&W images when needed.
 */
static int
setupMap(TIFFRGBAImage* img)
{
    int32_t x, range;

    range = (int32_t)((1L << img->bitspersample) - 1);

    /* treat 16 bit the same as eight bit */
    if (img->bitspersample == 16)
        range = (int32_t)255;

    img->Map = (TIFFRGBValue*)_TIFFmalloc((range + 1) * sizeof(TIFFRGBValue));
    if (img->Map == NULL) {
        TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
            "No space for photometric conversion table");
        return (0);
    }
    if (img->photometric == PHOTOMETRIC_MINISWHITE) {
        for (x = 0; x <= range; x++)
            img->Map[x] = (TIFFRGBValue)(((range - x) * 255) / range);
    } else {
        for (x = 0; x <= range; x++)
            img->Map[x] = (TIFFRGBValue)((x * 255) / range);
    }
    if (img->bitspersample <= 16 && (img->photometric == PHOTOMETRIC_MINISBLACK || img->photometric == PHOTOMETRIC_MINISWHITE)) {
        /*
	 * Use photometric mapping table to construct
	 * unpacking tables for samples <= 8 bits.
	 */
        if (!makebwmap(img))
            return (0);
        /* no longer need Map, free it */
        _TIFFfree(img->Map);
        img->Map = NULL;
    }
    return (1);
}

What also puzzles me, is that we try to invert floating point values,

fn process_photometry_f32(buffer: &mut [f32]) {
for datum in buffer.iter_mut() {
// FIXME: assumes [0, 1) range for floats
*datum = 1.0 - *datum
}
}

but again, I haven't found any code in libtiff which would manipulate floating-point data in such a way.
I also tried creating a copy of a 32-bit floating-point encoded file where I changed the PhotometricInterpretation tag from BlackIsZero to WhiteIsZero. Both of the files are displayed the same in GIMP, Krita fails to display the WhiteIsZero version, which seems to suggest that this inversion might be wrong.

But take this with a grain of salt. The libtiff codebase is a bit hard to read, so it's possible that I have missed something.

from image-tiff.

to-mas-kral avatar to-mas-kral commented on August 16, 2024

OK, the way libtiff handles these conversions is weird.

libtiff has a few different interfaces(man pages):

  • Raw IO - returns undecoded image data
  • Encoded IO - returns decoded data, swaps bytes to native byte order if needed
  • RGBA IO - decodes image data into 32-bit packed RGBA

The TIFFRGBAImage function (man pages) only supports 1, 2, 4, 8, 16 bit formats, which would partially explain why we weren't handling i32s and i64s consistently. The man pages also explain, that it's possible for users to define functions for converting from other uncommon formats to RGBA.

I also created two test images.
signed-minblack-minwhite-test.zip

I tried loading them with the TIFFRGBAImage function and it does inverse the data but treats the data as unsigned integers. It seems strange that libtiff doesn't handle signed format by default, but it would also explain why most graphics software on my machine (Gwenview, Krita) display these files badly. The only program that renders it correctly is GIMP, which presumably uses the more low-level libtiff functions.

Therefore it's questionable if we should do implicit conversions at all.
One solution would be to not do these conversions implicitly, but provide users with some standard procedures for inverting the colors. These procedures should also take SMinSampleValue and SMaxSampleValue into account.

from image-tiff.

fintelia avatar fintelia commented on August 16, 2024

We only ever do color inversion if the file specifies "white is zero". A lot of the weirdness comes from seeing that tag on files where that doesn't really make sense.

from image-tiff.

fintelia avatar fintelia commented on August 16, 2024

Looked through the liftiff source as well and came to a similar conclusion as @TomasKralCZ. I don't see anything that indicates our current strategy is clearly wrong. I'd say we leave things as they are.

We can revisit later if anyone comes across a more definitive answer or some software that creates images with different assumptions.

from image-tiff.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.