]> granicus.if.org Git - imagemagick/commitdiff
Moved reading of PS info to a separate method.
authorDirk Lemstra <dirk@lemstra.org>
Thu, 11 Jul 2019 21:36:47 +0000 (23:36 +0200)
committerDirk Lemstra <dirk@lemstra.org>
Thu, 11 Jul 2019 21:36:47 +0000 (23:36 +0200)
coders/ps.c

index 5b0144a3864441e8763f4996cc7a8bd4c84c56fc..6608b884f53a69dc93c0a79ad876c2bfb7488578 100644 (file)
 #include "MagickCore/utility.h"
 #include "ghostscript-private.h"
 \f
+/*
+  Typedef declaractions.
+*/
+typedef struct _PSInfo
+{
+  MagickBooleanType
+    cmyk;
+
+  SegmentInfo
+    bounds;
+
+  unsigned long
+    columns,
+    rows;
+
+  StringInfo
+    *icc_profile,
+    *photoshop_profile,
+    *xmp_profile;
+
+} PSInfo;
+\f
 /*
   Forward declarations.
 */
@@ -178,75 +200,36 @@ static inline int ProfileInteger(Image *image,short int *hex_digits)
   return(value);
 }
 
-static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
+static void ReadPSInfo(const ImageInfo *image_info,Image *image,
+  PSInfo *ps_info,ExceptionInfo *exception)
 {
-#define BoundingBox  "BoundingBox:"
 #define BeginDocument  "BeginDocument:"
-#define BeginXMPPacket  "<?xpacket begin="
-#define EndXMPPacket  "<?xpacket end="
-#define ICCProfile "BeginICCProfile:"
+#define EndDocument  "EndDocument:"
+#define PostscriptLevel  "!PS-"
+#define ImageData  "ImageData:"
+#define DocumentProcessColors  "DocumentProcessColors:"
 #define CMYKCustomColor  "CMYKCustomColor:"
 #define CMYKProcessColor  "CMYKProcessColor:"
-#define DocumentMedia  "DocumentMedia:"
 #define DocumentCustomColors  "DocumentCustomColors:"
-#define DocumentProcessColors  "DocumentProcessColors:"
-#define EndDocument  "EndDocument:"
+#define SpotColor  "+ "
+#define BoundingBox  "BoundingBox:"
+#define DocumentMedia  "DocumentMedia:"
 #define HiResBoundingBox  "HiResBoundingBox:"
-#define ImageData  "ImageData:"
 #define PageBoundingBox  "PageBoundingBox:"
-#define LanguageLevel  "LanguageLevel:"
 #define PageMedia  "PageMedia:"
-#define Pages  "Pages:"
+#define ICCProfile "BeginICCProfile:"
 #define PhotoshopProfile  "BeginPhotoshop:"
-#define PostscriptLevel  "!PS-"
-#define SpotColor  "+ "
+#define BeginXMPPacket  "<?xpacket begin="
+#define EndXMPPacket  "<?xpacket end="
 
   char
-    command[MagickPathExtent],
-    *density,
-    filename[MagickPathExtent],
-    geometry[MagickPathExtent],
-    input_filename[MagickPathExtent],
-    message[MagickPathExtent],
-    *options,
-    postscript_filename[MagickPathExtent];
-
-  const char
-    *option;
-
-  const DelegateInfo
-    *delegate_info;
-
-  GeometryInfo
-    geometry_info;
-
-  Image
-    *image,
-    *next,
-    *postscript_image;
-
-  ImageInfo
-    *read_info;
+    command[MagickPathExtent];
 
   int
-    c,
-    file;
+    c;
 
   MagickBooleanType
-    cmyk,
-    fitPage,
-    skip,
-    status;
-
-  MagickStatusType
-    flags;
-
-  PointInfo
-    delta,
-    resolution;
-
-  RectangleInfo
-    page;
+    skip;
 
   register char
     *p;
@@ -255,11 +238,7 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
     i;
 
   SegmentInfo
-    bounds,
-    hires_bounds;
-
-  short int
-    hex_digits[256];
+    bounds;
 
   size_t
     length;
@@ -268,43 +247,17 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
     count,
     priority;
 
-  StringInfo
-    *profile;
+  short int
+    hex_digits[256];
 
   unsigned long
-    columns,
     extent,
-    language_level,
-    pages,
-    rows,
-    scene,
     spotcolor;
 
-  /*
-    Open image file.
-  */
-  assert(image_info != (const ImageInfo *) NULL);
-  assert(image_info->signature == MagickCoreSignature);
-  if (image_info->debug != MagickFalse)
-    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
-      image_info->filename);
-  assert(exception != (ExceptionInfo *) NULL);
-  assert(exception->signature == MagickCoreSignature);
-  image=AcquireImage(image_info,exception);
-  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
-  if (status == MagickFalse)
-    {
-      image=DestroyImageList(image);
-      return((Image *) NULL);
-    }
-  status=AcquireUniqueSymbolicLink(image_info->filename,input_filename);
-  if (status == MagickFalse)
-    {
-      ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
-        image_info->filename);
-      image=DestroyImageList(image);
-      return((Image *) NULL);
-    }
+  (void) memset(&bounds,0,sizeof(bounds));
+  (void) memset(ps_info,0,sizeof(*ps_info));
+  ps_info->cmyk=image_info->colorspace == CMYKColorspace ? MagickTrue :
+    MagickFalse;
   /*
     Initialize hex values.
   */
