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