The main issue in the code you linked is not related to OpenGL nor is it related to loading images. The problem is, that the way the contents are loaded from the file is unreliable. Take this for example:
// read the width
if ((i = fread(&image->sizeX, 4, 1, file)) != 1) {
printf("Error reading width from %s.\n", filename);
return 0;
}
The problem here is, that sizeof(Image::sizeX) is not neccesarily 4 "chars". The type is unsigned long which is at least 4 but it can be longer. And it's very likely to be 8 on modern systems. Which means, that 4 of the 8 "chars" are left whatever they already were before the read, which is in the usual care nonzero garbage.
Also the whole endianess issue is not addressed. The only way to implement robust binary loading is by setting all bits explicitly by assignment from a well defined expression. In the case of the field Image::sizeX you could write it as
char buf[4];
// read the width
if ((i = fread(buf, 4, 1, file)) != 1) {
printf("Error reading width from %s.\n", filename);
return 0;
}
image->sizeX =
((unsigned long)buf[0]) |
(((unsigned long)buf[1])<<8) |
(((unsigned long)buf[2])<<16)|
(((unsigned long)buf[3])<<24);
Writing it this way is the only way to read binary data in a robust and plattform independent way. Is it tedious to write? Yes, it is. That's why you'd write a number of helper functions to abstract this away.