@@ -331,48 +284,9 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
   hex_digits[(int) 'D']=13;
   hex_digits[(int) 'E']=14;
   hex_digits[(int) 'F']=15;
-  /*
-    Set the page density.
-  */
-  delta.x=DefaultResolution;
-  delta.y=DefaultResolution;
-  if ((image->resolution.x == 0.0) || (image->resolution.y == 0.0))
-    {
-      flags=ParseGeometry(PSDensityGeometry,&geometry_info);
-      image->resolution.x=geometry_info.rho;
-      image->resolution.y=geometry_info.sigma;
-      if ((flags & SigmaValue) == 0)
-        image->resolution.y=image->resolution.x;
-    }
-  if (image_info->density != (char *) NULL)
-    {
-      flags=ParseGeometry(image_info->density,&geometry_info);
-      image->resolution.x=geometry_info.rho;
-      image->resolution.y=geometry_info.sigma;
-      if ((flags & SigmaValue) == 0)
-        image->resolution.y=image->resolution.x;
-    }
-  (void) ParseAbsoluteGeometry(PSPageGeometry,&page);
-  if (image_info->page != (char *) NULL)
-    (void) ParseAbsoluteGeometry(image_info->page,&page);
-  resolution=image->resolution;
-  page.width=(size_t) ceil((double) (page.width*resolution.x/delta.x)-0.5);
-  page.height=(size_t) ceil((double) (page.height*resolution.y/delta.y)-0.5);
-  /*
-    Determine page geometry from the Postscript bounding box.
-  */
-  (void) memset(&bounds,0,sizeof(bounds));
-  (void) memset(command,0,sizeof(command));
-  cmyk=image_info->colorspace == CMYKColorspace ? MagickTrue : MagickFalse;
-  (void) memset(&hires_bounds,0,sizeof(hires_bounds));
-  columns=0;
-  rows=0;
-  priority=0;
-  rows=0;
   extent=0;
+  priority=0;
   spotcolor=0;
-  language_level=1;
-  pages=(~0UL);
   skip=MagickFalse;
   p=command;
   for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
@@ -396,17 +310,10 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
     if (skip != MagickFalse)
       continue;
     if (LocaleNCompare(PostscriptLevel,command,strlen(PostscriptLevel)) == 0)
-      {
-        (void) SetImageProperty(image,"ps:Level",command+4,exception);
-        if (GlobExpression(command,"*EPSF-*",MagickTrue) != MagickFalse)
-          pages=1;
-      }
-    if (LocaleNCompare(LanguageLevel,command,strlen(LanguageLevel)) == 0)
-      (void) sscanf(command,LanguageLevel " %lu",&language_level);
-    if (LocaleNCompare(Pages,command,strlen(Pages)) == 0)
-      (void) sscanf(command,Pages " %lu",&pages);
+      (void) SetImageProperty(image,"ps:Level",command+4,exception);
     if (LocaleNCompare(ImageData,command,strlen(ImageData)) == 0)
-      (void) sscanf(command,ImageData " %lu %lu",&columns,&rows);
+      (void) sscanf(command,ImageData " %lu %lu",&ps_info->columns,
+        &ps_info->rows);
     /*
       Is this a CMYK document?
     */
