DanBloomberg / leptonica

Leptonica is an open source library containing software that is broadly useful for image processing and image analysis applications. The official github repository for Leptonica is: danbloomberg/leptonica. See leptonica.org for more documentation.
Other
1.74k stars 387 forks source link

RGB order changed when calling pixReadWithHint/pixWrite #675

Closed sinall closed 1 year ago

sinall commented 1 year ago
auto pix = pixReadWithHint("source.bmp", IFF_BMP);
auto ret = pixWrite("target.bmp", pix, IFF_BMP);

The source.bmp is captured by ATL CImage on Windows 11.

Testing images are attached.

image images.zip

DanBloomberg commented 1 year ago

pixReadWithHint() ignores the second arg if the input image format is not jpeg. So there's no issue there.

I wrote the following test code, run on linux, and there are no issues with component order. Try it, and let me know the results on Windows.

    pix1 = pixRead("source.bmp");
//    pix1 = pixReadWithHint("source.bmp", IFF_BMP);   // ignores 2nd arg
    pixWrite("/tmp/junk1.bmp", pix1, IFF_BMP);
    pixWrite("/tmp/junk1.png", pix1, IFF_PNG);
    pix2 = pixRead("/tmp/junk1.bmp");
    pix3 = pixRead("/tmp/junk1.png");
    pixEqual(pix2, pix1, &same);
    lept_stderr("same: %d\n", same);
    pixEqual(pix3, pix1, &same);
    lept_stderr("same: %d\n", same);
    pixDisplay(pix2, 300, 100);
    pixDisplay(pix3, 500, 100);
    pixWrite("/tmp/junk2.bmp", pix2, IFF_BMP);
    writeImageFileInfo("/tmp/junk1.bmp", stderr, 0);
    writeImageFileInfo("/tmp/junk2.bmp", stderr, 0);
sinall commented 1 year ago

pixReadWithHint() ignores the second arg if the input image format is not jpeg. So there's no issue there.

I wrote the following test code, run on linux, and there are no issues with component order. Try it, and let me know the results on Windows.

    pix1 = pixRead("source.bmp");
//    pix1 = pixReadWithHint("source.bmp", IFF_BMP);   // ignores 2nd arg
    pixWrite("/tmp/junk1.bmp", pix1, IFF_BMP);
    pixWrite("/tmp/junk1.png", pix1, IFF_PNG);
    pix2 = pixRead("/tmp/junk1.bmp");
    pix3 = pixRead("/tmp/junk1.png");
    pixEqual(pix2, pix1, &same);
    lept_stderr("same: %d\n", same);
    pixEqual(pix3, pix1, &same);
    lept_stderr("same: %d\n", same);
    pixDisplay(pix2, 300, 100);
    pixDisplay(pix3, 500, 100);
    pixWrite("/tmp/junk2.bmp", pix2, IFF_BMP);
    writeImageFileInfo("/tmp/junk1.bmp", stderr, 0);
    writeImageFileInfo("/tmp/junk2.bmp", stderr, 0);
auto pix = pixRead("source.bmp");
auto ret = pixWrite("target.bmp", pix, IFF_BMP);

The same as previous, not working!

DanBloomberg commented 1 year ago

Please send all output from that test code, both to stderr and files written.

GerHobbelt commented 1 year ago

Interestingly, when inspecting both BMP files with a hex inspection tool, it turns out source.bmp (here called test-rgba.bmp) and target.bmp differ quite a bit:

See also this hex comparison (using Beyond Compare in Hex Compare mode): note the 20 00 vs. 18 00 little endian 32 vs. 24 bpp values at offset 0x1C (bits per pixel)

image

Another interesting thing to note is that the source BGRA values are rotated to RGB in the target. That's not possibly an endian swap mistake or suchlike, as then the alpha channel of the source (first value: 31) should have ended up front instead, instead of the observed 33 value (target, offset 0x36)

Ran the C++ code

auto pix = pixRead("source.bmp");
auto ret = pixWrite("target.bmp", pix, IFF_BMP);

on Win10/64 with latest leptonica (+ irrelevant patches) and was not able to produce target.bmp from source.bmp.

Other interesting things to note:


@sinall: So are you running an old version of leptonica -- I haven't run a git blame analysis to see if there ever was a bug in BMP I/O code that could trigger this -- or a patched/augmented system?


Code used to test: (test-rgba.bmp in there is identical to original source.bmp; DEMOPATH and a few other bits in there are specific to my patched copy of leptonica, so you'll have to adjust/remove those lines to make them work with regular leptonica)

issue675.zip

DanBloomberg commented 1 year ago

We are unable to find a problem on linux or Windows. Will leave this open for a while in case @sinall has more information to share.

DanBloomberg commented 1 year ago

This problem is fixed on linux and Windows.