GraphicsMagick: ReadJXLImage()/ReadHEIFImage(): EXIF offset, EOI...

GraphicsMagick Commits <[email protected]>
Newsgroups gmane.comp.video.graphicsmagick.cvs
Message-ID <mailman.1870.1680198314.1789.graphicsmagick-commit@lists.sourceforge.net>
changeset 3f33eb4c4b92 in /hg/GraphicsMagick
details: http://hg.GraphicsMagick.org/hg/GraphicsMagick?cmd=changeset;node=3f33eb4c4b92
summary: ReadJXLImage()/ReadHEIFImage(): EXIF offset, EOI marker handling, and XMP parsing fixes by Milos Komarcevic.

diffstat:

 ChangeLog                              |  10 ++++++
 VisualMagick/installer/inc/version.isx |   4 +-
 coders/heif.c                          |  52 ++++++++++++++++++++++++++++++---
 coders/jxl.c                           |  32 +++++++++++++++++---
 magick/version.h                       |   4 +-
 www/Changelog.html                     |  11 +++++++
 6 files changed, 98 insertions(+), 15 deletions(-)

diffs (227 lines):

diff -r 11f622f51ff5 -r 3f33eb4c4b92 ChangeLog
--- a/ChangeLog	Sun Mar 26 18:02:08 2023 -0500
+++ b/ChangeLog	Thu Mar 30 12:44:56 2023 -0500
@@ -1,3 +1,13 @@
+2023-03-30  Bob Friesenhahn  <[email protected]>
+
+	* coders/jxl.c (ReadJXLImage): Fix JXL EXIF offset handling, and
+	deal with any EOI marker. (From SourceForge patch #69 submitted by
+	Milos Komarcevic).
+
+	* coders/heif.c (ReadHEIFImage): Fix HEIF EXIF offset handling,
+	and deal with any EOI marker.  Also fix HEIF XMP parsing. (From
+	SourceForge patch #69 submitted by Milos Komarcevic).
+
 2023-03-26  Bob Friesenhahn  <[email protected]>
 
 	* coders/identity.c (ReadIdentityImage): Return a PseudoClass
diff -r 11f622f51ff5 -r 3f33eb4c4b92 VisualMagick/installer/inc/version.isx
--- a/VisualMagick/installer/inc/version.isx	Sun Mar 26 18:02:08 2023 -0500
+++ b/VisualMagick/installer/inc/version.isx	Thu Mar 30 12:44:56 2023 -0500
@@ -10,5 +10,5 @@
 
 #define public MagickPackageName "GraphicsMagick"
 #define public MagickPackageVersion "1.4"
-#define public MagickPackageVersionAddendum ".020230326"
-#define public MagickPackageReleaseDate "snapshot-20230326"
+#define public MagickPackageVersionAddendum ".020230330"
+#define public MagickPackageReleaseDate "snapshot-20230330"
diff -r 11f622f51ff5 -r 3f33eb4c4b92 coders/heif.c
--- a/coders/heif.c	Sun Mar 26 18:02:08 2023 -0500
+++ b/coders/heif.c	Thu Mar 30 12:44:56 2023 -0500
@@ -1,5 +1,5 @@
 /*
-% Copyright (C) 2022 GraphicsMagick Group
+% Copyright (C) 2023 GraphicsMagick Group
 %
 % This program is covered by multiple licenses, which are described in
 % Copyright.txt. You should have received a copy of Copyright.txt with this
@@ -171,6 +171,7 @@
         *profile_name;
 
       size_t
+        exif_pad = 0,
         profile_size;
 
       unsigned char
@@ -195,8 +196,11 @@
 
       if (NULL != profile_name && profile_size > 0)
         {
+          if (strncmp(profile_name,"Exif",4) == 0)
+            exif_pad=2;
+
           /* Allocate memory for profile */
-          profile=MagickAllocateResourceLimitedArray(unsigned char*,profile_size,
+          profile=MagickAllocateResourceLimitedArray(unsigned char*,profile_size+exif_pad,
                                                      sizeof(*profile));
           if (profile == (unsigned char*) NULL)
             {
@@ -210,7 +214,7 @@
             since they indicate the offset to the start of the TIFF
             header of the Exif data.
           */
-          err=heif_image_handle_get_metadata(heif_image_handle,ids[i],profile);
+          err=heif_image_handle_get_metadata(heif_image_handle,ids[i],profile+exif_pad);
 
           if (err.code != heif_error_Ok)
             {
@@ -226,12 +230,48 @@
 
           if (strncmp(profile_name,"Exif",4) == 0 && profile_size > 4)
             {
-              /* skip TIFF-Header */
-              SetImageProfile(image,profile_name,profile+4,profile_size-4);
+              /* Parse and skip offset to TIFF header */
+              unsigned char *p = profile;
+              magick_uint32_t offset;
+
+              /* Big-endian offset decoding */
+              offset = p[exif_pad+0] << 24 |
+                       p[exif_pad+1] << 16 |
+                       p[exif_pad+2] << 8 |
+                       p[exif_pad+3];
+
+              /*
+                If the TIFF header offset is not zero, then need to
+                move the TIFF data forward to the correct offset.
+              */
+              profile_size -= 4;
+              if (offset > 0 && offset < profile_size)
+                {
+                  profile_size -= offset;
+
+                  /* Strip any EOI marker if payload starts with a JPEG marker */
+                  if (profile_size > 2 &&
+                      (memcmp(p+exif_pad+4,"\xff\xd8",2) == 0 ||
+                      memcmp(p+exif_pad+4,"\xff\xe1",2) == 0) &&
+                      memcmp(p+exif_pad+4+profile_size-2,"\xff\xd9",2) == 0)
+                    profile_size -= 2;
+
+                  (void) memmove(p+exif_pad+4,p+exif_pad+4+offset,profile_size);
+                }
+
+              p[0]='E';
+              p[1]='x';
+              p[2]='i';
+              p[3]='f';
+              p[4]='\0';
+              p[5]='\0';
+
+              SetImageProfile(image,"EXIF",profile,profile_size+exif_pad+4);
             }
           else
             {
-              SetImageProfile(image,profile_name,profile,profile_size);
+              if (NULL != content_type && strncmp(content_type,"application/rdf+xml",19) == 0)
+                SetImageProfile(image,"XMP",profile,profile_size);
             }
           MagickFreeResourceLimitedMemory(profile);
         }
diff -r 11f622f51ff5 -r 3f33eb4c4b92 coders/jxl.c
--- a/coders/jxl.c	Sun Mar 26 18:02:08 2023 -0500
+++ b/coders/jxl.c	Thu Mar 30 12:44:56 2023 -0500
@@ -1,5 +1,5 @@
 /*
-% Copyright (C) 2022 GraphicsMagick Group
+% Copyright (C) 2023 GraphicsMagick Group
 %
 % This program is covered by multiple licenses, which are described in
 % Copyright.txt. You should have received a copy of Copyright.txt with this
@@ -912,9 +912,12 @@
                                         type[0],type[1],type[2],type[3], (unsigned long) profile_size);
 
                   /* Ignore tiny profiles */
-                  if (profile_size < 4)
+                  if (profile_size < 12)
                     break;
 
+                  /* Discard raw box size and type bytes */
+                  profile_size -= 8;
+
                   if (LocaleNCompare(type,"Exif",sizeof(type)) == 0)
                     {
                       /*
@@ -980,7 +983,12 @@
       unsigned char *p = exif_profile;
       magick_uint32_t exif_profile_offset;
 
-      (void) memcpy(&exif_profile_offset,p+exif_pad,sizeof(exif_profile_offset));
+      /* Big-endian offset decoding */
+      exif_profile_offset = p[exif_pad+0] << 24 |
+                            p[exif_pad+1] << 16 |
+                            p[exif_pad+2] << 8 |
+                            p[exif_pad+3];
+
 #if 0
       fprintf(stderr,
               "BOX-1: %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x\n",
@@ -992,9 +1000,23 @@
                             (unsigned long) exif_size, exif_profile_offset);
 
       /*
-        FIXME: If the TIFF header offset is not zero, then need to
+        If the TIFF header offset is not zero, then need to
         move the TIFF data forward to the correct offset.
       */
+      exif_size -= 4;
+      if (exif_profile_offset > 0 && exif_profile_offset < exif_size)
+        {
+          exif_size -= exif_profile_offset;
+
+          /* Strip any EOI marker if payload starts with a JPEG marker */
+          if (exif_size > 2 &&
+              (memcmp(p+exif_pad+4,"\xff\xd8",2) == 0 ||
+               memcmp(p+exif_pad+4,"\xff\xe1",2) == 0) &&
+              memcmp(p+exif_pad+4+exif_size-2,"\xff\xd9",2) == 0)
+            exif_size -= 2;
+
+          (void) memmove(p+exif_pad+4,p+exif_pad+4+exif_profile_offset,exif_size);
+        }
 
       p[0]='E';
       p[1]='x';
@@ -1008,7 +1030,7 @@
               "BOX-2: %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x\n",
               p[0], p[1],p[2], p[3], p[4], p[5], p[6], p[7],  p[8],  p[9],  p[10],  p[11]);
 #endif
-      (void) SetImageProfile(image,"EXIF",exif_profile,exif_size+exif_pad);
+      (void) SetImageProfile(image,"EXIF",exif_profile,exif_size+exif_pad+4);
 
       MagickFreeResourceLimitedMemory(exif_profile);
     }
diff -r 11f622f51ff5 -r 3f33eb4c4b92 magick/version.h
--- a/magick/version.h	Sun Mar 26 18:02:08 2023 -0500
+++ b/magick/version.h	Thu Mar 30 12:44:56 2023 -0500
@@ -38,8 +38,8 @@
 #define MagickLibVersion  0x272402
 #define MagickLibVersionText  "1.4"
 #define MagickLibVersionNumber 27,24,2
-#define MagickChangeDate   "20230326"
-#define MagickReleaseDate  "snapshot-20230326"
+#define MagickChangeDate   "20230330"
+#define MagickReleaseDate  "snapshot-20230330"
 
 /*
   The MagickLibInterfaceNewest and MagickLibInterfaceOldest defines
diff -r 11f622f51ff5 -r 3f33eb4c4b92 www/Changelog.html
--- a/www/Changelog.html	Sun Mar 26 18:02:08 2023 -0500
+++ b/www/Changelog.html	Thu Mar 30 12:44:56 2023 -0500
@@ -37,6 +37,17 @@
 </div>
 
 <div class="document">
+<p>2023-03-30  Bob Friesenhahn  &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li><p>coders/jxl.c (ReadJXLImage): Fix JXL EXIF offset handling, and
+deal with any EOI marker. (From SourceForge patch #69 submitted by
+Milos Komarcevic).</p></li>
+<li><p>coders/heif.c (ReadHEIFImage): Fix HEIF EXIF offset handling,
+and deal with any EOI marker.  Also fix HEIF XMP parsing. (From
+SourceForge patch #69 submitted by Milos Komarcevic).</p></li>
+</ul>
+</blockquote>
 <p>2023-03-26  Bob Friesenhahn  &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
 <blockquote>
 <ul class="simple">
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.