Page 1 of 1

libpng 1.5 support

Posted: Mon Dec 10, 2012 12:58 am
by Myckel
In libpng 1.5 a new API was introduced. As a result, code using the pre-1.5 API doesn't build against a 1.5 lib/headers:

Code: Select all

g++ -DHAVE_CONFIG_H -I. -I/usr/include/SDL -I/usr/include/AL -I/usr/include/lua5.1 -I./src/luabind -I./src/luabind/luabind -I./src/luabind/luabind/detail -I./src/luabind/src -I./src -I./src/engine -I./src/engine/audio -I./src/engine/video -I./src/engine/script -I./src/global -I./src/common -I./src/common/global -I./src/common/gui -I./src/modes -I./src/modes/battle -I./src/modes/boot -I./src/modes/map -I./src/modes/menu -I./src/modes/save -I./src/modes/shop -DDATADIR=\"/usr/local/share/games/allacrost\" -DLOCALEDIR=\"/usr/local/share/games/allacrost/txt\" -DPACKAGE=\"allacrost\" -I/usr/X11R6/include -Wall -O3 -I/usr/include/qt4 -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtOpenGL -I/usr/include/qt4/Qt3Support -DQT_CLEAN_NAMESPACE -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT3_SUPPORT -DQT_SHARED -Wall -O3 -MT image_base.o -MD -MP -MF .deps/image_base.Tpo -c -o image_base.o `test -f 'src/engine/video/image_base.cpp' || echo './'`src/engine/video/image_base.cpp
src/engine/video/image_base.cpp: In member function 'bool hoa_video::private_video::ImageMemory::_LoadPngImage(const std::string&)':
src/engine/video/image_base.cpp:264:18: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:265:19: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:266:26: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:266:44: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:279:23: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:283:14: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:286:34: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:287:35: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:289:50: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:290:17: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:300:34: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:301:35: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:303:50: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:312:34: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:313:35: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:315:50: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:324:34: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:325:35: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:327:50: error: invalid use of incomplete type 'struct png_info'
/usr/include/png.h:745:16: error: forward declaration of 'struct png_info'
src/engine/video/image_base.cpp:225:30: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result
make[2]: *** [image_base.o] Error 1
make[2]: Leaving directory `/home/myckel/Software/allacrost/trunk/game'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/myckel/Software/allacrost/trunk/game'
make: *** [all] Error 2
Making code compatible for 1.5 should also build against the pre-1.5 API. My experience with VegaStrike (which had also no 1.5 support) showed that adapting the code should be relative easy (patch was only a few lines).

Re: libpng 1.5 support

Posted: Mon Dec 10, 2012 3:41 pm
by Roots
I think I'll get around to looking into this in a day or two. I'm going to need your help to test it though (or someone else with libpng15 installed). I only have 1.2 installed on my own system and no easy way to upgrade to 1.5.

Re: libpng 1.5 support

Posted: Mon Dec 10, 2012 3:47 pm
by Myckel
I can give it a try. My system is 1.5-only.

Re: libpng 1.5 support

Posted: Tue Dec 18, 2012 11:28 am
by Roots
Sorry I haven't been able to get to this issue yet. There's just a million things I am working on for the project right now, and unfortunately this isn't high up on the priority list. I'm trying to complete the code import from Valyria Tear before I start hacking away in other areas. I did make some progress toward libpng1.5 support today, due to a code import from VT. Here's what I just committed. You still won't be able to compile because I haven't touched the major problems present in image_base.cpp though. Just wanted to let you know that at least I got something, and what the hold up on this support is.

Code: Select all

	// TODO: Examine if the following png calls are still required. libpng15 changed the way some operations are done
	// open up the IO stuff and read the PNG
	png_init_io(png_ptr, fp);
	png_set_sig_bytes(png_ptr, 8);
	png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, NULL);

	cols = png_get_image_width(png_ptr, info_ptr);
	rows = png_get_image_height(png_ptr, info_ptr);
	bpp = png_get_bit_depth(png_ptr, info_ptr) * 8;

	// In versions of libpng prior to 15, this is how we retrieved the information
// 	cols = info_ptr->width;
// 	rows = info_ptr->height;
// 	bpp = info_ptr->channels * 8;

	// and clean up.
	png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
	fclose(fp);

Re: libpng 1.5 support

Posted: Thu Dec 20, 2012 12:50 pm
by Myckel
Take your time. Currently debugging the video drivers (the bug that I mentioned in the VT post). This is most likely still going to take some time.

Re: libpng 1.5 support

Posted: Sun Jun 23, 2013 5:11 pm
by hagabaka
Hi, I've created a patch for building with png 1.5, and tested it on Arch Linux. PNG's release notes seem to say the png_get_ functions are available in old versions too, but I don't know how to test it with an older version of the library.

Code: Select all

Index: src/engine/video/image.cpp
===================================================================
--- src/engine/video/image.cpp	(revision 2040)
+++ src/engine/video/image.cpp	(working copy)
@@ -684,9 +684,9 @@
 	png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, NULL);
 
 	// grab the relevant data...
-	cols = info_ptr->width;
-	rows = info_ptr->height;
-	bpp = info_ptr->channels * 8;
+	cols = png_get_image_width(png_ptr, info_ptr);
+	rows = png_get_image_height(png_ptr, info_ptr);
+	bpp = png_get_channels(png_ptr, info_ptr) * 8;
 
 	// and clean up.
 	png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
Index: src/engine/video/image_base.cpp
===================================================================
--- src/engine/video/image_base.cpp	(revision 2040)
+++ src/engine/video/image_base.cpp	(working copy)
@@ -261,9 +261,9 @@
 	uint8** row_pointers = png_get_rows(png_ptr, info_ptr);
 
 	// copy metadata
-	width = info_ptr->width;
-	height = info_ptr->height;
-	pixels = malloc(info_ptr->width * info_ptr->height * 4);
+	width = png_get_image_width(png_ptr, info_ptr);
+	height = png_get_image_height(png_ptr, info_ptr);
+	pixels = malloc(width * height * 4);
 
 	// check that we were able to allocate enough memory for the PNG
 	if (pixels == NULL) {
@@ -276,18 +276,21 @@
 	// convert the damn thing so that it works in our format
 	// this is mostly just byteswapping and adding extra data - we want everything in four channels
 	// for the moment, anyway
-	uint32 bpp = info_ptr->channels;
+	uint32 bpp = png_get_channels(png_ptr, info_ptr);
 	uint8* img_pixel = NULL;
 	uint8* dst_pixel = NULL;
 
-	if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) {
+	if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) {
 		// colours come from a palette - for this colour type, we have to look up the colour from the palette
+		png_colorp palette;
+		int num_palette;
+		png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
 		png_color c;
-		for (uint32 y = 0; y < info_ptr->height; y++) {
-			for (uint32 x = 0; x < info_ptr->width; x++) {
+		for (uint32 y = 0; y < height; y++) {
+			for (uint32 x = 0; x < width; x++) {
 				img_pixel = row_pointers[y] + (x * bpp);
-				dst_pixel = ((uint8*)pixels) + ((y * info_ptr->width) + x) * 4;
-				c = info_ptr->palette[img_pixel[0]];
+				dst_pixel = ((uint8*)pixels) + ((y * width) + x) * 4;
+				c = palette[img_pixel[0]];
 
 				dst_pixel[0] = c.red;
 				dst_pixel[1] = c.green;
@@ -297,10 +300,10 @@
 		}
 	}
 	else if (bpp == 1) {
-		for (uint32 y = 0; y < info_ptr->height; y++) {
-			for (uint32 x = 0; x < info_ptr->width; x++) {
+		for (uint32 y = 0; y < height; y++) {
+			for (uint32 x = 0; x < width; x++) {
 				img_pixel = row_pointers[y] + (x * bpp);
-				dst_pixel = ((uint8*)pixels) + ((y * info_ptr->width) + x) * 4;
+				dst_pixel = ((uint8*)pixels) + ((y * width) + x) * 4;
 				dst_pixel[0] = img_pixel[0];
 				dst_pixel[1] = img_pixel[0];
 				dst_pixel[2] = img_pixel[0];
@@ -309,10 +312,10 @@
 		}
 	}
 	else if (bpp == 3) {
-		for (uint32 y = 0; y < info_ptr->height; y++) {
-			for (uint32 x = 0; x < info_ptr->width; x++) {
+		for (uint32 y = 0; y < height; y++) {
+			for (uint32 x = 0; x < width; x++) {
 				img_pixel = row_pointers[y] + (x * bpp);
-				dst_pixel = ((uint8*)pixels) + ((y * info_ptr->width) + x) * 4;
+				dst_pixel = ((uint8*)pixels) + ((y * width) + x) * 4;
 				dst_pixel[0] = img_pixel[0];
 				dst_pixel[1] = img_pixel[1];
 				dst_pixel[2] = img_pixel[2];
@@ -321,10 +324,10 @@
 		}
 	}
 	else if (bpp == 4) {
-		for (uint32 y = 0; y < info_ptr->height; y++) {
-			for (uint32 x = 0; x < info_ptr->width; x++) {
+		for (uint32 y = 0; y < height; y++) {
+			for (uint32 x = 0; x < width; x++) {
 				img_pixel = row_pointers[y] + (x * bpp);
-				dst_pixel = ((uint8*)pixels) + ((y * info_ptr->width) + x) * 4;
+				dst_pixel = ((uint8*)pixels) + ((y * width) + x) * 4;
 				dst_pixel[0] = img_pixel[0];
 				dst_pixel[1] = img_pixel[1];
 				dst_pixel[2] = img_pixel[2];