Postscript Delegate Failed

IMagick is a native PHP extension to create and modify images using the ImageMagick API. ImageMagick Studio LLC did not write nor does it maintain the IMagick extension, however, IMagick users are welcome to discuss the extension here.
Post Reply
clintsulis
Posts: 8
Joined: 2013-10-15T12:15:41-07:00
Authentication code: 6789
Location: Santa Fe, NM

Postscript Delegate Failed

Post by clintsulis »

Greetings everybody! I am in desperate need of help with troubleshooting using ImageMagick through PHP to convert PDF to GIF. I have this working fine on my development machine. Now I am trying to setup the production server with the latest versions and am receiving the following PostScript Delegate Failed error:

Error Message:

Code: Select all

Fatal error: Uncaught exception 'ImagickException' with message 'Postscript delegate failed `d:/web/content/document/publication.pdf': No such file or directory @ error/pdf.c/ReadPDFImage/682' in D:\web\content\library\pdfThumb.php:30 Stack trace: #0 D:\web\content\library\pdfThumb.php(30): Imagick->__construct('d:\web\co...') #1 D:\web\content\library\pdfThumb.php(15): pdfThumbGenerate('d:\web\co...', 'd:\web\co...', 0, 170, 0) #2 D:\web\content\index.php(173): pdfThumb(Array, 170, 0) #3 {main} thrown in D:\web\content\library\pdfThumb.php on line 30
I am able to convert PDF to GIF on the server using the convert command-line with no problem. I am also able to use ImageMagick through PHP to convert and resize other images. The problem only occurs when I try to convert from a PDF using ImageMagick through PHP. This suggests there is some problem with ImageMagick PostScript delegation through PHP which does not exist from command-line.

When using ImageMagick through PHP it seems as if it simply can't find and/or run the GhostScript executable. I can actually uninstall GhostScript and receive the exact same error from PHP, which really illustrates the fact that it just can't find/execute GS.

My instincts tell me that this is a permissions issue with being able to run the GhostScript executable through PHP Imagick, but I am not sure what else to try... I'm anxiously awaiting your analysis and suggestions.

Things I Have Tried:
  • I am able to execute the conversion from a command-line which converts the PDF to GIF with no problems.
  • I am able to use ImageMagick through PHP to convert and resize other input formats with no problems.
  • I have verified that ImageMagick and GhostScript binary paths are both defined in the PATH environment variable.
  • I have verified that Imagick shows up healthy on the phpinfo() page and it does.
  • I have examined the path in a PHP script using getenv('PATH') to be sure GS and Imagick paths are there, and they are.
  • I have checked the delegates with "convert -list delegate" command and the correct full path to GS is present.
  • I have tried using both relative and absolute file system paths for the input/output files. This did not fix it.
  • I have reinstalled ImageMagick and GhostScript in different orders, GS before Imagick and vice-versa. This did not fix it.
  • I have adjusted permissions to provide IUSR with read access to the GS program files folder. This did not fix it.
  • I have adjusted permissions to provide IUSR with full permissions to c:\windows\temp folder. This did not fix it.
  • I have changed the website's application pool to run as administrator. This did not fix it.
Here is a bunch of information about my command-line success, path variable, and PHP code below in case that might help.

Convert Command-Line Success:

Code: Select all

convert -resize 170 d:/web/content/document/publication.pdf[0] d:/web/content/document/publication.gif
Path Variable using PHP getenv('PATH') Function:

Code: Select all

C:\Program Files (x86)\gs\gs9.10\bin;C:\Program Files (x86)\ImageMagick-6.8.7-Q16;C:\Program Files (x86)\PHP\v5.4;C:\Windows\system32\inetsrv;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;
PHP Code Which Worked on Development but Fails on Production:

Code: Select all

$pdfFile = "d:/web/content/document/publication.pdf";
$pdfThumb = "d:/web/content/document/publication.gif";

$data = new imagick($pdfFile."[0]");
$data->setImageFormat("gif");
$data->resizeImage(170, 220, imagick::FILTER_LANCZOS, 1);
$data->writeImage($pdfThumb);
$data->clear();
$data->destroy();
ImageMagick Configuration:

Code: Select all

> convert -list configure

Path: [built-in]

Name           Value
-------------------------------------------------------------------------------
FEATURES       OpenMP
NAME           ImageMagick
QuantumDepth   16

Path: C:\Program Files (x86)\ImageMagick-6.8.7-Q16\configure.xml

Name           Value
-------------------------------------------------------------------------------
CC             vs10
COPYRIGHT      Copyright (C) 1999-2013 ImageMagick Studio LLC
DELEGATES      bzlib freetype jpeg jp2 lcms png tiff x11 xml wmf zlib
FEATURES       OpenMP
HOST           Windows
LIB_VERSION    0x687
LIB_VERSION_NUMBER 6,8,7,0
NAME           ImageMagick
RELEASE_DATE   2013-10-01
VERSION        6.8.7
WEBSITE        http://www.imagemagick.org
ImageMagick Delegates:

