]> granicus.if.org Git - imagemagick/commitdiff
The 8bim profile will be updated when the iptc profile is changed.
authordirk <dirk@git.imagemagick.org>
Mon, 21 Apr 2014 17:19:03 +0000 (17:19 +0000)
committerdirk <dirk@git.imagemagick.org>
Mon, 21 Apr 2014 17:19:03 +0000 (17:19 +0000)
MagickCore/profile.c
coders/meta.c

index 304dee0099e269882db04fa37135fcec61af128e..a7b8408f3686d846107f770586a9065bb1da24eb 100644 (file)
   source_type,target_profile,target_type,intent,flags);
 #define cmsOpenProfileFromMemTHR(context,profile,length) \
   cmsOpenProfileFromMem(profile,length)
-#endif
+#endif\r
+\r
+/*\r
+  Forward declarations\r
+*/\r
+static MagickBooleanType\r
+  SetImageProfileInternal(Image *,const char *,const StringInfo *,\r
+    const MagickBooleanType,ExceptionInfo *);\r
+\r
+static void\r
+  WriteTo8BimProfile(Image *,const char*,const StringInfo *);
 \f
 /*
   Typedef declarations
@@ -204,6 +214,7 @@ MagickExport MagickBooleanType DeleteImageProfile(Image *image,const char *name)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   if (image->profiles == (SplayTreeInfo *) NULL)
     return(MagickFalse);
+  WriteTo8BimProfile(image,name,(StringInfo *) NULL);
   return(DeleteNodeFromSplayTree((SplayTreeInfo *) image->profiles,name));
 }
 \f
@@ -1024,6 +1035,7 @@ MagickExport StringInfo *RemoveImageProfile(Image *image,const char *name)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   if (image->profiles == (SplayTreeInfo *) NULL)
     return((StringInfo *) NULL);
+  WriteTo8BimProfile(image,name,(StringInfo *) NULL);
   profile=(StringInfo *) RemoveNodeFromSplayTree((SplayTreeInfo *)
     image->profiles,name);
   return(profile);
@@ -1134,9 +1146,121 @@ static inline const unsigned char *ReadResourceShort(const unsigned char *p,
   *quantum=(unsigned short) (*p++ << 8);
   *quantum|=(unsigned short) (*p++ << 0);
   return(p);
-}
-
-static MagickBooleanType GetProfilesFromResourceBlock(Image *image,
+}static inline void WriteResourceLong(unsigned char *p,\r
+  const unsigned int quantum)\r
+{\r
+  unsigned char\r
+    buffer[4];\r
+\r
+  buffer[0]=(unsigned char) (quantum >> 24);\r
+  buffer[1]=(unsigned char) (quantum >> 16);\r
+  buffer[2]=(unsigned char) (quantum >> 8);\r
+  buffer[3]=(unsigned char) quantum;\r
+  (void) CopyMagickMemory(p,buffer,4);\r
+}\r
+\r
+static void WriteTo8BimProfile(Image *image,const char *name,\r
+  const StringInfo *iptc_profile)\r
+{\r
+\r
+  const unsigned char\r
+    *datum,\r
+    *s;\r
+\r
+  register const unsigned char\r
+    *p;\r
+\r
+  size_t\r
+    length;\r
+\r
+  StringInfo\r
+    *profile;\r
+\r
+  ssize_t\r
+    count;\r
+\r
+  unsigned char\r
+    length_byte;\r
+\r
+  unsigned int\r
+    value;\r
+\r
+  unsigned short\r
+    id;\r
+\r
+  if (LocaleCompare(name,"iptc") != 0)\r
+    return;\r
+  profile=(StringInfo *)GetValueFromSplayTree((SplayTreeInfo *)image->profiles,\r
+    "8bim");\r
+  if (profile == (StringInfo *) NULL)\r
+    return;\r
+  datum=GetStringInfoDatum(profile);\r
+  length=GetStringInfoLength(profile);\r
+  for (p=datum; p < (datum+length-16); )\r
+  {\r
+    s=p;\r
+    if (LocaleNCompare((char *) p,"8BIM",4) != 0)\r
+      break;\r
+    p+=4;\r
+    p=ReadResourceShort(p,&id);\r
+    p=ReadResourceByte(p,&length_byte);\r
+    p+=length_byte;\r
+    if (((length_byte+1) & 0x01) != 0)\r
+      p++;\r
+    if (p > (datum+length-4))\r
+      break;\r
+    p=ReadResourceLong(p,&value);\r
+    count=(ssize_t) value;\r
+    if ((p > (datum+length-count)) || (count > length))\r
+      break;\r
+    if ((count & 0x01) != 0)\r
+      count++;\r
+    if (id == 0x0404)\r
+      {\r
+        size_t\r
+          offset,\r
+          rest;\r
+\r
+        ssize_t\r
+          new_count;\r
+\r
+        StringInfo\r
+          *new_profile;\r
+\r
+        new_count=0;\r
+        rest=(datum+length)-(p+count);\r
+        if (iptc_profile == (StringInfo *) NULL)\r
+          {\r
+            offset=(s-datum);\r
+            new_profile=AcquireStringInfo(offset+rest);\r
+            (void) CopyMagickMemory(new_profile->datum,datum,offset);\r
+          }\r
+        else\r
+          {\r
+            offset=(p-datum);\r
+            new_count=iptc_profile->length;\r
+            if ((new_count & 0x01) != 0)\r
+              new_count++;\r
+            new_profile=AcquireStringInfo(offset+new_count+rest);\r
+            (void) CopyMagickMemory(new_profile->datum,datum,offset-4);\r
+            WriteResourceLong(new_profile->datum+offset-4,\r
+              iptc_profile->length);\r
+            (void) CopyMagickMemory(new_profile->datum+offset,\r
+              iptc_profile->datum,iptc_profile->length);\r
+          }\r
+        (void) CopyMagickMemory(new_profile->datum+offset+new_count,p+count,\r
+          rest);\r
+        (void) AddValueToSplayTree((SplayTreeInfo *) image->profiles,\r
+          ConstantString("8bim"),CloneStringInfo(new_profile));\r
+        new_profile=DestroyStringInfo(new_profile);\r
+        break;\r
+      }\r
+    else\r
+      p+=count;\r
+  }\r
+}\r
+\r
+static void GetProfilesFromResourceBlock(Image *image,
   const StringInfo *resource_block,ExceptionInfo *exception)
 {
   const unsigned char
@@ -1219,7 +1343,8 @@ static MagickBooleanType GetProfilesFromResourceBlock(Image *image,
         */
         profile=AcquireStringInfo(count);
         SetStringInfoDatum(profile,p);
