GraphicsMagick: coders/tiff.c Check recipe compatibility for TIF...

GraphicsMagick Commits <[email protected]> Sun, 17 Dec 2023 04:37:42 -0600
Newsgroups gmane.comp.video.graphicsmagick.cvs
Message-ID <mailman.13140.1702809477.7940.graphicsmagick-commit@lists.sourceforge.net>
changeset 9a403d97bcda in /hg/GraphicsMagick
details: http://hg.GraphicsMagick.org/hg/GraphicsMagick?cmd=changeset;node=9a403d97bcda
summary: coders/tiff.c Check recipe compatibility for TIFFSetField().

diffstat:

 ChangeLog     |    4 +
 coders/tiff.c |  160 ++++++++++++++++++++++++++++++---------------------------
 2 files changed, 88 insertions(+), 76 deletions(-)

diffs (206 lines):

diff -r d4ebc98a80f4 -r 9a403d97bcda ChangeLog
--- a/ChangeLog	Sat Dec 16 20:54:32 2023 +0100
+++ b/ChangeLog	Sun Dec 17 11:37:18 2023 +0100
@@ -1,3 +1,7 @@
+2023-12-16  Fojtik Jaroslav  <[email protected]>
+
+	* coders/tiff.c Check recipe compatibility for TIFFSetField().
+
 2023-12-16  Fojtik Jaroslav  <[email protected]>
 
 	* coders/tiff.c Attempt to store EXIF inside TIFF image.
diff -r d4ebc98a80f4 -r 9a403d97bcda coders/tiff.c
--- a/coders/tiff.c	Sat Dec 16 20:54:32 2023 +0100
+++ b/coders/tiff.c	Sun Dec 17 11:37:18 2023 +0100
@@ -4442,12 +4442,13 @@
 {
 const char EXIF[6] = {'E','x','i','f',0,0};
 uint32_t IFDpos;
-uint16_t EntryNum;
-uint16_t Tag, Field;
+uint16_t EntryNum;
+uint16_t Tag, Field;
 uint32_t Long2, Value;
 int FieldCount = 0;
 uint32_t(*LD_UINT32)(const unsigned char *Mem);
 uint16_t(*LD_UINT16)(const unsigned char *Mem);
+const TIFFField *fip;  // = TIFFFindField(tif, tag, TIFF_ANY);
 /* TIFFField FakeField; */
 
   if(profile_data==NULL || profile_length<12+8) return 0;
@@ -4458,20 +4459,20 @@
     if(profile_length<12+8) return 0;
   }
 
