delegate.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %           DDDD   EEEEE  L      EEEEE   GGGG   AAA   TTTTT  EEEEE            %
00006 %           D   D  E      L      E      G      A   A    T    E                %
00007 %           D   D  EEE    L      EEE    G  GG  AAAAA    T    EEE              %
00008 %           D   D  E      L      E      G   G  A   A    T    E                %
00009 %           DDDD   EEEEE  LLLLL  EEEEE   GGG   A   A    T    EEEEE            %
00010 %                                                                             %
00011 %                                                                             %
00012 %             MagickCore Methods to Read/Write/Invoke Delegates               %
00013 %                                                                             %
00014 %                             Software Design                                 %
00015 %                               John Cristy                                   %
00016 %                               October 1998                                  %
00017 %                                                                             %
00018 %                                                                             %
00019 %  Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization      %
00020 %  dedicated to making software imaging solutions freely available.           %
00021 %                                                                             %
00022 %  You may not use this file except in compliance with the License.  You may  %
00023 %  obtain a copy of the License at                                            %
00024 %                                                                             %
00025 %    http://www.imagemagick.org/script/license.php                            %
00026 %                                                                             %
00027 %  Unless required by applicable law or agreed to in writing, software        %
00028 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00029 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00030 %  See the License for the specific language governing permissions and        %
00031 %  limitations under the License.                                             %
00032 %                                                                             %
00033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00034 %
00035 %  The Delegates methods associate a set of commands with a particular
00036 %  image format.  ImageMagick uses delegates for formats it does not handle
00037 %  directly.
00038 %
00039 %  Thanks to Bob Friesenhahn for the initial inspiration and design of the
00040 %  delegates methods.
00041 %
00042 %
00043 */
00044 
00045 /*
00046   Include declarations.
00047 */
00048 #include "magick/studio.h"
00049 #include "magick/property.h"
00050 #include "magick/blob.h"
00051 #include "magick/client.h"
00052 #include "magick/configure.h"
00053 #include "magick/constitute.h"
00054 #include "magick/delegate.h"
00055 #include "magick/exception.h"
00056 #include "magick/exception-private.h"
00057 #include "magick/hashmap.h"
00058 #include "magick/list.h"
00059 #include "magick/memory_.h"
00060 #include "magick/policy.h"
00061 #include "magick/resource_.h"
00062 #include "magick/semaphore.h"
00063 #include "magick/string_.h"
00064 #include "magick/token.h"
00065 #include "magick/utility.h"
00066 #include "magick/xml-tree.h"
00067 
00068 /*
00069   Define declarations.
00070 */
00071 #define DelegateFilename  "delegates.xml"
00072 
00073 /*
00074   Declare delegate map.
00075 */
00076 static const char
00077   *DelegateMap = (const char *)
00078     "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
00079     "<delegatemap>"
00080     "  <delegate decode=\"autotrace\" stealth=\"True\" command=\"&quot;autotrace&quot; -output-format svg -output-file &quot;%o&quot; &quot;%i&quot;\"/>"
00081     "  <delegate decode=\"avi:decode\" stealth=\"True\" command=\"&quot;mplayer&quot; &quot;%i&quot; -really-quiet -ao null -vo png:z=3\"/>"
00082     "  <delegate decode=\"browse\" stealth=\"True\" spawn=\"True\" command=\"&quot;xdg-open&quot; http://www.imagemagick.org/\"/>"
00083     "  <delegate decode=\"cgm\" thread-support=\"False\" command=\"&quot;ralcgm&quot; -d ps -oC &lt; &quot;%i&quot; &gt; &quot;%o&quot; 2&gt; &quot;%u&quot;\"/>"
00084     "  <delegate decode=\"dng:decode\" command=\"&quot;/usr/bin/ufraw-batch&quot; --silent --wb=camera --black-point=auto --exposure=auto --create-id=also --out-type=ppm16 &quot;--output=%u.pnm&quot; &quot;%i&quot;\"/>"
00085     "  <delegate decode=\"edit\" stealth=\"True\" command=\"&quot;xterm&quot; -title &quot;Edit Image Comment&quot; -e vi &quot;%o&quot;\"/>"
00086     "  <delegate decode=\"eps\" encode=\"pdf\" mode=\"bi\" command=\"&quot;gs&quot; -q -dQUIET -dSAFER -dPARANOIDSAFE -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=0 &quot;-sDEVICE=pdfwrite&quot; &quot;-sOutputFile=%o&quot; &quot;-f%i&quot;\"/>"
00087     "  <delegate decode=\"eps\" encode=\"ps\" mode=\"bi\" command=\"&quot;gs&quot; -q -dQUIET -dSAFER -dPARANOIDSAFE -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=0 &quot;-sDEVICE=pswrite&quot; &quot;-sOutputFile=%o&quot; &quot;-f%i&quot;\"/>"
00088     "  <delegate decode=\"fig\" command=\"&quot;fig2dev&quot; -L ps &quot;%i&quot; &quot;%o&quot;\"/>"
00089     "  <delegate decode=\"gplt\" command=\"&quot;echo&quot; &quot;set size 1.25,0.62     set terminal postscript portrait color solid; set output &quot;%o&quot;; load &quot;%i&quot;&quot; &gt; &quot;%u&quot;;&quot;gnuplot&quot; &quot;%u&quot;\"/>"
00090     "  <delegate decode=\"hdr\" command=\"&quot;ra_pfm&quot; &quot;%i&quot; &quot;%o&quot;\"/>"
00091     "  <delegate decode=\"hpg\" command=\"&quot;hp2xx&quot; -q -m eps -f `basename &quot;%o&quot;` &quot;%i&quot;     mv -f `basename &quot;%o&quot;` &quot;%o&quot;\"/>"
00092     "  <delegate decode=\"hpgl\" command=\"if [ -e hp2xx -o -e /usr/bin/hp2xx ]; then     hp2xx -q -m eps -f `basename &quot;%o&quot;` &quot;%i&quot;     mv -f `basename &quot;%o&quot;` &quot;%o   else     echo &quot;You need to install hp2xx to use HPGL files with ImageMagick.&quot;     exit 1   fi\"/>"
00093     "  <delegate decode=\"htm\" command=\"&quot;html2ps&quot; -U -o &quot;%o&quot; &quot;%i&quot;\"/>"
00094     "  <delegate decode=\"html\" command=\"&quot;html2ps&quot; -U -o &quot;%o&quot; &quot;%i&quot;\"/>"
00095     "  <delegate decode=\"https\" command=\"&quot;wget&quot; -q -O &quot;%o&quot; &quot;https:%M&quot;\"/>"
00096     "  <delegate decode=\"ilbm\" command=\"&quot;ilbmtoppm&quot; &quot;%i&quot; &gt; &quot;%o&quot;\"/>"
00097     "  <delegate decode=\"man\" command=\"&quot;groff&quot; -man -Tps &quot;%i&quot; &gt; &quot;%o&quot;\"/>"
00098     "  <delegate decode=\"mpeg:decode\" stealth=\"True\" command=\"&quot;ffmpeg&quot; --i &quot;%i&quot; -vcodec pam -an -f rawvideo -y &quot;%u0.pam&quot; 2;&gt; &quot;%Z&quot;\"/>"
00099     "  <delegate decode=\"null\" encode=\"mpeg:encode\" stealth=\"True\" command=\"&quot;ffmpeg&quot; &quot;%M%%d.jpg&quot; &quot;%u.%m&quot; 2;&gt; &quot;%Z&quot;\"/>"
00100     "  <delegate decode=\"pcl:color\" stealth=\"True\" command=\"&quot;pcl6&quot; -dQUIET -dSAFER -dPARANOIDSAFE -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=0 &quot;-sDEVICE=ppmraw&quot; -dTextAlphaBits=%u -dGraphicsAlphaBits=%u &quot;-r%s&quot; %s &quot;-sOutputFile=%s&quot; &quot;%s&quot;\"/>"
00101     "  <delegate decode=\"pcl:cmyk\" stealth=\"True\" command=\"&quot;pcl6&quot; -dQUIET -dSAFER -dPARANOIDSAFE -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=0 &quot;-sDEVICE=bmpsep8&quot; -dTextAlphaBits=%u -dGraphicsAlphaBits=%u &quot;-r%s&quot; %s &quot;-sOutputFile=%s&quot; &quot;%s&quot;\"/>"
00102     "  <delegate decode=\"pcl:mono\" stealth=\"True\" command=\"&quot;pcl6&quot; -dQUIET -dSAFER -dPARANOIDSAFE -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=0 &quot;-sDEVICE=pbmraw&quot; -dTextAlphaBits=%u -dGraphicsAlphaBits=%u &quot;-r%s&quot; %s &quot;-sOutputFile=%s&quot; &quot;%s&quot;\"/>"
00103     "  <delegate decode=\"pdf\" encode=\"eps\" mode=\"bi\" command=\"&quot;gs&quot; -q -dQUIET -dSAFER -dPARANOIDSAFE -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=0 &quot;-sDEVICE=epswrite&quot; &quot;-sOutputFile=%o&quot; &quot;-f%i&quot;\"/>"
00104     "  <delegate decode=\"pdf\" encode=\"ps\" mode=\"bi\" command=\"&quot;gs&quot; -q -dQUIET -dSAFER -dPARANOIDSAFE -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=0 &quot;-sDEVICE=pswrite&quot; &quot;-sOutputFile=%o&quot; &quot;-f%i&quot;\"/>"
00105     "  <delegate decode=\"pic\" command=\"&quot;ra_pfm&quot; &quot;%i&quot; &quot;%o&quot;\"/>"
00106     "  <delegate decode=\"pnm\" encode=\"ilbm\" mode=\"encode\" command=\"&quot;ppmtoilbm&quot; -24if &quot;%i&quot; &gt; &quot;%o&quot;\"/>"
00107     "  <delegate decode=\"pnm\" encode=\"launch\" mode=\"encode\" command=\"&quot;gimp&quot; &quot;%i&quot;\"/>"
00108     "  <delegate decode=\"pov\" command=\"&quot;povray&quot; &quot;+i&quot;%i&quot;&quot; -D0 +o&quot;%o&quot; +fn%q +w%w +h%h +a -q9 -kfi&quot;%s&quot; -kff&quot;%n&quot;     &quot;convert&quot; -concatenate &quot;%o*.png&quot; &quot;%o&quot;\"/>"
00109     "  <delegate decode=\"ps\" encode=\"eps\" mode=\"bi\" command=\"&quot;gs&quot; -q -dQUIET -dSAFER -dPARANOIDSAFE -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=0 &quot;-sDEVICE=epswrite&quot; &quot;-sOutputFile=%o&quot; &quot;-f%i&quot;\"/>"
00110     "  <delegate decode=\"ps\" encode=\"pdf\" mode=\"bi\" command=\"&quot;gs&quot; -q -dQUIET -dSAFER -dPARANOIDSAFE -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=0 &quot;-sDEVICE=pdfwrite&quot; &quot;-sOutputFile=%o&quot; &quot;-f%i&quot;\"/>"
00111     "  <delegate decode=\"ps\" encode=\"print\" mode=\"encode\" command=\"lpr &quot;%i&quot;\"/>"
00112     "  <delegate decode=\"ps:alpha\" stealth=\"True\" command=\"&quot;gs&quot; -q -dQUIET -dSAFER -dPARANOIDSAFE -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=0 &quot;-sDEVICE=pngalpha&quot; -dTextAlphaBits=%u -dGraphicsAlphaBits=%u &quot;-r%s&quot; %s &quot;-sOutputFile=%s&quot; &quot;-f%s&quot; &quot;-f%s&quot;\"/>"
00113     "  <delegate decode=\"ps:bbox\" stealth=\"True\" command=\"&quot;gs&quot; -q -dQUIET -dSAFER -dPARANOIDSAFE -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=0 &quot;-sDEVICE=bbox&quot; -dTextAlphaBits=%u -dGraphicsAlphaBits=%u &quot;-r%s&quot; %s &quot;-sOutputFile=%s&quot; &quot;-f%s&quot; &quot;-f%s&quot;\"/>"
00114     "  <delegate decode=\"ps:cmyk\" stealth=\"True\" command=\"&quot;gs&quot; -q -dQUIET -dSAFER -dPARANOIDSAFE -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=0 &quot;-sDEVICE=pam&quot; -dTextAlphaBits=%u -dGraphicsAlphaBits=%u &quot;-r%s&quot; %s &quot;-sOutputFile=%s&quot; &quot;-f%s&quot; &quot;-f%s&quot;\"/>"
00115     "  <delegate decode=\"ps:color\" stealth=\"True\" command=\"&quot;gs&quot; -q -dQUIET -dSAFER -dPARANOIDSAFE -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=0 &quot;-sDEVICE=pnmraw&quot; -dTextAlphaBits=%u -dGraphicsAlphaBits=%u &quot;-r%s&quot; %s &quot;-sOutputFile=%s&quot; &quot;-f%s&quot; &quot;-f%s&quot;\"/>"
00116     "  <delegate decode=\"ps:mono\" stealth=\"True\" command=\"&quot;gs&quot; -q -dQUIET -dSAFER -dPARANOIDSAFE -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=0 &quot;-sDEVICE=pnmraw&quot; -dTextAlphaBits=%u -dGraphicsAlphaBits=%u &quot;-r%s&quot; %s &quot;-sOutputFile=%s&quot; &quot;-f%s&quot; &quot;-f%s&quot;\"/>"
00117     "  <delegate decode=\"rad\" command=\"&quot;ra_pfm&quot; &quot;%i&quot; &quot;%o&quot;\"/>"
00118     "  <delegate decode=\"rgba\" encode=\"rle\" mode=\"encode\" command=\"&quot;rawtorle&quot; -o &quot;%o&quot; -v &quot;%i&quot;\"/>"
00119     "  <delegate decode=\"scan\" command=\"&quot;scanimage&quot; -d &quot;%i&quot; &gt; &quot;%o&quot;\"/>"
00120     "  <delegate encode=\"show\" stealth=\"True\" spawn=\"True\" command=\"&quot;/usr/local/bin/display&quot; -immutable -delay 0 -window-group %g -title &quot;%l of %f&quot; &quot;tmp:%i&quot;\"/>"
00121     "  <delegate decode=\"shtml\" command=\"&quot;html2ps&quot; -U -o &quot;%o&quot; &quot;%i&quot;\"/>"
00122     "  <delegate decode=\"svg\" command=\"&quot;wmf2eps&quot; -o &quot;%o&quot; &quot;%i&quot;\"/>"
00123     "  <delegate decode=\"txt\" encode=\"ps\" mode=\"bi\" command=\"&quot;enscript&quot; -o &quot;%o&quot; &quot;%i&quot;\"/>"
00124     "  <delegate encode=\"win\" stealth=\"True\" spawn=\"True\" command=\"&quot;/usr/local/bin/display&quot; -immutable -delay 0 -window-group %g -title &quot;%l of %f&quot; &quot;tmp:%i&quot;\"/>"
00125     "  <delegate decode=\"wmf\" command=\"&quot;wmf2eps&quot; -o &quot;%o&quot; &quot;%i&quot;\"/>"
00126     "</delegatemap>";
00127 
00128 /*
00129   Global declaractions.
00130 */
00131 static LinkedListInfo
00132   *delegate_list = (LinkedListInfo *) NULL;
00133 
00134 static SemaphoreInfo
00135   *delegate_semaphore = (SemaphoreInfo *) NULL;
00136 
00137 static volatile MagickBooleanType
00138   instantiate_delegate = MagickFalse;
00139 
00140 /*
00141   Forward declaractions.
00142 */
00143 static MagickBooleanType
00144   InitializeDelegateList(ExceptionInfo *),
00145   LoadDelegateLists(const char *,ExceptionInfo *);
00146 
00147 /*
00148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00149 %                                                                             %
00150 %                                                                             %
00151 %                                                                             %
00152 %   D e s t r o y D e l e g a t e L i s t                                     %
00153 %                                                                             %
00154 %                                                                             %
00155 %                                                                             %
00156 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00157 %
00158 %  DestroyDelegateList() deallocates memory associated with the delegates list.
00159 %
00160 %  The format of the DestroyDelegateList method is:
00161 %
00162 %      DestroyDelegateList(void)
00163 %
00164 */
00165 
00166 static void *DestroyDelegate(void *delegate_info)
00167 {
00168   register DelegateInfo
00169     *p;
00170 
00171   p=(DelegateInfo *) delegate_info;
00172   if (p->path != (char *) NULL)
00173     p->path=DestroyString(p->path);
00174   if (p->decode != (char *) NULL)
00175     p->decode=DestroyString(p->decode);
00176   if (p->encode != (char *) NULL)
00177     p->encode=DestroyString(p->encode);
00178   if (p->commands != (char *) NULL)
00179     p->commands=DestroyString(p->commands);
00180   p=(DelegateInfo *) RelinquishMagickMemory(p);
00181   return((void *) NULL);
00182 }
00183 
00184 
00185 MagickExport void DestroyDelegateList(void)
00186 {
00187   AcquireSemaphoreInfo(&delegate_semaphore);
00188   if (delegate_list != (LinkedListInfo *) NULL)
00189     delegate_list=DestroyLinkedList(delegate_list,DestroyDelegate);
00190   instantiate_delegate=MagickFalse;
00191   RelinquishSemaphoreInfo(delegate_semaphore);
00192   DestroySemaphoreInfo(&delegate_semaphore);
00193 }
00194 
00195 /*
00196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00197 %                                                                             %
00198 %                                                                             %
00199 %                                                                             %
00200 %   G e t D e l e g a t e C o m m a n d                                       %
00201 %                                                                             %
00202 %                                                                             %
00203 %                                                                             %
00204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00205 %
00206 %  GetDelegateCommand() replaces any embedded formatting characters with the
00207 %  appropriate image attribute and returns the resulting command.
00208 %
00209 %  The format of the GetDelegateCommand method is:
00210 %
00211 %      char *GetDelegateCommand(const ImageInfo *image_info,Image *image,
00212 %        const char *decode,const char *encode,ExceptionInfo *exception)
00213 %
00214 %  A description of each parameter follows:
00215 %
00216 %    o command: Method GetDelegateCommand returns the command associated
00217 %      with specified delegate tag.
00218 %
00219 %    o image_info: the image info.
00220 %
00221 %    o image: the image.
00222 %
00223 %    o decode: Specifies the decode delegate we are searching for as a
00224 %      character string.
00225 %
00226 %    o encode: Specifies the encode delegate we are searching for as a
00227 %      character string.
00228 %
00229 %    o exception: return any errors or warnings in this structure.
00230 %
00231 */
00232 MagickExport char *GetDelegateCommand(const ImageInfo *image_info,Image *image,
00233   const char *decode,const char *encode,ExceptionInfo *exception)
00234 {
00235   char
00236     *command,
00237     **commands;
00238 
00239   const DelegateInfo
00240     *delegate_info;
00241 
00242   register long
00243     i;
00244 
00245   assert(image_info != (ImageInfo *) NULL);
00246   assert(image_info->signature == MagickSignature);
00247   assert(image != (Image *) NULL);
00248   assert(image->signature == MagickSignature);
00249   if (image->debug != MagickFalse)
00250     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00251   delegate_info=GetDelegateInfo(decode,encode,exception);
00252   if (delegate_info == (const DelegateInfo *) NULL)
00253     {
00254       (void) ThrowMagickException(exception,GetMagickModule(),DelegateError,
00255         "NoTagFound","`%s'",decode ? decode : encode);
00256       return((char *) NULL);
00257     }
00258   commands=StringToList(delegate_info->commands);
00259   if (commands == (char **) NULL)
00260     {
00261       (void) ThrowMagickException(exception,GetMagickModule(),
00262         ResourceLimitError,"MemoryAllocationFailed","`%s'",
00263         decode ? decode : encode);
00264       return((char *) NULL);
00265     }
00266   command=InterpretImageProperties(image_info,image,commands[0]);
00267   if (command == (char *) NULL)
00268     (void) ThrowMagickException(exception,GetMagickModule(),ResourceLimitError,
00269       "MemoryAllocationFailed","`%s'",commands[0]);
00270   /*
00271     Relinquish resources.
00272   */
00273   for (i=0; commands[i] != (char *) NULL; i++)
00274     commands[i]=DestroyString(commands[i]);
00275   commands=(char **) RelinquishMagickMemory(commands);
00276   return(command);
00277 }
00278 
00279 /*
00280 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00281 %                                                                             %
00282 %                                                                             %
00283 %                                                                             %
00284 %   G e t D e l e g a t e C o m m a n d s                                     %
00285 %                                                                             %
00286 %                                                                             %
00287 %                                                                             %
00288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00289 %
00290 %  GetDelegateCommands() returns the commands associated with a delegate.
00291 %
00292 %  The format of the GetDelegateCommands method is:
00293 %
00294 %      const char *GetDelegateCommands(const DelegateInfo *delegate_info)
00295 %
00296 %  A description of each parameter follows:
00297 %
00298 %    o delegate_info:  The delegate info.
00299 %
00300 */
00301 MagickExport const char *GetDelegateCommands(const DelegateInfo *delegate_info)
00302 {
00303   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00304   assert(delegate_info != (DelegateInfo *) NULL);
00305   assert(delegate_info->signature == MagickSignature);
00306   return(delegate_info->commands);
00307 }
00308 
00309 /*
00310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00311 %                                                                             %
00312 %                                                                             %
00313 %                                                                             %
00314 %   G e t D e l e g a t e I n f o                                             %
00315 %                                                                             %
00316 %                                                                             %
00317 %                                                                             %
00318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00319 %
00320 %  GetDelegateInfo() returns any delegates associated with the specified tag.
00321 %
00322 %  The format of the GetDelegateInfo method is:
00323 %
00324 %      const DelegateInfo *GetDelegateInfo(const char *decode,
00325 %        const char *encode,ExceptionInfo *exception)
00326 %
00327 %  A description of each parameter follows:
00328 %
00329 %    o decode: Specifies the decode delegate we are searching for as a
00330 %      character string.
00331 %
00332 %    o encode: Specifies the encode delegate we are searching for as a
00333 %      character string.
00334 %
00335 %    o exception: return any errors or warnings in this structure.
00336 %
00337 */
00338 MagickExport const DelegateInfo *GetDelegateInfo(const char *decode,
00339   const char *encode,ExceptionInfo *exception)
00340 {
00341   register const DelegateInfo
00342     *p;
00343 
00344   assert(exception != (ExceptionInfo *) NULL);
00345   if ((delegate_list == (LinkedListInfo *) NULL) ||
00346       (instantiate_delegate == MagickFalse))
00347     if (InitializeDelegateList(exception) == MagickFalse)
00348       return((const DelegateInfo *) NULL);
00349   if ((delegate_list == (LinkedListInfo *) NULL) ||
00350       (IsLinkedListEmpty(delegate_list) != MagickFalse))
00351     return((const DelegateInfo *) NULL);
00352   if ((LocaleCompare(decode,"*") == 0) && (LocaleCompare(encode,"*") == 0))
00353     return((const DelegateInfo *) GetValueFromLinkedList(delegate_list,0));
00354   /*
00355     Search for named delegate.
00356   */
00357   AcquireSemaphoreInfo(&delegate_semaphore);
00358   ResetLinkedListIterator(delegate_list);
00359   p=(const DelegateInfo *) GetNextValueInLinkedList(delegate_list);
00360   while (p != (const DelegateInfo *) NULL)
00361   {
00362     if (p->mode > 0)
00363       {
00364         if (LocaleCompare(p->decode,decode) == 0)
00365           break;
00366         p=(const DelegateInfo *) GetNextValueInLinkedList(delegate_list);
00367         continue;
00368       }
00369     if (p->mode < 0)
00370       {
00371         if (LocaleCompare(p->encode,encode) == 0)
00372           break;
00373         p=(const DelegateInfo *) GetNextValueInLinkedList(delegate_list);
00374         continue;
00375       }
00376     if (LocaleCompare(decode,p->decode) == 0)
00377       if (LocaleCompare(encode,p->encode) == 0)
00378         break;
00379     if (LocaleCompare(decode,"*") == 0)
00380       if (LocaleCompare(encode,p->encode) == 0)
00381         break;
00382     if (LocaleCompare(decode,p->decode) == 0)
00383       if (LocaleCompare(encode,"*") == 0)
00384         break;
00385     p=(const DelegateInfo *) GetNextValueInLinkedList(delegate_list);
00386   }
00387   if (p != (const DelegateInfo *) NULL)
00388     (void) InsertValueInLinkedList(delegate_list,0,
00389       RemoveElementByValueFromLinkedList(delegate_list,p));
00390   RelinquishSemaphoreInfo(delegate_semaphore);
00391   return(p);
00392 }
00393 
00394 /*
00395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00396 %                                                                             %
00397 %                                                                             %
00398 %                                                                             %
00399 %   G e t D e l e g a t e I n f o L i s t                                     %
00400 %                                                                             %
00401 %                                                                             %
00402 %                                                                             %
00403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00404 %
00405 %  GetDelegateInfoList() returns any delegates that match the specified pattern.
00406 %
00407 %  The delegate of the GetDelegateInfoList function is:
00408 %
00409 %      const DelegateInfo **GetDelegateInfoList(const char *pattern,
00410 %        unsigned long *number_delegates,ExceptionInfo *exception)
00411 %
00412 %  A description of each parameter follows:
00413 %
00414 %    o pattern: Specifies a pointer to a text string containing a pattern.
00415 %
00416 %    o number_delegates:  This integer returns the number of delegates in the
00417 %      list.
00418 %
00419 %    o exception: return any errors or warnings in this structure.
00420 %
00421 */
00422 
00423 #if defined(__cplusplus) || defined(c_plusplus)
00424 extern "C" {
00425 #endif
00426 
00427 static int DelegateInfoCompare(const void *x,const void *y)
00428 {
00429   const DelegateInfo
00430     **p,
00431     **q;
00432 
00433   p=(const DelegateInfo **) x,
00434   q=(const DelegateInfo **) y;
00435   if (LocaleCompare((*p)->path,(*q)->path) == 0)
00436     {
00437       if ((*p)->decode == (char *) NULL)
00438         if (((*p)->encode != (char *) NULL) &&
00439             ((*q)->encode != (char *) NULL))
00440           return(strcmp((*p)->encode,(*q)->encode));
00441       if (((*p)->decode != (char *) NULL) &&
00442           ((*q)->decode != (char *) NULL))
00443         return(strcmp((*p)->decode,(*q)->decode));
00444     }
00445   return(LocaleCompare((*p)->path,(*q)->path));
00446 }
00447 
00448 #if defined(__cplusplus) || defined(c_plusplus)
00449 }
00450 #endif
00451 
00452 MagickExport const DelegateInfo **GetDelegateInfoList(const char *pattern,
00453   unsigned long *number_delegates,ExceptionInfo *exception)
00454 {
00455   const DelegateInfo
00456     **delegates;
00457 
00458   register const DelegateInfo
00459     *p;
00460 
00461   register long
00462     i;
00463 
00464   /*
00465     Allocate delegate list.
00466   */
00467   assert(pattern != (char *) NULL);
00468   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00469   assert(number_delegates != (unsigned long *) NULL);
00470   *number_delegates=0;
00471   p=GetDelegateInfo("*","*",exception);
00472   if (p == (const DelegateInfo *) NULL)
00473     return((const DelegateInfo **) NULL);
00474   delegates=(const DelegateInfo **) AcquireQuantumMemory((size_t)
00475     GetNumberOfElementsInLinkedList(delegate_list)+1UL,sizeof(*delegates));
00476   if (delegates == (const DelegateInfo **) NULL)
00477     return((const DelegateInfo **) NULL);
00478   /*
00479     Generate delegate list.
00480   */
00481   AcquireSemaphoreInfo(&delegate_semaphore);
00482   ResetLinkedListIterator(delegate_list);
00483   p=(const DelegateInfo *) GetNextValueInLinkedList(delegate_list);
00484   for (i=0; p != (const DelegateInfo *) NULL; )
00485   {
00486     if ((p->stealth == MagickFalse) &&
00487         ((GlobExpression(p->decode,pattern,MagickFalse) != MagickFalse) ||
00488          (GlobExpression(p->encode,pattern,MagickFalse) != MagickFalse)))
00489       delegates[i++]=p;
00490     p=(const DelegateInfo *) GetNextValueInLinkedList(delegate_list);
00491   }
00492   RelinquishSemaphoreInfo(delegate_semaphore);
00493   qsort((void *) delegates,(size_t) i,sizeof(*delegates),DelegateInfoCompare);
00494   delegates[i]=(DelegateInfo *) NULL;
00495   *number_delegates=(unsigned long) i;
00496   return(delegates);
00497 }
00498 
00499 /*
00500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00501 %                                                                             %
00502 %                                                                             %
00503 %                                                                             %
00504 %   G e t D e l e g a t e L i s t                                             %
00505 %                                                                             %
00506 %                                                                             %
00507 %                                                                             %
00508 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00509 %
00510 %  GetDelegateList() returns any image format delegates that match the
00511 %  specified  pattern.
00512 %
00513 %  The format of the GetDelegateList function is:
00514 %
00515 %      char **GetDelegateList(const char *pattern,
00516 %        unsigned long *number_delegates,ExceptionInfo *exception)
00517 %
00518 %  A description of each parameter follows:
00519 %
00520 %    o pattern: Specifies a pointer to a text string containing a pattern.
00521 %
00522 %    o number_delegates:  This integer returns the number of delegates
00523 %      in the list.
00524 %
00525 %    o exception: return any errors or warnings in this structure.
00526 %
00527 */
00528 
00529 #if defined(__cplusplus) || defined(c_plusplus)
00530 extern "C" {
00531 #endif
00532 
00533 static int DelegateCompare(const void *x,const void *y)
00534 {
00535   register const char
00536     **p,
00537     **q;
00538 
00539   p=(const char **) x;
00540   q=(const char **) y;
00541   return(LocaleCompare(*p,*q));
00542 }
00543 
00544 #if defined(__cplusplus) || defined(c_plusplus)
00545 }
00546 #endif
00547 
00548 MagickExport char **GetDelegateList(const char *pattern,
00549   unsigned long *number_delegates,ExceptionInfo *exception)
00550 {
00551   char
00552     **delegates;
00553 
00554   register const DelegateInfo
00555     *p;
00556 
00557   register long
00558     i;
00559 
00560   /*
00561     Allocate delegate list.
00562   */
00563   assert(pattern != (char *) NULL);
00564   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00565   assert(number_delegates != (unsigned long *) NULL);
00566   *number_delegates=0;
00567   p=GetDelegateInfo("*","*",exception);
00568   if (p == (const DelegateInfo *) NULL)
00569     return((char **) NULL);
00570   delegates=(char **) AcquireQuantumMemory((size_t)
00571     GetNumberOfElementsInLinkedList(delegate_list)+1UL,sizeof(*delegates));
00572   if (delegates == (char **) NULL)
00573     return((char **) NULL);
00574   AcquireSemaphoreInfo(&delegate_semaphore);
00575   ResetLinkedListIterator(delegate_list);
00576   p=(const DelegateInfo *) GetNextValueInLinkedList(delegate_list);
00577   for (i=0; p != (const DelegateInfo *) NULL; )
00578   {
00579     if ((p->stealth == MagickFalse) &&
00580         (GlobExpression(p->decode,pattern,MagickFalse) != MagickFalse))
00581       delegates[i++]=ConstantString(p->decode);
00582     if ((p->stealth == MagickFalse) &&
00583         (GlobExpression(p->encode,pattern,MagickFalse) != MagickFalse))
00584       delegates[i++]=ConstantString(p->encode);
00585     p=(const DelegateInfo *) GetNextValueInLinkedList(delegate_list);
00586   }
00587   RelinquishSemaphoreInfo(delegate_semaphore);
00588   qsort((void *) delegates,(size_t) i,sizeof(*delegates),DelegateCompare);
00589   delegates[i]=(char *) NULL;
00590   *number_delegates=(unsigned long) i;
00591   return(delegates);
00592 }
00593 
00594 /*
00595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00596 %                                                                             %
00597 %                                                                             %
00598 %                                                                             %
00599 %   G e t D e l e g a t e M o d e                                             %
00600 %                                                                             %
00601 %                                                                             %
00602 %                                                                             %
00603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00604 %
00605 %  GetDelegateMode() returns the mode of the delegate.
00606 %
00607 %  The format of the GetDelegateMode method is:
00608 %
00609 %      long GetDelegateMode(const DelegateInfo *delegate_info)
00610 %
00611 %  A description of each parameter follows:
00612 %
00613 %    o delegate_info:  The delegate info.
00614 %
00615 */
00616 MagickExport long GetDelegateMode(const DelegateInfo *delegate_info)
00617 {
00618   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00619   assert(delegate_info != (DelegateInfo *) NULL);
00620   assert(delegate_info->signature == MagickSignature);
00621   return(delegate_info->mode);
00622 }
00623 
00624 /*
00625 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00626 %                                                                             %
00627 %                                                                             %
00628 %                                                                             %
00629 +   G e t D e l e g a t e T h r e a d S u p p o r t                           %
00630 %                                                                             %
00631 %                                                                             %
00632 %                                                                             %
00633 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00634 %
00635 %  GetDelegateThreadSupport() returns MagickTrue if the delegate supports
00636 %  threads.
00637 %
00638 %  The format of the GetDelegateThreadSupport method is:
00639 %
00640 %      MagickBooleanType GetDelegateThreadSupport(
00641 %        const DelegateInfo *delegate_info)
00642 %
00643 %  A description of each parameter follows:
00644 %
00645 %    o delegate_info:  The delegate info.
00646 %
00647 */
00648 MagickExport MagickBooleanType GetDelegateThreadSupport(
00649   const DelegateInfo *delegate_info)
00650 {
00651   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00652   assert(delegate_info != (DelegateInfo *) NULL);
00653   assert(delegate_info->signature == MagickSignature);
00654   return(delegate_info->thread_support);
00655 }
00656 
00657 /*
00658 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00659 %                                                                             %
00660 %                                                                             %
00661 %                                                                             %
00662 +   I n i t i a l i z e D e l e g a t e L i s t                               %
00663 %                                                                             %
00664 %                                                                             %
00665 %                                                                             %
00666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00667 %
00668 %  InitializeDelegateList() initializes the delegate list.
00669 %
00670 %  The format of the InitializeDelegateList method is:
00671 %
00672 %      MagickBooleanType InitializeDelegateList(ExceptionInfo *exception)
00673 %
00674 %  A description of each parameter follows.
00675 %
00676 %    o exception: return any errors or warnings in this structure.
00677 %
00678 */
00679 static MagickBooleanType InitializeDelegateList(ExceptionInfo *exception)
00680 {
00681   if ((delegate_list == (LinkedListInfo *) NULL) &&
00682       (instantiate_delegate == MagickFalse))
00683     {
00684       AcquireSemaphoreInfo(&delegate_semaphore);
00685       if ((delegate_list == (LinkedListInfo *) NULL) &&
00686           (instantiate_delegate == MagickFalse))
00687         {
00688           (void) LoadDelegateLists(DelegateFilename,exception);
00689           instantiate_delegate=MagickTrue;
00690         }
00691       RelinquishSemaphoreInfo(delegate_semaphore);
00692     }
00693   return(delegate_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
00694 }
00695 
00696 /*
00697 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00698 %                                                                             %
00699 %                                                                             %
00700 %                                                                             %
00701 %   I n v o k e D e l e g a t e                                               %
00702 %                                                                             %
00703 %                                                                             %
00704 %                                                                             %
00705 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00706 %
00707 %  InvokeDelegate replaces any embedded formatting characters with the
00708 %  appropriate image attribute and executes the resulting command.  MagickFalse
00709 %  is returned if the commands execute with success otherwise MagickTrue.
00710 %
00711 %  The format of the InvokeDelegate method is:
00712 %
00713 %      MagickBooleanType InvokeDelegate(ImageInfo *image_info,Image *image,
00714 %        const char *decode,const char *encode,ExceptionInfo *exception)
00715 %
00716 %  A description of each parameter follows:
00717 %
00718 %    o image_info: the imageInfo.
00719 %
00720 %    o image: the image.
00721 %
00722 %    o exception: return any errors or warnings in this structure.
00723 %
00724 */
00725 
00726 static inline size_t MagickMin(const size_t x,const size_t y)
00727 {
00728   if (x < y)
00729     return(x);
00730   return(y);
00731 }
00732 
00733 static MagickBooleanType CopyDelegateFile(const char *source,
00734   const char *destination)
00735 {
00736   int
00737     destination_file,
00738     source_file;
00739 
00740   MagickBooleanType
00741     status;
00742 
00743   register size_t
00744     i;
00745 
00746   size_t
00747     length,
00748     quantum;
00749 
00750   ssize_t
00751     count;
00752 
00753   struct stat
00754     attributes;
00755 
00756   unsigned char
00757     *buffer;
00758 
00759   /*
00760     Return if destination file already exists and is not empty.
00761   */
00762   assert(source != (const char *) NULL);
00763   assert(destination != (char *) NULL);
00764   status=GetPathAttributes(destination,&attributes);
00765   if ((status != MagickFalse) && (attributes.st_size != 0))
00766     return(MagickTrue);
00767   /*
00768     Copy source file to destination.
00769   */
00770   destination_file=open(destination,O_WRONLY | O_BINARY | O_CREAT,S_MODE);
00771   if (destination_file == -1)
00772     return(MagickFalse);
00773   source_file=open(source,O_RDONLY | O_BINARY);
00774   if (source_file == -1)
00775     {
00776       (void) close(destination_file);
00777       return(MagickFalse);
00778     }
00779   quantum=(size_t) MagickMaxBufferExtent;
00780   if ((fstat(source_file,&attributes) == 0) && (attributes.st_size != 0))
00781     quantum=MagickMin((size_t) attributes.st_size,MagickMaxBufferExtent);
00782   buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
00783   if (buffer == (unsigned char *) NULL)
00784     {
00785       (void) close(source_file);
00786       (void) close(destination_file);
00787       return(MagickFalse);
00788     }
00789   length=0;
00790   for (i=0; ; i+=count)
00791   {
00792     count=(ssize_t) read(source_file,buffer,quantum);
00793     if (count <= 0)
00794       break;
00795     length=(size_t) count;
00796     count=(ssize_t) write(destination_file,buffer,length);
00797     if ((size_t) count != length)
00798       break;
00799   }
00800   (void) close(destination_file);
00801   (void) close(source_file);
00802   buffer=(unsigned char *) RelinquishMagickMemory(buffer);
00803   return(i != 0 ? MagickTrue : MagickFalse);
00804 }
00805 
00806 MagickExport MagickBooleanType InvokeDelegate(ImageInfo *image_info,
00807   Image *image,const char *decode,const char *encode,ExceptionInfo *exception)
00808 {
00809   char
00810     *command,
00811     **commands,
00812     input_filename[MaxTextExtent],
00813     output_filename[MaxTextExtent];
00814 
00815   const DelegateInfo
00816     *delegate_info;
00817 
00818   MagickBooleanType
00819     status,
00820     temporary;
00821 
00822   register long
00823     i;
00824 
00825   PolicyRights
00826     rights;
00827 
00828   /*
00829     Get delegate.
00830   */
00831   assert(image_info != (ImageInfo *) NULL);
00832   assert(image_info->signature == MagickSignature);
00833   assert(image != (Image *) NULL);
00834   assert(image->signature == MagickSignature);
00835   if (image->debug != MagickFalse)
00836     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00837   rights=ExecutePolicyRights;
00838   if (IsRightsAuthorized(DelegatePolicyDomain,rights,decode) == MagickFalse)
00839     {
00840       (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
00841         "NotAuthorized","`%s'",decode);
00842       return(MagickFalse);
00843     }
00844   if (IsRightsAuthorized(DelegatePolicyDomain,rights,encode) == MagickFalse)
00845     {
00846       (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
00847         "NotAuthorized","`%s'",encode);
00848       return(MagickFalse);
00849     }
00850   temporary=(*image->filename == '\0') ? MagickTrue : MagickFalse;
00851   if (temporary != MagickFalse)
00852     if (AcquireUniqueFilename(image->filename) == MagickFalse)
00853       {
00854         ThrowFileException(exception,FileOpenError,
00855           "UnableToCreateTemporaryFile",image->filename);
00856         return(MagickFalse);
00857       }
00858   delegate_info=GetDelegateInfo(decode,encode,exception);
00859   if (delegate_info == (DelegateInfo *) NULL)
00860     {
00861       if (temporary != MagickFalse)
00862         (void) RelinquishUniqueFileResource(image->filename);
00863       (void) ThrowMagickException(exception,GetMagickModule(),DelegateError,
00864         "NoTagFound","`%s'",decode ? decode : encode);
00865       return(MagickFalse);
00866     }
00867   if (*image_info->filename == '\0')
00868     {
00869       if (AcquireUniqueFilename(image_info->filename) == MagickFalse)
00870         {
00871           if (temporary != MagickFalse)
00872             (void) RelinquishUniqueFileResource(image->filename);
00873           ThrowFileException(exception,FileOpenError,
00874             "UnableToCreateTemporaryFile",image_info->filename);
00875           return(MagickFalse);
00876         }
00877       image_info->temporary=MagickTrue;
00878     }
00879   if ((delegate_info->mode != 0) &&
00880       (((decode != (const char *) NULL) &&
00881         (delegate_info->encode != (char *) NULL)) ||
00882        ((encode != (const char *) NULL) &&
00883         (delegate_info->decode != (char *) NULL))))
00884     {
00885       char
00886         *magick;
00887 
00888       ImageInfo
00889         *clone_info;
00890 
00891       register Image
00892         *p;
00893 
00894       /*
00895         Delegate requires a particular image format.
00896       */
00897       if (AcquireUniqueFilename(image_info->unique) == MagickFalse)
00898         {
00899           ThrowFileException(exception,FileOpenError,
00900             "UnableToCreateTemporaryFile",image_info->unique);
00901           return(MagickFalse);
00902         }
00903       if (AcquireUniqueFilename(image_info->zero) == MagickFalse)
00904         {
00905           (void) RelinquishUniqueFileResource(image_info->zero);
00906           ThrowFileException(exception,FileOpenError,
00907             "UnableToCreateTemporaryFile",image_info->zero);
00908           return(MagickFalse);
00909         }
00910       magick=InterpretImageProperties(image_info,image,decode != (char *) NULL ?
00911         delegate_info->encode : delegate_info->decode);
00912       if (magick == (char *) NULL)
00913         {
00914           (void) RelinquishUniqueFileResource(image_info->unique);
00915           (void) RelinquishUniqueFileResource(image_info->zero);
00916           if (temporary != MagickFalse)
00917             (void) RelinquishUniqueFileResource(image->filename);
00918           (void) ThrowMagickException(exception,GetMagickModule(),
00919             DelegateError,"DelegateFailed","`%s'",decode ? decode : encode);
00920           return(MagickFalse);
00921         }
00922       LocaleUpper(magick);
00923       clone_info=CloneImageInfo(image_info);
00924       (void) CopyMagickString((char *) clone_info->magick,magick,
00925         MaxTextExtent);
00926       if (LocaleCompare(magick,"NULL") != 0)
00927         (void) CopyMagickString(image->magick,magick,MaxTextExtent);
00928       magick=DestroyString(magick);
00929       (void) FormatMagickString(clone_info->filename,MaxTextExtent,"%s:",
00930         delegate_info->decode);
00931       (void) SetImageInfo(clone_info,MagickTrue,exception);
00932       (void) CopyMagickString(clone_info->filename,image_info->filename,
00933         MaxTextExtent);
00934       (void) CopyMagickString(image_info->filename,image->filename,
00935         MaxTextExtent);
00936       for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
00937       {
00938         (void) FormatMagickString(p->filename,MaxTextExtent,"%s:%s",
00939           delegate_info->decode,clone_info->filename);
00940         status=WriteImage(clone_info,p);
00941         if (status == MagickFalse)
00942           {
00943             (void) RelinquishUniqueFileResource(image_info->unique);
00944             (void) RelinquishUniqueFileResource(image_info->zero);
00945             if (temporary != MagickFalse)
00946               (void) RelinquishUniqueFileResource(image->filename);
00947             clone_info=DestroyImageInfo(clone_info);
00948             (void) ThrowMagickException(exception,GetMagickModule(),
00949               DelegateError,"DelegateFailed","`%s'",decode ? decode : encode);
00950             return(MagickFalse);
00951           }
00952         if (clone_info->adjoin != MagickFalse)
00953           break;
00954       }
00955       (void) RelinquishUniqueFileResource(image_info->unique);
00956       (void) RelinquishUniqueFileResource(image_info->zero);
00957       clone_info=DestroyImageInfo(clone_info);
00958     }
00959   /*
00960     Invoke delegate.
00961   */
00962   commands=StringToList(delegate_info->commands);
00963   if (commands == (char **) NULL)
00964     {
00965       if (temporary != MagickFalse)
00966         (void) RelinquishUniqueFileResource(image->filename);
00967       (void) ThrowMagickException(exception,GetMagickModule(),
00968         ResourceLimitError,"MemoryAllocationFailed","`%s'",
00969         decode ? decode : encode);
00970       return(MagickFalse);
00971     }
00972   command=(char *) NULL;
00973   status=MagickFalse;
00974   (void) CopyMagickString(output_filename,image_info->filename,MaxTextExtent);
00975   (void) CopyMagickString(input_filename,image->filename,MaxTextExtent);
00976   for (i=0; commands[i] != (char *) NULL; i++)
00977   {
00978     status=AcquireUniqueSymbolicLink(output_filename,image_info->filename);
00979     if (AcquireUniqueFilename(image_info->unique) == MagickFalse)
00980       {
00981         ThrowFileException(exception,FileOpenError,
00982           "UnableToCreateTemporaryFile",image_info->unique);
00983         break;
00984       }
00985     if (AcquireUniqueFilename(image_info->zero) == MagickFalse)
00986       {
00987         (void) RelinquishUniqueFileResource(image_info->unique);
00988         ThrowFileException(exception,FileOpenError,
00989           "UnableToCreateTemporaryFile",image_info->zero);
00990         break;
00991       }
00992     if (LocaleCompare(decode,"SCAN") != 0)
00993       {
00994         status=AcquireUniqueSymbolicLink(input_filename,image->filename);
00995         if (status == MagickFalse)
00996           {
00997             ThrowFileException(exception,FileOpenError,
00998               "UnableToCreateTemporaryFile",input_filename);
00999             break;
01000           }
01001       }
01002     status=MagickFalse;
01003     command=InterpretImageProperties(image_info,image,commands[i]);
01004     if (command != (char *) NULL)
01005       {
01006         /*
01007           Execute delegate.
01008         */
01009         if (delegate_info->spawn != MagickFalse)
01010           (void) ConcatenateString(&command," &");
01011         status=SystemCommand(image_info->verbose,command) != 0 ?  MagickTrue :
01012           MagickFalse;
01013         if (delegate_info->spawn != MagickFalse)
01014           (void) sleep(2);
01015         command=DestroyString(command);
01016       }
01017     if (LocaleCompare(decode,"SCAN") != 0)
01018       {
01019         if (CopyDelegateFile(image->filename,input_filename) == MagickFalse)
01020           (void) RelinquishUniqueFileResource(input_filename);
01021       }
01022     if (CopyDelegateFile(image_info->filename,output_filename) == MagickFalse)
01023       (void) RelinquishUniqueFileResource(output_filename);
01024     if (image_info->temporary != MagickFalse)
01025       (void) RelinquishUniqueFileResource(image_info->filename);
01026     (void) RelinquishUniqueFileResource(image_info->unique);
01027     (void) RelinquishUniqueFileResource(image_info->zero);
01028     (void) RelinquishUniqueFileResource(image_info->filename);
01029     (void) RelinquishUniqueFileResource(image->filename);
01030     if (status != MagickFalse)
01031       {
01032         (void) ThrowMagickException(exception,GetMagickModule(),DelegateError,
01033           "DelegateFailed","`%s'",commands[i]);
01034         break;
01035       }
01036     commands[i]=DestroyString(commands[i]);
01037   }
01038   (void) CopyMagickString(image_info->filename,output_filename,MaxTextExtent);
01039   (void) CopyMagickString(image->filename,input_filename,MaxTextExtent);
01040   /*
01041     Relinquish resources.
01042   */
01043   for ( ; commands[i] != (char *) NULL; i++)
01044     commands[i]=DestroyString(commands[i]);
01045   commands=(char **) RelinquishMagickMemory(commands);
01046   if (temporary != MagickFalse)
01047     (void) RelinquishUniqueFileResource(image->filename);
01048   return(status == MagickFalse ? MagickTrue : MagickFalse);
01049 }
01050 
01051 /*
01052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01053 %                                                                             %
01054 %                                                                             %
01055 %                                                                             %
01056 %  L i s t D e l e g a t e I n f o                                            %
01057 %                                                                             %
01058 %                                                                             %
01059 %                                                                             %
01060 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01061 %
01062 %  ListDelegateInfo() lists the image formats to a file.
01063 %
01064 %  The format of the ListDelegateInfo method is:
01065 %
01066 %      MagickBooleanType ListDelegateInfo(FILE *file,ExceptionInfo *exception)
01067 %
01068 %  A description of each parameter follows.
01069 %
01070 %    o file:  An pointer to a FILE.
01071 %
01072 %    o exception: return any errors or warnings in this structure.
01073 %
01074 */
01075 MagickExport MagickBooleanType ListDelegateInfo(FILE *file,
01076   ExceptionInfo *exception)
01077 {
01078   const DelegateInfo
01079     **delegate_info;
01080 
01081   char
01082     **commands,
01083     delegate[MaxTextExtent];
01084 
01085   const char
01086     *path;
01087 
01088   long
01089     j;
01090 
01091   register long
01092     i;
01093 
01094   unsigned long
01095     number_delegates;
01096 
01097   if (file == (const FILE *) NULL)
01098     file=stdout;
01099   delegate_info=GetDelegateInfoList("*",&number_delegates,exception);
01100   if (delegate_info == (const DelegateInfo **) NULL)
01101     return(MagickFalse);
01102   path=(const char *) NULL;
01103   for (i=0; i < (long) number_delegates; i++)
01104   {
01105     if (delegate_info[i]->stealth != MagickFalse)
01106       continue;
01107     if ((path == (const char *) NULL) ||
01108         (LocaleCompare(path,delegate_info[i]->path) != 0))
01109       {
01110         if (delegate_info[i]->path != (char *) NULL)
01111           (void) fprintf(file,"\nPath: %s\n\n",delegate_info[i]->path);
01112         (void) fprintf(file,"Delegate                Command\n");
01113         (void) fprintf(file,"-------------------------------------------------"
01114           "------------------------------\n");
01115       }
01116     path=delegate_info[i]->path;
01117     *delegate='\0';
01118     if (delegate_info[i]->encode != (char *) NULL)
01119       (void) CopyMagickString(delegate,delegate_info[i]->encode,MaxTextExtent);
01120     (void) ConcatenateMagickString(delegate,"        ",MaxTextExtent);
01121     delegate[8]='\0';
01122     commands=StringToList(delegate_info[i]->commands);
01123     if (commands == (char **) NULL)
01124       continue;
01125     (void) fprintf(file,"%11s%c=%c%s  ",delegate_info[i]->decode ?
01126       delegate_info[i]->decode : "",delegate_info[i]->mode <= 0 ? '<' : ' ',
01127       delegate_info[i]->mode >= 0 ? '>' : ' ',delegate);
01128     StripString(commands[0]);
01129     (void) fprintf(file,"\"%s\"\n",commands[0]);
01130     for (j=1; commands[j] != (char *) NULL; j++)
01131     {
01132       StripString(commands[j]);
01133       (void) fprintf(file,"                     \"%s\"\n",commands[j]);
01134     }
01135     for (j=0; commands[j] != (char *) NULL; j++)
01136       commands[j]=DestroyString(commands[j]);
01137     commands=(char **) RelinquishMagickMemory(commands);
01138   }
01139   (void) fflush(file);
01140   delegate_info=(const DelegateInfo **)
01141     RelinquishMagickMemory((void *) delegate_info);
01142   return(MagickTrue);
01143 }
01144 
01145 /*
01146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01147 %                                                                             %
01148 %                                                                             %
01149 %                                                                             %
01150 +   L o a d D e l e g a t e L i s t                                           %
01151 %                                                                             %
01152 %                                                                             %
01153 %                                                                             %
01154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01155 %
01156 %  LoadDelegateList() loads the delegate configuration file which provides a
01157 %  mapping between delegate attributes and a delegate name.
01158 %
01159 %  The format of the LoadDelegateList method is:
01160 %
01161 %      MagickBooleanType LoadDelegateList(const char *xml,const char *filename,
01162 %        const unsigned long depth,ExceptionInfo *exception)
01163 %
01164 %  A description of each parameter follows:
01165 %
01166 %    o xml:  The delegate list in XML format.
01167 %
01168 %    o filename:  The delegate list filename.
01169 %
01170 %    o depth: depth of <include /> statements.
01171 %
01172 %    o exception: return any errors or warnings in this structure.
01173 %
01174 */
01175 static MagickBooleanType LoadDelegateList(const char *xml,const char *filename,
01176   const unsigned long depth,ExceptionInfo *exception)
01177 {
01178   char
01179     keyword[MaxTextExtent],
01180     *token;
01181 
01182   const char
01183     *q;
01184 
01185   DelegateInfo
01186     *delegate_info;
01187 
01188   MagickBooleanType
01189     status;
01190 
01191   /*
01192     Load the delegate map file.
01193   */
01194   (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
01195     "Loading delegate configuration file \"%s\" ...",filename);
01196   if (xml == (const char *) NULL)
01197     return(MagickFalse);
01198   if (delegate_list == (LinkedListInfo *) NULL)
01199     {
01200       delegate_list=NewLinkedList(0);
01201       if (delegate_list == (LinkedListInfo *) NULL)
01202         {
01203           ThrowFileException(exception,ResourceLimitError,
01204             "MemoryAllocationFailed",filename);
01205           return(MagickFalse);
01206         }
01207     }
01208   status=MagickTrue;
01209   delegate_info=(DelegateInfo *) NULL;
01210   token=AcquireString(xml);
01211   for (q=(const char *) xml; *q != '\0'; )
01212   {
01213     /*
01214       Interpret XML.
01215     */
01216     GetMagickToken(q,&q,token);
01217     if (*token == '\0')
01218       break;
01219     (void) CopyMagickString(keyword,token,MaxTextExtent);
01220     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
01221       {
01222         /*
01223           Doctype element.
01224         */
01225         while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
01226           GetMagickToken(q,&q,token);
01227         continue;
01228       }
01229     if (LocaleNCompare(keyword,"<!--",4) == 0)
01230       {
01231         /*
01232           Comment element.
01233         */
01234         while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
01235           GetMagickToken(q,&q,token);
01236         continue;
01237       }
01238     if (LocaleCompare(keyword,"<include") == 0)
01239       {
01240         /*
01241           Include element.
01242         */
01243         while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
01244         {
01245           (void) CopyMagickString(keyword,token,MaxTextExtent);
01246           GetMagickToken(q,&q,token);
01247           if (*token != '=')
01248             continue;
01249           GetMagickToken(q,&q,token);
01250           if (LocaleCompare(keyword,"file") == 0)
01251             {
01252               if (depth > 200)
01253                 (void) ThrowMagickException(exception,GetMagickModule(),
01254                   ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
01255               else
01256                 {
01257                   char
01258                     path[MaxTextExtent],
01259                     *xml;
01260 
01261                   GetPathComponent(filename,HeadPath,path);
01262                   if (*path != '\0')
01263                     (void) ConcatenateMagickString(path,DirectorySeparator,
01264                       MaxTextExtent);
01265                   if (*token == *DirectorySeparator)
01266                     (void) CopyMagickString(path,token,MaxTextExtent);
01267                   else
01268                     (void) ConcatenateMagickString(path,token,MaxTextExtent);
01269                   xml=FileToString(path,~0,exception);
01270                   if (xml != (char *) NULL)
01271                     {
01272                       status=LoadDelegateList(xml,path,depth+1,exception);
01273                       xml=(char *) RelinquishMagickMemory(xml);
01274                     }
01275                 }
01276             }
01277         }
01278         continue;
01279       }
01280     if (LocaleCompare(keyword,"<delegate") == 0)
01281       {
01282         /*
01283           Delegate element.
01284         */
01285         delegate_info=(DelegateInfo *) AcquireMagickMemory(
01286           sizeof(*delegate_info));
01287         if (delegate_info == (DelegateInfo *) NULL)
01288           ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
01289         (void) ResetMagickMemory(delegate_info,0,sizeof(*delegate_info));
01290         delegate_info->path=ConstantString(filename);
01291         delegate_info->signature=MagickSignature;
01292         continue;
01293       }
01294     if (delegate_info == (DelegateInfo *) NULL)
01295       continue;
01296     if (LocaleCompare(keyword,"/>") == 0)
01297       {
01298         status=AppendValueToLinkedList(delegate_list,delegate_info);
01299         if (status == MagickFalse)
01300           (void) ThrowMagickException(exception,GetMagickModule(),
01301             ResourceLimitError,"MemoryAllocationFailed","`%s'",
01302             delegate_info->commands);
01303         delegate_info=(DelegateInfo *) NULL;
01304       }
01305     GetMagickToken(q,(const char **) NULL,token);
01306     if (*token != '=')
01307       continue;
01308     GetMagickToken(q,&q,token);
01309     GetMagickToken(q,&q,token);
01310     switch (*keyword)
01311     {
01312       case 'C':
01313       case 'c':
01314       {
01315         if (LocaleCompare((char *) keyword,"command") == 0)
01316           {
01317             char
01318               *commands;
01319 
01320             commands=AcquireString(token);
01321 #if defined(__WINDOWS__)
01322             if (strchr(commands,'@') != (char *) NULL)
01323               {
01324                 char
01325                   path[MaxTextExtent];
01326 
01327                 NTGhostscriptEXE(path,MaxTextExtent);
01328                 (void) SubstituteString((char **) &commands,"@PSDelegate@",
01329                   path);
01330                 (void) SubstituteString((char **) &commands,"\\","/");
01331               }
01332 #endif
01333             (void) SubstituteString((char **) &commands,"&amp;","&");
01334             (void) SubstituteString((char **) &commands,"&quot;","\"");
01335             (void) SubstituteString((char **) &commands,"&gt;",">");
01336             (void) SubstituteString((char **) &commands,"&lt;","<");
01337             delegate_info->commands=commands;
01338             break;
01339           }
01340         break;
01341       }
01342       case 'D':
01343       case 'd':
01344       {
01345         if (LocaleCompare((char *) keyword,"decode") == 0)
01346           {
01347             delegate_info->decode=ConstantString(token);
01348             delegate_info->mode=1;
01349             break;
01350           }
01351         break;
01352       }
01353       case 'E':
01354       case 'e':
01355       {
01356         if (LocaleCompare((char *) keyword,"encode") == 0)
01357           {
01358             delegate_info->encode=ConstantString(token);
01359             delegate_info->mode=(-1);
01360             break;
01361           }
01362         break;
01363       }
01364       case 'M':
01365       case 'm':
01366       {
01367         if (LocaleCompare((char *) keyword,"mode") == 0)
01368           {
01369             delegate_info->mode=1;
01370             if (LocaleCompare(token,"bi") == 0)
01371               delegate_info->mode=0;
01372             else
01373               if (LocaleCompare(token,"encode") == 0)
01374                 delegate_info->mode=(-1);
01375             break;
01376           }
01377         break;
01378       }
01379       case 'S':
01380       case 's':
01381       {
01382         if (LocaleCompare((char *) keyword,"spawn") == 0)
01383           {
01384             delegate_info->spawn=IsMagickTrue(token);
01385             break;
01386           }
01387         if (LocaleCompare((char *) keyword,"stealth") == 0)
01388           {
01389             delegate_info->stealth=IsMagickTrue(token);
01390             break;
01391           }
01392         break;
01393       }
01394       case 'T':
01395       case 't':
01396       {
01397         if (LocaleCompare((char *) keyword,"thread-support") == 0)
01398           {
01399             delegate_info->thread_support=IsMagickTrue(token);
01400             break;
01401           }
01402         break;
01403       }
01404       default:
01405         break;
01406     }
01407   }
01408   token=(char *) RelinquishMagickMemory(token);
01409   return(status);
01410 }
01411 
01412 /*
01413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01414 %                                                                             %
01415 %                                                                             %
01416 %                                                                             %
01417 %  L o a d D e l e g a t e L i s t s                                          %
01418 %                                                                             %
01419 %                                                                             %
01420 %                                                                             %
01421 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01422 %
01423 %  LoadDelegateList() loads one or more delegate configuration file which
01424 %  provides a mapping between delegate attributes and a delegate name.
01425 %
01426 %  The format of the LoadDelegateLists method is:
01427 %
01428 %      MagickBooleanType LoadDelegateLists(const char *filename,
01429 %        ExceptionInfo *exception)
01430 %
01431 %  A description of each parameter follows:
01432 %
01433 %    o filename: the font file name.
01434 %
01435 %    o exception: return any errors or warnings in this structure.
01436 %
01437 */
01438 static MagickBooleanType LoadDelegateLists(const char *filename,
01439   ExceptionInfo *exception)
01440 {
01441 #if defined(MAGICKCORE_EMBEDDABLE_SUPPORT)
01442   return(LoadDelegateList(DelegateMap,"built-in",0,exception));
01443 #else
01444   const StringInfo
01445     *option;
01446 
01447   LinkedListInfo
01448     *options;
01449 
01450   MagickStatusType
01451     status;
01452 
01453   status=MagickFalse;
01454   options=GetConfigureOptions(filename,exception);
01455   option=(const StringInfo *) GetNextValueInLinkedList(options);
01456   while (option != (const StringInfo *) NULL)
01457   {
01458     status|=LoadDelegateList((const char *) GetStringInfoDatum(option),
01459       GetStringInfoPath(option),0,exception);
01460     option=(const StringInfo *) GetNextValueInLinkedList(options);
01461   }
01462   options=DestroyConfigureOptions(options);
01463   if ((delegate_list == (LinkedListInfo *) NULL) ||
01464       (IsLinkedListEmpty(delegate_list) != MagickFalse))
01465     status|=LoadDelegateList(DelegateMap,"built-in",0,exception);
01466   return(status != 0 ? MagickTrue : MagickFalse);
01467 #endif
01468 }

Generated on Thu Jul 2 12:03:14 2009 for MagickCore by  doxygen 1.5.8