[prev in list] [next in list] [prev in thread] [next in thread] 

List:       graphicsmagick-commit
Subject:    [GM-commit] GraphicsMagick: coders/png.c: Added read_user_chunk_callback() f...
From:       GraphicsMagick Commits <graphicsmagick-commit () lists ! sourceforge ! net>
Date:       2017-01-22 16:03:21
Message-ID: hg.aa2d356f8825.1485101001.2950750188400161634 () src ! simplesystems ! org
[Download RAW message or body]

changeset aa2d356f8825 in /hg/GraphicsMagick
details: http://hg.GraphicsMagick.org/hg/GraphicsMagick?cmd=changeset;node=aa2d356f8825
summary: coders/png.c: Added read_user_chunk_callback() function

diffstat:

 ChangeLog    |    9 +++++
 coders/png.c |  105 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 104 insertions(+), 10 deletions(-)

diffs (186 lines):

diff -r be20577ab948 -r aa2d356f8825 ChangeLog
--- a/ChangeLog	Sat Jan 07 11:10:18 2017 -0600
+++ b/ChangeLog	Sun Jan 22 11:03:10 2017 -0500
@@ -1,3 +1,12 @@
+2017-01-21  Glenn Randers-Pehrson  <glennrp@simple.dallas.tx.us>
+
+	* coders/png.c: Added read_user_chunk_callback() function
+	and used it to implement a private PNG caNv (canvas) chunk
+	for remembering the original dimensions and offsets when an
+	image is cropped.  Previously we used the oFFs chunk for this
+	purpose, but this had potential conflicts with other applications
+	that also use the oFFs chunk.
+
 2017-01-07  Bob Friesenhahn  <bfriesen@simple.dallas.tx.us>
 
 	* TclMagick/Makefile.am (AM_DISTCHECK_CONFIGURE_FLAGS): Applied
diff -r be20577ab948 -r aa2d356f8825 coders/png.c
--- a/coders/png.c	Sat Jan 07 11:10:18 2017 -0600
+++ b/coders/png.c	Sun Jan 22 11:03:10 2017 -0500
@@ -194,6 +194,7 @@
 static png_byte const mng_SHOW[5]={ 83,  72,  79,  87, '\0'};
 static png_byte const mng_TERM[5]={ 84,  69,  82,  77, '\0'};
 static png_byte const mng_bKGD[5]={ 98,  75,  71,  68, '\0'};
+static png_byte const mng_caNv[5]={ 99,  97,  78, 118, '\0'};
 static png_byte const mng_cHRM[5]={ 99,  72,  82,  77, '\0'};
 static png_byte const mng_gAMA[5]={103,  65,  77,  65, '\0'};
 static png_byte const mng_iCCP[5]={105,  67,  67,  80, '\0'};
@@ -1212,6 +1213,62 @@
   return MagickTrue;
 }
 
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+static int read_user_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
+{
+  Image
+    *image;
+
+
+  /* The unknown chunk structure contains the chunk data:
+     png_byte name[5];
+     png_byte *data;
+     png_size_t size;
+
+     Note that libpng has already taken care of the CRC handling.
+  */
+
+  LogMagickEvent(CoderEvent,GetMagickModule(),
+     "    read_user_chunk: found %c%c%c%c chunk",
+       chunk->name[0],chunk->name[1],chunk->name[2],chunk->name[3]);
+
+  /* caNv */
+  if (chunk->name[0] ==  99 &&
+      chunk->name[1] ==  97 &&
+      chunk->name[2] ==  78 &&
+      chunk->name[3] == 118)
+    {
+     /* recognized caNv */
+
+     if (chunk->size != 16)
+       return(-1); /* Error return */
+
+     image=(Image *) png_get_user_chunk_ptr(ping);
+
+     image->page.width=(size_t) ((chunk->data[0] << 24) |
+        (chunk->data[1] << 16) | (chunk->data[2] << 8) | chunk->data[3]);
+
+     image->page.height=(size_t) ((chunk->data[4] << 24) |
+        (chunk->data[5] << 16) | (chunk->data[6] << 8) | chunk->data[7]);
+
+     image->page.x=(size_t) ((chunk->data[8] << 24) |
+        (chunk->data[9] << 16) | (chunk->data[10] << 8) | chunk->data[11]);
+
+     image->page.y=(size_t) ((chunk->data[12] << 24) |
+        (chunk->data[13] << 16) | (chunk->data[14] << 8) | chunk->data[15]);
+
+     /* Return one of the following: */
+        /* return(-n);  chunk had an error */
+        /* return(0);  did not recognize */
+        /* return(n);  success */
+
+     return(1);
+    }
+
+  return(0); /* Did not recognize */
+}
+#endif
+
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -1441,16 +1498,16 @@
       (void) png_permit_mng_features(ping,PNG_ALL_MNG_FEATURES);
       png_set_read_fn(ping,image,png_get_data);
 #else
