1

I want to display the values in the loaded 8 bit image for code analysis purpose and find that the loaded image has no values?

I have the following primary lines to help me:

#define CHANNEL_NUM 1 
int width, height, bpp;

uint8_t* image = stbi_load("FTTESTGS.bmp", &width, &height, &bpp, CHANNEL_NUM);
if (image == NULL) {printf("Error in loading the image\n");}

size_t n = sizeof(image) / sizeof(image[0]);
std::cout << "The size is " << n << '\n';

for (size_t i = 0; i < n; i++) {std::cout << image[i];}

std::cout << '\n' << "The largest element is " << *std::max_element(image, image + width * height) << '\n';

It compiles. No errors. My output is unfortunately showing me size of 8, no values, and the largest element is nothing.

The size is 8

The largest element is  

I am not sure where the problem lays. Any suggestions are welcomed! Here's a screenshot of the code:

enter image description here

nolimits
  • 43
  • 1
  • 3
  • 16
  • 2
    You cannot use that method for finding the size of your data block. That only works on _arrays_ which have a size known at compile time. Since `image` is a _pointer_ (not an array), `sizeof(image)` is just the size of a pointer which on your system is clearly 8 bytes. And of course it's a pointer to `uint8_t`, so `sizeof(image[0])` is 1. I don't know what this "stb" library is, but presumably it has methods for obtaining sizes, row strides etc. If not, use simple math like `width * height * (bpp >> 8) & CHANNEL_NUM` or whatever makes sense. – paddy Jan 28 '21 at 00:50
  • I should add that `cout << image[i]` might not behave the way you expect. The type `uint8_t` will be treated as a character type by the stream output operator, and so it will write the value as text. Internally, that value is probably binary data, and if you want its value shown as an integer you should cast it first (_e.g._ `std::cout << static_cast(image[i])`). You might also want to output a space between each value in that case. Or dump it as hex which has a fixed size (_e.g._ `cout << hex << setfill('0');` and then `cout << setw(2) << static_cast(image[i]);`) – paddy Jan 28 '21 at 00:54
  • Thanks @paddy, the cast shows me now everything like 0 0 15 185 255 255 255 185 15 0 0 . So good so far, Yoda says. However, the outputs for size, and largest value are still messed up :( – nolimits Jan 28 '21 at 02:20
  • As I explained, you are calculating the size incorrectly. You simply cannot do it this way. For the maximum element, that also needs a cast because once again you're supplying a character type to the stream output operator. – paddy Jan 28 '21 at 02:54
  • Thanks a lot @paddy. Ii really doesnt like it when I do static_castsizeof(image) or static_cast*std::max_element(image, image + width * height). Sorry, I am a really new to this :( – nolimits Jan 28 '21 at 22:15
  • You can't just invent your own syntax. Look at what I wrote, and then what you wrote. – paddy Jan 29 '21 at 02:12

1 Answers1

2

stb_image is written in C and so it relies on C arrays instead of the handy standard containers of C++. It looks like you don't have much experience with C arrays, so I suggest you read up on them.


As for the problem at hand, @paddy already mentioned that sizeof doesn't exactly do what you think it does. stbi_load allocates an array on the heap internally, loads the image data to it, and returns a pointer to the first element of that array. Since image is just a pointer (you even declared it as such), sizeof(image) gives you the size of a pointer in bytes (8 on a 64bit system).

As far as I know, you can't get the size of an array allocated in such a way but that's why stbi_load gives you the width and height of the loaded image:

size_t n = width * height * CHANNEL_NUM;

Another issue pointed out by @paddy is that couting an uint8_t will result in a character getting printed. You can read up on it here but long story short: a couple of unfortunate quirks in C++ lead to some integer types (int8_t and uint8_t) getting interpreted as chars (char and unsigned char). To avoid this, you have to explicitly cast them to an integer type that always behaves as an integer (```unsigned int`` for example) when printing. Check this out to see what I mean.

static_cast<unsigned int>( image[i] );
Kelemen Máté
  • 442
  • 3
  • 12