]> granicus.if.org Git - imagemagick/commitdiff
Improved error messages when a coder uses Ghostscript.
authordirk <dirk@git.imagemagick.org>
Sat, 3 May 2014 13:00:18 +0000 (13:00 +0000)
committerdirk <dirk@git.imagemagick.org>
Sat, 3 May 2014 13:00:18 +0000 (13:00 +0000)
MagickCore/delegate-private.h
MagickCore/nt-base.c
MagickCore/utility.c
coders/pdf.c
coders/ps.c

index 8f6757f624a90e1750d02b995c768caa17947e05..9b4e65333a02d050f5243e6f29045ca63da0bb62 100644 (file)
@@ -43,6 +43,9 @@ typedef struct gs_main_instance_s
 
 typedef struct _GhostInfo
 {
+  void
+    (MagickDLLCall *delete_instance)(gs_main_instance *);
+
   int
     (MagickDLLCall *exit)(gs_main_instance *);
 
@@ -55,8 +58,10 @@ typedef struct _GhostInfo
   int
     (MagickDLLCall *run_string)(gs_main_instance *,const char *,int,int *);
 
-  void
-    (MagickDLLCall *delete_instance)(gs_main_instance *);
+  int
+    (MagickDLLCall *set_stdio)(gs_main_instance *,int(MagickDLLCall *)(void *,
+      char *,int),int(MagickDLLCall *)(void *,const char *,int),
+      int(MagickDLLCall *)(void *,const char *,int));
 } GhostInfo;
 
 extern MagickPrivate MagickBooleanType
index ebdb25460922f7dae0cbbefdb64b449504edf709..4c2bc48849ab6d9d229c604d998c964a5f1d519e 100644 (file)
@@ -1367,6 +1367,8 @@ MagickPrivate int NTGhostscriptLoadDLL(void)
   if (ghost_handle == (void *) NULL)
     return(FALSE);
   (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo));
+  ghost_info.delete_instance=(void (MagickDLLCall *) (gs_main_instance *)) (
+    lt_dlsym(ghost_handle,"gsapi_delete_instance"));
   ghost_info.exit=(int (MagickDLLCall *)(gs_main_instance*))
     lt_dlsym(ghost_handle,"gsapi_exit");
   ghost_info.init_with_args=(int (MagickDLLCall *)(gs_main_instance *,int,
@@ -1375,11 +1377,14 @@ MagickPrivate int NTGhostscriptLoadDLL(void)
     lt_dlsym(ghost_handle,"gsapi_new_instance"));
   ghost_info.run_string=(int (MagickDLLCall *)(gs_main_instance *,const char *,
     int,int *)) (lt_dlsym(ghost_handle,"gsapi_run_string"));
-  ghost_info.delete_instance=(void (MagickDLLCall *) (gs_main_instance *)) (
-    lt_dlsym(ghost_handle,"gsapi_delete_instance"));
-  if ((ghost_info.exit == NULL) || (ghost_info.init_with_args == NULL) ||
-      (ghost_info.new_instance == NULL) || (ghost_info.run_string == NULL) ||
-      (ghost_info.delete_instance == NULL))
+  ghost_info.set_stdio=(int (MagickDLLCall *)(gs_main_instance *,int(
+    MagickDLLCall *)(void *,char *,int),int(MagickDLLCall *)(void *,
+    const char *,int),int(MagickDLLCall *)(void *,const char *,int)))
+    (lt_dlsym(ghost_handle,"gsapi_set_stdio"));
+  if ((ghost_info.delete_instance == NULL) || (ghost_info.exit == NULL) ||
+      (ghost_info.init_with_args == NULL) || (ghost_info.new_instance == NULL)
+      || (ghost_info.run_string == NULL) || (ghost_info.set_stdio == NULL)
+      )
     return(FALSE);
   return(TRUE);
 }