-        (void) SetImageProfile(image,"iptc",profile,exception);
+        (void) SetImageProfileInternal(image,"iptc",profile,MagickTrue,
+          exception);
         profile=DestroyStringInfo(profile);
         p+=count;
         break;
@@ -1239,7 +1364,8 @@ static MagickBooleanType GetProfilesFromResourceBlock(Image *image,
         */
         profile=AcquireStringInfo(count);
         SetStringInfoDatum(profile,p);
-        (void) SetImageProfile(image,"icc",profile,exception);
+        (void) SetImageProfileInternal(image,"icc",profile,MagickTrue,
+          exception);
         profile=DestroyStringInfo(profile);
         p+=count;
         break;
@@ -1251,7 +1377,8 @@ static MagickBooleanType GetProfilesFromResourceBlock(Image *image,
         */
         profile=AcquireStringInfo(count);
         SetStringInfoDatum(profile,p);
-        (void) SetImageProfile(image,"exif",profile,exception);
+        (void) SetImageProfileInternal(image,"exif",profile,MagickTrue,
+          exception);
         profile=DestroyStringInfo(profile);
         p+=count;
         break;
@@ -1263,7 +1390,8 @@ static MagickBooleanType GetProfilesFromResourceBlock(Image *image,
         */
         profile=AcquireStringInfo(count);
         SetStringInfoDatum(profile,p);
-        (void) SetImageProfile(image,"xmp",profile,exception);
+        (void) SetImageProfileInternal(image,"xmp",profile,MagickTrue,
+          exception);
         profile=DestroyStringInfo(profile);
         p+=count;
         break;
@@ -1277,11 +1405,11 @@ static MagickBooleanType GetProfilesFromResourceBlock(Image *image,
     if ((count & 0x01) != 0)
       p++;
   }
-  return(MagickTrue);
 }
 
-MagickExport MagickBooleanType SetImageProfile(Image *image,const char *name,
-  const StringInfo *profile,ExceptionInfo *exception)
+static MagickBooleanType SetImageProfileInternal(Image *image,const char *name,
+  const StringInfo *profile,const MagickBooleanType recursive,
+  ExceptionInfo *exception)
 {
   char
     key[MaxTextExtent],
@@ -1298,11 +1426,16 @@ MagickExport MagickBooleanType SetImageProfile(Image *image,const char *name,
     image->profiles=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
       DestroyProfile);
   (void) CopyMagickString(key,name,MaxTextExtent);
+  LocaleLower(key);
   status=AddValueToSplayTree((SplayTreeInfo *) image->profiles,
     ConstantString(key),CloneStringInfo(profile));
-  if ((status != MagickFalse) &&
-      ((LocaleCompare(name,"iptc") == 0) || (LocaleCompare(name,"8bim") == 0)))
-    (void) GetProfilesFromResourceBlock(image,profile,exception);
+  if (status != MagickFalse)
+    {
+      if (LocaleCompare(name,"8bim") == 0)
+        GetProfilesFromResourceBlock(image,profile,exception);
+      else if (recursive == MagickFalse)\r
+        WriteTo8BimProfile(image,name,profile);
+    }
   /*
     Inject profile into image properties.
   */
@@ -1310,6 +1443,12 @@ MagickExport MagickBooleanType SetImageProfile(Image *image,const char *name,
   (void) GetImageProperty(image,property,exception);
   return(status);
 }
+
+MagickExport MagickBooleanType SetImageProfile(Image *image,const char *name,
+  const StringInfo *profile,ExceptionInfo *exception)
+{
+  return(SetImageProfileInternal(image,name,profile,MagickFalse,exception));
+}
 \f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 2edf9838043a5515f1906d83ab113831c31ce1db..f659ce180456feac1d184ad0feff76c433f68943 100644 (file)
@@ -1063,6 +1063,39 @@ static int jpeg_extract(Image *ifile, Image *ofile)
 }
 #endif
 
+static inline void CopyBlob(Image *source,Image *destination)
+{
+  ssize_t
+    i;
+
+  unsigned char
+    *buffer;
+
+  ssize_t
+    count,
+    length;
+
+  buffer=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
+    sizeof(*buffer));
+  if (buffer != (unsigned char *) NULL)
+    {
+      i=0;
+      while ((length=ReadBlob(source,MagickMaxBufferExtent,buffer)) != 0)
+      {
+        count=0;
+        for (i=0; i < (ssize_t) length; i+=count)
+        {
+          count=WriteBlob(destination,(size_t) (length-i),buffer+i);
+          if (count <= 0)
+            break;
+        }
+        if (i < (ssize_t) length)
+          break;
+      }
+      buffer=(unsigned char *) RelinquishMagickMemory(buffer);
+    }
+}
+
 static Image *ReadMETAImage(const ImageInfo *image_info,
   ExceptionInfo *exception)
 {
@@ -1070,9 +1103,6 @@ static Image *ReadMETAImage(const ImageInfo *image_info,
     *buff,
     *image;
 
-  int
-    c;
-
   MagickBooleanType
     status;
 
@@ -1138,15 +1168,7 @@ static Image *ReadMETAImage(const ImageInfo *image_info,
             (void) WriteBlobByte(buff,0x0);
         }
       else
-        {
-          for ( ; ; )
-          {
-            c=ReadBlobByte(image);
-            if (c == EOF)
-              break;
-            (void) WriteBlobByte(buff,(unsigned char) c);
-          }
-        }
+        CopyBlob(image,buff);
       profile=BlobToStringInfo(GetBlobStreamData(buff),(size_t)
         GetBlobSize(buff));
       if (profile == (StringInfo *) NULL)
@@ -1214,48 +1236,7 @@ static Image *ReadMETAImage(const ImageInfo *image_info,
             }
         }
       else
-        {
-#ifdef SLOW_METHOD
-          for ( ; ; )
-          {
-            /* Really - really slow - FIX ME PLEASE!!!! */
-            c=ReadBlobByte(image);
-            if (c == EOF)
-              break;
-            (void) WriteBlobByte(buff,c);
-          }
-#else
-          ssize_t
-            i;
-
-          unsigned char
-            *buffer;
-
-          ssize_t
-            count,
-            length;
-
-          buffer=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
-            sizeof(*buffer));
-          if (buffer != (unsigned char *) NULL)
-            {
-              i=0;
-              while ((length=ReadBlob(image,MagickMaxBufferExtent,buffer)) != 0)
-              {
-                count=0;
-                for (i=0; i < (ssize_t) length; i+=count)
-                {
-                  count=WriteBlob(buff,(size_t) (length-i),buffer+i);
-                  if (count <= 0)
-                    break;
-                }
-                if (i < (ssize_t) length)
-                  break;
-              }
-              buffer=(unsigned char *) RelinquishMagickMemory(buffer);
-            }
-#endif
-        }
+        CopyBlob(image,buff);
       profile=BlobToStringInfo(GetBlobStreamData(buff),(size_t)
         GetBlobSize(buff));
       if (profile == (StringInfo *) NULL)
@@ -1281,13 +1262,7 @@ static Image *ReadMETAImage(const ImageInfo *image_info,
           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
         }
       AttachBlob(buff->blob,blob,length);
-      for ( ; ; )
-      {
-        c=ReadBlobByte(image);
-        if (c == EOF)
-          break;
-        (void) WriteBlobByte(buff,(unsigned char) c);
-      }
+      CopyBlob(image,buff);
       profile=BlobToStringInfo(GetBlobStreamData(buff),(size_t)
         GetBlobSize(buff));
       if (profile == (StringInfo *) NULL)
@@ -1300,9 +1275,6 @@ static Image *ReadMETAImage(const ImageInfo *image_info,
     }
   if (LocaleCompare(image_info->magick,"IPTC") == 0)
     {
-      register unsigned char
-        *p;
-
       buff=AcquireImage((ImageInfo *) NULL,exception);
       if (buff == (Image *) NULL)
         ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
@@ -1313,40 +1285,11 @@ static Image *ReadMETAImage(const ImageInfo *image_info,
           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
         }
       AttachBlob(buff->blob,blob,length);
-      /* write out the header - length field patched below */
-      (void) WriteBlob(buff,11,(unsigned char *) "8BIM\04\04\0\0\0\0\0");
-      (void) WriteBlobByte(buff,0xc6);
-      if (LocaleCompare(image_info->magick,"IPTCTEXT") == 0)
-        {
-          length=(size_t) parse8BIM(image,buff);
-          if (length & 1)
-            (void) WriteBlobByte(buff,0x00);
-        }
-      else if (LocaleCompare(image_info->magick,"IPTCWTEXT") == 0)
-        {
-        }
-      else
-        {
-          for ( ; ; )
-          {
-            c=ReadBlobByte(image);
-            if (c == EOF)
-              break;
-            (void) WriteBlobByte(buff,(unsigned char) c);
-          }
-        }
+      CopyBlob(image,buff);
       profile=BlobToStringInfo(GetBlobStreamData(buff),(size_t)
         GetBlobSize(buff));
       if (profile == (StringInfo *) NULL)
         ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
-      /*
-        subtract off the length of the 8BIM stuff.
-      */
-      length=GetStringInfoLength(profile)-12;
-      p=GetStringInfoDatum(profile);
-      p[10]=(unsigned char) (length >> 8);
-      p[11]=(unsigned char) (length & 0xff);
-      SetStringInfoDatum(profile,GetBlobStreamData(buff));
       (void) SetImageProfile(image,"8bim",profile,exception);
       profile=DestroyStringInfo(profile);
       blob=DetachBlob(buff->blob);
@@ -1365,13 +1308,7 @@ static Image *ReadMETAImage(const ImageInfo *image_info,
           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
         }
       AttachBlob(buff->blob,blob,length);
-      for ( ; ; )
-      {
-        c=ReadBlobByte(image);
-        if (c == EOF)
-          break;
-        (void) WriteBlobByte(buff,(unsigned char) c);
-      }
+      CopyBlob(image,buff);
       profile=BlobToStringInfo(GetBlobStreamData(buff),(size_t)
         GetBlobSize(buff));
       if (profile == (StringInfo *) NULL)