@@ -416,12 +323,12 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
         if ((GlobExpression(command,"*Cyan*",MagickTrue) != MagickFalse) ||
             (GlobExpression(command,"*Magenta*",MagickTrue) != MagickFalse) ||
             (GlobExpression(command,"*Yellow*",MagickTrue) != MagickFalse))
-          cmyk=MagickTrue;
+          ps_info->cmyk=MagickTrue;
       }
     if (LocaleNCompare(CMYKCustomColor,command,strlen(CMYKCustomColor)) == 0)
-      cmyk=MagickTrue;
+      ps_info->cmyk=MagickTrue;
     if (LocaleNCompare(CMYKProcessColor,command,strlen(CMYKProcessColor)) == 0)
-      cmyk=MagickTrue;
+      ps_info->cmyk=MagickTrue;
     length=strlen(DocumentCustomColors);
     if ((LocaleNCompare(DocumentCustomColors,command,length) == 0) ||
         (LocaleNCompare(CMYKCustomColor,command,strlen(CMYKCustomColor)) == 0) ||
@@ -451,6 +358,75 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
         value=DestroyString(value);
         continue;
       }
+    if (LocaleNCompare(ICCProfile,command,strlen(ICCProfile)) == 0)
+      {
+        unsigned char
+          *datum;
+
+        /*
+          Read ICC profile.
+        */
+        ps_info->icc_profile=AcquireStringInfo(MagickPathExtent);
+        datum=GetStringInfoDatum(ps_info->icc_profile);
+        for (i=0; (c=ProfileInteger(image,hex_digits)) != EOF; i++)
+        {
+          if (i >= (ssize_t) GetStringInfoLength(ps_info->icc_profile))
+            {
+              SetStringInfoLength(ps_info->icc_profile,(size_t) i << 1);
+              datum=GetStringInfoDatum(ps_info->icc_profile);
+            }
+          datum[i]=(unsigned char) c;
+        }
+        SetStringInfoLength(ps_info->icc_profile,(size_t) i+1);
+        continue;
+      }
+    if (LocaleNCompare(PhotoshopProfile,command,strlen(PhotoshopProfile)) == 0)
+      {
+        unsigned char
+          *q;
+
+        /*
+          Read Photoshop profile.
+        */
+        count=(ssize_t) sscanf(command,PhotoshopProfile " %lu",&extent);
+        if (count != 1)
+          continue;
+        length=extent;
+        if ((MagickSizeType) length > GetBlobSize(image))
+          continue;
+        ps_info->photoshop_profile=BlobToStringInfo((const void *) NULL,length);
+        if (ps_info->photoshop_profile != (StringInfo *) NULL)
+          {
+            q=GetStringInfoDatum(ps_info->photoshop_profile);
+            for (i=0; i < (ssize_t) length; i++)
+              *q++=(unsigned char) ProfileInteger(image,hex_digits);
+          }
+        continue;
+      }
+    if (LocaleNCompare(BeginXMPPacket,command,strlen(BeginXMPPacket)) == 0)
+      {
+        /*
+          Read XMP profile.
+        */
+        p=command;
+        ps_info->xmp_profile=StringToStringInfo(command);
+        for (i=(ssize_t) GetStringInfoLength(ps_info->xmp_profile)-1; c != EOF; i++)
+        {
+          SetStringInfoLength(ps_info->xmp_profile,(size_t) (i+1));
+          c=ReadBlobByte(image);
+          GetStringInfoDatum(ps_info->xmp_profile)[i]=(unsigned char) c;
+          *p++=(char) c;
+          if ((strchr("\n\r%",c) == (char *) NULL) &&
+              ((size_t) (p-command) < (MagickPathExtent-1)))
+            continue;
+          *p='\0';
+          p=command;
+          if (LocaleNCompare(EndXMPPacket,command,strlen(EndXMPPacket)) == 0)
+            break;
+        }
+        SetStringInfoLength(ps_info->xmp_profile,(size_t) i);
+        continue;
+      }
     if (image_info->page != (char *) NULL)
       continue;
     /*
@@ -490,26 +466,153 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
       }
     if ((count != 4) || (i < (ssize_t) priority))
       continue;
-    if ((fabs(bounds.x2-bounds.x1) <= fabs(hires_bounds.x2-hires_bounds.x1)) ||
-        (fabs(bounds.y2-bounds.y1) <= fabs(hires_bounds.y2-hires_bounds.y1)))
+    if ((fabs(bounds.x2-bounds.x1) <= fabs(ps_info->bounds.x2-ps_info->bounds.x1)) ||
+        (fabs(bounds.y2-bounds.y1) <= fabs(ps_info->bounds.y2-ps_info->bounds.y1)))
       if (i ==  (ssize_t) priority)
         continue;
-    hires_bounds=bounds;
+    ps_info->bounds=bounds;
     priority=i;
   }
-  if ((fabs(hires_bounds.x2-hires_bounds.x1) >= MagickEpsilon) &&
-      (fabs(hires_bounds.y2-hires_bounds.y1) >= MagickEpsilon))
+}
+
+static inline void CleanupPSInfo(PSInfo *pdf_info)
+{
+  if (pdf_info->icc_profile != (StringInfo *) NULL)
+    pdf_info->icc_profile=DestroyStringInfo(pdf_info->icc_profile);
+  if (pdf_info->photoshop_profile != (StringInfo *) NULL)
+    pdf_info->photoshop_profile=DestroyStringInfo(pdf_info->photoshop_profile);
+  if (pdf_info->xmp_profile != (StringInfo *) NULL)
+    pdf_info->xmp_profile=DestroyStringInfo(pdf_info->xmp_profile);
+}
+
+static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+  char
+    command[MagickPathExtent],
+    *density,
+    filename[MagickPathExtent],
+    geometry[MagickPathExtent],
+    input_filename[MagickPathExtent],
+    message[MagickPathExtent],
+    *options,
+    postscript_filename[MagickPathExtent];
+
+  const char
+    *option;
+
+  const DelegateInfo
+    *delegate_info;
+
+  GeometryInfo
+    geometry_info;
+
+  Image
+    *image,
+    *next,
+    *postscript_image;
+
+  ImageInfo
+    *read_info;
+
+  int
+    file;
+
+  MagickBooleanType
+    fitPage,
+    status;
+
+  MagickStatusType
+    flags;
+
+  PointInfo
+    delta,
+    resolution;
+
+  PSInfo
+    info;
+
+  RectangleInfo
+    page;
+
+  register ssize_t
+    i;
+
+  ssize_t
+    count;
+
+  unsigned long
+    scene;
+
+  /*
+    Open image file.
+  */
+  assert(image_info != (const ImageInfo *) NULL);
+  assert(image_info->signature == MagickCoreSignature);
+  if (image_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
+      image_info->filename);
+  assert(exception != (ExceptionInfo *) NULL);
+  assert(exception->signature == MagickCoreSignature);
+  image=AcquireImage(image_info,exception);
+  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+  if (status == MagickFalse)
+    {
+      image=DestroyImageList(image);
+      return((Image *) NULL);
+    }
+  status=AcquireUniqueSymbolicLink(image_info->filename,input_filename);
+  if (status == MagickFalse)
+    {
+      ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
+        image_info->filename);
+      image=DestroyImageList(image);
+      return((Image *) NULL);
+    }
+  /*
+    Set the page density.
+  */
+  delta.x=DefaultResolution;
+  delta.y=DefaultResolution;
+  if ((image->resolution.x == 0.0) || (image->resolution.y == 0.0))
+    {
+      flags=ParseGeometry(PSDensityGeometry,&geometry_info);
+      image->resolution.x=geometry_info.rho;
+      image->resolution.y=geometry_info.sigma;
+      if ((flags & SigmaValue) == 0)
+        image->resolution.y=image->resolution.x;
+    }
+  if (image_info->density != (char *) NULL)
+    {
+      flags=ParseGeometry(image_info->density,&geometry_info);
+      image->resolution.x=geometry_info.rho;
+      image->resolution.y=geometry_info.sigma;
+      if ((flags & SigmaValue) == 0)
+        image->resolution.y=image->resolution.x;
+    }
+  (void) ParseAbsoluteGeometry(PSPageGeometry,&page);
+  if (image_info->page != (char *) NULL)
+    (void) ParseAbsoluteGeometry(image_info->page,&page);
+  resolution=image->resolution;
+  page.width=(size_t) ceil((double) (page.width*resolution.x/delta.x)-0.5);
+  page.height=(size_t) ceil((double) (page.height*resolution.y/delta.y)-0.5);
+  /*
+    Determine page geometry from the Postscript bounding box.
+  */
+  ReadPSInfo(image_info,image,&info,exception);
+  (void) CloseBlob(image);
+  /*
+    Set Postscript render geometry.
+  */
+  if ((fabs(info.bounds.x2-info.bounds.x1) >= MagickEpsilon) &&
+      (fabs(info.bounds.y2-info.bounds.y1) >= MagickEpsilon))
     {
-      /*
-        Set Postscript render geometry.
-      */
       (void) FormatLocaleString(geometry,MagickPathExtent,"%gx%g%+.15g%+.15g",
-        hires_bounds.x2-hires_bounds.x1,hires_bounds.y2-hires_bounds.y1,
-        hires_bounds.x1,hires_bounds.y1);
+        info.bounds.x2-info.bounds.x1,info.bounds.y2-info.bounds.y1,
+        info.bounds.x1,info.bounds.y1);
       (void) SetImageProperty(image,"ps:HiResBoundingBox",geometry,exception);
