1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % % 6 % RRRR EEEEE GGG IIIII SSSSS TTTTT RRRR Y Y % 7 % R R E G I SS T R R Y Y % 8 % RRRR EEE G GGG I SSS T RRRR Y % 9 % R R E G G I SS T R R Y % 10 % R R EEEEE GGG IIIII SSSSS T R R Y % 11 % % 12 % % 13 % MagickCore Registry Methods % 14 % % 15 % Software Design % 16 % Cristy % 17 % March 2000 % 18 % % 19 % % 20 % Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 21 % dedicated to making software imaging solutions freely available. % 22 % % 23 % You may not use this file except in compliance with the License. You may % 24 % obtain a copy of the License at % 25 % % 26 % http://www.imagemagick.org/script/license.php % 27 % % 28 % Unless required by applicable law or agreed to in writing, software % 29 % distributed under the License is distributed on an "AS IS" BASIS, % 30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 31 % See the License for the specific language governing permissions and % 32 % limitations under the License. % 33 % % 34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 35 % 36 % 37 % 38 */ 39 40 /* 42 Include declarations. 43 */ 44 #include "MagickCore/studio.h" 45 #include "MagickCore/exception.h" 46 #include "MagickCore/exception-private.h" 47 #include "MagickCore/image.h" 48 #include "MagickCore/list.h" 49 #include "MagickCore/memory_.h" 50 #include "MagickCore/registry.h" 51 #include "MagickCore/registry-private.h" 52 #include "MagickCore/splay-tree.h" 53 #include "MagickCore/string_.h" 54 #include "MagickCore/utility.h" 55 56 /* 58 Typedef declarations. 59 */ 60 typedef struct _RegistryInfo 61 { 62 RegistryType 63 type; 64 65 void 66 *value; 67 68 size_t 69 signature; 70 } RegistryInfo; 71 72 /* 74 Static declarations. 75 */ 76 static SplayTreeInfo 77 *registry = (SplayTreeInfo *) NULL; 78 79 static SemaphoreInfo 80 *registry_semaphore = (SemaphoreInfo *) NULL; 81 82 /* 84 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 85 % % 86 % % 87 % % 88 % D e f i n e I m a g e R e g i s t r y % 89 % % 90 % % 91 % % 92 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 93 % 94 % DefineImageRegistry() associates a key/value pair with the image registry. 95 % 96 % The format of the DefineImageRegistry method is: 97 % 98 % MagickBooleanType DefineImageRegistry(const RegistryType type, 99 % const char *option,ExceptionInfo *exception) 100 % 101 % A description of each parameter follows: 102 % 103 % o type: the type. 104 % 105 % o option: the option. 106 % 107 % o exception: the exception. 108 % 109 */ 110 MagickExport MagickBooleanType DefineImageRegistry(const RegistryType type, 111 const char *option,ExceptionInfo *exception) 112 { 113 char 114 key[MagickPathExtent], 115 value[MagickPathExtent]; 116 117 register char 118 *p; 119 120 assert(option != (const char *) NULL); 121 (void) CopyMagickString(key,option,MagickPathExtent); 122 for (p=key; *p != '\0'; p++) 123 if (*p == '=') 124 break; 125 *value='\0'; 126 if (*p == '=') 127 (void) CopyMagickString(value,p+1,MagickPathExtent); 128 *p='\0'; 129 return(SetImageRegistry(type,key,value,exception)); 130 } 131 132 /* 134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 135 % % 136 % % 137 % % 138 % D e l e t e I m a g e R e g i s t r y % 139 % % 140 % % 141 % % 142 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 143 % 144 % DeleteImageRegistry() deletes a key from the image registry. 145 % 146 % The format of the DeleteImageRegistry method is: 147 % 148 % MagickBooleanType DeleteImageRegistry(const char *key) 149 % 150 % A description of each parameter follows: 151 % 152 % o key: the registry. 153 % 154 */ 155 MagickExport MagickBooleanType DeleteImageRegistry(const char *key) 156 { 157 if (IsEventLogging() != MagickFalse) 158 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key); 159 if (registry == (void *) NULL) 160 return(MagickFalse); 161 return(DeleteNodeFromSplayTree(registry,key)); 162 } 163 164 /* 166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 167 % % 168 % % 169 % % 170 % G e t I m a g e R e g i s t r y % 171 % % 172 % % 173 % % 174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 175 % 176 % GetImageRegistry() returns a value associated with an image registry key. 177 % 178 % The format of the GetImageRegistry method is: 179 % 180 % void *GetImageRegistry(const RegistryType type,const char *key, 181 % ExceptionInfo *exception) 182 % 183 % A description of each parameter follows: 184 % 185 % o type: the type. 186 % 187 % o key: the key. 188 % 189 % o exception: the exception. 190 % 191 */ 192 MagickExport void *GetImageRegistry(const RegistryType type,const char *key, 193 ExceptionInfo *exception) 194 { 195 void 196 *value; 197 198 RegistryInfo 199 *registry_info; 200 201 if (IsEventLogging() != MagickFalse) 202 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key); 203 if (registry == (void *) NULL) 204 return((void *) NULL); 205 registry_info=(RegistryInfo *) GetValueFromSplayTree(registry,key); 206 if (registry_info == (void *) NULL) 207 { 208 (void) ThrowMagickException(exception,GetMagickModule(),RegistryError, 209 "UnableToGetRegistryID","`%s'",key); 210 return((void *) NULL); 211 } 212 value=(void *) NULL; 213 switch (type) 214 { 215 case ImageRegistryType: 216 { 217 if (type == registry_info->type) 218 value=(void *) CloneImageList((Image *) registry_info->value,exception); 219 break; 220 } 221 case ImageInfoRegistryType: 222 { 223 if (type == registry_info->type) 224 value=(void *) CloneImageInfo((ImageInfo *) registry_info->value); 225 break; 226 } 227 case StringRegistryType: 228 { 229 switch (registry_info->type) 230 { 231 case ImageRegistryType: 232 { 233 value=(Image *) ConstantString(((Image *) 234 registry_info->value)->filename); 235 break; 236 } 237 case ImageInfoRegistryType: 238 { 239 value=(Image *) ConstantString(((ImageInfo *) 240 registry_info->value)->filename); 241 break; 242 } 243 case StringRegistryType: 244 { 245 value=(void *) ConstantString((char *) registry_info->value); 246 break; 247 } 248 default: 249 break; 250 } 251 break; 252 } 253 default: 254 break; 255 } 256 return(value); 257 } 258 259 /* 261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 262 % % 263 % % 264 % % 265 % G e t N e x t I m a g e R e g i s t r y % 266 % % 267 % % 268 % % 269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 270 % 271 % GetNextImageRegistry() gets the next image registry value. 272 % 273 % The format of the GetNextImageRegistry method is: 274 % 275 % char *GetNextImageRegistry(void) 276 % 277 */ 278 MagickExport char *GetNextImageRegistry(void) 279 { 280 if (IsEventLogging() != MagickFalse) 281 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 282 if (registry == (void *) NULL) 283 return((char *) NULL); 284 return((char *) GetNextKeyInSplayTree(registry)); 285 } 286 287 /* 289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 290 % % 291 % % 292 % % 293 + R e g i s t r y C o m p o n e n t G e n e s i s % 294 % % 295 % % 296 % % 297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 298 % 299 % RegistryComponentGenesis() instantiates the registry component. 300 % 301 % The format of the RegistryComponentGenesis method is: 302 % 303 % MagickBooleanType RegistryComponentGenesis(void) 304 % 305 */ 306 MagickPrivate MagickBooleanType RegistryComponentGenesis(void) 307 { 308 if (registry_semaphore == (SemaphoreInfo *) NULL) 309 registry_semaphore=AcquireSemaphoreInfo(); 310 return(MagickTrue); 311 } 312 313 /* 315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 316 % % 317 % % 318 % % 319 % R e g i s t r y C o m p o n e n t T e r m i n u s % 320 % % 321 % % 322 % % 323 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 324 % 325 % RegistryComponentTerminus() destroys the registry component. 326 % 327 % The format of the DestroyDefines method is: 328 % 329 % void RegistryComponentTerminus(void) 330 % 331 */ 332 MagickPrivate void RegistryComponentTerminus(void) 333 { 334 if (registry_semaphore == (SemaphoreInfo *) NULL) 335 ActivateSemaphoreInfo(®istry_semaphore); 336 LockSemaphoreInfo(registry_semaphore); 337 if (IsEventLogging() != MagickFalse) 338 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 339 if (registry != (void *) NULL) 340 registry=DestroySplayTree(registry); 341 UnlockSemaphoreInfo(registry_semaphore); 342 RelinquishSemaphoreInfo(®istry_semaphore); 343 } 344 345 /* 347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 348 % % 349 % % 350 % % 351 % R e m o v e I m a g e R e g i s t r y % 352 % % 353 % % 354 % % 355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 356 % 357 % RemoveImageRegistry() removes a key from the image registry and returns its 358 % value. 359 % 360 % The format of the RemoveImageRegistry method is: 361 % 362 % void *RemoveImageRegistry(const char *key) 363 % 364 % A description of each parameter follows: 365 % 366 % o key: the registry. 367 % 368 */ 369 MagickExport void *RemoveImageRegistry(const char *key) 370 { 371 if (IsEventLogging() != MagickFalse) 372 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key); 373 if (registry == (void *) NULL) 374 return((void *) NULL); 375 return(RemoveNodeFromSplayTree(registry,key)); 376 } 377 378 /* 380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 381 % % 382 % % 383 % % 384 % R e s e t I m a g e R e g i s t r y I t e r a t o r % 385 % % 386 % % 387 % % 388 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 389 % 390 % ResetImageRegistryIterator() resets the registry iterator. Use it in 391 % conjunction with GetNextImageRegistry() to iterate over all the values 392 % in the image registry. 393 % 394 % The format of the ResetImageRegistryIterator method is: 395 % 396 % ResetImageRegistryIterator(void) 397 % 398 */ 399 MagickExport void ResetImageRegistryIterator(void) 400 { 401 if (IsEventLogging() != MagickFalse) 402 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 403 if (registry == (void *) NULL) 404 return; 405 ResetSplayTreeIterator(registry); 406 } 407 408 /* 410 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 411 % % 412 % % 413 % % 414 % S e t I m a g e R e g i s t r y % 415 % % 416 % % 417 % % 418 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 419 % 420 % SetImageRegistry() associates a value with an image registry key. 421 % 422 % The format of the SetImageRegistry method is: 423 % 424 % MagickBooleanType SetImageRegistry(const RegistryType type, 425 % const char *key,const void *value,ExceptionInfo *exception) 426 % 427 % A description of each parameter follows: 428 % 429 % o type: the type. 430 % 431 % o key: the key. 432 % 433 % o value: the value. 434 % 435 % o exception: the exception. 436 % 437 */ 438 439 static void *DestroyRegistryNode(void *registry_info) 440 { 441 register RegistryInfo 442 *p; 443 444 p=(RegistryInfo *) registry_info; 445 switch (p->type) 446 { 447 case StringRegistryType: 448 default: 449 { 450 p->value=RelinquishMagickMemory(p->value); 451 break; 452 } 453 case ImageRegistryType: 454 { 455 p->value=(void *) DestroyImageList((Image *) p->value); 456 break; 457 } 458 case ImageInfoRegistryType: 459 { 460 p->value=(void *) DestroyImageInfo((ImageInfo *) p->value); 461 break; 462 } 463 } 464 return(RelinquishMagickMemory(p)); 465 } 466 467 MagickExport MagickBooleanType SetImageRegistry(const RegistryType type, 468 const char *key,const void *value,ExceptionInfo *exception) 469 { 470 MagickBooleanType 471 status; 472 473 RegistryInfo 474 *registry_info; 475 476 void 477 *clone_value; 478 479 if (IsEventLogging() != MagickFalse) 480 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key); 481 if (value == (const void *) NULL) 482 return(MagickFalse); 483 clone_value=(void *) NULL; 484 switch (type) 485 { 486 case StringRegistryType: 487 default: 488 { 489 const char 490 *string; 491 492 string=(const char *) value; 493 clone_value=(void *) ConstantString(string); 494 break; 495 } 496 case ImageRegistryType: 497 { 498 const Image 499 *image; 500 501 image=(const Image *) value; 502 if (image->signature != MagickCoreSignature) 503 { 504 (void) ThrowMagickException(exception,GetMagickModule(),RegistryError, 505 "UnableToSetRegistry","%s",key); 506 return(MagickFalse); 507 } 508 clone_value=(void *) CloneImageList(image,exception); 509 break; 510 } 511 case ImageInfoRegistryType: 512 { 513 const ImageInfo 514 *image_info; 515 516 image_info=(const ImageInfo *) value; 517 if (image_info->signature != MagickCoreSignature) 518 { 519 (void) ThrowMagickException(exception,GetMagickModule(),RegistryError, 520 "UnableToSetRegistry","%s",key); 521 return(MagickFalse); 522 } 523 clone_value=(void *) CloneImageInfo(image_info); 524 break; 525 } 526 } 527 if (clone_value == (void *) NULL) 528 return(MagickFalse); 529 registry_info=(RegistryInfo *) AcquireMagickMemory(sizeof(*registry_info)); 530 if (registry_info == (RegistryInfo *) NULL) 531 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 532 (void) ResetMagickMemory(registry_info,0,sizeof(*registry_info)); 533 registry_info->type=type; 534 registry_info->value=clone_value; 535 registry_info->signature=MagickCoreSignature; 536 if (registry == (SplayTreeInfo *) NULL) 537 { 538 if (registry_semaphore == (SemaphoreInfo *) NULL) 539 ActivateSemaphoreInfo(®istry_semaphore); 540 LockSemaphoreInfo(registry_semaphore); 541 if (registry == (SplayTreeInfo *) NULL) 542 registry=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory, 543 DestroyRegistryNode); 544 UnlockSemaphoreInfo(registry_semaphore); 545 } 546 status=AddValueToSplayTree(registry,ConstantString(key),registry_info); 547 return(status); 548 } 549