index d74f4b0215b39ee778bfea8658553b32a25d62d1..9faa024ed04833a42c7dba4e5d4144f9396789ea 100644 (file)
@@ -2028,7 +2028,7 @@ MagickExport int SystemCommand(const MagickBooleanType asynchronous,
 #endif
   if (status < 0)
     (void) ThrowMagickException(exception,GetMagickModule(),DelegateError,
-      "'%s' (%d)",command,status);
+      "FailedToExecuteCommand","`%s' (%d)",command,status);
   if (shell_command != command)
     shell_command=DestroyString(shell_command);
   for (i=0; i < (ssize_t) number_arguments; i++)
index b97d28e6756f0149474b8251276b2b21e652ccca..baf61e906c403907e9fa2628584116998cdd246c 100644 (file)
@@ -125,15 +125,55 @@ static MagickBooleanType
 %    o exception: return any errors or warnings in this structure.
 %
 */
+static int MagickDLLCall PDFDelegateMessage(void *handle,const char *msg,
+  int len)
+{
+  char
+    **messages;
+
+  size_t offset;
+
+  offset=0;
+  messages=(char **)handle;
+  if (*messages == (char *) NULL)
+    *messages=(char *) AcquireQuantumMemory(len+1,sizeof(char *));
+  else
+    {
+      offset=strlen(*messages);
+      *messages=(char *) ResizeQuantumMemory(*messages,offset+len+1,
+        sizeof(char *));
+    }
+  (void) memcpy(*messages+offset,msg,len);
+  (*messages)[offset+len] ='\0';
+  return(len);
+}
+
 static MagickBooleanType InvokePDFDelegate(const MagickBooleanType verbose,
   const char *command,ExceptionInfo *exception)
 {
+#define SetArgsStart \
+  if (args_start == (const char *) NULL) \
+    { \
+      if (command[0] != '"') \
+        args_start=strchr(command,' '); \
+      else \
+        { \
+          args_start=strchr(command+1,'"'); \
+          if (args_start != (const char *) NULL) \
+            args_start++; \
+        } \
+    }
+
+  const char
+    *args_start=NULL;
+
   int
     status;
 
 #if defined(MAGICKCORE_GS_DELEGATE) || defined(MAGICKCORE_WINDOWS_SUPPORT)
   char
-    **argv;
+    **argv,
+    *errors;
 
   const GhostInfo
     *ghost_info;
@@ -156,15 +196,18 @@ static MagickBooleanType InvokePDFDelegate(const MagickBooleanType verbose,
 
   ghost_info=(&ghost_info_struct);
   (void) ResetMagickMemory(&ghost_info,0,sizeof(ghost_info));
+  ghost_info_struct.delete_instance=(void (*)(gs_main_instance *))
+    gsapi_delete_instance;
+  ghost_info_struct.exit=(int (*)(gs_main_instance *)) gsapi_exit;
   ghost_info_struct.new_instance=(int (*)(gs_main_instance **,void *))
     gsapi_new_instance;
   ghost_info_struct.init_with_args=(int (*)(gs_main_instance *,int,char **))
     gsapi_init_with_args;
   ghost_info_struct.run_string=(int (*)(gs_main_instance *,const char *,int,
     int *)) gsapi_run_string;
-  ghost_info_struct.delete_instance=(void (*)(gs_main_instance *))
-    gsapi_delete_instance;
-  ghost_info_struct.exit=(int (*)(gs_main_instance *)) gsapi_exit;
+  ghost_info_struct.set_stdio=(int (*)(gs_main_instance *,int(*)(void *,char *,
+    int),int(*)(void *,const char *,int),int(*)(void *, const char *, int)))
+    gsapi_set_stdio;
 #endif
   if (ghost_info == (GhostInfo *) NULL)
     {
@@ -174,9 +217,11 @@ static MagickBooleanType InvokePDFDelegate(const MagickBooleanType verbose,
   if (verbose != MagickFalse)
     {
       (void) fputs("[ghostscript library]",stdout);
-      (void) fputs(strchr(command,' '),stdout);
+      SetArgsStart
+      (void) fputs(args_start,stdout);
     }
-  status=(ghost_info->new_instance)(&interpreter,(void *) NULL);
+  errors=(char *) NULL;
+  status=(ghost_info->new_instance)(&interpreter,(void *) &errors);
   if (status < 0)
     {
       status=SystemCommand(MagickFalse,verbose,command,exception);
@@ -186,6 +231,8 @@ static MagickBooleanType InvokePDFDelegate(const MagickBooleanType verbose,
   argv=StringToArgv(command,&argc);
   if (argv == (char **) NULL)
     return(MagickFalse);
+  (void) (ghost_info->set_stdio)(interpreter,(int(MagickDLLCall *)(void *,
+    char *,int)) NULL,PDFDelegateMessage,PDFDelegateMessage);
   status=(ghost_info->init_with_args)(interpreter,argc-1,argv+1);
   if (status == 0)
     status=(ghost_info->run_string)(interpreter,"systemdict /start get exec\n",
@@ -200,17 +247,18 @@ static MagickBooleanType InvokePDFDelegate(const MagickBooleanType verbose,
   argv=(char **) RelinquishMagickMemory(argv);
   if ((status != 0) && (status != -101))
     {
-      char
-        *message;
-
-      message=GetExceptionMessage(errno);
+      SetArgsStart
       (void) ThrowMagickException(exception,GetMagickModule(),DelegateError,
-        "`%s': %s",command,message);
-      message=DestroyString(message);
+        "PDFDelegateFailed","`[ghostscript library]%s': %s",args_start,
+        errors);
+      if (errors != (char *) NULL)
+        errors=DestroyString(errors);
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
         "Ghostscript returns status %d, exit code %d",status,code);
       return(MagickFalse);
     }
+  if (errors != (char *) NULL)
+    errors=DestroyString(errors);
   return(MagickTrue);
 #else
   status=SystemCommand(MagickFalse,verbose,command,exception);
@@ -704,8 +752,6 @@ static Image *ReadPDFImage(const ImageInfo *image_info,ExceptionInfo *exception)
   read_info=DestroyImageInfo(read_info);
   if (pdf_image == (Image *) NULL)
     {
-      ThrowFileException(exception,DelegateError,"PostscriptDelegateFailed",
-        image_info->filename);
       image=DestroyImage(image);
       return((Image *) NULL);
     }
index 6b6d316dac00a7af919d5322e119a2de1b003259..962deb151b1069a6d92f2b51c25860217799ae27 100644 (file)
@@ -114,15 +114,55 @@ static MagickBooleanType
 %    o exception: return any errors or warnings in this structure.
 %
 */
+static int MagickDLLCall PostscriptDelegateMessage(void *handle,
+  const char *msg,int len)
+{
+  char
+    **messages;
+
+  size_t offset;
+
+  offset=0;
+  messages=(char **)handle;
+  if (*messages == (char *) NULL)
+    *messages=(char *) AcquireQuantumMemory(len+1,sizeof(char *));
+  else
+    {
+      offset=strlen(*messages);
+      *messages=(char *) ResizeQuantumMemory(*messages,offset+len+1,
+        sizeof(char *));
+    }
+  (void) memcpy(*messages+offset,msg,len);
+  (*messages)[offset+len] ='\0';
+  return(len);
+}
+
 static MagickBooleanType InvokePostscriptDelegate(
   const MagickBooleanType verbose,const char *command,ExceptionInfo *exception)
 {
+#define SetArgsStart \
+  if (args_start == (const char *) NULL) \
+    { \
+      if (command[0] != '"') \
+        args_start=strchr(command,' '); \
+      else \
+        { \
+          args_start=strchr(command+1,'"'); \
+          if (args_start != (const char *) NULL) \
+            args_start++; \
+        } \
+    }
+
+  const char
+    *args_start=NULL;
+
   int
     status;
 
 #if defined(MAGICKCORE_GS_DELEGATE) || defined(MAGICKCORE_WINDOWS_SUPPORT)
   char
-    **argv;
+    **argv,
+    *errors;
 
   const GhostInfo
     *ghost_info;
@@ -145,15 +185,18 @@ static MagickBooleanType InvokePostscriptDelegate(
 
   ghost_info=(&ghost_info_struct);
   (void) ResetMagickMemory(&ghost_info,0,sizeof(ghost_info));
+  ghost_info_struct.delete_instance=(void (*)(gs_main_instance *))
+    gsapi_delete_instance;
+  ghost_info_struct.exit=(int (*)(gs_main_instance *)) gsapi_exit;
   ghost_info_struct.new_instance=(int (*)(gs_main_instance **,void *))
     gsapi_new_instance;
   ghost_info_struct.init_with_args=(int (*)(gs_main_instance *,int,char **))
     gsapi_init_with_args;
   ghost_info_struct.run_string=(int (*)(gs_main_instance *,const char *,int,
     int *)) gsapi_run_string;
-  ghost_info_struct.delete_instance=(void (*)(gs_main_instance *))
-    gsapi_delete_instance;
-  ghost_info_struct.exit=(int (*)(gs_main_instance *)) gsapi_exit;
+  ghost_info_struct.set_stdio=(int (*)(gs_main_instance *,int(*)(void *,char *,
+    int),int(*)(void *,const char *,int),int(*)(void *, const char *, int)))
+    gsapi_set_stdio;
 #endif
   if (ghost_info == (GhostInfo *) NULL)
     {
@@ -163,9 +206,11 @@ static MagickBooleanType InvokePostscriptDelegate(
   if (verbose != MagickFalse)
     {
       (void) fputs("[ghostscript library]",stdout);
-      (void) fputs(strchr(command,' '),stdout);
+      SetArgsStart
+      (void) fputs(args_start,stdout);
     }
-  status=(ghost_info->new_instance)(&interpreter,(void *) NULL);
+  errors=(char *) NULL;
+  status=(ghost_info->new_instance)(&interpreter,(void *) &errors);
   if (status < 0)
     {
       status=SystemCommand(MagickFalse,verbose,command,exception);
@@ -175,6 +220,8 @@ static MagickBooleanType InvokePostscriptDelegate(
   argv=StringToArgv(command,&argc);
   if (argv == (char **) NULL)
     return(MagickFalse);
+  (void) (ghost_info->set_stdio)(interpreter,(int(MagickDLLCall *)(void *,
+    char *,int)) NULL,PostscriptDelegateMessage,PostscriptDelegateMessage);
   status=(ghost_info->init_with_args)(interpreter,argc-1,argv+1);
   if (status == 0)
     status=(ghost_info->run_string)(interpreter,"systemdict /start get exec\n",
@@ -189,17 +236,18 @@ static MagickBooleanType InvokePostscriptDelegate(
   argv=(char **) RelinquishMagickMemory(argv);
   if ((status != 0) && (status != -101))
     {
-      char
-        *message;
-
-      message=GetExceptionMessage(errno);
+      SetArgsStart
       (void) ThrowMagickException(exception,GetMagickModule(),DelegateError,
-        "`%s': %s",command,message);
-      message=DestroyString(message);
+        "PostscriptDelegateFailed","`[ghostscript library]%s': %s",args_start,
+        errors);
+      if (errors != (char *) NULL)
+        errors=DestroyString(errors);
       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
         "Ghostscript returns status %d, exit code %d",status,code);
       return(MagickFalse);
     }
+  if (errors != (char *) NULL)
+    errors=DestroyString(errors);
   return(MagickTrue);
 #else
   status=SystemCommand(MagickFalse,verbose,command,exception);
@@ -835,8 +883,6 @@ static Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception)
   if (postscript_image == (Image *) NULL)
     {
       image=DestroyImageList(image);
-      ThrowFileException(exception,DelegateError,"PostscriptDelegateFailed",
-        image_info->filename);
       return((Image *) NULL);
     }
   if (LocaleCompare(postscript_image->magick,"BMP") == 0)