Code: Select all

> convert -list delegate

Path: C:\Program Files (x86)\ImageMagick-6.8.7-Q16\delegates.xml

Delegate                Command
-------------------------------------------------------------------------------
        cdr =>          "uniconvertor" "%i" "%o.svg"; rename "%o.svg" "%o"
        cgm =>          "uniconvertor" "%i" "%o.svg"; rename "%o.svg" "%o"
        dot =>          "dot -Tps "%i" -o "%o"
        dvi =>          "dvips -q -o "%o" "%i"
        dxf =>          "uniconvertor" "%i" "%o.svg"; rename "%o.svg" "%o"
        emf =>          "emfplus.exe -format png -dpi %x\x%y "%i" "%o"
        eps<=>ps        "C:/Program Files (x86)/gs/gs9.10/bin/gswin32c.exe" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 -sDEVICE=pswrite "-sOutputFile=%o" -- "%i"
        eps<=>pdf       "C:/Program Files (x86)/gs/gs9.10/bin/gswin32c.exe" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -sDEVICE=pdfwrite "-sOutputFile=%o" -- "%i"
        fig =>          "uniconvertor" "%i" "%o.svg"; rename "%o.svg" "%o"
       gplt =>          "/bin/echo "set size 1.25,0.62     set terminal postscript portrait color solid; set output "%o"; load "%i"" > "%u";gnuplot %u"
        hpg =>          "hp2xx -q -m eps -f "%o" "%i"
       hpgl =>          "hp2xx -q -m eps -f "%o" "%i"
        htm =>          "html2ps -U -o "%o" "%i"
       html =>          "html2ps -U -o "%o" "%i"
       ilbm =>          "ilbmtoppm "%i" > "%o"
        jxr =>          "rename "%i" "%i.jxr"; "@JXRDecodeDelegate@" -i "%i.jxr" -o "%o.pnm"; rename "%i.jxr" "%i"; rename "%o.pnm" "%o"
        man =>          "groff -man -Tps "%i" > "%o"
mpeg:decode =>          "ffmpeg.exe" -v -1 -i "%i" -vframes %S -vcodec pam -an -f rawvideo -y "%u.pam"
        pdf<=>eps       "C:/Program Files (x86)/gs/gs9.10/bin/gswin32c.exe" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -sDEVICE=epswrite "-sOutputFile=%o" -- "%i"
        pdf<=>ps        "C:/Program Files (x86)/gs/gs9.10/bin/gswin32c.exe" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 -sDEVICE=pswrite "-sOutputFile=%o" -- "%i"
        pgp =>          "pgpv -fq "%i"
        png<= show      "cmd.exe /C start "%m" file:///"%i."
        png<= win       "cmd.exe /C start "%m" file:///"%i."
        png<= launch    "cmd.exe /C start "%m" file:///"%i."
        pnm<= jxr       "rename "%i" "%i.pnm"; "@JXREncodeDelegate@" -i "%i.pnm" -o "%o.jxr"; rename "%i.pnm" "%i"; rename "%o.jxr" "%o"
        pnm<= wdp       "rename "%i" "%i.pnm"; "@JXREncodeDelegate@" -i "%i.pnm" -o "%o.jxr"; rename "%i.pnm" "%i"; rename "%o.jxr" "%o"
        pnm<= ilbm      "ppmtoilbm -24if "%i" > "%o"
        pov =>          "povray "+i"%i"" -D0 +o"%o" +fn%q +w%w +h%h +a -q9 -kfi"%s" -kff"%n"     convert -concatenate %o*.png "%o"
         ps<=>eps       "C:/Program Files (x86)/gs/gs9.10/bin/gswin32c.exe" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 -sDEVICE=epswrite "-sOutputFile=%o" -- "%i"
         ps<=>pdf       "C:/Program Files (x86)/gs/gs9.10/bin/gswin32c.exe" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 -sDEVICE=pdfwrite "-sOutputFile=%o" -- "%i"
       rgba<= rle       "pnmtorle -o "%o" -v "%i"
       scan =>          "scanimage -d "%i" > "%o"
      shtml =>          "html2ps -U -o "%o" "%i"
        sid =>          "mrsidgeodecode -if sid -i "%i" -of tif -o "%o" > "%u"
        svg =>          "rsvg-convert" -o "%o" "%i"
        txt<=>ps        "enscript -o "%o" "%i"
        wdp =>          "rename "%i" "%i.jxr"; "@JXRDecodeDelegate@" -i "%i.jxr" -o "%o.pnm"; rename "%i.jxr" "%i"; rename "%o.pnm" "%o"
        wmf =>          "emfplus.exe -format png -dpi %x\x%y "%i" "%o"
        xcf =>          "xcftopnm "%i" > "%o"