-  if(profile_data[0]=='I' && profile_data[1]=='I')
-  {
-    LD_UINT32 = LD_UINT32_LO;
-    LD_UINT16 = LD_UINT16_LO;
-  }
-  else
-  {
-    if(profile_data[0]=='M' && profile_data[1]=='M')
-    {
-      LD_UINT32 = LD_UINT32_HI;
-      LD_UINT16 = LD_UINT16_HI;
-    }
-    else
-        return 0;
+  if(profile_data[0]=='I' && profile_data[1]=='I')
+  {
+    LD_UINT32 = LD_UINT32_LO;
+    LD_UINT16 = LD_UINT16_LO;
+  }
+  else
+  {
+    if(profile_data[0]=='M' && profile_data[1]=='M')
+    {
+      LD_UINT32 = LD_UINT32_HI;
+      LD_UINT16 = LD_UINT16_HI;
+    }
+    else
+        return 0;
   }
 
 /*
@@ -4481,53 +4482,56 @@
   }
 */
 
-  IFDpos = 4;
-  do
-  {
-    Value = LD_UINT32(profile_data+IFDpos);
-    if(Value<=IFDpos || Value<8) return FieldCount;	// 0 means stop; IFDPOS should progress.
-    IFDpos = Value;
-
-    EntryNum = LD_UINT16(profile_data+IFDpos);
-    IFDpos += 2;
-    while(EntryNum>0)
-    {
-      Tag = LD_UINT16(profile_data+IFDpos);
-      Field = LD_UINT16(profile_data+IFDpos+2);
-      Long2 = LD_UINT32(profile_data+IFDpos+4);
-      Value = LD_UINT32(profile_data+IFDpos+8);
-      if(logging)
-        (void)LogMagickEvent(CoderEvent,GetMagickModule(),"Extracted tag from EXIF %xh, Field %d, Long2 %d, val %d", Tag, Field, Long2, Value);
-
-    if(Tag != EXIFTAG_SECURITYCLASSIFICATION &&
-       Tag != EXIFTAG_IMAGEHISTORY &&
-       Tag != EXIFTAG_ISOSPEEDRATINGS)		/* libtiff doesn't understand these */
-      {
-        switch(Field)
-        {
-          case TIFF_ASCII: if(Value>=profile_length-1) break;
-                           if(TIFFSetField(tiff, Tag, profile_data+Value))
-                               FieldCount++;
-                           break;
-          case TIFF_BYTE:
-          case TIFF_SHORT:
-          case TIFF_LONG:  if(TIFFSetField(tiff, Tag, Value))
-                               FieldCount++;
-                           break;
-          //case TIFF_SRATIONAL:  ??
-          case TIFF_RATIONAL:
-                           {
-                           double d = Value / (double)Long2;
-                           if(TIFFSetField(tiff, Tag, d))
-                               FieldCount++;
-                           break;
-                           }
-        }
-      }
-      IFDpos += 12;	// Go to a next direntry.
-      if(IFDpos+12>=profile_length) return FieldCount;
-      EntryNum--;
-    }
+  IFDpos = 4;
+  do
+  {
+    Value = LD_UINT32(profile_data+IFDpos);
+    if(Value<=IFDpos || Value<8) return FieldCount;	// 0 means stop; IFDPOS should progress.
+    IFDpos = Value;
+
+    EntryNum = LD_UINT16(profile_data+IFDpos);
+    IFDpos += 2;
+    while(EntryNum>0)
+    {
+      Tag = LD_UINT16(profile_data+IFDpos);
+      Field = LD_UINT16(profile_data+IFDpos+2);
+      Long2 = LD_UINT32(profile_data+IFDpos+4);
+      Value = LD_UINT32(profile_data+IFDpos+8);
+      if(logging)
+        (void)LogMagickEvent(CoderEvent,GetMagickModule(),"Extracted tag from EXIF %xh, Field %d, Long2 %d, val %d", Tag, Field, Long2, Value);
+
+      fip = TIFFFindField(tiff, Tag, TIFF_ANY);
+      if(fip!=NULL)		/* libtiff doesn't understand these */
+      {
+        switch(Field)
+        {
+          case TIFF_ASCII: if(fip->field_type!=TIFF_ASCII) break;	/* Incompatible recipe.*/
+                           if(Value>=profile_length-1) break;		/* String outside EXIF boundary. */
+                           if(TIFFSetField(tiff, Tag, profile_data+Value))
+                               FieldCount++;
+                           break;
+          case TIFF_BYTE:
+          case TIFF_SHORT:
+          case TIFF_LONG:  if(fip->field_type!=TIFF_BYTE && fip->field_type!=TIFF_SHORT && fip->field_type!=TIFF_LONG)
+                               break;
+                           if(TIFFSetField(tiff, Tag, Value))
+                               FieldCount++;
+                           break;
+          //case TIFF_SRATIONAL:  ??
+          case TIFF_RATIONAL:
+                           if(fip->field_type == TIFF_RATIONAL)
+                           {
+                             double d = Value / (double)Long2;
+                             if(TIFFSetField(tiff, Tag, d))
+                                 FieldCount++;
+                           }
+                           break;
+        }
+      }
+      IFDpos += 12;	// Go to a next direntry.
+      if(IFDpos+12>=profile_length) return FieldCount;
+      EntryNum--;
+    }
   } while(IFDpos+4 < profile_length);
 
   return FieldCount;
@@ -6620,19 +6624,23 @@
           if((profile_data=GetImageProfile(image,"Exif",&profile_length)) != 0)
           {
             if(AddExifFields(tiff,profile_data,profile_length,logging) > 0)
-            {             /* Now write the directory of Exif data */
-              uint64_t dir_offset = 0;
-              if(!TIFFWriteCustomDirectory(tiff, &dir_offset)) 
-              {
-                LogMagickEvent(CoderEvent,GetMagickModule(),"failed TIFFWriteCustomDirectory() of the Exif data");
-              }
-              else
-              {  /* Go back to the first directory, and add the EXIFIFD pointer.
-                  std::cout << "diffdir = " << tiffdir << "\n"; */
-                TIFFSetDirectory(tiff, 0);
-                TIFFSetField(tiff, TIFFTAG_EXIFIFD, dir_offset);
-              }
-            }
+            {             /* Now write the directory of Exif data */
+              uint64_t dir_offset = 0;
+              if(!TIFFWriteCustomDirectory(tiff, &dir_offset)) 
+              {
+                LogMagickEvent(CoderEvent,GetMagickModule(),"Failed TIFFWriteCustomDirectory() of the Exif data");
+              }
+              else
+              {  // Go back to the first directory, and add the EXIFIFD pointer.
+                TIFFSetDirectory(tiff, 0);
+                TIFFSetField(tiff, TIFFTAG_EXIFIFD, dir_offset);
+                if(!TIFFWriteDirectory(tiff))
+                {
+                 (void)LogMagickEvent(CoderEvent,GetMagickModule(),
+                                "TIFFWriteDirectory EXIF returns failed status!");
+                }
+              }
+            }
           }
         }
 #endif