Log in to reply
 

[C++] PNG Dimensions? - solved


  • MODERATOR

    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:
    First image

    Second 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: 0

    Now 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.


Log in to reply
 

Looks like your connection to GTA5-Mods.com Forums was lost, please wait while we try to reconnect.