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-2019 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 % https://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/memory-private.h" 51 #include "MagickCore/registry.h" 52 #include "MagickCore/registry-private.h" 53 #include "MagickCore/splay-tree.h" 54 #include "MagickCore/string_.h" 55 #include "MagickCore/utility.h" 56 57 /* 59 Typedef declarations. 60 */ 61 typedef struct _RegistryInfo 62 { 63 RegistryType 64 type; 65 66 void 67 *value; 68 69 size_t 70 signature; 71 } RegistryInfo; 72 73 /* 75 Static declarations. 76 */ 77 static SplayTreeInfo 78 *registry = (SplayTreeInfo *) NULL; 79 80 static SemaphoreInfo 81 *registry_semaphore = (SemaphoreInfo *) NULL; 82 83 /* 85 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 86 % % 87 % % 88 % % 89 % D e f i n e I m a g e R e g i s t r y % 90 % % 91 % % 92 % % 93 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 94 % 95 % DefineImageRegistry() associates a key/value pair with the image registry. 96 % 97 % The format of the DefineImageRegistry method is: 98 % 99 % MagickBooleanType DefineImageRegistry(const RegistryType type, 100 % const char *option,ExceptionInfo *exception) 101 % 102 % A description of each parameter follows: 103 % 104 % o type: the type. 105 % 106 % o option: the option. 107 % 108 % o exception: the exception. 109 % 110 */ 111 MagickExport MagickBooleanType DefineImageRegistry(const RegistryType type, 112 const char *option,ExceptionInfo *exception) 113 { 114 char 115 key[MagickPathExtent], 116 value[MagickPathExtent]; 117 118 register char 119 *p; 120 121 assert(option != (const char *) NULL); 122 (void) CopyMagickString(key,option,MagickPathExtent); 123 for (p=key; *p != '\0'; p++) 124 if (*p == '=') 125 break; 126 *value='\0'; 127 if (*p == '=') 128 (void) CopyMagickString(value,p+1,MagickPathExtent); 129 *p='\0'; 130 return(SetImageRegistry(type,key,value,exception)); 131 } 132 133 /* 135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 136 % % 137 % % 138 % % 139 % D e l e t e I m a g e R e g i s t r y % 140 % % 141 % % 142 % % 143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 144 % 145 % DeleteImageRegistry() deletes a key from the image registry. 146 % 147 % The format of the DeleteImageRegistry method is: 148 % 149 % MagickBooleanType DeleteImageRegistry(const char *key) 150 % 151 % A description of each parameter follows: 152 % 153 % o key: the registry. 154 % 155 */ 156 MagickExport MagickBooleanType DeleteImageRegistry(const char *key) 157 { 158 if (IsEventLogging() != MagickFalse) 159 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key); 160 if (registry == (void *) NULL) 161 return(MagickFalse); 162 return(DeleteNodeFromSplayTree(registry,key)); 163 } 164 165 /* 167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 168 % % 169 % % 170 % % 171 % G e t I m a g e R e g i s t r y % 172 % % 173 % % 174 % % 175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 176 % 177 % GetImageRegistry() returns a value associated with an image registry key. 178 % 179 % The format of the GetImageRegistry method is: 180 % 181 % void *GetImageRegistry(const RegistryType type,const char *key, 182 % ExceptionInfo *exception) 183 % 184 % A description of each parameter follows: 185 % 186 % o type: the type. 187 % 188 % o key: the key. 189 % 190 % o exception: the exception. 191 % 192 */ 193 MagickExport void *GetImageRegistry(const RegistryType type,const char *key, 194 ExceptionInfo *exception) 195 { 196 void 197 *value; 198 199 RegistryInfo 200 *registry_info; 201 202 if (IsEventLogging() != MagickFalse) 203 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key); 204 if (registry == (void *) NULL) 205 return((void *) NULL); 206 registry_info=(RegistryInfo *) GetValueFromSplayTree(registry,key); 207 if (registry_info == (void *) NULL) 208 return((void *) NULL); 209 value=(void *) NULL; 210 switch (type) 211 { 212 case ImageRegistryType: 213 { 214 if (type == registry_info->type) 215 value=(void *) CloneImageList((Image *) registry_info->value,exception); 216 break; 217 } 218 case ImageInfoRegistryType: 219 { 220 if (type == registry_info->type) 221 value=(void *) CloneImageInfo((ImageInfo *) registry_info->value); 222 break; 223 } 224 case StringRegistryType: 225 { 226 switch (registry_info->type) 227 { 228 case ImageRegistryType: 229 { 230 value=(Image *) ConstantString(((Image *) 231 registry_info->value)->filename); 232 break; 233 } 234 case ImageInfoRegistryType: 235 { 236 value=(Image *) ConstantString(((ImageInfo *) 237 registry_info->value)->filename); 238 break; 239 } 240 case StringRegistryType: 241 { 242 value=(void *) ConstantString((char *) registry_info->value); 243 break; 244 } 245 default: 246 break; 247 } 248 break; 249 } 250 default: 251 break; 252 } 253 return(value); 254 } 255 256 /* 258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 259 % % 260 % % 261 % % 262 % G e t N e x t I m a g e R e g i s t r y % 263 % % 264 % % 265 % % 266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 267 % 268 % GetNextImageRegistry() gets the next image registry value. 269 % 270 % The format of the GetNextImageRegistry method is: 271 % 272 % char *GetNextImageRegistry(void) 273 % 274 */ 275 MagickExport char *GetNextImageRegistry(void) 276 { 277 if (IsEventLogging() != MagickFalse) 278 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 279 if (registry == (void *) NULL) 280 return((char *) NULL); 281 return((char *) GetNextKeyInSplayTree(registry)); 282 } 283 284 /* 286 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 287 % % 288 % % 289 % % 290 + R e g i s t r y C o m p o n e n t G e n e s i s % 291 % % 292 % % 293 % % 294 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 295 % 296 % RegistryComponentGenesis() instantiates the registry component. 297 % 298 % The format of the RegistryComponentGenesis method is: 299 % 300 % MagickBooleanType RegistryComponentGenesis(void) 301 % 302 */ 303 MagickPrivate MagickBooleanType RegistryComponentGenesis(void) 304 { 305 if (registry_semaphore == (SemaphoreInfo *) NULL) 306 registry_semaphore=AcquireSemaphoreInfo(); 307 return(MagickTrue); 308 } 309 310 /* 312 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 313 % % 314 % % 315 % % 316 % 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 % 317 % % 318 % % 319 % % 320 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 321 % 322 % RegistryComponentTerminus() destroys the registry component. 323 % 324 % The format of the DestroyDefines method is: 325 % 326 % void RegistryComponentTerminus(void) 327 % 328 */ 329 MagickPrivate void RegistryComponentTerminus(void) 330 { 331 if (registry_semaphore == (SemaphoreInfo *) NULL) 332 ActivateSemaphoreInfo(®istry_semaphore); 333 LockSemaphoreInfo(registry_semaphore); 334 if (IsEventLogging() != MagickFalse) 335 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 336 if (registry != (void *) NULL) 337 registry=DestroySplayTree(registry); 338 UnlockSemaphoreInfo(registry_semaphore); 339 RelinquishSemaphoreInfo(®istry_semaphore); 340 } 341 342 /* 344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 345 % % 346 % % 347 % % 348 % R e m o v e I m a g e R e g i s t r y % 349 % % 350 % % 351 % % 352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 353 % 354 % RemoveImageRegistry() removes a key from the image registry and returns its 355 % value. 356 % 357 % The format of the RemoveImageRegistry method is: 358 % 359 % void *RemoveImageRegistry(const char *key) 360 % 361 % A description of each parameter follows: 362 % 363 % o key: the registry. 364 % 365 */ 366 MagickExport void *RemoveImageRegistry(const char *key) 367 { 368 if (IsEventLogging() != MagickFalse) 369 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key); 370 if (registry == (void *) NULL) 371 return((void *) NULL); 372 return(RemoveNodeFromSplayTree(registry,key)); 373 } 374 375 /* 377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 378 % % 379 % % 380 % % 381 % 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 % 382 % % 383 % % 384 % % 385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 386 % 387 % ResetImageRegistryIterator() resets the registry iterator. Use it in 388 % conjunction with GetNextImageRegistry() to iterate over all the values 389 % in the image registry. 390 % 391 % The format of the ResetImageRegistryIterator method is: 392 % 393 % ResetImageRegistryIterator(void) 394 % 395 */ 396 MagickExport void ResetImageRegistryIterator(void) 397 { 398 if (IsEventLogging() != MagickFalse) 399 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 400 if (registry == (void *) NULL) 401 return; 402 ResetSplayTreeIterator(registry); 403 } 404 405 /* 407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 408 % % 409 % % 410 % % 411 % S e t I m a g e R e g i s t r y % 412 % % 413 % % 414 % % 415 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 416 % 417 % SetImageRegistry() associates a value with an image registry key. 418 % 419 % The format of the SetImageRegistry method is: 420 % 421 % MagickBooleanType SetImageRegistry(const RegistryType type, 422 % const char *key,const void *value,ExceptionInfo *exception) 423 % 424 % A description of each parameter follows: 425 % 426 % o type: the type. 427 % 428 % o key: the key. 429 % 430 % o value: the value. 431 % 432 % o exception: the exception. 433 % 434 */ 435 436 static void *DestroyRegistryNode(void *registry_info) 437 { 438 register RegistryInfo 439 *p; 440 441 p=(RegistryInfo *) registry_info; 442 switch (p->type) 443 { 444 case StringRegistryType: 445 default: 446 { 447 p->value=RelinquishMagickMemory(p->value); 448 break; 449 } 450 case ImageRegistryType: 451 { 452 p->value=(void *) DestroyImageList((Image *) p->value); 453 break; 454 } 455 case ImageInfoRegistryType: 456 { 457 p->value=(void *) DestroyImageInfo((ImageInfo *) p->value); 458 break; 459 } 460 } 461 return(RelinquishMagickMemory(p)); 462 } 463 464 MagickExport MagickBooleanType SetImageRegistry(const RegistryType type, 465 const char *key,const void *value,ExceptionInfo *exception) 466 { 467 MagickBooleanType 468 status; 469 470 RegistryInfo 471 *registry_info; 472 473 void 474 *clone_value; 475 476 if (IsEventLogging() != MagickFalse) 477 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key); 478 if (value == (const void *) NULL) 479 return(MagickFalse); 480 clone_value=(void *) NULL; 481 switch (type) 482 { 483 case StringRegistryType: 484 default: 485 { 486 const char 487 *string; 488 489 string=(const char *) value; 490 clone_value=(void *) ConstantString(string); 491 break; 492 } 493 case ImageRegistryType: 494 { 495 const Image 496 *image; 497 498 image=(const Image *) value; 499 if (image->signature != MagickCoreSignature) 500 { 501 (void) ThrowMagickException(exception,GetMagickModule(),RegistryError, 502 "UnableToSetRegistry","%s",key); 503 return(MagickFalse); 504 } 505 clone_value=(void *) CloneImageList(image,exception); 506 break; 507 } 508 case ImageInfoRegistryType: 509 { 510 const ImageInfo 511 *image_info; 512 513 image_info=(const ImageInfo *) value; 514 if (image_info->signature != MagickCoreSignature) 515 { 516 (void) ThrowMagickException(exception,GetMagickModule(),RegistryError, 517 "UnableToSetRegistry","%s",key); 518 return(MagickFalse); 519 } 520 clone_value=(void *) CloneImageInfo(image_info); 521 break; 522 } 523 } 524 if (clone_value == (void *) NULL) 525 return(MagickFalse); 526 registry_info=(RegistryInfo *) AcquireCriticalMemory(sizeof(*registry_info)); 527 (void) memset(registry_info,0,sizeof(*registry_info)); 528 registry_info->type=type; 529 registry_info->value=clone_value; 530 registry_info->signature=MagickCoreSignature; 531 if (registry == (SplayTreeInfo *) NULL) 532 { 533 if (registry_semaphore == (SemaphoreInfo *) NULL) 534 ActivateSemaphoreInfo(®istry_semaphore); 535 LockSemaphoreInfo(registry_semaphore); 536 if (registry == (SplayTreeInfo *) NULL) 537 registry=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory, 538 DestroyRegistryNode); 539 UnlockSemaphoreInfo(registry_semaphore); 540 } 541 status=AddValueToSplayTree(registry,ConstantString(key),registry_info); 542 return(status); 543 } 544