]> granicus.if.org Git - imagemagick/commitdiff
Added experimental PNG orNT chunk, to store image->orientation.
authorGlenn Randers-Pehrson <glennrp@gmail.com>
Wed, 26 Jul 2017 16:06:09 +0000 (12:06 -0400)
committerGlenn Randers-Pehrson <glennrp@gmail.com>
Wed, 26 Jul 2017 16:06:09 +0000 (12:06 -0400)
ChangeLog
coders/png.c

index a5e8e17b689669d8e862091aa0d2efe33de9edfd..908517d439411e308341a68207d421aba311c3c8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,11 +7,12 @@
     to prevent a bad free (reference
     https://github.com/ImageMagick/ImageMagick/issues/621).
 
-2017-07-24  7.0.6-4 Glenn Randers-Pehrson <glennrp@image...>
+2017-07-25  7.0.6-4 Glenn Randers-Pehrson <glennrp@image...>
   * Removed write_chunk_from_profile() from coders/png.c because it has
     not worked at least since version 6.7.6.
   * Removed many redundant checks before RelinquishMagickMemory(), which
     is safe to call with a NULL argument.
+  * Added experimental PNG orNT chunk, to store image->orientation.
 
 2017-07-24  7.0.6-3 Cristy  <quetzlzacatenango@image...>
   * Release ImageMagick version 7.0.6-3, GIT revision 20598:cc9c43b44:20170724.
index 5dad4c244f8649aad2dade23bdc5ab9d7012d324..eb96ae55eb6e6ffe116397b5835e9916f7a19851 100644 (file)
@@ -557,12 +557,13 @@ static const png_byte mng_eXIf[5]={101,  88,  73, 102, (png_byte) '\0'};
 static const png_byte mng_gAMA[5]={103,  65,  77,  65, (png_byte) '\0'};
 static const png_byte mng_iCCP[5]={105,  67,  67,  80, (png_byte) '\0'};
 static const png_byte mng_nEED[5]={110,  69,  69,  68, (png_byte) '\0'};
+static const png_byte mng_orNT[5]={111, 114,  78,  84, (png_byte) '\0'};
 static const png_byte mng_pHYg[5]={112,  72,  89, 103, (png_byte) '\0'};
-static const png_byte mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
 static const png_byte mng_pHYs[5]={112,  72,  89, 115, (png_byte) '\0'};
 static const png_byte mng_sBIT[5]={115,  66,  73,  84, (png_byte) '\0'};
 static const png_byte mng_sRGB[5]={115,  82,  71,  66, (png_byte) '\0'};
 static const png_byte mng_tRNS[5]={116,  82,  78,  83, (png_byte) '\0'};
+static const png_byte mng_vpAg[5]={118, 112,  65, 103, (png_byte) '\0'};
 
 #if defined(JNG_SUPPORTED)
 static const png_byte mng_IDAT[5]={ 73,  68,  65,  84, (png_byte) '\0'};
@@ -978,6 +979,64 @@ static const char* PngColorTypeToString(const unsigned int color_type)
   return result;
 }
 
+static int
+Magick_Orientation_to_Exif_Orientation(const OrientationType orientation)
+{
+  switch (orientation)
+  {
+    /* Convert to Exif orientations as defined in "Exchangeable image file
+     * format for digital still cameras: Exif Version 2.31",
+     * http://www.cipa.jp/std/documents/e/DC-008-Translation-2016-E.pdf
+     */
+
+    case TopLeftOrientation:
+       return 1;
+    case TopRightOrientation:
+       return 2;
+    case BottomRightOrientation:
+       return 3;
+    case BottomLeftOrientation:
+       return 4;
+    case LeftTopOrientation:
+       return 5;
+    case RightTopOrientation:
+       return 6;
+    case RightBottomOrientation:
+       return 7;
+    case LeftBottomOrientation:
+       return 8;
+    case UndefinedOrientation:
+    default:
+       return 0;
+  }
+}
+static OrientationType
+Magick_Orientation_from_Exif_Orientation(const int orientation)
+{
+  switch (orientation)
+  {
+    case 1:
+      return TopLeftOrientation;
+    case 2:
+      return TopRightOrientation;
+    case 3:
+      return BottomRightOrientation;
+    case 4:
+      return BottomLeftOrientation;
+    case 5:
+      return LeftTopOrientation;
+    case 6:
+      return RightTopOrientation;
+    case 7:
+      return RightBottomOrientation;
+    case 8:
+      return LeftBottomOrientation;
+    case 0:
+    default:
+      return UndefinedOrientation;
+  }
+}
+
 static int
 Magick_RenderingIntent_to_PNG_RenderingIntent(const RenderingIntent intent)
 {
@@ -1910,6 +1969,23 @@ static int read_user_chunk_callback(png_struct *ping, png_unknown_chunkp chunk)
       return(1);
     }
 
+  /* orNT */
+  if (chunk->name[0] == 111 &&
+      chunk->name[1] == 114 &&
+      chunk->name[2] ==  78 &&
+      chunk->name[3] ==  84)
+    {
+     /* recognized orNT */
+     if (chunk->size != 1)
+       return(-1); /* Error return */
+
+     image=(Image *) png_get_user_chunk_ptr(ping);
+
+     Magick_Orientation_from_Exif_Orientation((int) chunk->data[0]);
+
+     return(1);
+    }
+
   /* vpAg (deprecated, replaced by caNv) */
   if (chunk->name[0] == 118 &&
       chunk->name[1] == 112 &&
@@ -10991,6 +11067,20 @@ static MagickBooleanType WriteOnePNGImage(MngInfo *mng_info,
 
   png_write_info(ping,ping_info);
 
+  /* write orNT if image->orientation is defined */
+  if (image->orientation != UndefinedOrientation)
+    {
+      unsigned char
+        chunk[6];
+      (void) WriteBlobMSBULong(image,1L);  /* data length=1 */
+      PNGType(chunk,mng_orNT);
+      LogPNGChunk(logging,mng_orNT,1L);
+      /* PNG uses Exif orientation values */
+      chunk[4]=Magick_Orientation_to_Exif_Orientation(image->orientation);
+      (void) WriteBlob(image,5,chunk);
+      (void) WriteBlobMSBULong(image,crc32(0,chunk,5));
+    }
+
   ping_wrote_caNv = MagickFalse;
 
   /* write caNv chunk */