Development Server Environment (Works Great):
  • Windows 7 Pro
  • IIS v7.5
  • PHP 5.3.10
  • ImageMagick v6.7.6.0
  • GhostScript v9.05
Production Server Environment (Has Problems):
  • Windows Server 2012
  • IIS v8.0
  • PHP v5.4.14
  • ImageMagick v6.8.7-0
  • GhostScript v9.10
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Postscript Delegate Failed

Post by Bonzo »

Your "Convert Command-Line Success:" is using Imagemagick
Out of interest you should read the image in before the -resize

Your "PHP Code Which Worked on Development but Fails on Production:" is using Imagick.

Imagick has different versions and some code will work on one version and not another.

You could try this localy and online and see what you get:

Code: Select all


<?php  
$version = Imagick::getVersion(); 
echo "API version number: ".$version['versionNumber']."<br>"; 
echo "API version string: ".$version['versionString']."<br>"; 
 ?>
It may or may not be useful but I am not an Imagick expert.
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Postscript Delegate Failed

Post by Bonzo »

Out of interest have you tried:

Code: Select all

exec("convert d:/web/content/document/publication.pdf[0] -resize 170 d:/web/content/document/publication.gif");
Although to remove some other potential problems I would put the pdf file in the same folder as the code and save to the same folder in this test.
clintsulis
Posts: 8
Joined: 2013-10-15T12:15:41-07:00
Authentication code: 6789
Location: Santa Fe, NM

Re: Postscript Delegate Failed

Post by clintsulis »

Thanks for the prompt response!

I have performed the Imagick::getVersion() and this is the result:

Code: Select all

API version number: 1671
API version string: ImageMagick 6.8.7-0 2013-09-18 Q16 http://www.imagemagick.org
The exec command didn't generate any output and returned no errors. I can paste the exec string into a command-prompt and it generates fine.

So is there any way to manipulate or view the delegate configuration of Imagick? Do you have any other advice?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Postscript Delegate Failed

Post by fmw42 »

DELEGATES bzlib freetype jpeg jp2 lcms png tiff x11 xml wmf zlib
Since there is no listed gs, this would imply that either gs is not installed, not installed correctly or IM cannot find the path to gs.

Check your install log for gs and make sure there are no error messages. Or be sure you put the full path to gs in your delegates.xml file.

Also be sure you do not have multiple version of IM on the server.
clintsulis
Posts: 8
Joined: 2013-10-15T12:15:41-07:00
Authentication code: 6789
Location: Santa Fe, NM

Re: Postscript Delegate Failed

Post by clintsulis »

FWM42: Thanks for the response but the fact that GS is not listed as a delegate doesn't seem alarming to me because is not listed as a delegate on my development server either, which works perfectly in all ways.

On my production server: The path in delegates.xml is 100% correct, multiple versions of GS are not installed, and everything works fine with command-line convert.

I'm having trouble finding the GS installation log to check it for errors. Can you help me locate it?

Also, is it possible that there is some sort of permissions problem executing the gswin32c.exe file? I mean, from command-line I am an administrative user. Through a web page in PHP the situation is far less privileged. Know what I mean?
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Postscript Delegate Failed

Post by Bonzo »

Try this:

Code: Select all

<?php 
$array=array(); 
echo "<pre>";
exec("convert publication.pdf[0] -resize 170 publication.gif 2>&1", $array);  
echo "<br>".print_r($array)."<br>";  
echo "</pre>"; 
?>
clintsulis
Posts: 8
Joined: 2013-10-15T12:15:41-07:00
Authentication code: 6789
Location: Santa Fe, NM

Re: Postscript Delegate Failed

Post by clintsulis »

Bonzo: Thank you for your help so far, I truly appreciate your efforts! The code you provided worked like a charm.

For this test, the script and the publications.pdf are both in the root of the website. Here are the test results:

Exec Command - Relative Paths to Input/Output Files:

Code: Select all

Array
(
    [0] => convert.exe: Postscript delegate failed `publication.pdf': No such file or directory @ error/pdf.c/ReadPDFImage/682.
    [1] => convert.exe: no images defined `publication.gif' @ error/convert.c/ConvertImageCommand/3127.
)

1
Exec Command - Absolute Paths to Input/Output Files:

Code: Select all

Array
(
    [0] => convert.exe: Postscript delegate failed `d:/web/content/publication.pdf': No such file or directory @ error/pdf.c/ReadPDFImage/682.
    [1] => convert.exe: no images defined `d:/web/content/publication.gif' @ error/convert.c/ConvertImageCommand/3127.
)

1
Exec Command - Intentionally Bad Paths to Input File:

Code: Select all

