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:


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);
	}

bump, bump …

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.