GreycLab / CImg

The CImg Library is a small and open-source C++ toolkit for image processing
http://cimg.eu
Other
1.49k stars 285 forks source link

Error when trying to load/display 64-bit integer images #379

Closed BillTavis closed 1 year ago

BillTavis commented 1 year ago

I am working with 64-bit integer images (unsigned long long) and I am running into a couple issues. First, I need to save the images to file and then open them later. I tried using the .cimg filetype because I assumed this would be the closest to just directly storing the raw data in memory. Saving it worked fine and the filesize was exactly what I expected. However, when I try to load the image I get an error, using both the regular "load" and the "load_cimg" functions. I tried .ppm and .tiff and they did not work either. I know that most image file types do not support 64-bit.

Also, I am not able to display the image data directly using the .display() function. I wrote a short program to test it here. Upon execution, the image appears to be properly filled with numbers, and the display data printed in the console seems to be correct, but the display itself is blank and says "unknown" for all of the pixels. And both load functions give an error.

#include <iostream>
#include "CImg.h"

using namespace cimg_library;

int main(int argc, char *argv[]){
    CImg<unsigned long long> img64(1024,1024,1,1);
    cimg_forXY(img64,x,y)
        img64(x,y) = (long long)x * (long long)y;

    img64.display("test image");

    std::cout << "\ntest value: " << img64(400,500) << " == 400*500 == 200000\n\n";
    img64.save("img64.cimg");
    try {
        img64.load("img64.cimg");
    } catch (CImgException &e) {
        std::cout << "Regular load ERROR:" << e.what() << "\n"; 
    }
    try {
        img64.load_cimg("img64.cimg");
    } catch (CImgException &e) {
        std::cout << "cimg load ERROR:" << e.what() << "\n";
    }
    return 0;
}
dtschump commented 1 year ago

Interesting, thanks! I'll check that to see what happens.

dtschump commented 1 year ago

First thing : replacing CImg<unsigned long long> img64(1024,1024,1,1); with CImg<cimg_uint64> img64(1024,1024,1,1); makes all your code work. I guess there is something weird anyway, as it should work also when unsigned long long is used. Will check.

dtschump commented 1 year ago

Second thing: Basically img64.normalize(0,255) won't return a correct image if img64 is a CImg<unsigned long long>. That's what display() tries to do when displaying the image data, so there's clearly something wrong here. Still investigating.

dtschump commented 1 year ago

https://github.com/GreycLab/CImg/commit/32b3bb6ff6e716ac858262089354ad1cc815ae66 and https://github.com/GreycLab/CImg/commit/64839222d7ec5312497ca017e27e0bf90af3d66a should fix the issue. I've pushed a new CImg_latest.zip file on the website that reflects these changes.

I would recommend anyway to use cimg_uint64 as a template type, rather than unsigned long long, as it is certainly a better supported type.

BillTavis commented 1 year ago

Thanks! Using cimg_uint64 worked for me