Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: textures from libpng

  1. #1
    Junior Member Newbie wenhaug's Avatar
    Join Date
    Apr 2018
    Posts
    19

    textures from libpng

    Hello. I load textures from 24bit RGB png files using libpng.
    The problem is that it reads pngs made in one pc's Paint (Win10), but fails to read pngs made in another pc's Paint (Win10), although the format is 24 bit on each png.

    Error is: "An invalid parameter was passed to a function that considers invalid parameters fatal." in png_default_read_data(). Why?

    The program fails at png_read_image(png_ptr, row_pointers);
    The color and bit depth are the same for these two pcs' png files.

    Here is the libpng code:
    Code :
    int width, height;
    	for (int j = 0; j < materials.size(); ++j)
    	{
    		//header for testing if it is a png
    		png_byte header[8];
     
    		FILE *fp;
    		errno_t err;
     
    		if ((err = fopen_s(&fp, 
    			(object_root+materials[j].texture_name).c_str(), "rb")) != 0)
    		{
    			OutputDebugStringA("Faulire to open a png file.");
    			exit(EXIT_FAILURE);
    		}
     
    		//read the header
    		fread(header, 1, 8, fp);
     
    		//test if png
    		int is_png = !png_sig_cmp(header, 0, 8);
    		if (!is_png)
    		{
    			fclose(fp);
    			OutputDebugStringA("File is not of png format.");
    			exit(EXIT_FAILURE);
    		}
     
    		//create png struct
    		png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
    			NULL, NULL);
    		if (!png_ptr)
    		{
    			fclose(fp);
    			OutputDebugStringA("Failure to create a png struct.");
    			exit(EXIT_FAILURE);
    		}
     
    		//create png info struct
    		png_infop info_ptr = png_create_info_struct(png_ptr);
    		if (!info_ptr)
    		{
    			png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
    			fclose(fp);
    			OutputDebugStringA("Faulire to create a png info struct.");
    			exit(EXIT_FAILURE);
    		}
     
    		//create png info struct
    		png_infop end_info = png_create_info_struct(png_ptr);
    		if (!end_info)
    		{
    			png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
    			fclose(fp);
    			OutputDebugStringA("Faulire to create a png info struct.");
    			exit(EXIT_FAILURE);
    		}
     
    		//png error stuff, not sure libpng man suggests this.
    		if (setjmp(png_jmpbuf(png_ptr)))
    		{
    			png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
    			fclose(fp);
    			OutputDebugStringA("Faulire to set png error stuff.");
    			exit(EXIT_FAILURE);
    		}
     
    		//init png reading
    		png_init_io(png_ptr, fp);
     
    		//let libpng know you already read the first 8 bytes
    		png_set_sig_bytes(png_ptr, 8);
     
    		// read all the info up to the image data
    		png_read_info(png_ptr, info_ptr);
     
    		//variables to pass to get info
    		int bit_depth, color_type;
    		png_uint_32 twidth, theight;
     
    		// get info about png
    		png_get_IHDR(png_ptr, info_ptr, &twidth, &theight, &bit_depth, &color_type,
    			NULL, NULL, NULL);
     
    		//update width and height based on png info
    		width = twidth;
    		height = theight;
     
    		png_byte filler = 255;
     
    		if (color_type != PNG_COLOR_TYPE_RGB_ALPHA)
    		{
    			if (color_type == PNG_COLOR_TYPE_RGB)
    			{
    				png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER);
    			}
     
    			else
    			{
    				OutputDebugStringA("Not RGB png.");
    				exit(EXIT_FAILURE);
    			}
    		}
    		else
    		{
    			OutputDebugStringA("Not RGB png.");
    			exit(EXIT_FAILURE);
    		}
     
    		// Update the png info struct.
    		png_read_update_info(png_ptr, info_ptr);
     
    		// Row size in bytes.
    		int rowbytes = (int)png_get_rowbytes(png_ptr, info_ptr);;
     
    		// Allocate the image_data as a big block, to be given to opengl
    		png_byte *image_data = new png_byte[rowbytes * height];
     
    		if (!image_data)
    		{
    			//clean up memory and close stuff
    			png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
    			fclose(fp);
    			OutputDebugStringA("Faulire to allocate the image data as a big block.");
    			exit(EXIT_FAILURE);
    		}
     
    		//row_pointers is for pointing to image_data for reading the png with libpng
    		png_bytep *row_pointers = new png_bytep[height];
    		if (!row_pointers)
    		{
    			//clean up memory and close stuff
    			png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
    			delete[] image_data;
    			fclose(fp);
    			OutputDebugStringA("Faulire to allocate row pointers.");
    			exit(EXIT_FAILURE);
    		}
     
    		// set the individual row_pointers to point at the correct offsets of image_data
    		for (int i = 0; i < height; ++i)
    		{
    			row_pointers[height - 1 - i] = image_data + i * rowbytes;
    		}
     
     
     
    		//read the png into image_data through row_pointers
    		png_read_image(png_ptr, row_pointers);
     
    		if (j == 0)
    		{
    			glTexStorage3D(GL_TEXTURE_2D_ARRAY, mipLevelCount,
    				GL_RGBA8, width, height, (GLsizei)materials.size());
    		}
     
    		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, j, width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)image_data);
     
    		//clean up memory and close stuff
    		png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
     
    		delete[] image_data;
     
    		delete[] row_pointers;
    		fclose(fp);
    	}

  2. #2
    Junior Member Newbie wenhaug's Avatar
    Join Date
    Apr 2018
    Posts
    19
    bump, bump ...

  3. #3
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,362
    This doesn't really have anything to do with OpenGL. You might improve your chances if you posted to the libpng mailing list. You might also look at the source code for one of the many open-source projects that make use of libpng for clues as to what you could do differently.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •