[C++] PNG Dimensions? - solved
-
Hello! I'm having a mental breakdown because of how fucky this is.
I have two PNG files. One reads fine. The other reads not so fine. The first one is converted with HoneyView from a DDS file. The second one is saved from a larger sprite in Paint.NET.
First image:
Second image:
I'm currently using this code snippet to get the dimensions:
struct SpriteInfo { int Id; int Width; int Height; }; SpriteInfo spriteRPMDial; SpriteInfo spriteN0; //https://codereview.stackexchange.com/questions/149717/implementation-of-c-standard-library-function-ntohl/149751 uint32_t my_ntohl(uint32_t const net) { uint8_t data[4] = {}; memcpy(&data, &net, sizeof(data)); return ((uint32_t)data[3] << 0) | ((uint32_t)data[2] << 8) | ((uint32_t)data[1] << 16) | ((uint32_t)data[0] << 24); } void GetPNGDimensions(std::string file, int *width, int *height) { std::ifstream in(file); int _width, _height; in.seekg(16); in.read((char *)&_width, 4); in.read((char *)&_height, 4); *width = my_ntohl(_width); *height = my_ntohl(_height); } void createTextures(std::string skin) { std::string skinPath = Paths::GetModuleFolder(Paths::GetOurModuleHandle()) + modDir + skin; spriteRPMDial.Id = createTextureDefault(skinPath + "\\dialRPM.png", &spriteRPMDial); spriteN0.Id = createTextureDefault(skinPath + "\\N0.png", &spriteN0); logger.Write("dialRPM.png W: " + std::to_string(spriteRPMDial.Width) + " H: " + std::to_string(spriteRPMDial.Height)); logger.Write("N0.png W: " + std::to_string(spriteN0.Width) + " H: " + std::to_string(spriteN0.Height)); }
Output:
[02:57:02.252] dialRPM.png W: 16 H: 128
[02:57:02.252] N0.png W: 0 H: 0Now GetPNGDimensions worked great until it didn't. Or at least I think it doesn't. I tried the WinSock2.h ntohl, but got the same result of the textures reading 0. The headers of those PNGs don't look strange either, the two dimensions are neatly 16 bytes offset from the start. I'm completely lost here. Any other mistakes I made? Alternatives where I don't need to haul in a massive image library?
Update - the WinSock2.h ntohl returns exactly the same stuff my_ntohl does, both return gibberish for my small number textures:
[11:37:46.871] dialRPM.png W: 16 H: 128 [11:37:46.871] N0.png W: 204 H: -858993460 [11:39:19.781] dialRPM.png W: 16 H: 128 [11:39:19.782] N0.png W: 204 H: -858993460 // Repeat for N1 to N9 and NN, NR, NE. All 26x36 PNGs
Update - I ended up using lodepng. Works really well, though it added some weight to my binary. I still have no idea how the code I used is wrong, as lodepng does this:
unsigned lodepng_read32bitInt(const unsigned char* buffer) { return (unsigned)((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]); } unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize) { // things *w = lodepng_read32bitInt(&in[16]); *h = lodepng_read32bitInt(&in[20]); // more things }
Oh well.