-#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
+# if defined(PNG_READ_EMPTY_PLTE_SUPPORTED)
       png_permit_empty_plte(ping,MagickTrue);
       png_set_read_fn(ping,image,png_get_data);
-#else
+# else
       mng_info->image=image;
       mng_info->bytes_in_read_buffer=0;
       mng_info->found_empty_plte=MagickFalse;
       mng_info->have_saved_bkgd_index=MagickFalse;
       png_set_read_fn(ping,mng_info,mng_get_data);
-#endif
+# endif
 #endif
     }
   else
@@ -1458,14 +1515,17 @@
 
 #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
   /* Ignore unknown chunks */
-#if PNG_LIBPNG_VER < 10700 /* Avoid a libpng16 warning */
+# if PNG_LIBPNG_VER < 10700 /* Avoid a libpng16 warning */
   png_set_keep_unknown_chunks(ping, 2, NULL, 0);
-#else
+# else
   png_set_keep_unknown_chunks(ping, 1, NULL, 0);
-#endif
-  /* Ignore unused chunks */
+# endif
+  /* Ignore unused chunks and all unknown chunks except for caNv */
+  png_set_keep_unknown_chunks(ping, 2, (png_bytep) mng_caNv, 1);
   png_set_keep_unknown_chunks(ping, 1, unused_chunks,
                               (int)sizeof(unused_chunks)/5);
+  /* Callback for other unknown chunks */
+  png_set_read_user_chunk_fn(ping, image, read_user_chunk_callback);
 #endif
 
 #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
@@ -7156,11 +7216,16 @@
 #if defined(PNG_oFFs_SUPPORTED)
   if (mng_info->write_mng == 0 && (image->page.x || image->page.y))
     {
-      png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
+      if (!((image->page.width != 0 && image->page.width != image->columns) ||
+          (image->page.height != 0 && image->page.height != image->rows)))
+        {
+          png_set_oFFs(ping,ping_info,(png_int_32) image->page.x,
                    (png_int_32) image->page.y, 0);
-      if (logging)
-        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+          if (logging)
+            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                               "    Setting up oFFs chunk");
+        }
+      /* else write caNv instead, later */
     }
 #endif
 
@@ -7306,6 +7371,25 @@
 
   png_write_info(ping,ping_info);
 
+  /* write caNv chunk */
+  if ((image->page.width != 0 && image->page.width != image->columns) ||
+      (image->page.height != 0 && image->page.height != image->rows) ||
+      image->page.x != 0 || image->page.y != 0)
+    {
+      unsigned char
+        chunk[22];
+
+      (void) WriteBlobMSBULong(image,16L);  /* data length=8 */
+      PNGType(chunk,mng_caNv);
+      LogPNGChunk(logging,mng_caNv,16L);
+      PNGLong(chunk+4,(png_uint_32) image->page.width);
+      PNGLong(chunk+8,(png_uint_32) image->page.height);
+      PNGsLong(chunk+12,(png_int_32) image->page.x);
+      PNGsLong(chunk+16,(png_int_32) image->page.y);
+      (void) WriteBlob(image,20,chunk);
+      (void) WriteBlobMSBULong(image,crc32(0,chunk,20));
+    }
+
 #if (PNG_LIBPNG_VER == 10206)
   /* avoid libpng-1.2.6 bug by setting PNG_HAVE_IDAT flag */
 #define PNG_HAVE_IDAT               0x04
@@ -7632,6 +7716,7 @@
       png_set_text(ping,ping_info,text,1);
       png_free(ping,text);
     }
+
   if (logging)
     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
                           "  Writing PNG end info");

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Graphicsmagick-commit mailing list
Graphicsmagick-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/graphicsmagick-commit
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic