Home | History | Annotate | Download | only in MagickCore
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                         L      IIIII  SSSSS  TTTTT                          %
      7 %                         L        I    SS       T                            %
      8 %                         L        I     SSS     T                            %
      9 %                         L        I       SS    T                            %
     10 %                         LLLLL  IIIII  SSSSS    T                            %
     11 %                                                                             %
     12 %                                                                             %
     13 %                        MagickCore Image 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 %
     37 %
     38 */
     39 
     40 /*
     42   Include declarations.
     43 */
     44 #include "MagickCore/studio.h"
     45 #include "MagickCore/blob.h"
     46 #include "MagickCore/blob-private.h"
     47 #include "MagickCore/exception.h"
     48 #include "MagickCore/exception-private.h"
     49 #include "MagickCore/list.h"
     50 #include "MagickCore/memory_.h"
     51 #include "MagickCore/string_.h"
     52 
     53 /*
     55 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     56 %                                                                             %
     57 %                                                                             %
     58 %                                                                             %
     59 %   A p p e n d I m a g e T o L i s t                                         %
     60 %                                                                             %
     61 %                                                                             %
     62 %                                                                             %
     63 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     64 %
     65 %  AppendImageToList() appends the second image list to the end of the first
     66 %  list.  The given image list pointer is left unchanged, unless it was empty.
     67 %
     68 %  The format of the AppendImageToList method is:
     69 %
     70 %      AppendImageToList(Image *images,const Image *image)
     71 %
     72 %  A description of each parameter follows:
     73 %
     74 %    o images: the image list to be appended to.
     75 %
     76 %    o image: the appended image or image list.
     77 %
     78 */
     79 MagickExport void AppendImageToList(Image **images,const Image *append)
     80 {
     81   register Image
     82     *p,
     83     *q;
     84 
     85   assert(images != (Image **) NULL);
     86   if (append == (Image *) NULL)
     87     return;
     88   assert(append->signature == MagickCoreSignature);
     89   if (append->debug != MagickFalse)
     90     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",append->filename);
     91   if ((*images) == (Image *) NULL)
     92     {
     93       *images=(Image *) append;
     94       return;
     95     }
     96   assert((*images)->signature == MagickCoreSignature);
     97   p=GetLastImageInList(*images);
     98   q=GetFirstImageInList(append);
     99   p->next=q;
    100   q->previous=p;
    101 }
    102 
    103 /*
    105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    106 %                                                                             %
    107 %                                                                             %
    108 %                                                                             %
    109 %   C l o n e I m a g e L i s t                                               %
    110 %                                                                             %
    111 %                                                                             %
    112 %                                                                             %
    113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    114 %
    115 %  CloneImageList() returns a duplicate of the image list.
    116 %
    117 %  The format of the CloneImageList method is:
    118 %
    119 %      Image *CloneImageList(const Image *images,ExceptionInfo *exception)
    120 %
    121 %  A description of each parameter follows:
    122 %
    123 %    o images: the image list.
    124 %
    125 %    o exception: return any errors or warnings in this structure.
    126 %
    127 */
    128 MagickExport Image *CloneImageList(const Image *images,ExceptionInfo *exception)
    129 {
    130   Image
    131     *clone,
    132     *image;
    133 
    134   register Image
    135     *p;
    136 
    137   if (images == (Image *) NULL)
    138     return((Image *) NULL);
    139   assert(images->signature == MagickCoreSignature);
    140   while (images->previous != (Image *) NULL)
    141     images=images->previous;
    142   image=(Image *) NULL;
    143   for (p=(Image *) NULL; images != (Image *) NULL; images=images->next)
    144   {
    145     clone=CloneImage(images,0,0,MagickTrue,exception);
    146     if (clone == (Image *) NULL)
    147       {
    148         if (image != (Image *) NULL)
    149           image=DestroyImageList(image);
    150         return((Image *) NULL);
    151       }
    152     if (image == (Image *) NULL)
    153       {
    154         image=clone;
    155         p=image;
    156         continue;
    157       }
    158     p->next=clone;
    159     clone->previous=p;
    160     p=p->next;
    161   }
    162   return(image);
    163 }
    164 
    165 /*
    167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    168 %                                                                             %
    169 %                                                                             %
    170 %                                                                             %
    171 %   C l o n e I m a g e s                                                     %
    172 %                                                                             %
    173 %                                                                             %
    174 %                                                                             %
    175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    176 %
    177 %  CloneImages() clones one or more images from an image sequence, using a
    178 %  comma separated list of image numbers or ranges.
    179 %
    180 %  The numbers start at 0 for the first image in the list, while negative
    181 %  numbers refer to images starting counting from the end of the range. Images
    182 %  may be refered to multiple times to clone them multiple times. Images
    183 %  refered beyond the available number of images in list are ignored.
    184 %
    185 %  Images referenced may be reversed, and results in a clone of those images
    186 %  also being made with a reversed order.
    187 %
    188 %  The format of the CloneImages method is:
    189 %
    190 %      Image *CloneImages(const Image *images,const char *scenes,
    191 %        ExceptionInfo *exception)
    192 %
    193 %  A description of each parameter follows:
    194 %
    195 %    o images: the image sequence.
    196 %
    197 %    o scenes: This character string specifies which scenes to clone
    198 %      (e.g. 1,3-5,7-3,2).
    199 %
    200 %    o exception: return any errors or warnings in this structure.
    201 %
    202 */
    203 MagickExport Image *CloneImages(const Image *images,const char *scenes,
    204   ExceptionInfo *exception)
    205 {
    206   char
    207     *p;
    208 
    209   const Image
    210     *next;
    211 
    212   Image
    213     *clone_images,
    214     *image;
    215 
    216   long
    217     first,
    218     last,
    219     step;
    220 
    221   register ssize_t
    222     i;
    223 
    224   size_t
    225     length;
    226 
    227   assert(images != (const Image *) NULL);
    228   assert(images->signature == MagickCoreSignature);
    229   assert(scenes != (char *) NULL);
    230   if (images->debug != MagickFalse)
    231     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
    232   assert(exception != (ExceptionInfo *) NULL);
    233   assert(exception->signature == MagickCoreSignature);
    234   clone_images=NewImageList();
    235   images=GetFirstImageInList(images);
    236   length=GetImageListLength(images);
    237   for (p=(char *) scenes; *p != '\0';)
    238   {
    239     while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
    240       p++;
    241     first=strtol(p,&p,10);
    242     if (first < 0)
    243       first+=(long) length;
    244     last=first;
    245     while (isspace((int) ((unsigned char) *p)) != 0)
    246       p++;
    247     if (*p == '-')
    248       {
    249         last=strtol(p+1,&p,10);
    250         if (last < 0)
    251           last+=(long) length;
    252       }
    253     for (step=first > last ? -1 : 1; first != (last+step); first+=step)
    254     {
    255       i=0;
    256       for (next=images; next != (Image *) NULL; next=GetNextImageInList(next))
    257       {
    258         if (i == (ssize_t) first)
    259           {
    260             image=CloneImage(next,0,0,MagickTrue,exception);
    261             if (image == (Image *) NULL)
    262               break;
    263             AppendImageToList(&clone_images,image);
    264           }
    265         i++;
    266       }
    267     }
    268   }
    269   return(GetFirstImageInList(clone_images));
    270 }
    271 
    272 /*
    274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    275 %                                                                             %
    276 %                                                                             %
    277 %                                                                             %
    278 %   D e l e t e I m a g e F r o m L i s t                                     %
    279 %                                                                             %
    280 %                                                                             %
    281 %                                                                             %
    282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    283 %
    284 %  DeleteImageFromList() deletes an image from the list. List pointer
    285 %  is moved to the next image, if one is present. See RemoveImageFromList().
    286 %
    287 %  The format of the DeleteImageFromList method is:
    288 %
    289 %      DeleteImageFromList(Image **images)
    290 %
    291 %  A description of each parameter follows:
    292 %
    293 %    o images: the image list.
    294 %
    295 */
    296 MagickExport void DeleteImageFromList(Image **images)
    297 {
    298   Image
    299     *image;
    300 
    301   image=RemoveImageFromList(images);
    302   if (image != (Image *) NULL)
    303     (void) DestroyImage(image);
    304 }
    305 
    306 /*
    308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    309 %                                                                             %
    310 %                                                                             %
    311 %                                                                             %
    312 %   D e l e t e I m a g e s                                                   %
    313 %                                                                             %
    314 %                                                                             %
    315 %                                                                             %
    316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    317 %
    318 %  DeleteImages() deletes one or more images from an image sequence, using a
    319 %  comma separated list of image numbers or ranges.
    320 %
    321 %  The numbers start at 0 for the first image, while negative numbers refer to
    322 %  images starting counting from the end of the range. Images may be refered to
    323 %  multiple times without problems. Image refered beyond the available number
    324 %  of images in list are ignored.
    325 %
    326 %  If the referenced images are in the reverse order, that range will be
    327 %  completely ignored, unlike CloneImages().
    328 %
    329 %  The format of the DeleteImages method is:
    330 %
    331 %      DeleteImages(Image **images,const char *scenes,ExceptionInfo *exception)
    332 %
    333 %  A description of each parameter follows:
    334 %
    335 %    o images: the image sequence.
    336 %
    337 %    o scenes: This character string specifies which scenes to delete
    338 %      (e.g. 1,3-5,-2-6,2).
    339 %
    340 %    o exception: return any errors or warnings in this structure.
    341 %
    342 */
    343 MagickExport void DeleteImages(Image **images,const char *scenes,
    344   ExceptionInfo *exception)
    345 {
    346   char
    347     *p;
    348 
    349   Image
    350     *image;
    351 
    352   long
    353     first,
    354     last;
    355 
    356   MagickBooleanType
    357     *delete_list;
    358 
    359   register ssize_t
    360     i;
    361 
    362   size_t
    363     length;
    364 
    365   assert(images != (Image **) NULL);
    366   assert((*images)->signature == MagickCoreSignature);
    367   assert(scenes != (char *) NULL);
    368   if ((*images)->debug != MagickFalse)
    369     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
    370       (*images)->filename);
    371   assert(exception != (ExceptionInfo *) NULL);
    372   assert(exception->signature == MagickCoreSignature);
    373   *images=GetFirstImageInList(*images);
    374   length=GetImageListLength(*images);
    375   delete_list=(MagickBooleanType *) AcquireQuantumMemory(length,
    376     sizeof(*delete_list));
    377   if (delete_list == (MagickBooleanType *) NULL)
    378     {
    379       (void) ThrowMagickException(exception,GetMagickModule(),
    380         ResourceLimitError,"MemoryAllocationFailed","`%s'",(*images)->filename);
    381       return;
    382     }
    383   image=(*images);
    384   for (i=0; i < (ssize_t) length; i++)
    385     delete_list[i]=MagickFalse;
    386   /*
    387     Note which images will be deleted, avoid duplicates.
    388   */
    389   for (p=(char *) scenes; *p != '\0';)
    390   {
    391     while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
    392       p++;
    393     first=strtol(p,&p,10);
    394     if (first < 0)
    395       first+=(long) length;
    396     last=first;
    397     while (isspace((int) ((unsigned char) *p)) != 0)
    398       p++;
    399     if (*p == '-')
    400       {
    401         last=strtol(p+1,&p,10);
    402         if (last < 0)
    403           last+=(long) length;
    404       }
    405     if (first > last)
    406       continue;
    407     for (i=(ssize_t) first; i <= (ssize_t) last; i++)
    408       if ((i >= 0) && (i < (ssize_t) length))
    409         delete_list[i]=MagickTrue;
    410   }
    411   /*
    412     Delete images marked for deletion, once only.
    413   */
    414   image=(*images);
    415   for (i=0; i < (ssize_t) length; i++)
    416   {
    417     *images=image;
    418     image=GetNextImageInList(image);
    419     if (delete_list[i] != MagickFalse)
    420       DeleteImageFromList(images);
    421   }
    422   (void) RelinquishMagickMemory(delete_list);
    423   *images=GetFirstImageInList(*images);
    424 }
    425 
    426 /*
    428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    429 %                                                                             %
    430 %                                                                             %
    431 %                                                                             %
    432 %   D e s t r o y I m a g e L i s t                                           %
    433 %                                                                             %
    434 %                                                                             %
    435 %                                                                             %
    436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    437 %
    438 %  DestroyImageList() destroys an image list.
    439 %
    440 %  The format of the DestroyImageList method is:
    441 %
    442 %      Image *DestroyImageList(Image *image)
    443 %
    444 %  A description of each parameter follows:
    445 %
    446 %    o image: the image sequence.
    447 %
    448 */
    449 MagickExport Image *DestroyImageList(Image *images)
    450 {
    451   if (images == (Image *) NULL)
    452     return((Image *) NULL);
    453   assert(images->signature == MagickCoreSignature);
    454   if (images->debug != MagickFalse)
    455     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
    456   while (images != (Image *) NULL)
    457     DeleteImageFromList(&images);
    458   return((Image *) NULL);
    459 }
    460 
    461 /*
    463 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    464 %                                                                             %
    465 %                                                                             %
    466 %                                                                             %
    467 %   D u p l i c a t e I m a g e s                                             %
    468 %                                                                             %
    469 %                                                                             %
    470 %                                                                             %
    471 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    472 %
    473 %  DuplicateImages() duplicates one or more images from an image sequence,
    474 %  using a count and a comma separated list of image numbers or ranges.
    475 %
    476 %  The numbers start at 0 for the first image, while negative numbers refer to
    477 %  images starting counting from the end of the range. Images may be refered to
    478 %  multiple times without problems. Image refered beyond the available number
    479 %  of images in list are ignored.
    480 %
    481 %  The format of the DuplicateImages method is:
    482 %
    483 %      Image *DuplicateImages(Image *images,const size_t number_duplicates,
    484 %        const char *scenes,ExceptionInfo *exception)
    485 %
    486 %  A description of each parameter follows:
    487 %
    488 %    o images: the image sequence.
    489 %
    490 %    o number_duplicates: duplicate the image sequence this number of times.
    491 %
    492 %    o scenes: This character string specifies which scenes to duplicate (e.g.
    493 %      1,3-5,-2-6,2).
    494 %
    495 %    o exception: return any errors or warnings in this structure.
    496 %
    497 */
    498 MagickExport Image *DuplicateImages(Image *images,
    499   const size_t number_duplicates,const char *scenes,ExceptionInfo *exception)
    500 {
    501   Image
    502     *clone_images,
    503     *duplicate_images;
    504 
    505   register ssize_t
    506     i;
    507 
    508   /*
    509     Duplicate images.
    510   */
    511   assert(images != (Image *) NULL);
    512   assert(images->signature == MagickCoreSignature);
    513   assert(scenes != (char *) NULL);
    514   if (images->debug != MagickFalse)
    515     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
    516   assert(exception != (ExceptionInfo *) NULL);
    517   assert(exception->signature == MagickCoreSignature);
    518   duplicate_images=NewImageList();
    519   for (i=0; i < (ssize_t) number_duplicates; i++)
    520   {
    521     clone_images=CloneImages(images,scenes,exception);
    522     AppendImageToList(&duplicate_images,clone_images);
    523   }
    524   return(duplicate_images);
    525 }
    526 
    527 /*
    529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    530 %                                                                             %
    531 %                                                                             %
    532 %                                                                             %
    533 %   G e t F i r s t I m a g e I n L i s t                                     %
    534 %                                                                             %
    535 %                                                                             %
    536 %                                                                             %
    537 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    538 %
    539 %  GetFirstImageInList() returns a pointer to the first image in the list.
    540 %
    541 %  The format of the GetFirstImageInList method is:
    542 %
    543 %      Image *GetFirstImageInList(const Image *images)
    544 %
    545 %  A description of each parameter follows:
    546 %
    547 %    o images: the image list.
    548 %
    549 */
    550 MagickExport Image *GetFirstImageInList(const Image *images)
    551 {
    552   register const Image
    553     *p;
    554 
    555   if (images == (Image *) NULL)
    556     return((Image *) NULL);
    557   assert(images->signature == MagickCoreSignature);
    558   for (p=images; p->previous != (Image *) NULL; p=p->previous) ;
    559   return((Image *) p);
    560 }
    561 
    562 /*
    564 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    565 %                                                                             %
    566 %                                                                             %
    567 %                                                                             %
    568 %   G e t I m a g e F r o m L i s t                                           %
    569 %                                                                             %
    570 %                                                                             %
    571 %                                                                             %
    572 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    573 %
    574 %  GetImageFromList() returns an image at the specified index from the image
    575 %  list. Starting with 0 as the first image in the list.
    576 %
    577 %  A negative offset will return the image from the end of the list, such that
    578 %  an index of -1 is the last image.
    579 %
    580 %  If no such image exists at the specified offset a NULL image pointer is
    581 %  returned.  This will only happen if index is less that the negative of
    582 %  the list length, or larger than list length -1.  EG: ( -N to N-1 )
    583 %
    584 %  The format of the GetImageFromList method is:
    585 %
    586 %      Image *GetImageFromList(const Image *images,const ssize_t index)
    587 %
    588 %  A description of each parameter follows:
    589 %
    590 %    o images: the image list.
    591 %
    592 %    o index: the position within the list.
    593 %
    594 */
    595 MagickExport Image *GetImageFromList(const Image *images,const ssize_t index)
    596 {
    597   register const Image
    598     *p;
    599 
    600   register ssize_t
    601     i;
    602 
    603   if (images == (Image *) NULL)
    604     return((Image *) NULL);
    605   assert(images->signature == MagickCoreSignature);
    606   if (images->debug != MagickFalse)
    607     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
    608 
    609   /*
    610     Designed to efficiently find first image (index == 0), or last image
    611     (index == -1) as appropriate, without to go through the whole image list.
    612     That is it tries to avoid 'counting the whole list' to  handle the
    613     most common image indexes.
    614   */
    615   if ( index < 0 )
    616     {
    617       p=GetLastImageInList(images);
    618       for (i=-1; p != (Image *) NULL; p=p->previous)
    619         if (i-- == index)
    620           break;
    621     }
    622   else
    623     {
    624       p=GetFirstImageInList(images);
    625       for (i=0; p != (Image *) NULL; p=p->next)
    626         if (i++ == index)
    627           break;
    628     }
    629   return((Image *) p);
    630 }
    631 
    632 /*
    634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    635 %                                                                             %
    636 %                                                                             %
    637 %                                                                             %
    638 %   G e t I m a g e I n d e x I n L i s t                                     %
    639 %                                                                             %
    640 %                                                                             %
    641 %                                                                             %
    642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    643 %
    644 %  GetImageIndexInList() returns the offset in the list of the specified image.
    645 %
    646 %  The format of the GetImageIndexInList method is:
    647 %
    648 %      ssize_t GetImageIndexInList(const Image *images)
    649 %
    650 %  A description of each parameter follows:
    651 %
    652 %    o images: the image list.
    653 %
    654 */
    655 MagickExport ssize_t GetImageIndexInList(const Image *images)
    656 {
    657   register ssize_t
    658     i;
    659 
    660   if (images == (const Image *) NULL)
    661     return(-1);
    662   assert(images->signature == MagickCoreSignature);
    663   for (i=0; images->previous != (Image *) NULL; i++)
    664     images=images->previous;
    665   return(i);
    666 }
    667 
    668 /*
    670 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    671 %                                                                             %
    672 %                                                                             %
    673 %                                                                             %
    674 %   G e t I m a g e L i s t L e n g t h                                       %
    675 %                                                                             %
    676 %                                                                             %
    677 %                                                                             %
    678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    679 %
    680 %  GetImageListLength() returns the length of the list (the number of images in
    681 %  the list).
    682 %
    683 %  The format of the GetImageListLength method is:
    684 %
    685 %      size_t GetImageListLength(const Image *images)
    686 %
    687 %  A description of each parameter follows:
    688 %
    689 %    o images: the image list.
    690 %
    691 */
    692 MagickExport size_t GetImageListLength(const Image *images)
    693 {
    694   register ssize_t
    695     i;
    696 
    697   if (images == (Image *) NULL)
    698     return(0);
    699   assert(images->signature == MagickCoreSignature);
    700   if (images->debug != MagickFalse)
    701     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
    702   images=GetLastImageInList(images);
    703   for (i=0; images != (Image *) NULL; images=images->previous)
    704     i++;
    705   return((size_t) i);
    706 }
    707 
    708 /*
    710 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    711 %                                                                             %
    712 %                                                                             %
    713 %                                                                             %
    714 %   G e t L a s t I m a g e I n L i s t                                       %
    715 %                                                                             %
    716 %                                                                             %
    717 %                                                                             %
    718 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    719 %
    720 %  GetLastImageInList() returns a pointer to the last image in the list.
    721 %
    722 %  The format of the GetLastImageInList method is:
    723 %
    724 %      Image *GetLastImageInList(const Image *images)
    725 %
    726 %  A description of each parameter follows:
    727 %
    728 %    o images: the image list.
    729 %
    730 */
    731 MagickExport Image *GetLastImageInList(const Image *images)
    732 {
    733   register const Image
    734     *p;
    735 
    736   if (images == (Image *) NULL)
    737     return((Image *) NULL);
    738   assert(images->signature == MagickCoreSignature);
    739   for (p=images; p->next != (Image *) NULL; p=p->next) ;
    740   return((Image *) p);
    741 }
    742 
    743 /*
    745 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    746 %                                                                             %
    747 %                                                                             %
    748 %                                                                             %
    749 %   G e t N e x t I m a g e I n L i s t                                       %
    750 %                                                                             %
    751 %                                                                             %
    752 %                                                                             %
    753 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    754 %
    755 %  GetNextImageInList() returns the next image in the list.
    756 %
    757 %  The format of the GetNextImageInList method is:
    758 %
    759 %      Image *GetNextImageInList(const Image *images)
    760 %
    761 %  A description of each parameter follows:
    762 %
    763 %    o images: the image list.
    764 %
    765 */
    766 MagickExport Image *GetNextImageInList(const Image *images)
    767 {
    768   if (images == (Image *) NULL)
    769     return((Image *) NULL);
    770   assert(images->signature == MagickCoreSignature);
    771   if (images->debug != MagickFalse)
    772     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
    773   return(images->next);
    774 }
    775 
    776 /*
    778 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    779 %                                                                             %
    780 %                                                                             %
    781 %                                                                             %
    782 %   G e t P r e v i o u s I m a g e I n L i s t                               %
    783 %                                                                             %
    784 %                                                                             %
    785 %                                                                             %
    786 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    787 %
    788 %  GetPreviousImageInList() returns the previous image in the list.
    789 %
    790 %  The format of the GetPreviousImageInList method is:
    791 %
    792 %      Image *GetPreviousImageInList(const Image *images)
    793 %
    794 %  A description of each parameter follows:
    795 %
    796 %    o images: the image list.
    797 %
    798 */
    799 MagickExport Image *GetPreviousImageInList(const Image *images)
    800 {
    801   if (images == (Image *) NULL)
    802     return((Image *) NULL);
    803   assert(images->signature == MagickCoreSignature);
    804   return(images->previous);
    805 }
    806 
    807 /*
    809 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    810 %                                                                             %
    811 %                                                                             %
    812 %     I m a g e L i s t T o A r r a y                                         %
    813 %                                                                             %
    814 %                                                                             %
    815 %                                                                             %
    816 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    817 %
    818 %  ImageListToArray() is a convenience method that converts an image list to
    819 %  a sequential array, with a NULL image pointer at the end of the array.
    820 %
    821 %  The images remain part of the original image list, with the array providing
    822 %  an alternative means of indexing the image array.
    823 %
    824 %    group = ImageListToArray(images, exception);
    825 %    while (i = 0; group[i] != (Image *) NULL; i++)
    826 %      printf("%s\n", group[i]->filename);
    827 %    printf("%d images\n", i);
    828 %    group = RelinquishMagickMemory(group);
    829 %
    830 %  The format of the ImageListToArray method is:
    831 %
    832 %      Image **ImageListToArray(const Image *images,ExceptionInfo *exception)
    833 %
    834 %  A description of each parameter follows:
    835 %
    836 %    o image: the image list.
    837 %
    838 %    o exception: return any errors or warnings in this structure.
    839 %
    840 */
    841 MagickExport Image **ImageListToArray(const Image *images,
    842   ExceptionInfo *exception)
    843 {
    844   Image
    845     **group;
    846 
    847   register ssize_t
    848     i;
    849 
    850   if (images == (Image *) NULL)
    851     return((Image **) NULL);
    852   assert(images->signature == MagickCoreSignature);
    853   if (images->debug != MagickFalse)
    854     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
    855   group=(Image **) AcquireQuantumMemory((size_t) GetImageListLength(images)+1UL,
    856     sizeof(*group));
    857   if (group == (Image **) NULL)
    858     {
    859       (void) ThrowMagickException(exception,GetMagickModule(),
    860         ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
    861       return((Image **) NULL);
    862     }
    863   images=GetFirstImageInList(images);
    864   for (i=0; images != (Image *) NULL; images=images->next)
    865     group[i++]=(Image *) images;
    866   group[i]=(Image *) NULL;
    867   return(group);
    868 }
    869 
    870 /*
    872 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    873 %                                                                             %
    874 %                                                                             %
    875 %                                                                             %
    876 %   I n s e r t I m a g e I n L i s t                                         %
    877 %                                                                             %
    878 %                                                                             %
    879 %                                                                             %
    880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    881 %
    882 %  InsertImageInList() insert the given image or image list, into the first
    883 %  image list, immediately AFTER the image pointed to.  The given image list
    884 %  pointer is left unchanged unless previously empty.
    885 %
    886 %  The format of the InsertImageInList method is:
    887 %
    888 %      InsertImageInList(Image **images,Image *insert)
    889 %
    890 %  A description of each parameter follows:
    891 %
    892 %    o images: the image list to insert into.
    893 %
    894 %    o insert: the image list to insert.
    895 %
    896 */
    897 MagickExport void InsertImageInList(Image **images,Image *insert)
    898 {
    899   Image
    900     *split;
    901 
    902   assert(images != (Image **) NULL);
    903   assert(insert != (Image *) NULL);
    904   assert(insert->signature == MagickCoreSignature);
    905   if (insert->debug != MagickFalse)
    906     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",insert->filename);
    907   if ((*images) == (Image *) NULL)
    908     return;
    909   assert((*images)->signature == MagickCoreSignature);
    910   split=SplitImageList(*images);
    911   AppendImageToList(images,insert);
    912   AppendImageToList(images,split);
    913 }
    914 
    915 /*
    917 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    918 %                                                                             %
    919 %                                                                             %
    920 %                                                                             %
    921 %   N e w I m a g e L i s t                                                   %
    922 %                                                                             %
    923 %                                                                             %
    924 %                                                                             %
    925 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    926 %
    927 %  NewImageList() creates an empty image list.
    928 %
    929 %  The format of the NewImageList method is:
    930 %
    931 %      Image *NewImageList(void)
    932 %
    933 */
    934 MagickExport Image *NewImageList(void)
    935 {
    936   return((Image *) NULL);
    937 }
    938 
    939 /*
    941 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    942 %                                                                             %
    943 %                                                                             %
    944 %                                                                             %
    945 %   P r e p e n d I m a g e T o L i s t                                       %
    946 %                                                                             %
    947 %                                                                             %
    948 %                                                                             %
    949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    950 %
    951 %  PrependImageToList() prepends the image to the beginning of the list.
    952 %
    953 %  The format of the PrependImageToList method is:
    954 %
    955 %      PrependImageToList(Image *images,Image *image)
    956 %
    957 %  A description of each parameter follows:
    958 %
    959 %    o images: the image list.
    960 %
    961 %    o image: the image.
    962 %
    963 */
    964 MagickExport void PrependImageToList(Image **images,Image *prepend)
    965 {
    966   if (*images == (Image *) NULL)
    967     {
    968       *images=prepend;
    969       return;
    970     }
    971   AppendImageToList(&prepend,*images);
    972 }
    973 
    974 /*
    976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    977 %                                                                             %
    978 %                                                                             %
    979 %                                                                             %
    980 %   R e m o v e I m a g e F r o m L i s t                                     %
    981 %                                                                             %
    982 %                                                                             %
    983 %                                                                             %
    984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    985 %
    986 %  RemoveImageFromList() removes and returns the image pointed to.
    987 %
    988 %  The given image list pointer is set to point to the next image in list
    989 %  if it exists, otherwise it is set to the previous image, or NULL if list
    990 %  was emptied.
    991 %
    992 %  The format of the RemoveImageFromList method is:
    993 %
    994 %      Image *RemoveImageFromList(Image **images)
    995 %
    996 %  A description of each parameter follows:
    997 %
    998 %    o images: the image list.
    999 %
   1000 */
   1001 MagickExport Image *RemoveImageFromList(Image **images)
   1002 {
   1003   register Image
   1004     *p;
   1005 
   1006   assert(images != (Image **) NULL);
   1007   if ((*images) == (Image *) NULL)
   1008     return((Image *) NULL);
   1009   assert((*images)->signature == MagickCoreSignature);
   1010   if ((*images)->debug != MagickFalse)
   1011     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
   1012       (*images)->filename);
   1013   p=(*images);
   1014   if ((p->previous == (Image *) NULL) && (p->next == (Image *) NULL))
   1015     *images=(Image *) NULL;
   1016   else
   1017     {
   1018       if (p->previous != (Image *) NULL)
   1019         {
   1020           p->previous->next=p->next;
   1021           *images=p->previous;
   1022         }
   1023       if (p->next != (Image *) NULL)
   1024         {
   1025           p->next->previous=p->previous;
   1026           *images=p->next;
   1027         }
   1028       p->previous=(Image *) NULL;
   1029       p->next=(Image *) NULL;
   1030     }
   1031   return(p);
   1032 }
   1033 
   1034 /*
   1036 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1037 %                                                                             %
   1038 %                                                                             %
   1039 %                                                                             %
   1040 %   R e m o v e F i r s t I m a g e F r o m L i s t                           %
   1041 %                                                                             %
   1042 %                                                                             %
   1043 %                                                                             %
   1044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1045 %
   1046 %  RemoveFirstImageFromList() removes and returns the first image in the list.
   1047 %
   1048 %  If the given image list pointer pointed to the removed first image, it is
   1049 %  set to the new first image of list, or NULL if list was emptied, otherwise
   1050 %  it is left as is.
   1051 %
   1052 %  The format of the RemoveFirstImageFromList method is:
   1053 %
   1054 %      Image *RemoveFirstImageFromList(Image **images)
   1055 %
   1056 %  A description of each parameter follows:
   1057 %
   1058 %    o images: the image list.
   1059 %
   1060 */
   1061 MagickExport Image *RemoveFirstImageFromList(Image **images)
   1062 {
   1063   Image
   1064     *image;
   1065 
   1066   assert(images != (Image **) NULL);
   1067   if ((*images) == (Image *) NULL)
   1068     return((Image *) NULL);
   1069   assert((*images)->signature == MagickCoreSignature);
   1070   if ((*images)->debug != MagickFalse)
   1071     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
   1072       (*images)->filename);
   1073   image=(*images);
   1074   while (image->previous != (Image *) NULL)
   1075     image=image->previous;
   1076   if (image == *images)
   1077     *images=(*images)->next;
   1078   if (image->next != (Image *) NULL)
   1079     {
   1080       image->next->previous=(Image *) NULL;
   1081       image->next=(Image *) NULL;
   1082     }
   1083   return(image);
   1084 }
   1085 
   1086 /*
   1088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1089 %                                                                             %
   1090 %                                                                             %
   1091 %                                                                             %
   1092 %   R e m o v e L a s t I m a g e F r o m L i s t                             %
   1093 %                                                                             %
   1094 %                                                                             %
   1095 %                                                                             %
   1096 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1097 %
   1098 %  RemoveLastImageFromList() removes and returns the last image from the list.
   1099 %
   1100 %  If the given image list pointer pointed to the removed last image, it is
   1101 %  set to the new last image of list, or NULL if list was emptied, otherwise
   1102 %  it is left as is.
   1103 %
   1104 %  The format of the RemoveLastImageFromList method is:
   1105 %
   1106 %      Image *RemoveLastImageFromList(Image **images)
   1107 %
   1108 %  A description of each parameter follows:
   1109 %
   1110 %    o images: the image list.
   1111 %
   1112 */
   1113 MagickExport Image *RemoveLastImageFromList(Image **images)
   1114 {
   1115   Image
   1116     *image;
   1117 
   1118   assert(images != (Image **) NULL);
   1119   if ((*images) == (Image *) NULL)
   1120     return((Image *) NULL);
   1121   assert((*images)->signature == MagickCoreSignature);
   1122   if ((*images)->debug != MagickFalse)
   1123     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
   1124       (*images)->filename);
   1125   image=(*images);
   1126   while (image->next != (Image *) NULL)
   1127     image=image->next;
   1128   if (image == *images)
   1129     *images=(*images)->previous;
   1130   if (image->previous != (Image *) NULL)
   1131     {
   1132       image->previous->next=(Image *) NULL;
   1133       image->previous=(Image *) NULL;
   1134     }
   1135   return(image);
   1136 }
   1137 
   1138 /*
   1140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1141 %                                                                             %
   1142 %                                                                             %
   1143 %                                                                             %
   1144 %   R e p l a c e I m a g e I n L i s t                                       %
   1145 %                                                                             %
   1146 %                                                                             %
   1147 %                                                                             %
   1148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1149 %
   1150 %  ReplaceImageInList() replaces an image in the list with the given image, or
   1151 %  list of images.  Old image is destroyed.
   1152 %
   1153 %  The images list pointer is set to point to the first image of the inserted
   1154 %  list of images.
   1155 %
   1156 %  The format of the ReplaceImageInList method is:
   1157 %
   1158 %      ReplaceImageInList(Image **images,Image *replace)
   1159 %
   1160 %  A description of each parameter follows:
   1161 %
   1162 %    o images: the list and pointer to image to replace
   1163 %
   1164 %    o replace: the image or image list replacing the original
   1165 %
   1166 */
   1167 MagickExport void ReplaceImageInList(Image **images,Image *replace)
   1168 {
   1169   assert(images != (Image **) NULL);
   1170   assert(replace != (Image *) NULL);
   1171   assert(replace->signature == MagickCoreSignature);
   1172   if (replace->debug != MagickFalse)
   1173     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",replace->filename);
   1174   if ((*images) == (Image *) NULL)
   1175     return;
   1176   assert((*images)->signature == MagickCoreSignature);
   1177 
   1178   /* link next pointer */
   1179   replace=GetLastImageInList(replace);
   1180   replace->next=(*images)->next;
   1181   if (replace->next != (Image *) NULL)
   1182     replace->next->previous=replace;
   1183 
   1184   /* link previous pointer - set images position to first replacement image */
   1185   replace=GetFirstImageInList(replace);
   1186   replace->previous=(*images)->previous;
   1187   if (replace->previous != (Image *) NULL)
   1188     replace->previous->next=replace;
   1189 
   1190   /* destroy the replaced image that was in images */
   1191   (void) DestroyImage(*images);
   1192   (*images)=replace;
   1193 }
   1194 
   1195 /*
   1197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1198 %                                                                             %
   1199 %                                                                             %
   1200 %                                                                             %
   1201 %   R e p l a c e I m a g e I n L i s t R e t u r n L a s t                   %
   1202 %                                                                             %
   1203 %                                                                             %
   1204 %                                                                             %
   1205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1206 %
   1207 %  ReplaceImageInListReturnLast() is exactly as ReplaceImageInList() except
   1208 %  the images pointer is set to the last image in the list of replacemen
   1209 %  images.
   1210 %
   1211 %  This allows you to simply use GetNextImageInList() to go to the image
   1212 %  that follows the just replaced image, even if a list of replacement images
   1213 %  was inserted.
   1214 %
   1215 %  The format of the ReplaceImageInList method is:
   1216 %
   1217 %      ReplaceImageInListReturnLast(Image **images,Image *replace)
   1218 %
   1219 %  A description of each parameter follows:
   1220 %
   1221 %    o images: the list and pointer to image to replace
   1222 %
   1223 %    o replace: the image or image list replacing the original
   1224 %
   1225 */
   1226 MagickExport void ReplaceImageInListReturnLast(Image **images,Image *replace)
   1227 {
   1228   assert(images != (Image **) NULL);
   1229   assert(replace != (Image *) NULL);
   1230   assert(replace->signature == MagickCoreSignature);
   1231   if (replace->debug != MagickFalse)
   1232     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",replace->filename);
   1233   if ((*images) == (Image *) NULL)
   1234     return;
   1235   assert((*images)->signature == MagickCoreSignature);
   1236 
   1237   /* link previous pointer */
   1238   replace=GetFirstImageInList(replace);
   1239   replace->previous=(*images)->previous;
   1240   if (replace->previous != (Image *) NULL)
   1241     replace->previous->next=replace;
   1242 
   1243   /* link next pointer - set images position to last replacement image */
   1244   replace=GetLastImageInList(replace);
   1245   replace->next=(*images)->next;
   1246   if (replace->next != (Image *) NULL)
   1247     replace->next->previous=replace;
   1248 
   1249   /* destroy the replaced image that was in images */
   1250   (void) DestroyImage(*images);
   1251   (*images)=replace;
   1252 }
   1253 
   1254 /*
   1256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1257 %                                                                             %
   1258 %                                                                             %
   1259 %                                                                             %
   1260 %   R e v e r s e I m a g e L i s t                                           %
   1261 %                                                                             %
   1262 %                                                                             %
   1263 %                                                                             %
   1264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1265 %
   1266 %  ReverseImageList() reverses the order of an image list.
   1267 %  The list pointer is reset to that start of the re-ordered list.
   1268 %
   1269 %  The format of the ReverseImageList method is:
   1270 %
   1271 %      void ReverseImageList(Image **images)
   1272 %
   1273 %  A description of each parameter follows:
   1274 %
   1275 %    o images: the image list.
   1276 %
   1277 */
   1278 MagickExport void ReverseImageList(Image **images)
   1279 {
   1280   Image
   1281     *next;
   1282 
   1283   register Image
   1284     *p;
   1285 
   1286   assert(images != (Image **) NULL);
   1287   if ((*images) == (Image *) NULL)
   1288     return;
   1289   assert((*images)->signature == MagickCoreSignature);
   1290   if ((*images)->debug != MagickFalse)
   1291     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
   1292       (*images)->filename);
   1293   for (p=(*images); p->next != (Image *) NULL; p=p->next) ;
   1294   *images=p;
   1295   for ( ; p != (Image *) NULL; p=p->next)
   1296   {
   1297     next=p->next;
   1298     p->next=p->previous;
   1299     p->previous=next;
   1300   }
   1301 }
   1302 
   1303 /*
   1305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1306 %                                                                             %
   1307 %                                                                             %
   1308 %                                                                             %
   1309 %   S p l i c e I m a g e I n t o L i s t                                     %
   1310 %                                                                             %
   1311 %                                                                             %
   1312 %                                                                             %
   1313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1314 %
   1315 %  SpliceImageIntoList() removes 'length' images from the list and replaces
   1316 %  them with the specified splice. Removed images are returned.
   1317 %
   1318 %  The format of the SpliceImageIntoList method is:
   1319 %
   1320 %      SpliceImageIntoList(Image **images,const size_t,
   1321 %        const Image *splice)
   1322 %
   1323 %  A description of each parameter follows:
   1324 %
   1325 %    o images: the image list.
   1326 %
   1327 %    o length: the length of the image list to remove.
   1328 %
   1329 %    o splice: Replace the removed image list with this list.
   1330 %
   1331 */
   1332 MagickExport Image *SpliceImageIntoList(Image **images,
   1333   const size_t length,const Image *splice)
   1334 {
   1335   Image
   1336     *image,
   1337     *split;
   1338 
   1339   register size_t
   1340     i;
   1341 
   1342   assert(images != (Image **) NULL);
   1343   assert(splice != (Image *) NULL);
   1344   assert(splice->signature == MagickCoreSignature);
   1345   if ((*images) == (Image *) NULL)
   1346     return((Image *) NULL);
   1347   assert((*images)->signature == MagickCoreSignature);
   1348   if ((*images)->debug != MagickFalse)
   1349     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
   1350       (*images)->filename);
   1351   split=SplitImageList(*images);
   1352   AppendImageToList(images,splice);
   1353   image=(Image *) NULL;
   1354   for (i=0; (i < length) && (split != (Image *) NULL); i++)
   1355     AppendImageToList(&image,RemoveImageFromList(&split));
   1356   AppendImageToList(images,split);
   1357   return(image);
   1358 }
   1359 
   1360 /*
   1362 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1363 %                                                                             %
   1364 %                                                                             %
   1365 %                                                                             %
   1366 %   S p l i t I m a g e L i s t                                               %
   1367 %                                                                             %
   1368 %                                                                             %
   1369 %                                                                             %
   1370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1371 %
   1372 %  SplitImageList() splits an image into two lists, after given image
   1373 %  The list that was split off is returned, which may be empty.
   1374 %
   1375 %  The format of the SplitImageList method is:
   1376 %
   1377 %      Image *SplitImageList(Image *images)
   1378 %
   1379 %  A description of each parameter follows:
   1380 %
   1381 %    o images: the image list.
   1382 %
   1383 */
   1384 MagickExport Image *SplitImageList(Image *images)
   1385 {
   1386   if ((images == (Image *) NULL) || (images->next == (Image *) NULL))
   1387     return((Image *) NULL);
   1388   images=images->next;
   1389   images->previous->next=(Image *) NULL;
   1390   images->previous=(Image *) NULL;
   1391   return(images);
   1392 }
   1393 
   1394 /*
   1396 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1397 %                                                                             %
   1398 %                                                                             %
   1399 %                                                                             %
   1400 +   S y n c I m a g e L i s t                                                 %
   1401 %                                                                             %
   1402 %                                                                             %
   1403 %                                                                             %
   1404 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1405 %
   1406 %  SyncImageList() synchronizes the scene numbers in an image list.
   1407 %
   1408 %  The format of the SyncImageList method is:
   1409 %
   1410 %      void SyncImageList(Image *images)
   1411 %
   1412 %  A description of each parameter follows:
   1413 %
   1414 %    o images: the image list.
   1415 %
   1416 */
   1417 MagickExport void SyncImageList(Image *images)
   1418 {
   1419   register Image
   1420     *p,
   1421     *q;
   1422 
   1423   if (images == (Image *) NULL)
   1424     return;
   1425   assert(images->signature == MagickCoreSignature);
   1426   for (p=images; p != (Image *) NULL; p=p->next)
   1427   {
   1428     for (q=p->next; q != (Image *) NULL; q=q->next)
   1429       if (p->scene == q->scene)
   1430         break;
   1431     if (q != (Image *) NULL)
   1432       break;
   1433   }
   1434   if (p == (Image *) NULL)
   1435     return;
   1436   for (p=images->next; p != (Image *) NULL; p=p->next)
   1437     p->scene=p->previous->scene+1;
   1438 }
   1439 
   1440 /*
   1442 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1443 %                                                                             %
   1444 %                                                                             %
   1445 %                                                                             %
   1446 +   S y n c N e x t I m a g e I n L i s t                                     %
   1447 %                                                                             %
   1448 %                                                                             %
   1449 %                                                                             %
   1450 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1451 %
   1452 %  SyncNextImageInList() returns the next image in the list after the blob
   1453 %  referenced is synchronized with the current image.
   1454 %
   1455 %  The format of the SyncNextImageInList method is:
   1456 %
   1457 %      Image *SyncNextImageInList(const Image *images)
   1458 %
   1459 %  A description of each parameter follows:
   1460 %
   1461 %    o images: the image list.
   1462 %
   1463 */
   1464 MagickExport Image *SyncNextImageInList(const Image *images)
   1465 {
   1466   if (images == (Image *) NULL)
   1467     return((Image *) NULL);
   1468   assert(images->signature == MagickCoreSignature);
   1469   if (images->next == (Image *) NULL)
   1470     return((Image *) NULL);
   1471   if (images->blob != images->next->blob)
   1472     {
   1473       DestroyBlob(images->next);
   1474       images->next->blob=ReferenceBlob(images->blob);
   1475     }
   1476   images->next->compression=images->compression;
   1477   images->next->endian=images->endian;
   1478   return(images->next);
   1479 }
   1480