Array
(
    [0] => convert.exe: unable to open image `missing.pdf': No such file or directory @ error/blob.c/OpenBlob/2643.
    [1] => convert.exe: no images defined `missing.gif' @ error/convert.c/ConvertImageCommand/3127.
)

1
Since the failure with exec and the failure using PHP Imagick are identical and both reference the same line number 682 in the source code, I decided to take a look at what that line is in the pdf.c file of the source code:

ImageMagick PDF.C Source Code Error Refers To:

Code: Select all

679:  if (pdf_image == (Image *) NULL)
680:    {
681:      ThrowFileException(exception,DelegateError,"PostscriptDelegateFailed",
682:        image_info->filename);
683:      image=DestroyImage(image);
684:      return((Image *) NULL);
685:    }
This proves that command-line works, but PHP Imagick and PHP Exec methods both fail with the same error referncing line #682 in the pdf.c file of the ImageMagick source code.

Does anybody know what these results are telling us?
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Postscript Delegate Failed

Post by Bonzo »

A good bit of detective work clintsulis; Imagemagick's error reporting is not great and the two errors you had from my code are basically saying something went wrong before the save.

You have reached the end of my knowledge and I can not think of anything else to try. Other people have had problems with code working in the command line and not php but I can not remember what the answers were now. As fmw42 said it would be a good idea to confirm that both are using the same version of Imagemagick. This can be done with convert -version in the command line and this in php:

Code: Select all

<?php
echo "<pre>";
system("convert -version");  
echo "</pre>";
?>  	
Note: system( ) displays the output whereas exec( ) will not.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Postscript Delegate Failed

Post by fmw42 »

I was questioning if there are multiple version of IM on the system that are in conflict.
clintsulis
Posts: 8
Joined: 2013-10-15T12:15:41-07:00
Authentication code: 6789
Location: Santa Fe, NM

Re: Postscript Delegate Failed

Post by clintsulis »

Nope, there is only one version. The server is brand new with a fresh OS install. Thanks for trying to help guys.

The problem still remains: Postscript delegation fails through php_imagick but works fine command-line with convert utility.

I suppose it could be failing at any of the following points:
  • php_imagick.dll doesn't know where to find the gswin32c.exe executable.
  • php_imagick.dll knows where to find the executable but doesn't have permissions to execute it.
  • gswin32c.exe is executed but does not return data to php_imagick.dll for some reason.
Does anyone have any ideas related to file system permissions, software install location, imagick/gs version mismatch, permissions to read windows registry, application pool identities, manually modifying delegates.xml file, or anything else that we haven't thought of or covered already?

I really don't want to stop using this awesome software. I absolutely love it!
clintsulis
Posts: 8
Joined: 2013-10-15T12:15:41-07:00
Authentication code: 6789
Location: Santa Fe, NM

Re: Postscript Delegate Failed

Post by clintsulis »

I decided to try converting several different PDF input files and accidentally discovered that GS is actually being called! The error is something to do with GhostScript passing information back to ImageMagick!

The lines that begin with **** are clearly being output by GhostScript, yet the same PostScript Delegate Failed error occurs:

Code: Select all

Array
(
    [0] =>    **** Warning:  An error occurred while reading an XREF table.
    [1] =>    **** The file has been damaged.  This may have been caused
    [2] =>    **** by a problem while converting or transfering the file.
    [3] =>    **** Ghostscript will attempt to recover the data.
    [4] => 
    [5] =>    **** This file had errors that were repaired or ignored.
    [6] =>    **** The file was produced by:
    [7] =>    **** >>>> Microsoft® Office Word 2007 <<<<
    [8] =>    **** Please notify the author of the software that produced this
    [9] =>    **** file that it does not conform to Adobe's published PDF
    [10] =>    **** specification.
    [11] => 
    [12] => convert.exe: Postscript delegate failed `publication.pdf': No such file or directory @ error/pdf.c/ReadPDFImage/682.
    [13] => convert.exe: no images defined `publication.gif' @ error/convert.c/ConvertImageCommand/3127.
)

1
Does this mean that GhostScript is failing to write an output file that ImageMagick then fails to read which results in the "No such file or directory" error?

If so, where does GhostScript write temp files? What permissions are required to those locations? (giddy with excitement)
clintsulis
Posts: 8
Joined: 2013-10-15T12:15:41-07:00
Authentication code: 6789
Location: Santa Fe, NM

Re: Postscript Delegate Failed

Post by clintsulis »

WOO HOO!!!! THE ISSUE IS SOLVED!!!

All I needed to do was provide both IIS_IUSRS and IUSR with full permissions to the C:\Windows\Temp folder.

I had allowed one but not the other. I hope this thread helps someone else in the future overcome this confusing situation.

Thanks again for those who helped. Without your assistance I never would have stumbled upon the answer!

:D
Post Reply