|
MagickCore
6.7.5
|
00001 /* 00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00003 % % 00004 % % 00005 % % 00006 % CCCC OOO N N FFFFF IIIII GGGG U U RRRR EEEEE % 00007 % C O O NN N F I G U U R R E % 00008 % C O O N N N FFF I G GG U U RRRR EEE % 00009 % C O O N NN F I G G U U R R E % 00010 % CCCC OOO N N F IIIII GGG UUU R R EEEEE % 00011 % % 00012 % % 00013 % MagickCore Image Configure Methods % 00014 % % 00015 % Software Design % 00016 % John Cristy % 00017 % July 2003 % 00018 % % 00019 % % 00020 % Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization % 00021 % dedicated to making software imaging solutions freely available. % 00022 % % 00023 % You may not use this file except in compliance with the License. You may % 00024 % obtain a copy of the License at % 00025 % % 00026 % http://www.imagemagick.org/script/license.php % 00027 % % 00028 % Unless required by applicable law or agreed to in writing, software % 00029 % distributed under the License is distributed on an "AS IS" BASIS, % 00030 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 00031 % See the License for the specific language governing permissions and % 00032 % limitations under the License. % 00033 % % 00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00035 % 00036 % 00037 */ 00038 00039 /* 00040 Include declarations. 00041 */ 00042 #include "MagickCore/studio.h" 00043 #include "MagickCore/blob.h" 00044 #include "MagickCore/client.h" 00045 #include "MagickCore/configure.h" 00046 #include "MagickCore/configure-private.h" 00047 #include "MagickCore/exception.h" 00048 #include "MagickCore/exception-private.h" 00049 #include "MagickCore/hashmap.h" 00050 #include "MagickCore/log.h" 00051 #include "MagickCore/memory_.h" 00052 #include "MagickCore/semaphore.h" 00053 #include "MagickCore/string_.h" 00054 #include "MagickCore/string-private.h" 00055 #include "MagickCore/token.h" 00056 #include "MagickCore/utility.h" 00057 #include "MagickCore/utility-private.h" 00058 #include "MagickCore/xml-tree.h" 00059 00060 /* 00061 Define declarations. 00062 */ 00063 #define ConfigureFilename "configure.xml" 00064 00065 /* 00066 Typedef declarations. 00067 */ 00068 typedef struct _ConfigureMapInfo 00069 { 00070 const char 00071 *name, 00072 *value; 00073 } ConfigureMapInfo; 00074 00075 /* 00076 Static declarations. 00077 */ 00078 static const ConfigureMapInfo 00079 ConfigureMap[] = 00080 { 00081 { "NAME", "ImageMagick" } 00082 }; 00083 00084 static LinkedListInfo 00085 *configure_list = (LinkedListInfo *) NULL; 00086 00087 static SemaphoreInfo 00088 *configure_semaphore = (SemaphoreInfo *) NULL; 00089 00090 static volatile MagickBooleanType 00091 instantiate_configure = MagickFalse; 00092 00093 /* 00094 Forward declarations. 00095 */ 00096 static MagickBooleanType 00097 InitializeConfigureList(ExceptionInfo *), 00098 LoadConfigureLists(const char *,ExceptionInfo *); 00099 00100 /* 00101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00102 % % 00103 % % 00104 % % 00105 + C o n f i g u r e C o m p o n e n t G e n e s i s % 00106 % % 00107 % % 00108 % % 00109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00110 % 00111 % ConfigureComponentGenesis() instantiates the configure component. 00112 % 00113 % The format of the ConfigureComponentGenesis method is: 00114 % 00115 % MagickBooleanType ConfigureComponentGenesis(void) 00116 % 00117 */ 00118 MagickPrivate MagickBooleanType ConfigureComponentGenesis(void) 00119 { 00120 AcquireSemaphoreInfo(&configure_semaphore); 00121 return(MagickTrue); 00122 } 00123 00124 /* 00125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00126 % % 00127 % % 00128 % % 00129 + C o n f i g u r e C o m p o n e n t T e r m i n u s % 00130 % % 00131 % % 00132 % % 00133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00134 % 00135 % ConfigureComponentTerminus() destroys the configure component. 00136 % 00137 % The format of the ConfigureComponentTerminus method is: 00138 % 00139 % ConfigureComponentTerminus(void) 00140 % 00141 */ 00142 00143 static void *DestroyConfigureElement(void *configure_info) 00144 { 00145 register ConfigureInfo 00146 *p; 00147 00148 p=(ConfigureInfo *) configure_info; 00149 if (p->exempt == MagickFalse) 00150 { 00151 if (p->value != (char *) NULL) 00152 p->value=DestroyString(p->value); 00153 if (p->name != (char *) NULL) 00154 p->name=DestroyString(p->name); 00155 if (p->path != (char *) NULL) 00156 p->path=DestroyString(p->path); 00157 } 00158 p=(ConfigureInfo *) RelinquishMagickMemory(p); 00159 return((void *) NULL); 00160 } 00161 00162 MagickPrivate void ConfigureComponentTerminus(void) 00163 { 00164 if (configure_semaphore == (SemaphoreInfo *) NULL) 00165 AcquireSemaphoreInfo(&configure_semaphore); 00166 LockSemaphoreInfo(configure_semaphore); 00167 if (configure_list != (LinkedListInfo *) NULL) 00168 configure_list=DestroyLinkedList(configure_list,DestroyConfigureElement); 00169 configure_list=(LinkedListInfo *) NULL; 00170 instantiate_configure=MagickFalse; 00171 UnlockSemaphoreInfo(configure_semaphore); 00172 DestroySemaphoreInfo(&configure_semaphore); 00173 } 00174 00175 /* 00176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00177 % % 00178 % % 00179 % % 00180 % D e s t r o y C o n f i g u r e O p t i o n s % 00181 % % 00182 % % 00183 % % 00184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00185 % 00186 % DestroyConfigureOptions() releases memory associated with an configure 00187 % options. 00188 % 00189 % The format of the DestroyProfiles method is: 00190 % 00191 % LinkedListInfo *DestroyConfigureOptions(Image *image) 00192 % 00193 % A description of each parameter follows: 00194 % 00195 % o image: the image. 00196 % 00197 */ 00198 00199 static void *DestroyOptions(void *option) 00200 { 00201 return(DestroyStringInfo((StringInfo *) option)); 00202 } 00203 00204 MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options) 00205 { 00206 assert(options != (LinkedListInfo *) NULL); 00207 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 00208 return(DestroyLinkedList(options,DestroyOptions)); 00209 } 00210 00211 /* 00212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00213 % % 00214 % % 00215 % % 00216 + G e t C o n f i g u r e I n f o % 00217 % % 00218 % % 00219 % % 00220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00221 % 00222 % GetConfigureInfo() searches the configure list for the specified name and if 00223 % found returns attributes for that element. 00224 % 00225 % The format of the GetConfigureInfo method is: 00226 % 00227 % const ConfigureInfo *GetConfigureInfo(const char *name, 00228 % ExceptionInfo *exception) 00229 % 00230 % A description of each parameter follows: 00231 % 00232 % o configure_info: GetConfigureInfo() searches the configure list for the 00233 % specified name and if found returns attributes for that element. 00234 % 00235 % o name: the configure name. 00236 % 00237 % o exception: return any errors or warnings in this structure. 00238 % 00239 */ 00240 MagickExport const ConfigureInfo *GetConfigureInfo(const char *name, 00241 ExceptionInfo *exception) 00242 { 00243 register const ConfigureInfo 00244 *p; 00245 00246 assert(exception != (ExceptionInfo *) NULL); 00247 if ((configure_list == (LinkedListInfo *) NULL) || 00248 (instantiate_configure == MagickFalse)) 00249 if (InitializeConfigureList(exception) == MagickFalse) 00250 return((const ConfigureInfo *) NULL); 00251 if ((configure_list == (LinkedListInfo *) NULL) || 00252 (IsLinkedListEmpty(configure_list) != MagickFalse)) 00253 return((const ConfigureInfo *) NULL); 00254 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0)) 00255 return((const ConfigureInfo *) GetValueFromLinkedList(configure_list,0)); 00256 /* 00257 Search for configure tag. 00258 */ 00259 LockSemaphoreInfo(configure_semaphore); 00260 ResetLinkedListIterator(configure_list); 00261 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list); 00262 while (p != (const ConfigureInfo *) NULL) 00263 { 00264 if (LocaleCompare(name,p->name) == 0) 00265 break; 00266 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list); 00267 } 00268 if (p != (ConfigureInfo *) NULL) 00269 (void) InsertValueInLinkedList(configure_list,0, 00270 RemoveElementByValueFromLinkedList(configure_list,p)); 00271 UnlockSemaphoreInfo(configure_semaphore); 00272 return(p); 00273 } 00274 00275 /* 00276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00277 % % 00278 % % 00279 % % 00280 % G e t C o n f i g u r e I n f o L i s t % 00281 % % 00282 % % 00283 % % 00284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00285 % 00286 % GetConfigureInfoList() returns any configure options that match the 00287 % specified pattern. 00288 % 00289 % The format of the GetConfigureInfoList function is: 00290 % 00291 % const ConfigureInfo **GetConfigureInfoList(const char *pattern, 00292 % size_t *number_options,ExceptionInfo *exception) 00293 % 00294 % A description of each parameter follows: 00295 % 00296 % o pattern: Specifies a pointer to a text string containing a pattern. 00297 % 00298 % o number_options: This integer returns the number of configure options in 00299 % the list. 00300 % 00301 % o exception: return any errors or warnings in this structure. 00302 % 00303 */ 00304 00305 #if defined(__cplusplus) || defined(c_plusplus) 00306 extern "C" { 00307 #endif 00308 00309 static int ConfigureInfoCompare(const void *x,const void *y) 00310 { 00311 const ConfigureInfo 00312 **p, 00313 **q; 00314 00315 p=(const ConfigureInfo **) x, 00316 q=(const ConfigureInfo **) y; 00317 if (LocaleCompare((*p)->path,(*q)->path) == 0) 00318 return(LocaleCompare((*p)->name,(*q)->name)); 00319 return(LocaleCompare((*p)->path,(*q)->path)); 00320 } 00321 00322 #if defined(__cplusplus) || defined(c_plusplus) 00323 } 00324 #endif 00325 00326 MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern, 00327 size_t *number_options,ExceptionInfo *exception) 00328 { 00329 const ConfigureInfo 00330 **options; 00331 00332 register const ConfigureInfo 00333 *p; 00334 00335 register ssize_t 00336 i; 00337 00338 /* 00339 Allocate configure list. 00340 */ 00341 assert(pattern != (char *) NULL); 00342 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern); 00343 assert(number_options != (size_t *) NULL); 00344 *number_options=0; 00345 p=GetConfigureInfo("*",exception); 00346 if (p == (const ConfigureInfo *) NULL) 00347 return((const ConfigureInfo **) NULL); 00348 options=(const ConfigureInfo **) AcquireQuantumMemory((size_t) 00349 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options)); 00350 if (options == (const ConfigureInfo **) NULL) 00351 return((const ConfigureInfo **) NULL); 00352 /* 00353 Generate configure list. 00354 */ 00355 LockSemaphoreInfo(configure_semaphore); 00356 ResetLinkedListIterator(configure_list); 00357 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list); 00358 for (i=0; p != (const ConfigureInfo *) NULL; ) 00359 { 00360 if ((p->stealth == MagickFalse) && 00361 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse)) 00362 options[i++]=p; 00363 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list); 00364 } 00365 UnlockSemaphoreInfo(configure_semaphore); 00366 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare); 00367 options[i]=(ConfigureInfo *) NULL; 00368 *number_options=(size_t) i; 00369 return(options); 00370 } 00371 00372 /* 00373 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00374 % % 00375 % % 00376 % % 00377 % G e t C o n f i g u r e L i s t % 00378 % % 00379 % % 00380 % % 00381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00382 % 00383 % GetConfigureList() returns any configure options that match the specified 00384 % pattern. 00385 % 00386 % The format of the GetConfigureList function is: 00387 % 00388 % char **GetConfigureList(const char *pattern, 00389 % size_t *number_options,ExceptionInfo *exception) 00390 % 00391 % A description of each parameter follows: 00392 % 00393 % o pattern: Specifies a pointer to a text string containing a pattern. 00394 % 00395 % o number_options: This integer returns the number of options in the list. 00396 % 00397 % o exception: return any errors or warnings in this structure. 00398 % 00399 */ 00400 00401 #if defined(__cplusplus) || defined(c_plusplus) 00402 extern "C" { 00403 #endif 00404 00405 static int ConfigureCompare(const void *x,const void *y) 00406 { 00407 register char 00408 **p, 00409 **q; 00410 00411 p=(char **) x; 00412 q=(char **) y; 00413 return(LocaleCompare(*p,*q)); 00414 } 00415 00416 #if defined(__cplusplus) || defined(c_plusplus) 00417 } 00418 #endif 00419 00420 MagickExport char **GetConfigureList(const char *pattern, 00421 size_t *number_options,ExceptionInfo *exception) 00422 { 00423 char 00424 **options; 00425 00426 register const ConfigureInfo 00427 *p; 00428 00429 register ssize_t 00430 i; 00431 00432 /* 00433 Allocate configure list. 00434 */ 00435 assert(pattern != (char *) NULL); 00436 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern); 00437 assert(number_options != (size_t *) NULL); 00438 *number_options=0; 00439 p=GetConfigureInfo("*",exception); 00440 if (p == (const ConfigureInfo *) NULL) 00441 return((char **) NULL); 00442 options=(char **) AcquireQuantumMemory((size_t) 00443 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options)); 00444 if (options == (char **) NULL) 00445 return((char **) NULL); 00446 LockSemaphoreInfo(configure_semaphore); 00447 ResetLinkedListIterator(configure_list); 00448 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list); 00449 for (i=0; p != (const ConfigureInfo *) NULL; ) 00450 { 00451 if ((p->stealth == MagickFalse) && 00452 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse)) 00453 options[i++]=ConstantString(p->name); 00454 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list); 00455 } 00456 UnlockSemaphoreInfo(configure_semaphore); 00457 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare); 00458 options[i]=(char *) NULL; 00459 *number_options=(size_t) i; 00460 return(options); 00461 } 00462 00463 /* 00464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00465 % % 00466 % % 00467 % % 00468 % G e t C o n f i g u r e O p t i o n % 00469 % % 00470 % % 00471 % % 00472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00473 % 00474 % GetConfigureOption() returns the value associated with the configure option. 00475 % 00476 % The format of the GetConfigureOption method is: 00477 % 00478 % char *GetConfigureOption(const char *option) 00479 % 00480 % A description of each parameter follows: 00481 % 00482 % o configure_info: The configure info. 00483 % 00484 */ 00485 MagickExport char *GetConfigureOption(const char *option) 00486 { 00487 const char 00488 *value; 00489 00490 const ConfigureInfo 00491 *configure_info; 00492 00493 ExceptionInfo 00494 *exception; 00495 00496 assert(option != (const char *) NULL); 00497 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option); 00498 exception=AcquireExceptionInfo(); 00499 configure_info=GetConfigureInfo(option,exception); 00500 exception=DestroyExceptionInfo(exception); 00501 if (configure_info == (ConfigureInfo *) NULL) 00502 return((char *) NULL); 00503 value=GetConfigureValue(configure_info); 00504 if ((value == (const char *) NULL) || (*value == '\0')) 00505 return((char *) NULL); 00506 return(ConstantString(value)); 00507 } 00508 00509 /* 00510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00511 % % 00512 % % 00513 % % 00514 % G e t C o n f i g u r e O p t i o n s % 00515 % % 00516 % % 00517 % % 00518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00519 % 00520 % GetConfigureOptions() returns any Magick configuration options associated 00521 % with the specified filename. 00522 % 00523 % The format of the GetConfigureOptions method is: 00524 % 00525 % LinkedListInfo *GetConfigureOptions(const char *filename, 00526 % ExceptionInfo *exception) 00527 % 00528 % A description of each parameter follows: 00529 % 00530 % o filename: the configure file name. 00531 % 00532 % o exception: return any errors or warnings in this structure. 00533 % 00534 */ 00535 MagickExport LinkedListInfo *GetConfigureOptions(const char *filename, 00536 ExceptionInfo *exception) 00537 { 00538 char 00539 path[MaxTextExtent]; 00540 00541 const char 00542 *element; 00543 00544 LinkedListInfo 00545 *options, 00546 *paths; 00547 00548 StringInfo 00549 *xml; 00550 00551 assert(filename != (const char *) NULL); 00552 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); 00553 assert(exception != (ExceptionInfo *) NULL); 00554 (void) CopyMagickString(path,filename,MaxTextExtent); 00555 /* 00556 Load XML from configuration files to linked-list. 00557 */ 00558 options=NewLinkedList(0); 00559 paths=GetConfigurePaths(filename,exception); 00560 if (paths != (LinkedListInfo *) NULL) 00561 { 00562 ResetLinkedListIterator(paths); 00563 element=(const char *) GetNextValueInLinkedList(paths); 00564 while (element != (const char *) NULL) 00565 { 00566 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename); 00567 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), 00568 "Searching for configure file: \"%s\"",path); 00569 xml=ConfigureFileToStringInfo(path); 00570 if (xml != (StringInfo *) NULL) 00571 (void) AppendValueToLinkedList(options,xml); 00572 element=(const char *) GetNextValueInLinkedList(paths); 00573 } 00574 paths=DestroyLinkedList(paths,RelinquishMagickMemory); 00575 } 00576 #if defined(MAGICKCORE_WINDOWS_SUPPORT) 00577 if (GetNumberOfElementsInLinkedList(options) == 0) 00578 { 00579 char 00580 *blob; 00581 00582 blob=(char *) NTResourceToBlob(filename); 00583 if (blob != (char *) NULL) 00584 { 00585 xml=AcquireStringInfo(0); 00586 SetStringInfoLength(xml,strlen(blob)+1); 00587 SetStringInfoDatum(xml,blob); 00588 SetStringInfoPath(xml,filename); 00589 (void) AppendValueToLinkedList(options,xml); 00590 } 00591 } 00592 #endif 00593 if (GetNumberOfElementsInLinkedList(options) == 0) 00594 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning, 00595 "UnableToOpenConfigureFile","`%s'",filename); 00596 ResetLinkedListIterator(options); 00597 return(options); 00598 } 00599 00600 /* 00601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00602 % % 00603 % % 00604 % % 00605 % G e t C o n f i g u r e P a t h s % 00606 % % 00607 % % 00608 % % 00609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00610 % 00611 % GetConfigurePaths() returns any Magick configuration paths associated 00612 % with the specified filename. 00613 % 00614 % The format of the GetConfigurePaths method is: 00615 % 00616 % LinkedListInfo *GetConfigurePaths(const char *filename, 00617 % ExceptionInfo *exception) 00618 % 00619 % A description of each parameter follows: 00620 % 00621 % o filename: the configure file name. 00622 % 00623 % o exception: return any errors or warnings in this structure. 00624 % 00625 */ 00626 MagickExport LinkedListInfo *GetConfigurePaths(const char *filename, 00627 ExceptionInfo *exception) 00628 { 00629 #define RegistryKey "ConfigurePath" 00630 #define MagickCoreDLL "CORE_RL_MagickCore_.dll" 00631 #define MagickCoreDebugDLL "CORE_DB_MagickCore_.dll" 00632 00633 char 00634 path[MaxTextExtent]; 00635 00636 LinkedListInfo 00637 *paths; 00638 00639 assert(filename != (const char *) NULL); 00640 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); 00641 assert(exception != (ExceptionInfo *) NULL); 00642 (void) CopyMagickString(path,filename,MaxTextExtent); 00643 paths=NewLinkedList(0); 00644 { 00645 char 00646 *configure_path; 00647 00648 /* 00649 Search $MAGICK_CONFIGURE_PATH. 00650 */ 00651 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH"); 00652 if (configure_path != (char *) NULL) 00653 { 00654 register char 00655 *p, 00656 *q; 00657 00658 for (p=configure_path-1; p != (char *) NULL; ) 00659 { 00660 (void) CopyMagickString(path,p+1,MaxTextExtent); 00661 q=strchr(path,DirectoryListSeparator); 00662 if (q != (char *) NULL) 00663 *q='\0'; 00664 q=path+strlen(path)-1; 00665 if ((q >= path) && (*q != *DirectorySeparator)) 00666 (void) ConcatenateMagickString(path,DirectorySeparator, 00667 MaxTextExtent); 00668 (void) AppendValueToLinkedList(paths,ConstantString(path)); 00669 p=strchr(p+1,DirectoryListSeparator); 00670 } 00671 configure_path=DestroyString(configure_path); 00672 } 00673 } 00674 #if defined(MAGICKCORE_INSTALLED_SUPPORT) 00675 #if defined(MAGICKCORE_SHARE_PATH) 00676 (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH)); 00677 #endif 00678 #if defined(MAGICKCORE_SHAREARCH_PATH) 00679 (void) AppendValueToLinkedList(paths,ConstantString( 00680 MAGICKCORE_SHAREARCH_PATH)); 00681 #endif 00682 #if defined(MAGICKCORE_CONFIGURE_PATH) 00683 (void) AppendValueToLinkedList(paths,ConstantString( 00684 MAGICKCORE_CONFIGURE_PATH)); 00685 #endif 00686 #if defined(MAGICKCORE_DOCUMENTATION_PATH) 00687 (void) AppendValueToLinkedList(paths,ConstantString( 00688 MAGICKCORE_DOCUMENTATION_PATH)); 00689 #endif 00690 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH)) 00691 { 00692 unsigned char 00693 *key_value; 00694 00695 /* 00696 Locate file via registry key. 00697 */ 00698 key_value=NTRegistryKeyLookup(RegistryKey); 00699 if (key_value != (unsigned char *) NULL) 00700 { 00701 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value, 00702 DirectorySeparator); 00703 (void) AppendValueToLinkedList(paths,ConstantString(path)); 00704 key_value=(unsigned char *) RelinquishMagickMemory(key_value); 00705 } 00706 } 00707 #endif 00708 #else 00709 { 00710 char 00711 *home; 00712 00713 /* 00714 Search under MAGICK_HOME. 00715 */ 00716 home=GetEnvironmentValue("MAGICK_HOME"); 00717 if (home != (char *) NULL) 00718 { 00719 #if !defined(MAGICKCORE_POSIX_SUPPORT) 00720 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home, 00721 DirectorySeparator); 00722 (void) AppendValueToLinkedList(paths,ConstantString(path)); 00723 #else 00724 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home, 00725 MAGICKCORE_CONFIGURE_RELATIVE_PATH); 00726 (void) AppendValueToLinkedList(paths,ConstantString(path)); 00727 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home, 00728 MAGICKCORE_SHARE_RELATIVE_PATH); 00729 (void) AppendValueToLinkedList(paths,ConstantString(path)); 00730 #endif 00731 home=DestroyString(home); 00732 } 00733 } 00734 if (*GetClientPath() != '\0') 00735 { 00736 #if !defined(MAGICKCORE_POSIX_SUPPORT) 00737 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(), 00738 DirectorySeparator); 00739 (void) AppendValueToLinkedList(paths,ConstantString(path)); 00740 #else 00741 char 00742 prefix[MaxTextExtent]; 00743 00744 /* 00745 Search based on executable directory if directory is known. 00746 */ 00747 (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent); 00748 ChopPathComponents(prefix,1); 00749 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix, 00750 MAGICKCORE_CONFIGURE_RELATIVE_PATH); 00751 (void) AppendValueToLinkedList(paths,ConstantString(path)); 00752 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix, 00753 MAGICKCORE_SHARE_RELATIVE_PATH); 00754 (void) AppendValueToLinkedList(paths,ConstantString(path)); 00755 #endif 00756 } 00757 /* 00758 Search current directory. 00759 */ 00760 (void) AppendValueToLinkedList(paths,ConstantString("")); 00761 #endif 00762 { 00763 char 00764 *home; 00765 00766 home=GetEnvironmentValue("HOME"); 00767 if (home == (char *) NULL) 00768 home=GetEnvironmentValue("USERPROFILE"); 00769 if (home != (char *) NULL) 00770 { 00771 /* 00772 Search $HOME/.magick. 00773 */ 00774 (void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick%s",home, 00775 DirectorySeparator,DirectorySeparator); 00776 (void) AppendValueToLinkedList(paths,ConstantString(path)); 00777 home=DestroyString(home); 00778 } 00779 } 00780 #if defined(MAGICKCORE_WINDOWS_SUPPORT) 00781 { 00782 char 00783 module_path[MaxTextExtent]; 00784 00785 if ((NTGetModulePath(MagickCoreDLL,module_path) != MagickFalse) || 00786 (NTGetModulePath(MagickCoreDebugDLL,module_path) != MagickFalse)) 00787 { 00788 unsigned char 00789 *key_value; 00790 00791 /* 00792 Search module path. 00793 */ 00794 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path, 00795 DirectorySeparator); 00796 key_value=NTRegistryKeyLookup(RegistryKey); 00797 if (key_value == (unsigned char *) NULL) 00798 (void) AppendValueToLinkedList(paths,ConstantString(path)); 00799 else 00800 key_value=(unsigned char *) RelinquishMagickMemory(key_value); 00801 } 00802 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse) 00803 { 00804 /* 00805 Search PerlMagick module path. 00806 */ 00807 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path, 00808 DirectorySeparator); 00809 (void) AppendValueToLinkedList(paths,ConstantString(path)); 00810 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path, 00811 "\\inc\\lib\\auto\\Image\\Magick\\"); 00812 (void) AppendValueToLinkedList(paths,ConstantString(path)); 00813 } 00814 } 00815 #endif 00816 return(paths); 00817 } 00818 00819 /* 00820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00821 % % 00822 % % 00823 % % 00824 % G e t C o n f i g u r e V a l u e % 00825 % % 00826 % % 00827 % % 00828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00829 % 00830 % GetConfigureValue() returns the value associated with the configure info. 00831 % 00832 % The format of the GetConfigureValue method is: 00833 % 00834 % const char *GetConfigureValue(const ConfigureInfo *configure_info) 00835 % 00836 % A description of each parameter follows: 00837 % 00838 % o configure_info: The configure info. 00839 % 00840 */ 00841 MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info) 00842 { 00843 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 00844 assert(configure_info != (ConfigureInfo *) NULL); 00845 assert(configure_info->signature == MagickSignature); 00846 return(configure_info->value); 00847 } 00848 00849 /* 00850 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00851 % % 00852 % % 00853 % % 00854 + I n i t i a l i z e C o n f i g u r e L i s t % 00855 % % 00856 % % 00857 % % 00858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00859 % 00860 % InitializeConfigureList() initializes the configure list. 00861 % 00862 % The format of the InitializeConfigureList method is: 00863 % 00864 % MagickBooleanType InitializeConfigureList(ExceptionInfo *exception) 00865 % 00866 % A description of each parameter follows. 00867 % 00868 % o exception: return any errors or warnings in this structure. 00869 % 00870 */ 00871 static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception) 00872 { 00873 if ((configure_list == (LinkedListInfo *) NULL) && 00874 (instantiate_configure == MagickFalse)) 00875 { 00876 if (configure_semaphore == (SemaphoreInfo *) NULL) 00877 AcquireSemaphoreInfo(&configure_semaphore); 00878 LockSemaphoreInfo(configure_semaphore); 00879 if ((configure_list == (LinkedListInfo *) NULL) && 00880 (instantiate_configure == MagickFalse)) 00881 { 00882 (void) LoadConfigureLists(ConfigureFilename,exception); 00883 instantiate_configure=MagickTrue; 00884 } 00885 UnlockSemaphoreInfo(configure_semaphore); 00886 } 00887 return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse); 00888 } 00889 00890 /* 00891 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00892 % % 00893 % % 00894 % % 00895 % L i s t C o n f i g u r e I n f o % 00896 % % 00897 % % 00898 % % 00899 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00900 % 00901 % ListConfigureInfo() lists the configure info to a file. 00902 % 00903 % The format of the ListConfigureInfo method is: 00904 % 00905 % MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception) 00906 % 00907 % A description of each parameter follows. 00908 % 00909 % o file: An pointer to a FILE. 00910 % 00911 % o exception: return any errors or warnings in this structure. 00912 % 00913 */ 00914 MagickExport MagickBooleanType ListConfigureInfo(FILE *file, 00915 ExceptionInfo *exception) 00916 { 00917 const char 00918 *name, 00919 *path, 00920 *value; 00921 00922 const ConfigureInfo 00923 **configure_info; 00924 00925 register ssize_t 00926 i; 00927 00928 size_t 00929 number_options; 00930 00931 ssize_t 00932 j; 00933 00934 if (file == (const FILE *) NULL) 00935 file=stdout; 00936 configure_info=GetConfigureInfoList("*",&number_options,exception); 00937 if (configure_info == (const ConfigureInfo **) NULL) 00938 return(MagickFalse); 00939 path=(const char *) NULL; 00940 for (i=0; i < (ssize_t) number_options; i++) 00941 { 00942 if (configure_info[i]->stealth != MagickFalse) 00943 continue; 00944 if ((path == (const char *) NULL) || 00945 (LocaleCompare(path,configure_info[i]->path) != 0)) 00946 { 00947 if (configure_info[i]->path != (char *) NULL) 00948 (void) FormatLocaleFile(file,"\nPath: %s\n\n", 00949 configure_info[i]->path); 00950 (void) FormatLocaleFile(file,"Name Value\n"); 00951 (void) FormatLocaleFile(file, 00952 "-------------------------------------------------" 00953 "------------------------------\n"); 00954 } 00955 path=configure_info[i]->path; 00956 name="unknown"; 00957 if (configure_info[i]->name != (char *) NULL) 00958 name=configure_info[i]->name; 00959 (void) FormatLocaleFile(file,"%s",name); 00960 for (j=(ssize_t) strlen(name); j <= 12; j++) 00961 (void) FormatLocaleFile(file," "); 00962 (void) FormatLocaleFile(file," "); 00963 value="unknown"; 00964 if (configure_info[i]->value != (char *) NULL) 00965 value=configure_info[i]->value; 00966 (void) FormatLocaleFile(file,"%s",value); 00967 (void) FormatLocaleFile(file,"\n"); 00968 } 00969 (void) fflush(file); 00970 configure_info=(const ConfigureInfo **) 00971 RelinquishMagickMemory((void *) configure_info); 00972 return(MagickTrue); 00973 } 00974 00975 /* 00976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00977 % % 00978 % % 00979 % % 00980 + L o a d C o n f i g u r e L i s t % 00981 % % 00982 % % 00983 % % 00984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00985 % 00986 % LoadConfigureList() loads the configure configuration file which provides a 00987 % mapping between configure attributes and a configure name. 00988 % 00989 % The format of the LoadConfigureList method is: 00990 % 00991 % MagickBooleanType LoadConfigureList(const char *xml,const char *filename, 00992 % const size_t depth,ExceptionInfo *exception) 00993 % 00994 % A description of each parameter follows: 00995 % 00996 % o xml: The configure list in XML format. 00997 % 00998 % o filename: The configure list filename. 00999 % 01000 % o depth: depth of <include /> statements. 01001 % 01002 % o exception: return any errors or warnings in this structure. 01003 % 01004 */ 01005 static MagickBooleanType LoadConfigureList(const char *xml,const char *filename, 01006 const size_t depth,ExceptionInfo *exception) 01007 { 01008 char 01009 keyword[MaxTextExtent], 01010 *token; 01011 01012 ConfigureInfo 01013 *configure_info; 01014 01015 const char 01016 *q; 01017 01018 MagickBooleanType 01019 status; 01020 01021 /* 01022 Load the configure map file. 01023 */ 01024 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), 01025 "Loading configure file \"%s\" ...",filename); 01026 if (configure_list == (LinkedListInfo *) NULL) 01027 { 01028 configure_list=NewLinkedList(0); 01029 if (configure_list == (LinkedListInfo *) NULL) 01030 { 01031 ThrowFileException(exception,ResourceLimitError, 01032 "MemoryAllocationFailed",filename); 01033 return(MagickFalse); 01034 } 01035 } 01036 status=MagickTrue; 01037 configure_info=(ConfigureInfo *) NULL; 01038 token=AcquireString((char *) xml); 01039 for (q=(char *) xml; *q != '\0'; ) 01040 { 01041 /* 01042 Interpret XML. 01043 */ 01044 GetMagickToken(q,&q,token); 01045 if (*token == '\0') 01046 break; 01047 (void) CopyMagickString(keyword,token,MaxTextExtent); 01048 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) 01049 { 01050 /* 01051 Doctype element. 01052 */ 01053 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) 01054 GetMagickToken(q,&q,token); 01055 continue; 01056 } 01057 if (LocaleNCompare(keyword,"<!--",4) == 0) 01058 { 01059 /* 01060 Comment element. 01061 */ 01062 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) 01063 GetMagickToken(q,&q,token); 01064 continue; 01065 } 01066 if (LocaleCompare(keyword,"<include") == 0) 01067 { 01068 /* 01069 Include element. 01070 */ 01071 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) 01072 { 01073 (void) CopyMagickString(keyword,token,MaxTextExtent); 01074 GetMagickToken(q,&q,token); 01075 if (*token != '=') 01076 continue; 01077 GetMagickToken(q,&q,token); 01078 if (LocaleCompare(keyword,"file") == 0) 01079 { 01080 if (depth > 200) 01081 (void) ThrowMagickException(exception,GetMagickModule(), 01082 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token); 01083 else 01084 { 01085 char 01086 path[MaxTextExtent], 01087 *xml; 01088 01089 GetPathComponent(filename,HeadPath,path); 01090 if (*path != '\0') 01091 (void) ConcatenateMagickString(path,DirectorySeparator, 01092 MaxTextExtent); 01093 if (*token == *DirectorySeparator) 01094 (void) CopyMagickString(path,token,MaxTextExtent); 01095 else 01096 (void) ConcatenateMagickString(path,token,MaxTextExtent); 01097 xml=FileToString(path,~0,exception); 01098 if (xml != (char *) NULL) 01099 { 01100 status=LoadConfigureList(xml,path,depth+1,exception); 01101 xml=(char *) RelinquishMagickMemory(xml); 01102 } 01103 } 01104 } 01105 } 01106 continue; 01107 } 01108 if (LocaleCompare(keyword,"<configure") == 0) 01109 { 01110 /* 01111 Configure element. 01112 */ 01113 configure_info=(ConfigureInfo *) AcquireMagickMemory( 01114 sizeof(*configure_info)); 01115 if (configure_info == (ConfigureInfo *) NULL) 01116 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 01117 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info)); 01118 configure_info->path=ConstantString(filename); 01119 configure_info->exempt=MagickFalse; 01120 configure_info->signature=MagickSignature; 01121 continue; 01122 } 01123 if (configure_info == (ConfigureInfo *) NULL) 01124 continue; 01125 if (LocaleCompare(keyword,"/>") == 0) 01126 { 01127 status=AppendValueToLinkedList(configure_list,configure_info); 01128 if (status == MagickFalse) 01129 (void) ThrowMagickException(exception,GetMagickModule(), 01130 ResourceLimitError,"MemoryAllocationFailed","`%s'", 01131 configure_info->name); 01132 configure_info=(ConfigureInfo *) NULL; 01133 } 01134 /* 01135 Parse configure element. 01136 */ 01137 GetMagickToken(q,(const char **) NULL,token); 01138 if (*token != '=') 01139 continue; 01140 GetMagickToken(q,&q,token); 01141 GetMagickToken(q,&q,token); 01142 switch (*keyword) 01143 { 01144 case 'N': 01145 case 'n': 01146 { 01147 if (LocaleCompare((char *) keyword,"name") == 0) 01148 { 01149 configure_info->name=ConstantString(token); 01150 break; 01151 } 01152 break; 01153 } 01154 case 'S': 01155 case 's': 01156 { 01157 if (LocaleCompare((char *) keyword,"stealth") == 0) 01158 { 01159 configure_info->stealth=IsMagickTrue(token); 01160 break; 01161 } 01162 break; 01163 } 01164 case 'V': 01165 case 'v': 01166 { 01167 if (LocaleCompare((char *) keyword,"value") == 0) 01168 { 01169 configure_info->value=ConstantString(token); 01170 break; 01171 } 01172 break; 01173 } 01174 default: 01175 break; 01176 } 01177 } 01178 token=(char *) RelinquishMagickMemory(token); 01179 return(status); 01180 } 01181 01182 /* 01183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01184 % % 01185 % % 01186 % % 01187 % L o a d C o n f i g u r e L i s t s % 01188 % % 01189 % % 01190 % % 01191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01192 % 01193 % LoadConfigureList() loads one or more configure configuration files which 01194 % provides a mapping between configure attributes and a configure name. 01195 % 01196 % The format of the LoadConfigureLists method is: 01197 % 01198 % MagickBooleanType LoadConfigureLists(const char *filename, 01199 % ExceptionInfo *exception) 01200 % 01201 % A description of each parameter follows: 01202 % 01203 % o filename: the font file name. 01204 % 01205 % o exception: return any errors or warnings in this structure. 01206 % 01207 */ 01208 static MagickBooleanType LoadConfigureLists(const char *filename, 01209 ExceptionInfo *exception) 01210 { 01211 const StringInfo 01212 *option; 01213 01214 LinkedListInfo 01215 *options; 01216 01217 MagickStatusType 01218 status; 01219 01220 register ssize_t 01221 i; 01222 01223 /* 01224 Load built-in configure map. 01225 */ 01226 status=MagickFalse; 01227 if (configure_list == (LinkedListInfo *) NULL) 01228 { 01229 configure_list=NewLinkedList(0); 01230 if (configure_list == (LinkedListInfo *) NULL) 01231 { 01232 ThrowFileException(exception,ResourceLimitError, 01233 "MemoryAllocationFailed",filename); 01234 return(MagickFalse); 01235 } 01236 } 01237 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++) 01238 { 01239 ConfigureInfo 01240 *configure_info; 01241 01242 register const ConfigureMapInfo 01243 *p; 01244 01245 p=ConfigureMap+i; 01246 configure_info=(ConfigureInfo *) AcquireMagickMemory( 01247 sizeof(*configure_info)); 01248 if (configure_info == (ConfigureInfo *) NULL) 01249 { 01250 (void) ThrowMagickException(exception,GetMagickModule(), 01251 ResourceLimitError,"MemoryAllocationFailed","`%s'", 01252 configure_info->name); 01253 continue; 01254 } 01255 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info)); 01256 configure_info->path=(char *) "[built-in]"; 01257 configure_info->name=(char *) p->name; 01258 configure_info->value=(char *) p->value; 01259 configure_info->exempt=MagickTrue; 01260 configure_info->signature=MagickSignature; 01261 status=AppendValueToLinkedList(configure_list,configure_info); 01262 if (status == MagickFalse) 01263 (void) ThrowMagickException(exception,GetMagickModule(), 01264 ResourceLimitError,"MemoryAllocationFailed","`%s'", 01265 configure_info->name); 01266 } 01267 /* 01268 Load external configure map. 01269 */ 01270 options=GetConfigureOptions(filename,exception); 01271 option=(const StringInfo *) GetNextValueInLinkedList(options); 01272 while (option != (const StringInfo *) NULL) 01273 { 01274 status|=LoadConfigureList((const char *) GetStringInfoDatum(option), 01275 GetStringInfoPath(option),0,exception); 01276 option=(const StringInfo *) GetNextValueInLinkedList(options); 01277 } 01278 options=DestroyConfigureOptions(options); 01279 return(status != 0 ? MagickTrue : MagickFalse); 01280 }