+
+// VS: wxPNGInfoStruct declared below is a hack that needs some explanation.
+// First, let me describe what's the problem: libpng uses jmp_buf in
+// its png_struct structure. Unfortunately, this structure is
+// compiler-specific and may vary in size, so if you use libpng compiled
+// as DLL with another compiler than the main executable, it may not work
+// (this is for example the case with wxMGL port and SciTech MGL library
+// that provides custom runtime-loadable libpng implementation with jmpbuf
+// disabled altogether). Luckily, it is still possible to use setjmp() &
+// longjmp() as long as the structure is not part of png_struct.
+//
+// Sadly, there's no clean way to attach user-defined data to png_struct.
+// There is only one customizable place, png_struct.io_ptr, which is meant
+// only for I/O routines and is set with png_set_read_fn or
+// png_set_write_fn. The hacky part is that we use io_ptr to store
+// a pointer to wxPNGInfoStruct that holds I/O structures _and_ jmp_buf.
+
+struct wxPNGInfoStruct
+{
+ jmp_buf jmpbuf;
+ bool verbose;
+
+ union
+ {
+ wxInputStream *in;
+ wxOutputStream *out;
+ } stream;
+};
+
+#define WX_PNG_INFO(png_ptr) ((wxPNGInfoStruct*)png_get_io_ptr(png_ptr))
+
+
+extern "C"
+{
+
+void PNGLINKAGEMODE _PNG_stream_reader( png_structp png_ptr, png_bytep data, png_size_t length )
+{
+ WX_PNG_INFO(png_ptr)->stream.in->Read(data, length);
+}
+
+void PNGLINKAGEMODE _PNG_stream_writer( png_structp png_ptr, png_bytep data, png_size_t length )
+{
+ WX_PNG_INFO(png_ptr)->stream.out->Write(data, length);
+}
+
+// from pngerror.c
+// so that the libpng doesn't send anything on stderr
+void
+PNGLINKAGEMODE wx_png_error(png_structp png_ptr, png_const_charp message)