-      page.width=(size_t) ceil((double) ((hires_bounds.x2-hires_bounds.x1)*
+      page.width=(size_t) ceil((double) ((info.bounds.x2-info.bounds.x1)*
         resolution.x/delta.x)-0.5);
-      page.height=(size_t) ceil((double) ((hires_bounds.y2-hires_bounds.y1)*
+      page.height=(size_t) ceil((double) ((info.bounds.y2-info.bounds.y1)*
         resolution.y/delta.y)-0.5);
     }
   fitPage=MagickFalse;
@@ -538,7 +641,7 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
       fitPage=MagickTrue;
     }
   if (IssRGBCompatibleColorspace(image_info->colorspace) != MagickFalse)
-    cmyk=MagickFalse;
+    info.cmyk=MagickFalse;
   /*
     Create Ghostscript control file.
   */
@@ -547,6 +650,7 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
     {
       ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
         image_info->filename);
+      CleanupPSInfo(&info);
       image=DestroyImageList(image);
       return((Image *) NULL);
     }
@@ -560,7 +664,7 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
         translate_geometry[MagickPathExtent];
 
       (void) FormatLocaleString(translate_geometry,MagickPathExtent,
-        "%g %g translate\n",-bounds.x1,-bounds.y1);
+        "%g %g translate\n",-info.bounds.x1,-info.bounds.y1);
       count=write(file,translate_geometry,(unsigned int)
         strlen(translate_geometry));
     }
