text: /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   L      IIIII  N   N  K   K  EEEEE  DDDD      L      IIIII  SSSSS  TTTTT   %
  %   L        I    NN  N  K  K   E      D   D     L        I    SS       T     %
  %   L        I    N N N  KKK    EEE    D   D  =  L        I     SSS     T     %
  %   L        I    N  NN  K  K   E      D   D     L        I       SS    T     %
  %   LLLLL  IIIII  N   N  K   K  EEEEE  DDDD      LLLLL  IIIII  SSSSS    T     %
  %                                                                             %
  %                                                                             %
  %                  MagickCore Linked-list Methods                             %
  %                                                                             %
  %                              Software Design                                %
  %                                   Cristy                                    %
  %                               December 2002                                 %
  %                                                                             %
  %                                                                             %
  %  Copyright 1999-2017 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://www.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.                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  This module implements the standard handy hash and linked-list methods for
  %  storing and retrieving large numbers of data elements.  It is loosely based
  %  on the Java implementation of these algorithms.
  %
  */
  
  /*
    Include declarations.
  */
  #include "MagickCore/studio.h"
  #include "MagickCore/exception.h"
  #include "MagickCore/exception-private.h"
  #include "MagickCore/linked-list.h"
  #include "MagickCore/locale_.h"
  #include "MagickCore/memory_.h"
  #include "MagickCore/semaphore.h"
  #include "MagickCore/signature-private.h"
  #include "MagickCore/string_.h"
  
  /*
    Typedef declarations.
  */
  typedef struct _ElementInfo
  {
    void
      *value;
  
    struct _ElementInfo
      *next;
  } ElementInfo;
  
  struct _LinkedListInfo
  {
    size_t
      capacity,
      elements;
  
    ElementInfo
      *head,
      *tail,
      *next;
  
    SemaphoreInfo
      *semaphore;
  
    size_t
      signature;
  };
  
  /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   A p p e n d V a l u e T o L i n k e d L i s t                             %
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  AppendValueToLinkedList() appends a value to the end of the linked-list.
  %
  %  The format of the AppendValueToLinkedList method is:
  %
  %      MagickBooleanType AppendValueToLinkedList(LinkedListInfo *list_info,
  %        const void *value)
  %
  %  A description of each parameter follows:
  %
  %    o list_info: the linked-list info.
  %
  %    o value: the value.
  %
  */
  MagickExport MagickBooleanType AppendValueToLinkedList(
    LinkedListInfo *list_info,const void *value)
  {
    register ElementInfo
      *next;
  
    assert(list_info != (LinkedListInfo *) NULL);
    assert(list_info->signature == MagickCoreSignature);
    if (list_info->elements == list_info->capacity)
      return(MagickFalse);
    next=(ElementInfo *) AcquireMagickMemory(sizeof(*next));
    if (next == (ElementInfo *) NULL)
      return(MagickFalse);
    next->value=(void *) value;
    next->next=(ElementInfo *) NULL;
    LockSemaphoreInfo(list_info->semaphore);
    if (list_info->next == (ElementInfo *) NULL)
      list_info->next=next;
    if (list_info->elements == 0)
      list_info->head=next;
    else
      list_info->tail->next=next;
    list_info->tail=next;
    list_info->elements++;
    UnlockSemaphoreInfo(list_info->semaphore);
    return(MagickTrue);
  }
  
  /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   C l e a r L i n k e d L i s t                                             %
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  ClearLinkedList() clears all the elements from the linked-list.
  %
  %  The format of the ClearLinkedList method is:
  %
  %      void ClearLinkedList(LinkedListInfo *list_info,
  %        void *(*relinquish_value)(void *))
  %
  %  A description of each parameter follows:
  %
  %    o list_info: the linked-list info.
  %
  %    o relinquish_value: the value deallocation method; typically
  %      RelinquishMagickMemory().
  %
  */
  MagickExport void ClearLinkedList(LinkedListInfo *list_info,
    void *(*relinquish_value)(void *))
  {
    ElementInfo
      *element;
  
    register ElementInfo
      *next;
  
    assert(list_info != (LinkedListInfo *) NULL);
    assert(list_info->signature == MagickCoreSignature);
    LockSemaphoreInfo(list_info->semaphore);
    next=list_info->head;
    while (next != (ElementInfo *) NULL)
    {
      if (relinquish_value != (void *(*)(void *)) NULL)
        next->value=relinquish_value(next->value);
      element=next;
      next=next->next;
      element=(ElementInfo *) RelinquishMagickMemory(element);
    }
    list_info->head=(ElementInfo *) NULL;
    list_info->tail=(ElementInfo *) NULL;
    list_info->next=(ElementInfo *) NULL;
    list_info->elements=0;
    UnlockSemaphoreInfo(list_info->semaphore);
  }
  
  /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   D e s t r o y L i n k e d L i s t                                         %
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  DestroyLinkedList() frees the linked-list and all associated resources.
  %
  %  The format of the DestroyLinkedList method is:
  %
  %      LinkedListInfo *DestroyLinkedList(LinkedListInfo *list_info,
  %        void *(*relinquish_value)(void *))
  %
  %  A description of each parameter follows:
  %
  %    o list_info: the linked-list info.
  %
  %    o relinquish_value: the value deallocation method;  typically
  %      RelinquishMagickMemory().
  %
  */
  MagickExport LinkedListInfo *DestroyLinkedList(LinkedListInfo *list_info,
    void *(*relinquish_value)(void *))
  {
    ElementInfo
      *entry;
  
    register ElementInfo
      *next;
  
    assert(list_info != (LinkedListInfo *) NULL);
    assert(list_info->signature == MagickCoreSignature);
    LockSemaphoreInfo(list_info->semaphore);
    for (next=list_info->head; next != (ElementInfo *) NULL; )
    {
      if (relinquish_value != (void *(*)(void *)) NULL)
        next->value=relinquish_value(next->value);
      entry=next;
      next=next->next;
      entry=(ElementInfo *) RelinquishMagickMemory(entry);
    }
    list_info->signature=(~MagickCoreSignature);
    UnlockSemaphoreInfo(list_info->semaphore);
    RelinquishSemaphoreInfo(&list_info->semaphore);
    list_info=(LinkedListInfo *) RelinquishMagickMemory(list_info);
    return(list_info);
  }
  
  /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   G e t L a s t V a l u e I n L i n k e d L i s t                           %
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  GetLastValueInLinkedList() gets the last value in the linked-list.
  %
  %  The format of the GetLastValueInLinkedList method is:
  %
  %      void *GetLastValueInLinkedList(LinkedListInfo *list_info)
  %
  %  A description of each parameter follows:
  %
  %    o list_info: the linked_list info.
  %
  */
  MagickExport void *GetLastValueInLinkedList(LinkedListInfo *list_info)
  {
    void
      *value;
  
    assert(list_info != (LinkedListInfo *) NULL);
    assert(list_info->signature == MagickCoreSignature);
    if (list_info->elements == 0)
      return((void *) NULL);
    LockSemaphoreInfo(list_info->semaphore);
    value=list_info->tail->value;
    UnlockSemaphoreInfo(list_info->semaphore);
    return(value);
  }
  
  /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   G e t N e x t V a l u e I n L i n k e d L i s t                           %
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  GetNextValueInLinkedList() gets the next value in the linked-list.
  %
  %  The format of the GetNextValueInLinkedList method is:
  %
  %      void *GetNextValueInLinkedList(LinkedListInfo *list_info)
  %
  %  A description of each parameter follows:
  %
  %    o list_info: the linked-list info.
  %
  */
  MagickExport void *GetNextValueInLinkedList(LinkedListInfo *list_info)
  {
    void
      *value;
  
    assert(list_info != (LinkedListInfo *) NULL);
    assert(list_info->signature == MagickCoreSignature);
    LockSemaphoreInfo(list_info->semaphore);
    if (list_info->next == (ElementInfo *) NULL)
      {
        UnlockSemaphoreInfo(list_info->semaphore);
        return((void *) NULL);
      }
    value=list_info->next->value;
    list_info->next=list_info->next->next;
    UnlockSemaphoreInfo(list_info->semaphore);
    return(value);
  }
  
  /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   G e t N u m b e r O f E l e m e n t s I n L i n k e d L i s t             %
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  GetNumberOfElementsInLinkedList() returns the number of entries in the
  %  linked-list.
  %
  %  The format of the GetNumberOfElementsInLinkedList method is:
  %
  %      size_t GetNumberOfElementsInLinkedList(
  %        const LinkedListInfo *list_info)
  %
  %  A description of each parameter follows:
  %
  %    o list_info: the linked-list info.
  %
  */
  MagickExport size_t GetNumberOfElementsInLinkedList(
    const LinkedListInfo *list_info)
  {
    assert(list_info != (LinkedListInfo *) NULL);
    assert(list_info->signature == MagickCoreSignature);
    return(list_info->elements);
  }
  
  /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   G e t V a l u e F r o m L i n k e d L i s t                               %
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  GetValueFromLinkedList() gets a value from the linked-list at the specified
  %  location.
  %
  %  The format of the GetValueFromLinkedList method is:
  %
  %      void *GetValueFromLinkedList(LinkedListInfo *list_info,
  %        const size_t index)
  %
  %  A description of each parameter follows:
  %
  %    o list_info: the linked_list info.
  %
  %    o index: the list index.
  %
  */
  MagickExport void *GetValueFromLinkedList(LinkedListInfo *list_info,
    const size_t index)
  {
    register ElementInfo
      *next;
  
    register ssize_t
      i;
  
    void
      *value;
  
    assert(list_info != (LinkedListInfo *) NULL);
    assert(list_info->signature == MagickCoreSignature);
    if (index >= list_info->elements)
      return((void *) NULL);
    LockSemaphoreInfo(list_info->semaphore);
    if (index == 0)
      {
        value=list_info->head->value;
        UnlockSemaphoreInfo(list_info->semaphore);
        return(value);
      }
    if (index == (list_info->elements-1))
      {
        value=list_info->tail->value;
        UnlockSemaphoreInfo(list_info->semaphore);
        return(value);
      }
    next=list_info->head;
    for (i=0; i < (ssize_t) index; i++)
      next=next->next;
    value=next->value;
    UnlockSemaphoreInfo(list_info->semaphore);
    return(value);
  }
  
  /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   I n s e r t V a l u e I n L i n k e d L i s t                             %
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  InsertValueInLinkedList() inserts an element in the linked-list at the
  %  specified location.
  %
  %  The format of the InsertValueInLinkedList method is:
  %
  %      MagickBooleanType InsertValueInLinkedList(ListInfo *list_info,
  %        const size_t index,const void *value)
  %
  %  A description of each parameter follows:
  %
  %    o list_info: the hashmap info.
  %
  %    o index: the index.
  %
  %    o value: the value.
  %
  */
  MagickExport MagickBooleanType InsertValueInLinkedList(
    LinkedListInfo *list_info,const size_t index,const void *value)
  {
    register ElementInfo
      *next;
  
    register ssize_t
      i;
  
    assert(list_info != (LinkedListInfo *) NULL);
    assert(list_info->signature == MagickCoreSignature);
    if (value == (const void *) NULL)
      return(MagickFalse);
    if ((index > list_info->elements) ||
        (list_info->elements == list_info->capacity))
      return(MagickFalse);
    next=(ElementInfo *) AcquireMagickMemory(sizeof(*next));
    if (next == (ElementInfo *) NULL)
      return(MagickFalse);
    next->value=(void *) value;
    next->next=(ElementInfo *) NULL;
    LockSemaphoreInfo(list_info->semaphore);
    if (list_info->elements == 0)
      {
        if (list_info->next == (ElementInfo *) NULL)
          list_info->next=next;
        list_info->head=next;
        list_info->tail=next;
      }
    else
      {
        if (index == 0)
          {
            if (list_info->next == list_info->head)
              list_info->next=next;
            next->next=list_info->head;
            list_info->head=next;
          }
        else
          if (index == list_info->elements)
            {
              if (list_info->next == (ElementInfo *) NULL)
                list_info->next=next;
              list_info->tail->next=next;
              list_info->tail=next;
            }
          else
            {
              ElementInfo
                *element;
  
              element=list_info->head;
              next->next=element->next;
              for (i=1; i < (ssize_t) index; i++)
              {
                element=element->next;
                next->next=element->next;
              }
              next=next->next;
              element->next=next;
              if (list_info->next == next->next)
                list_info->next=next;
            }
      }
    list_info->elements++;
    UnlockSemaphoreInfo(list_info->semaphore);
    return(MagickTrue);
  }
  
  /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   I n s e r t V a l u e I n S o r t e d L i n k e d L i s t                 %
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  InsertValueInSortedLinkedList() inserts a value in the sorted linked-list.
  %
  %  The format of the InsertValueInSortedLinkedList method is:
  %
  %      MagickBooleanType InsertValueInSortedLinkedList(ListInfo *list_info,
  %        int (*compare)(const void *,const void *),void **replace,
  %        const void *value)
  %
  %  A description of each parameter follows:
  %
  %    o list_info: the hashmap info.
  %
  %    o index: the index.
  %
  %    o compare: the compare method.
  %
  %    o replace: return previous element here.
  %
  %    o value: the value.
  %
  */
  MagickExport MagickBooleanType InsertValueInSortedLinkedList(
    LinkedListInfo *list_info,int (*compare)(const void *,const void *),
    void **replace,const void *value)
  {
    ElementInfo
      *element;
  
    register ElementInfo
      *next;
  
    register ssize_t
      i;
  
    assert(list_info != (LinkedListInfo *) NULL);
    assert(list_info->signature == MagickCoreSignature);
    if ((compare == (int (*)(const void *,const void *)) NULL) ||
        (value == (const void *) NULL))
      return(MagickFalse);
    if (list_info->elements == list_info->capacity)
      return(MagickFalse);
    next=(ElementInfo *) AcquireMagickMemory(sizeof(*next));
    if (next == (ElementInfo *) NULL)
      return(MagickFalse);
    next->value=(void *) value;
    element=(ElementInfo *) NULL;
    LockSemaphoreInfo(list_info->semaphore);
    next->next=list_info->head;
    while (next->next != (ElementInfo *) NULL)
    {
      i=(ssize_t) compare(value,next->next->value);
      if ((i < 0) || ((replace != (void **) NULL) && (i == 0)))
        {
          if (i == 0)
            {
              *replace=next->next->value;
              next->next=next->next->next;
              if (element != (ElementInfo *) NULL)
                element->next=(ElementInfo *) RelinquishMagickMemory(
                  element->next);
              list_info->elements--;
            }
          if (element != (ElementInfo *) NULL)
            element->next=next;
          else
            list_info->head=next;
          break;
        }
      element=next->next;
      next->next=next->next->next;
    }
    if (next->next == (ElementInfo *) NULL)
      {
        if (element != (ElementInfo *) NULL)
          element->next=next;
        else
          list_info->head=next;
        list_info->tail=next;
      }
    list_info->elements++;
    UnlockSemaphoreInfo(list_info->semaphore);
    return(MagickTrue);
  }
  
  /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   I s L i n k e d L i s t E m p t y                                         %
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  IsLinkedListEmpty() returns MagickTrue if the linked-list is empty.
  %
  %  The format of the IsLinkedListEmpty method is:
  %
  %      MagickBooleanType IsLinkedListEmpty(LinkedListInfo *list_info)
  %
  %  A description of each parameter follows:
  %
  %    o list_info: the linked-list info.
  %
  */
  MagickExport MagickBooleanType IsLinkedListEmpty(
    const LinkedListInfo *list_info)
  {
    assert(list_info != (LinkedListInfo *) NULL);
    assert(list_info->signature == MagickCoreSignature);
    return(list_info->elements == 0 ? MagickTrue : MagickFalse);
  }
  
  /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   L i n k e d L i s t T o A r r a y                                         %
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  LinkedListToArray() converts the linked-list to an array.
  %
  %  The format of the LinkedListToArray method is:
  %
  %      MagickBooleanType LinkedListToArray(LinkedListInfo *list_info,
  %        void **array)
  %
  %  A description of each parameter follows:
  %
  %    o list_info: the linked-list info.
  %
  %    o array: the array.
  %
  */
  MagickExport MagickBooleanType LinkedListToArray(LinkedListInfo *list_info,
    void **array)
  {
    register ElementInfo
      *next;
  
    register ssize_t
      i;
  
    assert(list_info != (LinkedListInfo *) NULL);
    assert(list_info->signature == MagickCoreSignature);
    if (array == (void **) NULL)
      return(MagickFalse);
    LockSemaphoreInfo(list_info->semaphore);
    next=list_info->head;
    for (i=0; next != (ElementInfo *) NULL; i++)
    {
      array[i]=next->value;
      next=next->next;
    }
    UnlockSemaphoreInfo(list_info->semaphore);
    return(MagickTrue);
  }
  
  /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   N e w L i n k e d L i s t I n f o                                         %
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  NewLinkedList() returns a pointer to a LinkedListInfo structure
  %  initialized to default values.
  %
  %  The format of the NewLinkedList method is:
  %
  %      LinkedListInfo *NewLinkedList(const size_t capacity)
  %
  %  A description of each parameter follows:
  %
  %    o capacity: the maximum number of elements in the list.
  %
  */
  MagickExport LinkedListInfo *NewLinkedList(const size_t capacity)
  {
    LinkedListInfo
      *list_info;
  
    list_info=(LinkedListInfo *) AcquireMagickMemory(sizeof(*list_info));
    if (list_info == (LinkedListInfo *) NULL)
      ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
    (void) ResetMagickMemory(list_info,0,sizeof(*list_info));
    list_info->capacity=capacity == 0 ? (size_t) (~0) : capacity;
    list_info->elements=0;
    list_info->head=(ElementInfo *) NULL;
    list_info->tail=(ElementInfo *) NULL;
    list_info->next=(ElementInfo *) NULL;
    list_info->semaphore=AcquireSemaphoreInfo();
    list_info->signature=MagickCoreSignature;
    return(list_info);
  }
  
  /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   R e m o v e E l e m e n t B y V a l u e F r o m L i n k e d L i s t       %
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  RemoveElementByValueFromLinkedList() removes an element from the linked-list
  %  by value.
  %
  %  The format of the RemoveElementByValueFromLinkedList method is:
  %
  %      void *RemoveElementByValueFromLinkedList(LinkedListInfo *list_info,
  %        const void *value)
  %
  %  A description of each parameter follows:
  %
  %    o list_info: the list info.
  %
  %    o value: the value.
  %
  */
  MagickExport void *RemoveElementByValueFromLinkedList(LinkedListInfo *list_info,
    const void *value)
  {
    ElementInfo
      *next;
  
    assert(list_info != (LinkedListInfo *) NULL);
    assert(list_info->signature == MagickCoreSignature);
    if ((list_info->elements == 0) || (value == (const void *) NULL))
      return((void *) NULL);
    LockSemaphoreInfo(list_info->semaphore);
    if (value == list_info->head->value)
      {
        if (list_info->next == list_info->head)
          list_info->next=list_info->head->next;
        next=list_info->head;
        list_info->head=list_info->head->next;
        next=(ElementInfo *) RelinquishMagickMemory(next);
      }
    else
      {
        ElementInfo
          *element;
  
        next=list_info->head;
        while ((next->next != (ElementInfo *) NULL) &&
               (next->next->value != value))
          next=next->next;
        if (next->next == (ElementInfo *) NULL)
          {
            UnlockSemaphoreInfo(list_info->semaphore);
            return((void *) NULL);
          }
        element=next->next;
        next->next=element->next;
        if (element == list_info->tail)
          list_info->tail=next;
        if (list_info->next == element)
          list_info->next=element->next;
        element=(ElementInfo *) RelinquishMagickMemory(element);
      }
    list_info->elements--;
    UnlockSemaphoreInfo(list_info->semaphore);
    return((void *) value);
  }
  
  /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   R e m o v e E l e m e n t F r o m L i n k e d L i s t                     %
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  RemoveElementFromLinkedList() removes an element from the linked-list at the
  %  specified location.
  %
  %  The format of the RemoveElementFromLinkedList method is:
  %
  %      void *RemoveElementFromLinkedList(LinkedListInfo *list_info,
  %        const size_t index)
  %
  %  A description of each parameter follows:
  %
  %    o list_info: the linked-list info.
  %
  %    o index: the index.
  %
  */
  MagickExport void *RemoveElementFromLinkedList(LinkedListInfo *list_info,
    const size_t index)
  {
    ElementInfo
      *next;
  
    register ssize_t
      i;
  
    void
      *value;
  
    assert(list_info != (LinkedListInfo *) NULL);
    assert(list_info->signature == MagickCoreSignature);
    if (index >= list_info->elements)
      return((void *) NULL);
    LockSemaphoreInfo(list_info->semaphore);
    if (index == 0)
      {
        if (list_info->next == list_info->head)
          list_info->next=list_info->head->next;
        value=list_info->head->value;
        next=list_info->head;
        list_info->head=list_info->head->next;
        next=(ElementInfo *) RelinquishMagickMemory(next);
      }
    else
      {
        ElementInfo
          *element;
  
        next=list_info->head;
        for (i=1; i < (ssize_t) index; i++)
          next=next->next;
        element=next->next;
        next->next=element->next;
        if (element == list_info->tail)
          list_info->tail=next;
        if (list_info->next == element)
          list_info->next=element->next;
        value=element->value;
        element=(ElementInfo *) RelinquishMagickMemory(element);
      }
    list_info->elements--;
    UnlockSemaphoreInfo(list_info->semaphore);
    return(value);
  }
  
  /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   R e m o v e L a s t E l e m e n t F r o m L i n k e d L i s t             %
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  RemoveLastElementFromLinkedList() removes the last element from the
  %  linked-list.
  %
  %  The format of the RemoveLastElementFromLinkedList method is:
  %
  %      void *RemoveLastElementFromLinkedList(LinkedListInfo *list_info)
  %
  %  A description of each parameter follows:
  %
  %    o list_info: the linked-list info.
  %
  */
  MagickExport void *RemoveLastElementFromLinkedList(LinkedListInfo *list_info)
  {
    void
      *value;
  
    assert(list_info != (LinkedListInfo *) NULL);
    assert(list_info->signature == MagickCoreSignature);
    if (list_info->elements == 0)
      return((void *) NULL);
    LockSemaphoreInfo(list_info->semaphore);
    if (list_info->next == list_info->tail)
      list_info->next=(ElementInfo *) NULL;
    if (list_info->elements == 1UL)
      {
        value=list_info->head->value;
        list_info->head=(ElementInfo *) NULL;
        list_info->tail=(ElementInfo *) RelinquishMagickMemory(list_info->tail);
      }
    else
      {
        ElementInfo
          *next;
  
        value=list_info->tail->value;
        next=list_info->head;
        while (next->next != list_info->tail)
          next=next->next;
        list_info->tail=(ElementInfo *) RelinquishMagickMemory(list_info->tail);
        list_info->tail=next;
        next->next=(ElementInfo *) NULL;
      }
    list_info->elements--;
    UnlockSemaphoreInfo(list_info->semaphore);
    return(value);
  }
  
  /*
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %   R e s e t L i n k e d L i s t I t e r a t o r                             %
  %                                                                             %
  %                                                                             %
  %                                                                             %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %  ResetLinkedListIterator() resets the lined-list iterator.  Use it in
  %  conjunction with GetNextValueInLinkedList() to iterate over all the values
  %  in the linked-list.
  %
  %  The format of the ResetLinkedListIterator method is:
  %
  %      ResetLinkedListIterator(LinkedListInfo *list_info)
  %
  %  A description of each parameter follows:
  %
  %    o list_info: the linked-list info.
  %
  */
  MagickExport void ResetLinkedListIterator(LinkedListInfo *list_info)
  {
    assert(list_info != (LinkedListInfo *) NULL);
    assert(list_info->signature == MagickCoreSignature);
    LockSemaphoreInfo(list_info->semaphore);
    list_info->next=list_info->head;
    UnlockSemaphoreInfo(list_info->semaphore);
  }
  