PNG re-work: split out write handling
authorTony Cook <tony@develop-help.com>
Tue, 10 Apr 2012 08:32:59 +0000 (18:32 +1000)
committerTony Cook <tony@develop-help.com>
Sun, 29 Apr 2012 03:40:56 +0000 (13:40 +1000)
PNG/impng.c

index 6ac9e8c..f95d434 100644 (file)
@@ -20,6 +20,9 @@ read_paletted(png_structp png_ptr, png_infop info_ptr, int channels, i_img_dim w
 static i_img *
 read_bilevel(png_structp png_ptr, png_infop info_ptr, i_img_dim width, i_img_dim height);
 
+static int
+write_direct8(png_structp png_ptr, png_infop info_ptr, i_img *im);
+
 unsigned
 i_png_lib_version(void) {
   return png_access_version_number();
@@ -191,12 +194,10 @@ i_writepng_wiol(i_img *im, io_glue *ig) {
 
   png_write_info(png_ptr, info_ptr);
 
-  vdata = data = mymalloc(im->xsize * im->channels);
-  for (y = 0; y < height; y++) {
-    i_gsamp(im, 0, im->xsize, y, data, NULL, im->channels);
-    png_write_row(png_ptr, (png_bytep)data);
+  if (!write_direct8(png_ptr, info_ptr, im)) {
+    png_destroy_write_struct(&png_ptr, &info_ptr);
+    return 0;
   }
-  myfree(data);
 
   png_write_end(png_ptr, info_ptr);
 
@@ -720,6 +721,28 @@ get_png_tags(i_img *im, png_structp png_ptr, png_infop info_ptr, int bit_depth)
   }
 }
 
+static int
+write_direct8(png_structp png_ptr, png_infop info_ptr, i_img *im) {
+  unsigned char *data, *volatile vdata = NULL;
+  i_img_dim y;
+
+  if (setjmp(png_jmpbuf(png_ptr))) {
+    if (vdata)
+      myfree(vdata);
+
+    return 0;
+  }
+
+  vdata = data = mymalloc(im->xsize * im->channels);
+  for (y = 0; y < im->ysize; y++) {
+    i_gsamp(im, 0, im->xsize, y, data, NULL, im->channels);
+    png_write_row(png_ptr, (png_bytep)data);
+  }
+  myfree(data);
+
+  return 1;
+}
+
 static void
 read_warn_handler(png_structp png_ptr, png_const_charp msg) {
   i_png_read_statep rs = (i_png_read_statep)png_get_error_ptr(png_ptr);