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