+ png_read_update_info(readp, infop);
+
+ /* Extract and check image properties. */
+
+ w = (int) png_get_image_width (readp, infop);
+ h = (int) png_get_image_height(readp, infop);
+
+ switch (png_get_color_type(readp, infop))
+ {
+ case PNG_COLOR_TYPE_GRAY: b = 1; break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA: b = 2; break;
+ case PNG_COLOR_TYPE_RGB: b = 3; break;
+ case PNG_COLOR_TYPE_RGB_ALPHA: b = 4; break;
+
+ default: longjmp(png_jmpbuf(readp), -1);
+ }
+
+ if (!(bytep = png_malloc(readp, h * png_sizeof(png_bytep))))
+ longjmp(png_jmpbuf(readp), -1);
+
+ /* Allocate the final pixel buffer and read pixels there. */
+
+ if ((p = (unsigned char *) malloc(w * h * b)))
+ {
+ for (i = 0; i < h; i++)
+ bytep[i] = p + w * b * (h - i - 1);
+
+ png_read_image(readp, bytep);
+ png_read_end(readp, NULL);
+
+ if (width) *width = w;
+ if (height) *height = h;
+ if (bytes) *bytes = b;
+ }
+
+ png_free(readp, bytep);