|
|
/*
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
% RRRR EEEEE GGG IIIII SSSSS TTTTT RRRR Y Y %
|
|
|
% R R E G I SS T R R Y Y %
|
|
|
% RRRR EEE G GGG I SSS T RRRR Y %
|
|
|
% R R E G G I SS T R R Y %
|
|
|
% R R EEEEE GGG IIIII SSSSS T R R Y %
|
|
|
% %
|
|
|
% %
|
|
|
% MagickCore Registry Methods %
|
|
|
% %
|
|
|
% Software Design %
|
|
|
% Cristy %
|
|
|
% March 2000 %
|
|
|
% %
|
|
|
% %
|
|
|
% Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization %
|
|
|
% dedicated to making software imaging solutions freely available. %
|
|
|
% %
|
|
|
% You may not use this file except in compliance with the License. You may %
|
|
|
% obtain a copy of the License at %
|
|
|
% %
|
|
|
% https://imagemagick.org/script/license.php %
|
|
|
% %
|
|
|
% Unless required by applicable law or agreed to in writing, software %
|
|
|
% distributed under the License is distributed on an "AS IS" BASIS, %
|
|
|
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
|
|
|
% See the License for the specific language governing permissions and %
|
|
|
% limitations under the License. %
|
|
|
% %
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
%
|
|
|
%
|
|
|
%
|
|
|
*/
|
|
|
|
|
|
/*
|
|
|
Include declarations.
|
|
|
*/
|
|
|
#include "MagickCore/studio.h"
|
|
|
#include "MagickCore/exception.h"
|
|
|
#include "MagickCore/exception-private.h"
|
|
|
#include "MagickCore/image.h"
|
|
|
#include "MagickCore/list.h"
|
|
|
#include "MagickCore/memory_.h"
|
|
|
#include "MagickCore/memory-private.h"
|
|
|
#include "MagickCore/registry.h"
|
|
|
#include "MagickCore/registry-private.h"
|
|
|
#include "MagickCore/splay-tree.h"
|
|
|
#include "MagickCore/string_.h"
|
|
|
#include "MagickCore/utility.h"
|
|
|
|
|
|
/*
|
|
|
Typedef declarations.
|
|
|
*/
|
|
|
typedef struct _RegistryInfo
|
|
|
{
|
|
|
RegistryType
|
|
|
type;
|
|
|
|
|
|
void
|
|
|
*value;
|
|
|
|
|
|
size_t
|
|
|
signature;
|
|
|
} RegistryInfo;
|
|
|
|
|
|
/*
|
|
|
Static declarations.
|
|
|
*/
|
|
|
static SplayTreeInfo
|
|
|
*registry = (SplayTreeInfo *) NULL;
|
|
|
|
|
|
static SemaphoreInfo
|
|
|
*registry_semaphore = (SemaphoreInfo *) NULL;
|
|
|
|
|
|
/*
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
% D e f i n e I m a g e R e g i s t r y %
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
%
|
|
|
% DefineImageRegistry() associates a key/value pair with the image registry.
|
|
|
%
|
|
|
% The format of the DefineImageRegistry method is:
|
|
|
%
|
|
|
% MagickBooleanType DefineImageRegistry(const RegistryType type,
|
|
|
% const char *option,ExceptionInfo *exception)
|
|
|
%
|
|
|
% A description of each parameter follows:
|
|
|
%
|
|
|
% o type: the type.
|
|
|
%
|
|
|
% o option: the option.
|
|
|
%
|
|
|
% o exception: the exception.
|
|
|
%
|
|
|
*/
|
|
|
MagickExport MagickBooleanType DefineImageRegistry(const RegistryType type,
|
|
|
const char *option,ExceptionInfo *exception)
|
|
|
{
|
|
|
char
|
|
|
key[MagickPathExtent],
|
|
|
value[MagickPathExtent];
|
|
|
|
|
|
char
|
|
|
*p;
|
|
|
|
|
|
assert(option != (const char *) NULL);
|
|
|
(void) CopyMagickString(key,option,MagickPathExtent);
|
|
|
for (p=key; *p != '\0'; p++)
|
|
|
if (*p == '=')
|
|
|
break;
|
|
|
*value='\0';
|
|
|
if (*p == '=')
|
|
|
(void) CopyMagickString(value,p+1,MagickPathExtent);
|
|
|
*p='\0';
|
|
|
return(SetImageRegistry(type,key,value,exception));
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
% D e l e t e I m a g e R e g i s t r y %
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
%
|
|
|
% DeleteImageRegistry() deletes a key from the image registry.
|
|
|
%
|
|
|
% The format of the DeleteImageRegistry method is:
|
|
|
%
|
|
|
% MagickBooleanType DeleteImageRegistry(const char *key)
|
|
|
%
|
|
|
% A description of each parameter follows:
|
|
|
%
|
|
|
% o key: the registry.
|
|
|
%
|
|
|
*/
|
|
|
MagickExport MagickBooleanType DeleteImageRegistry(const char *key)
|
|
|
{
|
|
|
if (IsEventLogging() != MagickFalse)
|
|
|
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
|
|
|
if (registry == (void *) NULL)
|
|
|
return(MagickFalse);
|
|
|
return(DeleteNodeFromSplayTree(registry,key));
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
% G e t I m a g e R e g i s t r y %
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
%
|
|
|
% GetImageRegistry() returns a value associated with an image registry key.
|
|
|
%
|
|
|
% The format of the GetImageRegistry method is:
|
|
|
%
|
|
|
% void *GetImageRegistry(const RegistryType type,const char *key,
|
|
|
% ExceptionInfo *exception)
|
|
|
%
|
|
|
% A description of each parameter follows:
|
|
|
%
|
|
|
% o type: the type.
|
|
|
%
|
|
|
% o key: the key.
|
|
|
%
|
|
|
% o exception: the exception.
|
|
|
%
|
|
|
*/
|
|
|
MagickExport void *GetImageRegistry(const RegistryType type,const char *key,
|
|
|
ExceptionInfo *exception)
|
|
|
{
|
|
|
void
|
|
|
*value;
|
|
|
|
|
|
RegistryInfo
|
|
|
*registry_info;
|
|
|
|
|
|
if (IsEventLogging() != MagickFalse)
|
|
|
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
|
|
|
if (registry == (void *) NULL)
|
|
|
return((void *) NULL);
|
|
|
registry_info=(RegistryInfo *) GetValueFromSplayTree(registry,key);
|
|
|
if (registry_info == (void *) NULL)
|
|
|
return((void *) NULL);
|
|
|
value=(void *) NULL;
|
|
|
switch (type)
|
|
|
{
|
|
|
case ImageRegistryType:
|
|
|
{
|
|
|
if (type == registry_info->type)
|
|
|
value=(void *) CloneImageList((Image *) registry_info->value,exception);
|
|
|
break;
|
|
|
}
|
|
|
case ImageInfoRegistryType:
|
|
|
{
|
|
|
if (type == registry_info->type)
|
|
|
value=(void *) CloneImageInfo((ImageInfo *) registry_info->value);
|
|
|
break;
|
|
|
}
|
|
|
case StringRegistryType:
|
|
|
{
|
|
|
switch (registry_info->type)
|
|
|
{
|
|
|
case ImageRegistryType:
|
|
|
{
|
|
|
value=(Image *) ConstantString(((Image *)
|
|
|
registry_info->value)->filename);
|
|
|
break;
|
|
|
}
|
|
|
case ImageInfoRegistryType:
|
|
|
{
|
|
|
value=(Image *) ConstantString(((ImageInfo *)
|
|
|
registry_info->value)->filename);
|
|
|
break;
|
|
|
}
|
|
|
case StringRegistryType:
|
|
|
{
|
|
|
value=(void *) ConstantString((char *) registry_info->value);
|
|
|
break;
|
|
|
}
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
return(value);
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
% G e t N e x t I m a g e R e g i s t r y %
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
%
|
|
|
% GetNextImageRegistry() gets the next image registry value.
|
|
|
%
|
|
|
% The format of the GetNextImageRegistry method is:
|
|
|
%
|
|
|
% char *GetNextImageRegistry(void)
|
|
|
%
|
|
|
*/
|
|
|
MagickExport char *GetNextImageRegistry(void)
|
|
|
{
|
|
|
if (IsEventLogging() != MagickFalse)
|
|
|
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
|
|
|
if (registry == (void *) NULL)
|
|
|
return((char *) NULL);
|
|
|
return((char *) GetNextKeyInSplayTree(registry));
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
+ R e g i s t r y C o m p o n e n t G e n e s i s %
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
%
|
|
|
% RegistryComponentGenesis() instantiates the registry component.
|
|
|
%
|
|
|
% The format of the RegistryComponentGenesis method is:
|
|
|
%
|
|
|
% MagickBooleanType RegistryComponentGenesis(void)
|
|
|
%
|
|
|
*/
|
|
|
MagickPrivate MagickBooleanType RegistryComponentGenesis(void)
|
|
|
{
|
|
|
if (registry_semaphore == (SemaphoreInfo *) NULL)
|
|
|
registry_semaphore=AcquireSemaphoreInfo();
|
|
|
return(MagickTrue);
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
% 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 %
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
%
|
|
|
% RegistryComponentTerminus() destroys the registry component.
|
|
|
%
|
|
|
% The format of the DestroyDefines method is:
|
|
|
%
|
|
|
% void RegistryComponentTerminus(void)
|
|
|
%
|
|
|
*/
|
|
|
MagickPrivate void RegistryComponentTerminus(void)
|
|
|
{
|
|
|
if (registry_semaphore == (SemaphoreInfo *) NULL)
|
|
|
ActivateSemaphoreInfo(®istry_semaphore);
|
|
|
LockSemaphoreInfo(registry_semaphore);
|
|
|
if (IsEventLogging() != MagickFalse)
|
|
|
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
|
|
|
if (registry != (void *) NULL)
|
|
|
registry=DestroySplayTree(registry);
|
|
|
UnlockSemaphoreInfo(registry_semaphore);
|
|
|
RelinquishSemaphoreInfo(®istry_semaphore);
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
% R e m o v e I m a g e R e g i s t r y %
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
%
|
|
|
% RemoveImageRegistry() removes a key from the image registry and returns its
|
|
|
% value.
|
|
|
%
|
|
|
% The format of the RemoveImageRegistry method is:
|
|
|
%
|
|
|
% void *RemoveImageRegistry(const char *key)
|
|
|
%
|
|
|
% A description of each parameter follows:
|
|
|
%
|
|
|
% o key: the registry.
|
|
|
%
|
|
|
*/
|
|
|
MagickExport void *RemoveImageRegistry(const char *key)
|
|
|
{
|
|
|
if (IsEventLogging() != MagickFalse)
|
|
|
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
|
|
|
if (registry == (void *) NULL)
|
|
|
return((void *) NULL);
|
|
|
return(RemoveNodeFromSplayTree(registry,key));
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
% 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 %
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
%
|
|
|
% ResetImageRegistryIterator() resets the registry iterator. Use it in
|
|
|
% conjunction with GetNextImageRegistry() to iterate over all the values
|
|
|
% in the image registry.
|
|
|
%
|
|
|
% The format of the ResetImageRegistryIterator method is:
|
|
|
%
|
|
|
% ResetImageRegistryIterator(void)
|
|
|
%
|
|
|
*/
|
|
|
MagickExport void ResetImageRegistryIterator(void)
|
|
|
{
|
|
|
if (IsEventLogging() != MagickFalse)
|
|
|
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
|
|
|
if (registry == (void *) NULL)
|
|
|
return;
|
|
|
ResetSplayTreeIterator(registry);
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
% S e t I m a g e R e g i s t r y %
|
|
|
% %
|
|
|
% %
|
|
|
% %
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
%
|
|
|
% SetImageRegistry() associates a value with an image registry key.
|
|
|
%
|
|
|
% The format of the SetImageRegistry method is:
|
|
|
%
|
|
|
% MagickBooleanType SetImageRegistry(const RegistryType type,
|
|
|
% const char *key,const void *value,ExceptionInfo *exception)
|
|
|
%
|
|
|
% A description of each parameter follows:
|
|
|
%
|
|
|
% o type: the type.
|
|
|
%
|
|
|
% o key: the key.
|
|
|
%
|
|
|
% o value: the value.
|
|
|
%
|
|
|
% o exception: the exception.
|
|
|
%
|
|
|
*/
|
|
|
|
|
|
static void *DestroyRegistryNode(void *registry_info)
|
|
|
{
|
|
|
RegistryInfo
|
|
|
*p;
|
|
|
|
|
|
p=(RegistryInfo *) registry_info;
|
|
|
switch (p->type)
|
|
|
{
|
|
|
case StringRegistryType:
|
|
|
default:
|
|
|
{
|
|
|
p->value=RelinquishMagickMemory(p->value);
|
|
|
break;
|
|
|
}
|
|
|
case ImageRegistryType:
|
|
|
{
|
|
|
p->value=(void *) DestroyImageList((Image *) p->value);
|
|
|
break;
|
|
|
}
|
|
|
case ImageInfoRegistryType:
|
|
|
{
|
|
|
p->value=(void *) DestroyImageInfo((ImageInfo *) p->value);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
return(RelinquishMagickMemory(p));
|
|
|
}
|
|
|
|
|
|
MagickExport MagickBooleanType SetImageRegistry(const RegistryType type,
|
|
|
const char *key,const void *value,ExceptionInfo *exception)
|
|
|
{
|
|
|
MagickBooleanType
|
|
|
status;
|
|
|
|
|
|
RegistryInfo
|
|
|
*registry_info;
|
|
|
|
|
|
void
|
|
|
*clone_value;
|
|
|
|
|
|
if (IsEventLogging() != MagickFalse)
|
|
|
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",key);
|
|
|
if (value == (const void *) NULL)
|
|
|
return(MagickFalse);
|
|
|
clone_value=(void *) NULL;
|
|
|
switch (type)
|
|
|
{
|
|
|
case StringRegistryType:
|
|
|
default:
|
|
|
{
|
|
|
const char
|
|
|
*string;
|
|
|
|
|
|
string=(const char *) value;
|
|
|
clone_value=(void *) ConstantString(string);
|
|
|
break;
|
|
|
}
|
|
|
case ImageRegistryType:
|
|
|
{
|
|
|
const Image
|
|
|
*image;
|
|
|
|
|
|
image=(const Image *) value;
|
|
|
if (image->signature != MagickCoreSignature)
|
|
|
{
|
|
|
(void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
|
|
|
"UnableToSetRegistry","%s",key);
|
|
|
return(MagickFalse);
|
|
|
}
|
|
|
clone_value=(void *) CloneImageList(image,exception);
|
|
|
break;
|
|
|
}
|
|
|
case ImageInfoRegistryType:
|
|
|
{
|
|
|
const ImageInfo
|
|
|
*image_info;
|
|
|
|
|
|
image_info=(const ImageInfo *) value;
|
|
|
if (image_info->signature != MagickCoreSignature)
|
|
|
{
|
|
|
(void) ThrowMagickException(exception,GetMagickModule(),RegistryError,
|
|
|
"UnableToSetRegistry","%s",key);
|
|
|
return(MagickFalse);
|
|
|
}
|
|
|
clone_value=(void *) CloneImageInfo(image_info);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
if (clone_value == (void *) NULL)
|
|
|
return(MagickFalse);
|
|
|
registry_info=(RegistryInfo *) AcquireCriticalMemory(sizeof(*registry_info));
|
|
|
(void) memset(registry_info,0,sizeof(*registry_info));
|
|
|
registry_info->type=type;
|
|
|
registry_info->value=clone_value;
|
|
|
registry_info->signature=MagickCoreSignature;
|
|
|
if (registry == (SplayTreeInfo *) NULL)
|
|
|
{
|
|
|
if (registry_semaphore == (SemaphoreInfo *) NULL)
|
|
|
ActivateSemaphoreInfo(®istry_semaphore);
|
|
|
LockSemaphoreInfo(registry_semaphore);
|
|
|
if (registry == (SplayTreeInfo *) NULL)
|
|
|
registry=NewSplayTree(CompareSplayTreeString,RelinquishMagickMemory,
|
|
|
DestroyRegistryNode);
|
|
|
UnlockSemaphoreInfo(registry_semaphore);
|
|
|
}
|
|
|
status=AddValueToSplayTree(registry,ConstantString(key),registry_info);
|
|
|
return(status);
|
|
|
}
|