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