Home | History | Annotate | Download | only in MagickCore
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %   L      IIIII  N   N  K   K  EEEEE  DDDD      L      IIIII  SSSSS  TTTTT   %
      7 %   L        I    NN  N  K  K   E      D   D     L        I    SS       T     %
      8 %   L        I    N N N  KKK    EEE    D   D  =  L        I     SSS     T     %
      9 %   L        I    N  NN  K  K   E      D   D     L        I       SS    T     %
     10 %   LLLLL  IIIII  N   N  K   K  EEEEE  DDDD      LLLLL  IIIII  SSSSS    T     %
     11 %                                                                             %
     12 %                                                                             %
     13 %                  MagickCore Linked-list Methods                             %
     14 %                                                                             %
     15 %                              Software Design                                %
     16 %                                   Cristy                                    %
     17 %                               December 2002                                 %
     18 %                                                                             %
     19 %                                                                             %
     20 %  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
     21 %  dedicated to making software imaging solutions freely available.           %
     22 %                                                                             %
     23 %  You may not use this file except in compliance with the License.  You may  %
     24 %  obtain a copy of the License at                                            %
     25 %                                                                             %
     26 %    http://www.imagemagick.org/script/license.php                            %
     27 %                                                                             %
     28 %  Unless required by applicable law or agreed to in writing, software        %
     29 %  distributed under the License is distributed on an "AS IS" BASIS,          %
     30 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
     31 %  See the License for the specific language governing permissions and        %
     32 %  limitations under the License.                                             %
     33 %                                                                             %
     34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     35 %
     36 %  This module implements the standard handy hash and linked-list methods for
     37 %  storing and retrieving large numbers of data elements.  It is loosely based
     38 %  on the Java implementation of these algorithms.
     39 %
     40 */
     41 
     42 /*
     44   Include declarations.
     45 */
     46 #include "MagickCore/studio.h"
     47 #include "MagickCore/exception.h"
     48 #include "MagickCore/exception-private.h"
     49 #include "MagickCore/linked-list.h"
     50 #include "MagickCore/locale_.h"
     51 #include "MagickCore/memory_.h"
     52 #include "MagickCore/semaphore.h"
     53 #include "MagickCore/signature-private.h"
     54 #include "MagickCore/string_.h"
     55 
     56 /*
     58   Typedef declarations.
     59 */
     60 typedef struct _ElementInfo
     61 {
     62   void
     63     *value;
     64 
     65   struct _ElementInfo
     66     *next;
     67 } ElementInfo;
     68 
     69 struct _LinkedListInfo
     70 {
     71   size_t
     72     capacity,
     73     elements;
     74 
     75   ElementInfo
     76     *head,
     77     *tail,
     78     *next;
     79 
     80   SemaphoreInfo
     81     *semaphore;
     82 
     83   size_t
     84     signature;
     85 };
     86 
     87 /*
     89 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     90 %                                                                             %
     91 %                                                                             %
     92 %                                                                             %
     93 %   A p p e n d V a l u e T o L i n k e d L i s t                             %
     94 %                                                                             %
     95 %                                                                             %
     96 %                                                                             %
     97 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     98 %
     99 %  AppendValueToLinkedList() appends a value to the end of the linked-list.
    100 %
    101 %  The format of the AppendValueToLinkedList method is:
    102 %
    103 %      MagickBooleanType AppendValueToLinkedList(LinkedListInfo *list_info,
    104 %        const void *value)
    105 %
    106 %  A description of each parameter follows:
    107 %
    108 %    o list_info: the linked-list info.
    109 %
    110 %    o value: the value.
    111 %
    112 */
    113 MagickExport MagickBooleanType AppendValueToLinkedList(
    114   LinkedListInfo *list_info,const void *value)
    115 {
    116   register ElementInfo
    117     *next;
    118 
    119   assert(list_info != (LinkedListInfo *) NULL);
    120   assert(list_info->signature == MagickCoreSignature);
    121   if (list_info->elements == list_info->capacity)
    122     return(MagickFalse);
    123   next=(ElementInfo *) AcquireMagickMemory(sizeof(*next));
    124   if (next == (ElementInfo *) NULL)
    125     return(MagickFalse);
    126   next->value=(void *) value;
    127   next->next=(ElementInfo *) NULL;
    128   LockSemaphoreInfo(list_info->semaphore);
    129   if (list_info->next == (ElementInfo *) NULL)
    130     list_info->next=next;
    131   if (list_info->elements == 0)
    132     list_info->head=next;
    133   else
    134     list_info->tail->next=next;
    135   list_info->tail=next;
    136   list_info->elements++;
    137   UnlockSemaphoreInfo(list_info->semaphore);
    138   return(MagickTrue);
    139 }
    140 
    141 /*
    143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    144 %                                                                             %
    145 %                                                                             %
    146 %                                                                             %
    147 %   C l e a r L i n k e d L i s t                                             %
    148 %                                                                             %
    149 %                                                                             %
    150 %                                                                             %
    151 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    152 %
    153 %  ClearLinkedList() clears all the elements from the linked-list.
    154 %
    155 %  The format of the ClearLinkedList method is:
    156 %
    157 %      void ClearLinkedList(LinkedListInfo *list_info,
    158 %        void *(*relinquish_value)(void *))
    159 %
    160 %  A description of each parameter follows:
    161 %
    162 %    o list_info: the linked-list info.
    163 %
    164 %    o relinquish_value: the value deallocation method; typically
    165 %      RelinquishMagickMemory().
    166 %
    167 */
    168 MagickExport void ClearLinkedList(LinkedListInfo *list_info,
    169   void *(*relinquish_value)(void *))
    170 {
    171   ElementInfo
    172     *element;
    173 
    174   register ElementInfo
    175     *next;
    176 
    177   assert(list_info != (LinkedListInfo *) NULL);
    178   assert(list_info->signature == MagickCoreSignature);
    179   LockSemaphoreInfo(list_info->semaphore);
    180   next=list_info->head;
    181   while (next != (ElementInfo *) NULL)
    182   {
    183     if (relinquish_value != (void *(*)(void *)) NULL)
    184       next->value=relinquish_value(next->value);
    185     element=next;
    186     next=next->next;
    187     element=(ElementInfo *) RelinquishMagickMemory(element);
    188   }
    189   list_info->head=(ElementInfo *) NULL;
    190   list_info->tail=(ElementInfo *) NULL;
    191   list_info->next=(ElementInfo *) NULL;
    192   list_info->elements=0;
    193   UnlockSemaphoreInfo(list_info->semaphore);
    194 }
    195 
    196 /*
    197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    198 %                                                                             %
    199 %                                                                             %
    200 %                                                                             %
    201 %   D e s t r o y L i n k e d L i s t                                         %
    202 %                                                                             %
    203 %                                                                             %
    204 %                                                                             %
    205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    206 %
    207 %  DestroyLinkedList() frees the linked-list and all associated resources.
    208 %
    209 %  The format of the DestroyLinkedList method is:
    210 %
    211 %      LinkedListInfo *DestroyLinkedList(LinkedListInfo *list_info,
    212 %        void *(*relinquish_value)(void *))
    213 %
    214 %  A description of each parameter follows:
    215 %
    216 %    o list_info: the linked-list info.
    217 %
    218 %    o relinquish_value: the value deallocation method;  typically
    219 %      RelinquishMagickMemory().
    220 %
    221 */
    222 MagickExport LinkedListInfo *DestroyLinkedList(LinkedListInfo *list_info,
    223   void *(*relinquish_value)(void *))
    224 {
    225   ElementInfo
    226     *entry;
    227 
    228   register ElementInfo
    229     *next;
    230 
    231   assert(list_info != (LinkedListInfo *) NULL);
    232   assert(list_info->signature == MagickCoreSignature);
    233   LockSemaphoreInfo(list_info->semaphore);
    234   for (next=list_info->head; next != (ElementInfo *) NULL; )
    235   {
    236     if (relinquish_value != (void *(*)(void *)) NULL)
    237       next->value=relinquish_value(next->value);
    238     entry=next;
    239     next=next->next;
    240     entry=(ElementInfo *) RelinquishMagickMemory(entry);
    241   }
    242   list_info->signature=(~MagickCoreSignature);
    243   UnlockSemaphoreInfo(list_info->semaphore);
    244   RelinquishSemaphoreInfo(&list_info->semaphore);
    245   list_info=(LinkedListInfo *) RelinquishMagickMemory(list_info);
    246   return(list_info);
    247 }
    248 
    249 /*
    251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    252 %                                                                             %
    253 %                                                                             %
    254 %                                                                             %
    255 %   G e t L a s t V a l u e I n L i n k e d L i s t                           %
    256 %                                                                             %
    257 %                                                                             %
    258 %                                                                             %
    259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    260 %
    261 %  GetLastValueInLinkedList() gets the last value in the linked-list.
    262 %
    263 %  The format of the GetLastValueInLinkedList method is:
    264 %
    265 %      void *GetLastValueInLinkedList(LinkedListInfo *list_info)
    266 %
    267 %  A description of each parameter follows:
    268 %
    269 %    o list_info: the linked_list info.
    270 %
    271 */
    272 MagickExport void *GetLastValueInLinkedList(LinkedListInfo *list_info)
    273 {
    274   void
    275     *value;
    276 
    277   assert(list_info != (LinkedListInfo *) NULL);
    278   assert(list_info->signature == MagickCoreSignature);
    279   if (list_info->elements == 0)
    280     return((void *) NULL);
    281   LockSemaphoreInfo(list_info->semaphore);
    282   value=list_info->tail->value;
    283   UnlockSemaphoreInfo(list_info->semaphore);
    284   return(value);
    285 }
    286 
    287 /*
    288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    289 %                                                                             %
    290 %                                                                             %
    291 %                                                                             %
    292 %   G e t N e x t V a l u e I n L i n k e d L i s t                           %
    293 %                                                                             %
    294 %                                                                             %
    295 %                                                                             %
    296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    297 %
    298 %  GetNextValueInLinkedList() gets the next value in the linked-list.
    299 %
    300 %  The format of the GetNextValueInLinkedList method is:
    301 %
    302 %      void *GetNextValueInLinkedList(LinkedListInfo *list_info)
    303 %
    304 %  A description of each parameter follows:
    305 %
    306 %    o list_info: the linked-list info.
    307 %
    308 */
    309 MagickExport void *GetNextValueInLinkedList(LinkedListInfo *list_info)
    310 {
    311   void
    312     *value;
    313 
    314   assert(list_info != (LinkedListInfo *) NULL);
    315   assert(list_info->signature == MagickCoreSignature);
    316   LockSemaphoreInfo(list_info->semaphore);
    317   if (list_info->next == (ElementInfo *) NULL)
    318     {
    319       UnlockSemaphoreInfo(list_info->semaphore);
    320       return((void *) NULL);
    321     }
    322   value=list_info->next->value;
    323   list_info->next=list_info->next->next;
    324   UnlockSemaphoreInfo(list_info->semaphore);
    325   return(value);
    326 }
    327 
    328 /*
    330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    331 %                                                                             %
    332 %                                                                             %
    333 %                                                                             %
    334 %   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             %
    335 %                                                                             %
    336 %                                                                             %
    337 %                                                                             %
    338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    339 %
    340 %  GetNumberOfElementsInLinkedList() returns the number of entries in the
    341 %  linked-list.
    342 %
    343 %  The format of the GetNumberOfElementsInLinkedList method is:
    344 %
    345 %      size_t GetNumberOfElementsInLinkedList(
    346 %        const LinkedListInfo *list_info)
    347 %
    348 %  A description of each parameter follows:
    349 %
    350 %    o list_info: the linked-list info.
    351 %
    352 */
    353 MagickExport size_t GetNumberOfElementsInLinkedList(
    354   const LinkedListInfo *list_info)
    355 {
    356   assert(list_info != (LinkedListInfo *) NULL);
    357   assert(list_info->signature == MagickCoreSignature);
    358   return(list_info->elements);
    359 }
    360 
    361 /*
    362 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    363 %                                                                             %
    364 %                                                                             %
    365 %                                                                             %
    366 %   G e t V a l u e F r o m L i n k e d L i s t                               %
    367 %                                                                             %
    368 %                                                                             %
    369 %                                                                             %
    370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    371 %
    372 %  GetValueFromLinkedList() gets a value from the linked-list at the specified
    373 %  location.
    374 %
    375 %  The format of the GetValueFromLinkedList method is:
    376 %
    377 %      void *GetValueFromLinkedList(LinkedListInfo *list_info,
    378 %        const size_t index)
    379 %
    380 %  A description of each parameter follows:
    381 %
    382 %    o list_info: the linked_list info.
    383 %
    384 %    o index: the list index.
    385 %
    386 */
    387 MagickExport void *GetValueFromLinkedList(LinkedListInfo *list_info,
    388   const size_t index)
    389 {
    390   register ElementInfo
    391     *next;
    392 
    393   register ssize_t
    394     i;
    395 
    396   void
    397     *value;
    398 
    399   assert(list_info != (LinkedListInfo *) NULL);
    400   assert(list_info->signature == MagickCoreSignature);
    401   if (index >= list_info->elements)
    402     return((void *) NULL);
    403   LockSemaphoreInfo(list_info->semaphore);
    404   if (index == 0)
    405     {
    406       value=list_info->head->value;
    407       UnlockSemaphoreInfo(list_info->semaphore);
    408       return(value);
    409     }
    410   if (index == (list_info->elements-1))
    411     {
    412       value=list_info->tail->value;
    413       UnlockSemaphoreInfo(list_info->semaphore);
    414       return(value);
    415     }
    416   next=list_info->head;
    417   for (i=0; i < (ssize_t) index; i++)
    418     next=next->next;
    419   value=next->value;
    420   UnlockSemaphoreInfo(list_info->semaphore);
    421   return(value);
    422 }
    423 
    424 /*
    425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    426 %                                                                             %
    427 %                                                                             %
    428 %                                                                             %
    429 %   I n s e r t V a l u e I n L i n k e d L i s t                             %
    430 %                                                                             %
    431 %                                                                             %
    432 %                                                                             %
    433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    434 %
    435 %  InsertValueInLinkedList() inserts an element in the linked-list at the
    436 %  specified location.
    437 %
    438 %  The format of the InsertValueInLinkedList method is:
    439 %
    440 %      MagickBooleanType InsertValueInLinkedList(ListInfo *list_info,
    441 %        const size_t index,const void *value)
    442 %
    443 %  A description of each parameter follows:
    444 %
    445 %    o list_info: the hashmap info.
    446 %
    447 %    o index: the index.
    448 %
    449 %    o value: the value.
    450 %
    451 */
    452 MagickExport MagickBooleanType InsertValueInLinkedList(
    453   LinkedListInfo *list_info,const size_t index,const void *value)
    454 {
    455   register ElementInfo
    456     *next;
    457 
    458   register ssize_t
    459     i;
    460 
    461   assert(list_info != (LinkedListInfo *) NULL);
    462   assert(list_info->signature == MagickCoreSignature);
    463   if (value == (const void *) NULL)
    464     return(MagickFalse);
    465   if ((index > list_info->elements) ||
    466       (list_info->elements == list_info->capacity))
    467     return(MagickFalse);
    468   next=(ElementInfo *) AcquireMagickMemory(sizeof(*next));
    469   if (next == (ElementInfo *) NULL)
    470     return(MagickFalse);
    471   next->value=(void *) value;
    472   next->next=(ElementInfo *) NULL;
    473   LockSemaphoreInfo(list_info->semaphore);
    474   if (list_info->elements == 0)
    475     {
    476       if (list_info->next == (ElementInfo *) NULL)
    477         list_info->next=next;
    478       list_info->head=next;
    479       list_info->tail=next;
    480     }
    481   else
    482     {
    483       if (index == 0)
    484         {
    485           if (list_info->next == list_info->head)
    486             list_info->next=next;
    487           next->next=list_info->head;
    488           list_info->head=next;
    489         }
    490       else
    491         if (index == list_info->elements)
    492           {
    493             if (list_info->next == (ElementInfo *) NULL)
    494               list_info->next=next;
    495             list_info->tail->next=next;
    496             list_info->tail=next;
    497           }
    498         else
    499           {
    500             ElementInfo
    501               *element;
    502 
    503             element=list_info->head;
    504             next->next=element->next;
    505             for (i=1; i < (ssize_t) index; i++)
    506             {
    507               element=element->next;
    508               next->next=element->next;
    509             }
    510             next=next->next;
    511             element->next=next;
    512             if (list_info->next == next->next)
    513               list_info->next=next;
    514           }
    515     }
    516   list_info->elements++;
    517   UnlockSemaphoreInfo(list_info->semaphore);
    518   return(MagickTrue);
    519 }
    520 
    521 /*
    523 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    524 %                                                                             %
    525 %                                                                             %
    526 %                                                                             %
    527 %   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                 %
    528 %                                                                             %
    529 %                                                                             %
    530 %                                                                             %
    531 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    532 %
    533 %  InsertValueInSortedLinkedList() inserts a value in the sorted linked-list.
    534 %
    535 %  The format of the InsertValueInSortedLinkedList method is:
    536 %
    537 %      MagickBooleanType InsertValueInSortedLinkedList(ListInfo *list_info,
    538 %        int (*compare)(const void *,const void *),void **replace,
    539 %        const void *value)
    540 %
    541 %  A description of each parameter follows:
    542 %
    543 %    o list_info: the hashmap info.
    544 %
    545 %    o index: the index.
    546 %
    547 %    o compare: the compare method.
    548 %
    549 %    o replace: return previous element here.
    550 %
    551 %    o value: the value.
    552 %
    553 */
    554 MagickExport MagickBooleanType InsertValueInSortedLinkedList(
    555   LinkedListInfo *list_info,int (*compare)(const void *,const void *),
    556   void **replace,const void *value)
    557 {
    558   ElementInfo
    559     *element;
    560 
    561   register ElementInfo
    562     *next;
    563 
    564   register ssize_t
    565     i;
    566 
    567   assert(list_info != (LinkedListInfo *) NULL);
    568   assert(list_info->signature == MagickCoreSignature);
    569   if ((compare == (int (*)(const void *,const void *)) NULL) ||
    570       (value == (const void *) NULL))
    571     return(MagickFalse);
    572   if (list_info->elements == list_info->capacity)
    573     return(MagickFalse);
    574   next=(ElementInfo *) AcquireMagickMemory(sizeof(*next));
    575   if (next == (ElementInfo *) NULL)
    576     return(MagickFalse);
    577   next->value=(void *) value;
    578   element=(ElementInfo *) NULL;
    579   LockSemaphoreInfo(list_info->semaphore);
    580   next->next=list_info->head;
    581   while (next->next != (ElementInfo *) NULL)
    582   {
    583     i=(ssize_t) compare(value,next->next->value);
    584     if ((i < 0) || ((replace != (void **) NULL) && (i == 0)))
    585       {
    586         if (i == 0)
    587           {
    588             *replace=next->next->value;
    589             next->next=next->next->next;
    590             if (element != (ElementInfo *) NULL)
    591               element->next=(ElementInfo *) RelinquishMagickMemory(
    592                 element->next);
    593             list_info->elements--;
    594           }
    595         if (element != (ElementInfo *) NULL)
    596           element->next=next;
    597         else
    598           list_info->head=next;
    599         break;
    600       }
    601     element=next->next;
    602     next->next=next->next->next;
    603   }
    604   if (next->next == (ElementInfo *) NULL)
    605     {
    606       if (element != (ElementInfo *) NULL)
    607         element->next=next;
    608       else
    609         list_info->head=next;
    610       list_info->tail=next;
    611     }
    612   list_info->elements++;
    613   UnlockSemaphoreInfo(list_info->semaphore);
    614   return(MagickTrue);
    615 }
    616 
    617 /*
    618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    619 %                                                                             %
    620 %                                                                             %
    621 %                                                                             %
    622 %   I s L i n k e d L i s t E m p t y                                         %
    623 %                                                                             %
    624 %                                                                             %
    625 %                                                                             %
    626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    627 %
    628 %  IsLinkedListEmpty() returns MagickTrue if the linked-list is empty.
    629 %
    630 %  The format of the IsLinkedListEmpty method is:
    631 %
    632 %      MagickBooleanType IsLinkedListEmpty(LinkedListInfo *list_info)
    633 %
    634 %  A description of each parameter follows:
    635 %
    636 %    o list_info: the linked-list info.
    637 %
    638 */
    639 MagickExport MagickBooleanType IsLinkedListEmpty(
    640   const LinkedListInfo *list_info)
    641 {
    642   assert(list_info != (LinkedListInfo *) NULL);
    643   assert(list_info->signature == MagickCoreSignature);
    644   return(list_info->elements == 0 ? MagickTrue : MagickFalse);
    645 }
    646 
    647 /*
    649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    650 %                                                                             %
    651 %                                                                             %
    652 %                                                                             %
    653 %   L i n k e d L i s t T o A r r a y                                         %
    654 %                                                                             %
    655 %                                                                             %
    656 %                                                                             %
    657 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    658 %
    659 %  LinkedListToArray() converts the linked-list to an array.
    660 %
    661 %  The format of the LinkedListToArray method is:
    662 %
    663 %      MagickBooleanType LinkedListToArray(LinkedListInfo *list_info,
    664 %        void **array)
    665 %
    666 %  A description of each parameter follows:
    667 %
    668 %    o list_info: the linked-list info.
    669 %
    670 %    o array: the array.
    671 %
    672 */
    673 MagickExport MagickBooleanType LinkedListToArray(LinkedListInfo *list_info,
    674   void **array)
    675 {
    676   register ElementInfo
    677     *next;
    678 
    679   register ssize_t
    680     i;
    681 
    682   assert(list_info != (LinkedListInfo *) NULL);
    683   assert(list_info->signature == MagickCoreSignature);
    684   if (array == (void **) NULL)
    685     return(MagickFalse);
    686   LockSemaphoreInfo(list_info->semaphore);
    687   next=list_info->head;
    688   for (i=0; next != (ElementInfo *) NULL; i++)
    689   {
    690     array[i]=next->value;
    691     next=next->next;
    692   }
    693   UnlockSemaphoreInfo(list_info->semaphore);
    694   return(MagickTrue);
    695 }
    696 
    697 /*
    699 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    700 %                                                                             %
    701 %                                                                             %
    702 %                                                                             %
    703 %   N e w L i n k e d L i s t I n f o                                         %
    704 %                                                                             %
    705 %                                                                             %
    706 %                                                                             %
    707 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    708 %
    709 %  NewLinkedList() returns a pointer to a LinkedListInfo structure
    710 %  initialized to default values.
    711 %
    712 %  The format of the NewLinkedList method is:
    713 %
    714 %      LinkedListInfo *NewLinkedList(const size_t capacity)
    715 %
    716 %  A description of each parameter follows:
    717 %
    718 %    o capacity: the maximum number of elements in the list.
    719 %
    720 */
    721 MagickExport LinkedListInfo *NewLinkedList(const size_t capacity)
    722 {
    723   LinkedListInfo
    724     *list_info;
    725 
    726   list_info=(LinkedListInfo *) AcquireMagickMemory(sizeof(*list_info));
    727   if (list_info == (LinkedListInfo *) NULL)
    728     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
    729   (void) ResetMagickMemory(list_info,0,sizeof(*list_info));
    730   list_info->capacity=capacity == 0 ? (size_t) (~0) : capacity;
    731   list_info->elements=0;
    732   list_info->head=(ElementInfo *) NULL;
    733   list_info->tail=(ElementInfo *) NULL;
    734   list_info->next=(ElementInfo *) NULL;
    735   list_info->semaphore=AcquireSemaphoreInfo();
    736   list_info->signature=MagickCoreSignature;
    737   return(list_info);
    738 }
    739 
    740 /*
    742 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    743 %                                                                             %
    744 %                                                                             %
    745 %                                                                             %
    746 %   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       %
    747 %                                                                             %
    748 %                                                                             %
    749 %                                                                             %
    750 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    751 %
    752 %  RemoveElementByValueFromLinkedList() removes an element from the linked-list
    753 %  by value.
    754 %
    755 %  The format of the RemoveElementByValueFromLinkedList method is:
    756 %
    757 %      void *RemoveElementByValueFromLinkedList(LinkedListInfo *list_info,
    758 %        const void *value)
    759 %
    760 %  A description of each parameter follows:
    761 %
    762 %    o list_info: the list info.
    763 %
    764 %    o value: the value.
    765 %
    766 */
    767 MagickExport void *RemoveElementByValueFromLinkedList(LinkedListInfo *list_info,
    768   const void *value)
    769 {
    770   ElementInfo
    771     *next;
    772 
    773   assert(list_info != (LinkedListInfo *) NULL);
    774   assert(list_info->signature == MagickCoreSignature);
    775   if ((list_info->elements == 0) || (value == (const void *) NULL))
    776     return((void *) NULL);
    777   LockSemaphoreInfo(list_info->semaphore);
    778   if (value == list_info->head->value)
    779     {
    780       if (list_info->next == list_info->head)
    781         list_info->next=list_info->head->next;
    782       next=list_info->head;
    783       list_info->head=list_info->head->next;
    784       next=(ElementInfo *) RelinquishMagickMemory(next);
    785     }
    786   else
    787     {
    788       ElementInfo
    789         *element;
    790 
    791       next=list_info->head;
    792       while ((next->next != (ElementInfo *) NULL) &&
    793              (next->next->value != value))
    794         next=next->next;
    795       if (next->next == (ElementInfo *) NULL)
    796         {
    797           UnlockSemaphoreInfo(list_info->semaphore);
    798           return((void *) NULL);
    799         }
    800       element=next->next;
    801       next->next=element->next;
    802       if (element == list_info->tail)
    803         list_info->tail=next;
    804       if (list_info->next == element)
    805         list_info->next=element->next;
    806       element=(ElementInfo *) RelinquishMagickMemory(element);
    807     }
    808   list_info->elements--;
    809   UnlockSemaphoreInfo(list_info->semaphore);
    810   return((void *) value);
    811 }
    812 
    813 /*
    815 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    816 %                                                                             %
    817 %                                                                             %
    818 %                                                                             %
    819 %   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                     %
    820 %                                                                             %
    821 %                                                                             %
    822 %                                                                             %
    823 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    824 %
    825 %  RemoveElementFromLinkedList() removes an element from the linked-list at the
    826 %  specified location.
    827 %
    828 %  The format of the RemoveElementFromLinkedList method is:
    829 %
    830 %      void *RemoveElementFromLinkedList(LinkedListInfo *list_info,
    831 %        const size_t index)
    832 %
    833 %  A description of each parameter follows:
    834 %
    835 %    o list_info: the linked-list info.
    836 %
    837 %    o index: the index.
    838 %
    839 */
    840 MagickExport void *RemoveElementFromLinkedList(LinkedListInfo *list_info,
    841   const size_t index)
    842 {
    843   ElementInfo
    844     *next;
    845 
    846   register ssize_t
    847     i;
    848 
    849   void
    850     *value;
    851 
    852   assert(list_info != (LinkedListInfo *) NULL);
    853   assert(list_info->signature == MagickCoreSignature);
    854   if (index >= list_info->elements)
    855     return((void *) NULL);
    856   LockSemaphoreInfo(list_info->semaphore);
    857   if (index == 0)
    858     {
    859       if (list_info->next == list_info->head)
    860         list_info->next=list_info->head->next;
    861       value=list_info->head->value;
    862       next=list_info->head;
    863       list_info->head=list_info->head->next;
    864       next=(ElementInfo *) RelinquishMagickMemory(next);
    865     }
    866   else
    867     {
    868       ElementInfo
    869         *element;
    870 
    871       next=list_info->head;
    872       for (i=1; i < (ssize_t) index; i++)
    873         next=next->next;
    874       element=next->next;
    875       next->next=element->next;
    876       if (element == list_info->tail)
    877         list_info->tail=next;
    878       if (list_info->next == element)
    879         list_info->next=element->next;
    880       value=element->value;
    881       element=(ElementInfo *) RelinquishMagickMemory(element);
    882     }
    883   list_info->elements--;
    884   UnlockSemaphoreInfo(list_info->semaphore);
    885   return(value);
    886 }
    887 
    888 /*
    889 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    890 %                                                                             %
    891 %                                                                             %
    892 %                                                                             %
    893 %   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             %
    894 %                                                                             %
    895 %                                                                             %
    896 %                                                                             %
    897 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    898 %
    899 %  RemoveLastElementFromLinkedList() removes the last element from the
    900 %  linked-list.
    901 %
    902 %  The format of the RemoveLastElementFromLinkedList method is:
    903 %
    904 %      void *RemoveLastElementFromLinkedList(LinkedListInfo *list_info)
    905 %
    906 %  A description of each parameter follows:
    907 %
    908 %    o list_info: the linked-list info.
    909 %
    910 */
    911 MagickExport void *RemoveLastElementFromLinkedList(LinkedListInfo *list_info)
    912 {
    913   void
    914     *value;
    915 
    916   assert(list_info != (LinkedListInfo *) NULL);
    917   assert(list_info->signature == MagickCoreSignature);
    918   if (list_info->elements == 0)
    919     return((void *) NULL);
    920   LockSemaphoreInfo(list_info->semaphore);
    921   if (list_info->next == list_info->tail)
    922     list_info->next=(ElementInfo *) NULL;
    923   if (list_info->elements == 1UL)
    924     {
    925       value=list_info->head->value;
    926       list_info->head=(ElementInfo *) NULL;
    927       list_info->tail=(ElementInfo *) RelinquishMagickMemory(list_info->tail);
    928     }
    929   else
    930     {
    931       ElementInfo
    932         *next;
    933 
    934       value=list_info->tail->value;
    935       next=list_info->head;
    936       while (next->next != list_info->tail)
    937         next=next->next;
    938       list_info->tail=(ElementInfo *) RelinquishMagickMemory(list_info->tail);
    939       list_info->tail=next;
    940       next->next=(ElementInfo *) NULL;
    941     }
    942   list_info->elements--;
    943   UnlockSemaphoreInfo(list_info->semaphore);
    944   return(value);
    945 }
    946 
    947 /*
    949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    950 %                                                                             %
    951 %                                                                             %
    952 %                                                                             %
    953 %   R e s e t L i n k e d L i s t I t e r a t o r                             %
    954 %                                                                             %
    955 %                                                                             %
    956 %                                                                             %
    957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    958 %
    959 %  ResetLinkedListIterator() resets the lined-list iterator.  Use it in
    960 %  conjunction with GetNextValueInLinkedList() to iterate over all the values
    961 %  in the linked-list.
    962 %
    963 %  The format of the ResetLinkedListIterator method is:
    964 %
    965 %      ResetLinkedListIterator(LinkedListInfo *list_info)
    966 %
    967 %  A description of each parameter follows:
    968 %
    969 %    o list_info: the linked-list info.
    970 %
    971 */
    972 MagickExport void ResetLinkedListIterator(LinkedListInfo *list_info)
    973 {
    974   assert(list_info != (LinkedListInfo *) NULL);
    975   assert(list_info->signature == MagickCoreSignature);
    976   LockSemaphoreInfo(list_info->semaphore);
    977   list_info->next=list_info->head;
    978   UnlockSemaphoreInfo(list_info->semaphore);
    979 }
    980