@@ -571,13 +675,14 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
   if (image_info->monochrome != MagickFalse)
     delegate_info=GetDelegateInfo("ps:mono",(char *) NULL,exception);
   else
-    if (cmyk != MagickFalse)
+    if (info.cmyk != MagickFalse)
       delegate_info=GetDelegateInfo("ps:cmyk",(char *) NULL,exception);
     else
       delegate_info=GetDelegateInfo("ps:alpha",(char *) NULL,exception);
   if (delegate_info == (const DelegateInfo *) NULL)
     {
       (void) RelinquishUniqueFileResource(postscript_filename);
+      CleanupPSInfo(&info);
       image=DestroyImageList(image);
       return((Image *) NULL);
     }
@@ -669,6 +774,7 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
       if (*message != '\0')
         (void) ThrowMagickException(exception,GetMagickModule(),
           DelegateError,"PostscriptDelegateFailed","`%s'",message);
+      CleanupPSInfo(&info);
       image=DestroyImageList(image);
       return((Image *) NULL);
     }
@@ -684,104 +790,13 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
           postscript_image=cmyk_image;
         }
     }
-  (void) SeekBlob(image,0,SEEK_SET);
-  for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
-  {
-    /*
-      Note document structuring comments.
-    */
-    *p++=(char) c;
-    if ((strchr("\n\r%",c) == (char *) NULL) &&
-        ((size_t) (p-command) < (MagickPathExtent-1)))
-      continue;
-    *p='\0';
-    p=command;
-    /*
-      Skip %%BeginDocument thru %%EndDocument.
-    */
-    if (LocaleNCompare(BeginDocument,command,strlen(BeginDocument)) == 0)
-      skip=MagickTrue;
-    if (LocaleNCompare(EndDocument,command,strlen(EndDocument)) == 0)
-      skip=MagickFalse;
-    if (skip != MagickFalse)
-      continue;
-    if (LocaleNCompare(ICCProfile,command,strlen(ICCProfile)) == 0)
-      {
-        unsigned char
-          *datum;
-
-        /*
-          Read ICC profile.
-        */
-        profile=AcquireStringInfo(MagickPathExtent);
-        datum=GetStringInfoDatum(profile);
-        for (i=0; (c=ProfileInteger(image,hex_digits)) != EOF; i++)
-        {
-          if (i >= (ssize_t) GetStringInfoLength(profile))
-            {
-              SetStringInfoLength(profile,(size_t) i << 1);
-              datum=GetStringInfoDatum(profile);
-            }
-          datum[i]=(unsigned char) c;
-        }
-        SetStringInfoLength(profile,(size_t) i+1);
-        (void) SetImageProfile(image,"icc",profile,exception);
-        profile=DestroyStringInfo(profile);
-        continue;
-      }
-    if (LocaleNCompare(PhotoshopProfile,command,strlen(PhotoshopProfile)) == 0)
-      {
-        unsigned char
-          *q;
-
-        /*
-          Read Photoshop profile.
-        */
-        count=(ssize_t) sscanf(command,PhotoshopProfile " %lu",&extent);
-        if (count != 1)
-          continue;
-        length=extent;
-        if ((MagickSizeType) length > GetBlobSize(image))
-          ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
-        profile=BlobToStringInfo((const void *) NULL,length);
-        if (profile != (StringInfo *) NULL)
-          {
-            q=GetStringInfoDatum(profile);
-            for (i=0; i < (ssize_t) length; i++)
-              *q++=(unsigned char) ProfileInteger(image,hex_digits);
-            (void) SetImageProfile(image,"8bim",profile,exception);
-            profile=DestroyStringInfo(profile);
-          }
-        continue;
-      }
-    if (LocaleNCompare(BeginXMPPacket,command,strlen(BeginXMPPacket)) == 0)
-      {
-        /*
-          Read XMP profile.
-        */
-        p=command;
-        profile=StringToStringInfo(command);
-        for (i=(ssize_t) GetStringInfoLength(profile)-1; c != EOF; i++)
-        {
-          SetStringInfoLength(profile,(size_t) (i+1));
-          c=ReadBlobByte(image);
-          GetStringInfoDatum(profile)[i]=(unsigned char) c;
-          *p++=(char) c;
-          if ((strchr("\n\r%",c) == (char *) NULL) &&
-              ((size_t) (p-command) < (MagickPathExtent-1)))
-            continue;
-          *p='\0';
-          p=command;
-          if (LocaleNCompare(EndXMPPacket,command,strlen(EndXMPPacket)) == 0)
-            break;
-        }
-        SetStringInfoLength(profile,(size_t) i);
-        (void) SetImageProfile(image,"xmp",profile,exception);
-        profile=DestroyStringInfo(profile);
-        continue;
-      }
-  }
-  (void) CloseBlob(image);
+  if (info.icc_profile != (StringInfo *) NULL)
+    (void) SetImageProfile(image,"icc",info.icc_profile,exception);
+  if (info.photoshop_profile != (StringInfo *) NULL)
+    (void) SetImageProfile(image,"8bim",info.photoshop_profile,exception);
+  if (info.xmp_profile != (StringInfo *) NULL)
+    (void) SetImageProfile(image,"xmp",info.xmp_profile,exception);
+  CleanupPSInfo(&info);
   if (image_info->number_scenes != 0)
     {
       Image
@@ -803,10 +818,10 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
       MagickPathExtent);
     (void) CopyMagickString(postscript_image->magick,image->magick,
       MagickPathExtent);
-    if (columns != 0)
-      postscript_image->magick_columns=columns;
-    if (rows != 0)
-      postscript_image->magick_rows=rows;
+    if (info.columns != 0)
+      postscript_image->magick_columns=info.columns;
+    if (info.rows != 0)
+      postscript_image->magick_rows=info.rows;
     postscript_image->page=page;
     (void) CloneImageProfiles(postscript_image,image);
     (void) CloneImageProperties(postscript_image,image);