]> granicus.if.org Git - imagemagick/commitdiff
...
authorCristy <urban-warrior@imagemagick.org>
Wed, 2 Jan 2019 15:51:53 +0000 (10:51 -0500)
committerCristy <urban-warrior@imagemagick.org>
Wed, 2 Jan 2019 15:51:53 +0000 (10:51 -0500)
MagickCore/linked-list.c

index dce51d5b7370eaa053a7715a4ccb1a99c096b0c5..dec197bd309008a593e655180dfdafb9ab279720 100644 (file)
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   L      IIIII  N   N  K   K  EEEEE  DDDD      L      IIIII  SSSSS  TTTTT   %\r
-%   L        I    NN  N  K  K   E      D   D     L        I    SS       T     %\r
-%   L        I    N N N  KKK    EEE    D   D  =  L        I     SSS     T     %\r
-%   L        I    N  NN  K  K   E      D   D     L        I       SS    T     %\r
-%   LLLLL  IIIII  N   N  K   K  EEEEE  DDDD      LLLLL  IIIII  SSSSS    T     %\r
-%                                                                             %\r
-%                                                                             %\r
-%                  MagickCore Linked-list Methods                             %\r
-%                                                                             %\r
-%                              Software Design                                %\r
-%                                   Cristy                                    %\r
-%                               December 2002                                 %\r
-%                                                                             %\r
-%                                                                             %\r
-%  Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization      %\r
-%  dedicated to making software imaging solutions freely available.           %\r
-%                                                                             %\r
-%  You may not use this file except in compliance with the License.  You may  %\r
-%  obtain a copy of the License at                                            %\r
-%                                                                             %\r
-%    https://imagemagick.org/script/license.php                               %\r
-%                                                                             %\r
-%  Unless required by applicable law or agreed to in writing, software        %\r
-%  distributed under the License is distributed on an "AS IS" BASIS,          %\r
-%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %\r
-%  See the License for the specific language governing permissions and        %\r
-%  limitations under the License.                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  This module implements the standard handy hash and linked-list methods for\r
-%  storing and retrieving large numbers of data elements.  It is loosely based\r
-%  on the Java implementation of these algorithms.\r
-%\r
-*/\r
-\f\r
-/*\r
-  Include declarations.\r
-*/\r
-#include "MagickCore/studio.h"\r
-#include "MagickCore/exception.h"\r
-#include "MagickCore/exception-private.h"\r
-#include "MagickCore/linked-list.h"\r
-#include "MagickCore/locale_.h"\r
-#include "MagickCore/memory_.h"\r
-#include "MagickCore/memory-private.h"\r
-#include "MagickCore/semaphore.h"\r
-#include "MagickCore/signature-private.h"\r
-#include "MagickCore/string_.h"\r
-\f\r
-/*\r
-  Typedef declarations.\r
-*/\r
-typedef struct _ElementInfo\r
-{\r
-  void\r
-    *value;\r
-\r
-  struct _ElementInfo\r
-    *next;\r
-} ElementInfo;\r
-\r
-struct _LinkedListInfo\r
-{\r
-  size_t\r
-    capacity,\r
-    elements;\r
-\r
-  ElementInfo\r
-    *head,\r
-    *tail,\r
-    *next;\r
-\r
-  SemaphoreInfo\r
-    *semaphore;\r
-\r
-  size_t\r
-    signature;\r
-};\r
-\f\r
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   A p p e n d V a l u e T o L i n k e d L i s t                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  AppendValueToLinkedList() appends a value to the end of the linked-list.\r
-%\r
-%  The format of the AppendValueToLinkedList method is:\r
-%\r
-%      MagickBooleanType AppendValueToLinkedList(LinkedListInfo *list_info,\r
-%        const void *value)\r
-%\r
-%  A description of each parameter follows:\r
-%\r
-%    o list_info: the linked-list info.\r
-%\r
-%    o value: the value.\r
-%\r
-*/\r
-MagickExport MagickBooleanType AppendValueToLinkedList(\r
-  LinkedListInfo *list_info,const void *value)\r
-{\r
-  register ElementInfo\r
-    *next;\r
-\r
-  assert(list_info != (LinkedListInfo *) NULL);\r
-  assert(list_info->signature == MagickCoreSignature);\r
-  if (list_info->elements == list_info->capacity)\r
-    return(MagickFalse);\r
-  next=(ElementInfo *) AcquireMagickMemory(sizeof(*next));\r
-  if (next == (ElementInfo *) NULL)\r
-    return(MagickFalse);\r
-  next->value=(void *) value;\r
-  next->next=(ElementInfo *) NULL;\r
-  LockSemaphoreInfo(list_info->semaphore);\r
-  if (list_info->next == (ElementInfo *) NULL)\r
-    list_info->next=next;\r
-  if (list_info->elements == 0)\r
-    list_info->head=next;\r
-  else\r
-    list_info->tail->next=next;\r
-  list_info->tail=next;\r
-  list_info->elements++;\r
-  UnlockSemaphoreInfo(list_info->semaphore);\r
-  return(MagickTrue);\r
-}\r
-\f\r
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   C l e a r L i n k e d L i s t                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  ClearLinkedList() clears all the elements from the linked-list.\r
-%\r
-%  The format of the ClearLinkedList method is:\r
-%\r
-%      void ClearLinkedList(LinkedListInfo *list_info,\r
-%        void *(*relinquish_value)(void *))\r
-%\r
-%  A description of each parameter follows:\r
-%\r
-%    o list_info: the linked-list info.\r
-%\r
-%    o relinquish_value: the value deallocation method; typically\r
-%      RelinquishMagickMemory().\r
-%\r
-*/\r
-MagickExport void ClearLinkedList(LinkedListInfo *list_info,\r
-  void *(*relinquish_value)(void *))\r
-{\r
-  ElementInfo\r
-    *element;\r
-\r
-  register ElementInfo\r
-    *next;\r
-\r
-  assert(list_info != (LinkedListInfo *) NULL);\r
-  assert(list_info->signature == MagickCoreSignature);\r
-  LockSemaphoreInfo(list_info->semaphore);\r
-  next=list_info->head;\r
-  while (next != (ElementInfo *) NULL)\r
-  {\r
-    if (relinquish_value != (void *(*)(void *)) NULL)\r
-      next->value=relinquish_value(next->value);\r
-    element=next;\r
-    next=next->next;\r
-    element=(ElementInfo *) RelinquishMagickMemory(element);\r
-  }\r
-  list_info->head=(ElementInfo *) NULL;\r
-  list_info->tail=(ElementInfo *) NULL;\r
-  list_info->next=(ElementInfo *) NULL;\r
-  list_info->elements=0;\r
-  UnlockSemaphoreInfo(list_info->semaphore);\r
-}\r
-\r
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   D e s t r o y L i n k e d L i s t                                         %\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  DestroyLinkedList() frees the linked-list and all associated resources.\r
-%\r
-%  The format of the DestroyLinkedList method is:\r
-%\r
-%      LinkedListInfo *DestroyLinkedList(LinkedListInfo *list_info,\r
-%        void *(*relinquish_value)(void *))\r
-%\r
-%  A description of each parameter follows:\r
-%\r
-%    o list_info: the linked-list info.\r
-%\r
-%    o relinquish_value: the value deallocation method;  typically\r
-%      RelinquishMagickMemory().\r
-%\r
-*/\r
-MagickExport LinkedListInfo *DestroyLinkedList(LinkedListInfo *list_info,\r
-  void *(*relinquish_value)(void *))\r
-{\r
-  ElementInfo\r
-    *entry;\r
-\r
-  register ElementInfo\r
-    *next;\r
-\r
-  assert(list_info != (LinkedListInfo *) NULL);\r
-  assert(list_info->signature == MagickCoreSignature);\r
-  LockSemaphoreInfo(list_info->semaphore);\r
-  for (next=list_info->head; next != (ElementInfo *) NULL; )\r
-  {\r
-    if (relinquish_value != (void *(*)(void *)) NULL)\r
-      next->value=relinquish_value(next->value);\r
-    entry=next;\r
-    next=next->next;\r
-    entry=(ElementInfo *) RelinquishMagickMemory(entry);\r
-  }\r
-  list_info->signature=(~MagickCoreSignature);\r
-  UnlockSemaphoreInfo(list_info->semaphore);\r
-  RelinquishSemaphoreInfo(&list_info->semaphore);\r
-  list_info=(LinkedListInfo *) RelinquishMagickMemory(list_info);\r
-  return(list_info);\r
-}\r
-\f\r
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   G e t L a s t V a l u e I n L i n k e d L i s t                           %\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  GetLastValueInLinkedList() gets the last value in the linked-list.\r
-%\r
-%  The format of the GetLastValueInLinkedList method is:\r
-%\r
-%      void *GetLastValueInLinkedList(LinkedListInfo *list_info)\r
-%\r
-%  A description of each parameter follows:\r
-%\r
-%    o list_info: the linked_list info.\r
-%\r
-*/\r
-MagickExport void *GetLastValueInLinkedList(LinkedListInfo *list_info)\r
-{\r
-  void\r
-    *value;\r
-\r
-  assert(list_info != (LinkedListInfo *) NULL);\r
-  assert(list_info->signature == MagickCoreSignature);\r
-  if (list_info->elements == 0)\r
-    return((void *) NULL);\r
-  LockSemaphoreInfo(list_info->semaphore);\r
-  value=list_info->tail->value;\r
-  UnlockSemaphoreInfo(list_info->semaphore);\r
-  return(value);\r
-}\r
-\r
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   G e t N e x t V a l u e I n L i n k e d L i s t                           %\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  GetNextValueInLinkedList() gets the next value in the linked-list.\r
-%\r
-%  The format of the GetNextValueInLinkedList method is:\r
-%\r
-%      void *GetNextValueInLinkedList(LinkedListInfo *list_info)\r
-%\r
-%  A description of each parameter follows:\r
-%\r
-%    o list_info: the linked-list info.\r
-%\r
-*/\r
-MagickExport void *GetNextValueInLinkedList(LinkedListInfo *list_info)\r
-{\r
-  void\r
-    *value;\r
-\r
-  assert(list_info != (LinkedListInfo *) NULL);\r
-  assert(list_info->signature == MagickCoreSignature);\r
-  LockSemaphoreInfo(list_info->semaphore);\r
-  if (list_info->next == (ElementInfo *) NULL)\r
-    {\r
-      UnlockSemaphoreInfo(list_info->semaphore);\r
-      return((void *) NULL);\r
-    }\r
-  value=list_info->next->value;\r
-  list_info->next=list_info->next->next;\r
-  UnlockSemaphoreInfo(list_info->semaphore);\r
-  return(value);\r
-}\r
-\f\r
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   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             %\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  GetNumberOfElementsInLinkedList() returns the number of entries in the\r
-%  linked-list.\r
-%\r
-%  The format of the GetNumberOfElementsInLinkedList method is:\r
-%\r
-%      size_t GetNumberOfElementsInLinkedList(\r
-%        const LinkedListInfo *list_info)\r
-%\r
-%  A description of each parameter follows:\r
-%\r
-%    o list_info: the linked-list info.\r
-%\r
-*/\r
-MagickExport size_t GetNumberOfElementsInLinkedList(\r
-  const LinkedListInfo *list_info)\r
-{\r
-  assert(list_info != (LinkedListInfo *) NULL);\r
-  assert(list_info->signature == MagickCoreSignature);\r
-  return(list_info->elements);\r
-}\r
-\r
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   G e t V a l u e F r o m L i n k e d L i s t                               %\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  GetValueFromLinkedList() gets a value from the linked-list at the specified\r
-%  location.\r
-%\r
-%  The format of the GetValueFromLinkedList method is:\r
-%\r
-%      void *GetValueFromLinkedList(LinkedListInfo *list_info,\r
-%        const size_t index)\r
-%\r
-%  A description of each parameter follows:\r
-%\r
-%    o list_info: the linked_list info.\r
-%\r
-%    o index: the list index.\r
-%\r
-*/\r
-MagickExport void *GetValueFromLinkedList(LinkedListInfo *list_info,\r
-  const size_t index)\r
-{\r
-  register ElementInfo\r
-    *next;\r
-\r
-  register ssize_t\r
-    i;\r
-\r
-  void\r
-    *value;\r
-\r
-  assert(list_info != (LinkedListInfo *) NULL);\r
-  assert(list_info->signature == MagickCoreSignature);\r
-  if (index >= list_info->elements)\r
-    return((void *) NULL);\r
-  LockSemaphoreInfo(list_info->semaphore);\r
-  if (index == 0)\r
-    {\r
-      value=list_info->head->value;\r
-      UnlockSemaphoreInfo(list_info->semaphore);\r
-      return(value);\r
-    }\r
-  if (index == (list_info->elements-1))\r
-    {\r
-      value=list_info->tail->value;\r
-      UnlockSemaphoreInfo(list_info->semaphore);\r
-      return(value);\r
-    }\r
-  next=list_info->head;\r
-  for (i=0; i < (ssize_t) index; i++)\r
-    next=next->next;\r
-  value=next->value;\r
-  UnlockSemaphoreInfo(list_info->semaphore);\r
-  return(value);\r
-}\r
-\r
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   I n s e r t V a l u e I n L i n k e d L i s t                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  InsertValueInLinkedList() inserts an element in the linked-list at the\r
-%  specified location.\r
-%\r
-%  The format of the InsertValueInLinkedList method is:\r
-%\r
-%      MagickBooleanType InsertValueInLinkedList(ListInfo *list_info,\r
-%        const size_t index,const void *value)\r
-%\r
-%  A description of each parameter follows:\r
-%\r
-%    o list_info: the hashmap info.\r
-%\r
-%    o index: the index.\r
-%\r
-%    o value: the value.\r
-%\r
-*/\r
-MagickExport MagickBooleanType InsertValueInLinkedList(\r
-  LinkedListInfo *list_info,const size_t index,const void *value)\r
-{\r
-  register ElementInfo\r
-    *next;\r
-\r
-  register ssize_t\r
-    i;\r
-\r
-  assert(list_info != (LinkedListInfo *) NULL);\r
-  assert(list_info->signature == MagickCoreSignature);\r
-  if (value == (const void *) NULL)\r
-    return(MagickFalse);\r
-  if ((index > list_info->elements) ||\r
-      (list_info->elements == list_info->capacity))\r
-    return(MagickFalse);\r
-  next=(ElementInfo *) AcquireMagickMemory(sizeof(*next));\r
-  if (next == (ElementInfo *) NULL)\r
-    return(MagickFalse);\r
-  next->value=(void *) value;\r
-  next->next=(ElementInfo *) NULL;\r
-  LockSemaphoreInfo(list_info->semaphore);\r
-  if (list_info->elements == 0)\r
-    {\r
-      if (list_info->next == (ElementInfo *) NULL)\r
-        list_info->next=next;\r
-      list_info->head=next;\r
-      list_info->tail=next;\r
-    }\r
-  else\r
-    {\r
-      if (index == 0)\r
-        {\r
-          if (list_info->next == list_info->head)\r
-            list_info->next=next;\r
-          next->next=list_info->head;\r
-          list_info->head=next;\r
-        }\r
-      else\r
-        if (index == list_info->elements)\r
-          {\r
-            if (list_info->next == (ElementInfo *) NULL)\r
-              list_info->next=next;\r
-            list_info->tail->next=next;\r
-            list_info->tail=next;\r
-          }\r
-        else\r
-          {\r
-            ElementInfo\r
-              *element;\r
-\r
-            element=list_info->head;\r
-            next->next=element->next;\r
-            for (i=1; i < (ssize_t) index; i++)\r
-            {\r
-              element=element->next;\r
-              next->next=element->next;\r
-            }\r
-            next=next->next;\r
-            element->next=next;\r
-            if (list_info->next == next->next)\r
-              list_info->next=next;\r
-          }\r
-    }\r
-  list_info->elements++;\r
-  UnlockSemaphoreInfo(list_info->semaphore);\r
-  return(MagickTrue);\r
-}\r
-\f\r
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   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                 %\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  InsertValueInSortedLinkedList() inserts a value in the sorted linked-list.\r
-%\r
-%  The format of the InsertValueInSortedLinkedList method is:\r
-%\r
-%      MagickBooleanType InsertValueInSortedLinkedList(ListInfo *list_info,\r
-%        int (*compare)(const void *,const void *),void **replace,\r
-%        const void *value)\r
-%\r
-%  A description of each parameter follows:\r
-%\r
-%    o list_info: the hashmap info.\r
-%\r
-%    o index: the index.\r
-%\r
-%    o compare: the compare method.\r
-%\r
-%    o replace: return previous element here.\r
-%\r
-%    o value: the value.\r
-%\r
-*/\r
-MagickExport MagickBooleanType InsertValueInSortedLinkedList(\r
-  LinkedListInfo *list_info,int (*compare)(const void *,const void *),\r
-  void **replace,const void *value)\r
-{\r
-  ElementInfo\r
-    *element;\r
-\r
-  register ElementInfo\r
-    *next;\r
-\r
-  register ssize_t\r
-    i;\r
-\r
-  assert(list_info != (LinkedListInfo *) NULL);\r
-  assert(list_info->signature == MagickCoreSignature);\r
-  if ((compare == (int (*)(const void *,const void *)) NULL) ||\r
-      (value == (const void *) NULL))\r
-    return(MagickFalse);\r
-  if (list_info->elements == list_info->capacity)\r
-    return(MagickFalse);\r
-  next=(ElementInfo *) AcquireMagickMemory(sizeof(*next));\r
-  if (next == (ElementInfo *) NULL)\r
-    return(MagickFalse);\r
-  next->value=(void *) value;\r
-  element=(ElementInfo *) NULL;\r
-  LockSemaphoreInfo(list_info->semaphore);\r
-  next->next=list_info->head;\r
-  while (next->next != (ElementInfo *) NULL)\r
-  {\r
-    i=(ssize_t) compare(value,next->next->value);\r
-    if ((i < 0) || ((replace != (void **) NULL) && (i == 0)))\r
-      {\r
-        if (i == 0)\r
-          {\r
-            *replace=next->next->value;\r
-            next->next=next->next->next;\r
-            if (element != (ElementInfo *) NULL)\r
-              element->next=(ElementInfo *) RelinquishMagickMemory(\r
-                element->next);\r
-            list_info->elements--;\r
-          }\r
-        if (element != (ElementInfo *) NULL)\r
-          element->next=next;\r
-        else\r
-          list_info->head=next;\r
-        break;\r
-      }\r
-    element=next->next;\r
-    next->next=next->next->next;\r
-  }\r
-  if (next->next == (ElementInfo *) NULL)\r
-    {\r
-      if (element != (ElementInfo *) NULL)\r
-        element->next=next;\r
-      else\r
-        list_info->head=next;\r
-      list_info->tail=next;\r
-    }\r
-  list_info->elements++;\r
-  UnlockSemaphoreInfo(list_info->semaphore);\r
-  return(MagickTrue);\r
-}\r
-\r
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   I s L i n k e d L i s t E m p t y                                         %\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  IsLinkedListEmpty() returns MagickTrue if the linked-list is empty.\r
-%\r
-%  The format of the IsLinkedListEmpty method is:\r
-%\r
-%      MagickBooleanType IsLinkedListEmpty(LinkedListInfo *list_info)\r
-%\r
-%  A description of each parameter follows:\r
-%\r
-%    o list_info: the linked-list info.\r
-%\r
-*/\r
-MagickExport MagickBooleanType IsLinkedListEmpty(\r
-  const LinkedListInfo *list_info)\r
-{\r
-  assert(list_info != (LinkedListInfo *) NULL);\r
-  assert(list_info->signature == MagickCoreSignature);\r
-  return(list_info->elements == 0 ? MagickTrue : MagickFalse);\r
-}\r
-\f\r
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   L i n k e d L i s t T o A r r a y                                         %\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  LinkedListToArray() converts the linked-list to an array.\r
-%\r
-%  The format of the LinkedListToArray method is:\r
-%\r
-%      MagickBooleanType LinkedListToArray(LinkedListInfo *list_info,\r
-%        void **array)\r
-%\r
-%  A description of each parameter follows:\r
-%\r
-%    o list_info: the linked-list info.\r
-%\r
-%    o array: the array.\r
-%\r
-*/\r
-MagickExport MagickBooleanType LinkedListToArray(LinkedListInfo *list_info,\r
-  void **array)\r
-{\r
-  register ElementInfo\r
-    *next;\r
-\r
-  register ssize_t\r
-    i;\r
-\r
-  assert(list_info != (LinkedListInfo *) NULL);\r
-  assert(list_info->signature == MagickCoreSignature);\r
-  if (array == (void **) NULL)\r
-    return(MagickFalse);\r
-  LockSemaphoreInfo(list_info->semaphore);\r
-  next=list_info->head;\r
-  for (i=0; next != (ElementInfo *) NULL; i++)\r
-  {\r
-    array[i]=next->value;\r
-    next=next->next;\r
-  }\r
-  UnlockSemaphoreInfo(list_info->semaphore);\r
-  return(MagickTrue);\r
-}\r
-\f\r
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   N e w L i n k e d L i s t I n f o                                         %\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  NewLinkedList() returns a pointer to a LinkedListInfo structure\r
-%  initialized to default values.\r
-%\r
-%  The format of the NewLinkedList method is:\r
-%\r
-%      LinkedListInfo *NewLinkedList(const size_t capacity)\r
-%\r
-%  A description of each parameter follows:\r
-%\r
-%    o capacity: the maximum number of elements in the list.\r
-%\r
-*/\r
-MagickExport LinkedListInfo *NewLinkedList(const size_t capacity)\r
-{\r
-  LinkedListInfo\r
-    *list_info;\r
-\r
-  list_info=(LinkedListInfo *) AcquireCriticalMemory(sizeof(*list_info));\r
-  (void) memset(list_info,0,sizeof(*list_info));\r
-  list_info->capacity=capacity == 0 ? (size_t) (~0) : capacity;\r
-  list_info->elements=0;\r
-  list_info->head=(ElementInfo *) NULL;\r
-  list_info->tail=(ElementInfo *) NULL;\r
-  list_info->next=(ElementInfo *) NULL;\r
-  list_info->semaphore=AcquireSemaphoreInfo();\r
-  list_info->signature=MagickCoreSignature;\r
-  return(list_info);\r
-}\r
-\f\r
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   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       %\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  RemoveElementByValueFromLinkedList() removes an element from the linked-list\r
-%  by value.\r
-%\r
-%  The format of the RemoveElementByValueFromLinkedList method is:\r
-%\r
-%      void *RemoveElementByValueFromLinkedList(LinkedListInfo *list_info,\r
-%        const void *value)\r
-%\r
-%  A description of each parameter follows:\r
-%\r
-%    o list_info: the list info.\r
-%\r
-%    o value: the value.\r
-%\r
-*/\r
-MagickExport void *RemoveElementByValueFromLinkedList(LinkedListInfo *list_info,\r
-  const void *value)\r
-{\r
-  ElementInfo\r
-    *next;\r
-\r
-  assert(list_info != (LinkedListInfo *) NULL);\r
-  assert(list_info->signature == MagickCoreSignature);\r
-  if ((list_info->elements == 0) || (value == (const void *) NULL))\r
-    return((void *) NULL);\r
-  LockSemaphoreInfo(list_info->semaphore);\r
-  if (value == list_info->head->value)\r
-    {\r
-      if (list_info->next == list_info->head)\r
-        list_info->next=list_info->head->next;\r
-      next=list_info->head;\r
-      list_info->head=list_info->head->next;\r
-      next=(ElementInfo *) RelinquishMagickMemory(next);\r
-    }\r
-  else\r
-    {\r
-      ElementInfo\r
-        *element;\r
-\r
-      next=list_info->head;\r
-      while ((next->next != (ElementInfo *) NULL) &&\r
-             (next->next->value != value))\r
-        next=next->next;\r
-      if (next->next == (ElementInfo *) NULL)\r
-        {\r
-          UnlockSemaphoreInfo(list_info->semaphore);\r
-          return((void *) NULL);\r
-        }\r
-      element=next->next;\r
-      next->next=element->next;\r
-      if (element == list_info->tail)\r
-        list_info->tail=next;\r
-      if (list_info->next == element)\r
-        list_info->next=element->next;\r
-      element=(ElementInfo *) RelinquishMagickMemory(element);\r
-    }\r
-  list_info->elements--;\r
-  UnlockSemaphoreInfo(list_info->semaphore);\r
-  return((void *) value);\r
-}\r
-\f\r
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   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                     %\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  RemoveElementFromLinkedList() removes an element from the linked-list at the\r
-%  specified location.\r
-%\r
-%  The format of the RemoveElementFromLinkedList method is:\r
-%\r
-%      void *RemoveElementFromLinkedList(LinkedListInfo *list_info,\r
-%        const size_t index)\r
-%\r
-%  A description of each parameter follows:\r
-%\r
-%    o list_info: the linked-list info.\r
-%\r
-%    o index: the index.\r
-%\r
-*/\r
-MagickExport void *RemoveElementFromLinkedList(LinkedListInfo *list_info,\r
-  const size_t index)\r
-{\r
-  ElementInfo\r
-    *next;\r
-\r
-  register ssize_t\r
-    i;\r
-\r
-  void\r
-    *value;\r
-\r
-  assert(list_info != (LinkedListInfo *) NULL);\r
-  assert(list_info->signature == MagickCoreSignature);\r
-  if (index >= list_info->elements)\r
-    return((void *) NULL);\r
-  LockSemaphoreInfo(list_info->semaphore);\r
-  if (index == 0)\r
-    {\r
-      if (list_info->next == list_info->head)\r
-        list_info->next=list_info->head->next;\r
-      value=list_info->head->value;\r
-      next=list_info->head;\r
-      list_info->head=list_info->head->next;\r
-      next=(ElementInfo *) RelinquishMagickMemory(next);\r
-    }\r
-  else\r
-    {\r
-      ElementInfo\r
-        *element;\r
-\r
-      next=list_info->head;\r
-      for (i=1; i < (ssize_t) index; i++)\r
-        next=next->next;\r
-      element=next->next;\r
-      next->next=element->next;\r
-      if (element == list_info->tail)\r
-        list_info->tail=next;\r
-      if (list_info->next == element)\r
-        list_info->next=element->next;\r
-      value=element->value;\r
-      element=(ElementInfo *) RelinquishMagickMemory(element);\r
-    }\r
-  list_info->elements--;\r
-  UnlockSemaphoreInfo(list_info->semaphore);\r
-  return(value);\r
-}\r
-\r
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   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             %\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  RemoveLastElementFromLinkedList() removes the last element from the\r
-%  linked-list.\r
-%\r
-%  The format of the RemoveLastElementFromLinkedList method is:\r
-%\r
-%      void *RemoveLastElementFromLinkedList(LinkedListInfo *list_info)\r
-%\r
-%  A description of each parameter follows:\r
-%\r
-%    o list_info: the linked-list info.\r
-%\r
-*/\r
-MagickExport void *RemoveLastElementFromLinkedList(LinkedListInfo *list_info)\r
-{\r
-  void\r
-    *value;\r
-\r
-  assert(list_info != (LinkedListInfo *) NULL);\r
-  assert(list_info->signature == MagickCoreSignature);\r
-  if (list_info->elements == 0)\r
-    return((void *) NULL);\r
-  LockSemaphoreInfo(list_info->semaphore);\r
-  if (list_info->next == list_info->tail)\r
-    list_info->next=(ElementInfo *) NULL;\r
-  if (list_info->elements == 1UL)\r
-    {\r
-      value=list_info->head->value;\r
-      list_info->head=(ElementInfo *) NULL;\r
-      list_info->tail=(ElementInfo *) RelinquishMagickMemory(list_info->tail);\r
-    }\r
-  else\r
-    {\r
-      ElementInfo\r
-        *next;\r
-\r
-      value=list_info->tail->value;\r
-      next=list_info->head;\r
-      while (next->next != list_info->tail)\r
-        next=next->next;\r
-      list_info->tail=(ElementInfo *) RelinquishMagickMemory(list_info->tail);\r
-      list_info->tail=next;\r
-      next->next=(ElementInfo *) NULL;\r
-    }\r
-  list_info->elements--;\r
-  UnlockSemaphoreInfo(list_info->semaphore);\r
-  return(value);\r
-}\r
-\f\r
-/*\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%   R e s e t L i n k e d L i s t I t e r a t o r                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%                                                                             %\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-%\r
-%  ResetLinkedListIterator() resets the lined-list iterator.  Use it in\r
-%  conjunction with GetNextValueInLinkedList() to iterate over all the values\r
-%  in the linked-list.\r
-%\r
-%  The format of the ResetLinkedListIterator method is:\r
-%\r
-%      ResetLinkedListIterator(LinkedListInfo *list_info)\r
-%\r
-%  A description of each parameter follows:\r
-%\r
-%    o list_info: the linked-list info.\r
-%\r
-*/\r
-MagickExport void ResetLinkedListIterator(LinkedListInfo *list_info)\r
-{\r
-  assert(list_info != (LinkedListInfo *) NULL);\r
-  assert(list_info->signature == MagickCoreSignature);\r
-  LockSemaphoreInfo(list_info->semaphore);\r
-  list_info->next=list_info->head;\r
-  UnlockSemaphoreInfo(list_info->semaphore);\r
-}\r
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   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-2019 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.                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  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.
+%
+*/
+\f
+/*
+  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/memory-private.h"
+#include "MagickCore/semaphore.h"
+#include "MagickCore/signature-private.h"
+#include "MagickCore/string_.h"
+\f
+/*
+  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;
+};
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   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);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   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);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   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);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   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);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   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);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   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);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   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 *) AcquireCriticalMemory(sizeof(*list_info));
+  (void) memset(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);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   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);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   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);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   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);
+}