GreycLab / CImg

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

unsigned int image maxes out at 16777216 #356

Closed BillTavis closed 2 years ago

BillTavis commented 2 years ago

Hello, I am trying to use an image as a pixel hit-count buffer, using code like CImg<unsigned int> img; img.fill(1); img(3,4)++; While it does appear at first to function correctly, I found out after a couple days that the maximum value allowed is far less than the 4 billion it should be for a 32 bit uint. My values were being clipped to 16777216, which after some googling seems to be the largest integer possible using 32 bit floats, which leads me to believe that the cimg library is internally using floats somewhere even though I have declared it as an int. How can I get around this? Is there some way to force all operations to be done purely as integers?

dtschump commented 2 years ago

That is unexpected. This is not what I observe, with my test code:

#include "CImg.h"
using namespace cimg_library;

int main() {
  CImg<unsigned int> img(1,1);
  img.fill(0);
  for (unsigned int k = 0; k<(1U<<31); ++k) ++img(0,0);

  std::fprintf(stderr,"VALUE = %u\n",img(0,0));

  return 0;
}

gives:

$ ./foo
VALUE = 2147483648
BillTavis commented 2 years ago

ah, sorry, I should have done a simple test case before posting. In my actual code the image is a class member, and then gets instantiated in a function, so it's actually something more like this:

class {
   CImg<float> img;
   ...
};
void function() {
   img = CImg<unsigned int>(100,100);
   ....
}

It's a long file and I have been using this for years (and it seemed to have been functioning as if it was a uint), so I forgot that it was originally declared as a float. That was my mistake. But with that said, until now I thought this was legal behavior, that an image container type could by changed dynamically, which is why I didn't bother to check how it was originally defined. I do think it is confusing to allow redeclaration if it is not going to behave correctly. I would prefer to have the compiler throw an error.

dtschump commented 2 years ago

No the use of templates does not make possible the dynamic change of pixel type for an image. Also, a declaration as

img = CImg<unsigned int>(100,100);

will convert the pixel type of the image during the copy. It is actually very handy to allow this kind of image copy.

BillTavis commented 2 years ago

ok thanks for clarifying