]> granicus.if.org Git - imagemagick/blob - MagickCore/list.c
4240b2414a72e13591281a7bcb13a360c2678a44
[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 %                                John Cristy                                  %
17 %                               December 2002                                 %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
21 %  dedicated to making software imaging solutions freely available.           %
22 %                                                                             %
23 %  You may not use this file except in compliance with the License.  You may  %
24 %  obtain a copy of the License at                                            %
25 %                                                                             %
26 %    http://www.imagemagick.org/script/license.php                            %
27 %                                                                             %
28 %  Unless required by applicable law or agreed to in writing, software        %
29 %  distributed under the License is distributed on an "AS IS" BASIS,          %
30 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
31 %  See the License for the specific language governing permissions and        %
32 %  limitations under the License.                                             %
33 %                                                                             %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %
37 %
38 */
39 \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 == MagickSignature);
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 == MagickSignature);
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 == MagickSignature);
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 == MagickSignature);
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 == MagickSignature);
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 == MagickSignature);
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 == MagickSignature);
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 duplicate deleted
382   */
383   for (p=(char *) scenes; *p != '\0';)
384   {
385     while ((isspace((int) *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   }
417   (void) RelinquishMagickMemory(delete_list);
418   *images=GetFirstImageInList(*images);
419 }
420 \f
421 /*
422 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
423 %                                                                             %
424 %                                                                             %
425 %                                                                             %
426 %   D e s t r o y I m a g e L i s t                                           %
427 %                                                                             %
428 %                                                                             %
429 %                                                                             %
430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
431 %
432 %  DestroyImageList() destroys an image list.
433 %
434 %  The format of the DestroyImageList method is:
435 %
436 %      Image *DestroyImageList(Image *image)
437 %
438 %  A description of each parameter follows:
439 %
440 %    o image: the image sequence.
441 %
442 */
443 MagickExport Image *DestroyImageList(Image *images)
444 {
445   if (images == (Image *) NULL)
446     return((Image *) NULL);
447   assert(images->signature == MagickSignature);
448   if (images->debug != MagickFalse)
449     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
450   while (images != (Image *) NULL)
451     DeleteImageFromList(&images);
452   return((Image *) NULL);
453 }
454 \f
455 /*
456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
457 %                                                                             %
458 %                                                                             %
459 %                                                                             %
460 %   D u p l i c a t e I m a g e s                                             %
461 %                                                                             %
462 %                                                                             %
463 %                                                                             %
464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465 %
466 %  DuplicateImages() duplicates one or more images from an image sequence,
467 %  using a count and a comma separated list of image numbers or ranges.
468 %
469 %  The numbers start at 0 for the first image, while negative numbers refer to
470 %  images starting counting from the end of the range. Images may be refered to
471 %  multiple times without problems. Image refered beyond the available number
472 %  of images in list are ignored.
473 %
474 %  The format of the DuplicateImages method is:
475 %
476 %      Image *DuplicateImages(Image *images,const size_t number_duplicates,
477 %        const char *scenes,ExceptionInfo *exception)
478 %
479 %  A description of each parameter follows:
480 %
481 %    o images: the image sequence.
482 %
483 %    o number_duplicates: duplicate the image sequence this number of times.
484 %
485 %    o scenes: This character string specifies which scenes to duplicate (e.g.
486 %      1,3-5,-2-6,2).
487 %
488 %    o exception: return any errors or warnings in this structure.
489 %
490 */
491 MagickExport Image *DuplicateImages(Image *images,
492   const size_t number_duplicates,const char *scenes,ExceptionInfo *exception)
493 {
494   Image
495     *clone_images,
496     *duplicate_images;
497
498   register ssize_t
499     i;
500
501   /*
502     Duplicate images.
503   */
504   assert(images != (Image *) NULL);
505   assert(images->signature == MagickSignature);
506   assert(scenes != (char *) NULL);
507   if (images->debug != MagickFalse)
508     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
509   assert(exception != (ExceptionInfo *) NULL);
510   assert(exception->signature == MagickSignature);
511   duplicate_images=NewImageList();
512   for (i=0; i < (ssize_t) number_duplicates; i++)
513   {
514     clone_images=CloneImages(images,scenes,exception);
515     AppendImageToList(&duplicate_images,clone_images);
516   }
517   return(duplicate_images);
518 }
519 \f
520 /*
521 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
522 %                                                                             %
523 %                                                                             %
524 %                                                                             %
525 %   G e t F i r s t I m a g e I n L i s t                                     %
526 %                                                                             %
527 %                                                                             %
528 %                                                                             %
529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
530 %
531 %  GetFirstImageInList() returns a pointer to the first image in the list.
532 %
533 %  The format of the GetFirstImageInList method is:
534 %
535 %      Image *GetFirstImageInList(const Image *images)
536 %
537 %  A description of each parameter follows:
538 %
539 %    o images: the image list.
540 %
541 */
542 MagickExport Image *GetFirstImageInList(const Image *images)
543 {
544   register const Image
545     *p;
546
547   if (images == (Image *) NULL)
548     return((Image *) NULL);
549   assert(images->signature == MagickSignature);
550   for (p=images; p->previous != (Image *) NULL; p=p->previous) ;
551   return((Image *) p);
552 }
553 \f
554 /*
555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
556 %                                                                             %
557 %                                                                             %
558 %                                                                             %
559 %   G e t I m a g e F r o m L i s t                                           %
560 %                                                                             %
561 %                                                                             %
562 %                                                                             %
563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
564 %
565 %  GetImageFromList() returns an image at the specified index from the image
566 %  list. Starting with 0 as the first image in the list.
567 %
568 %  A negative offset will return the image from the end of the list, such that
569 %  an index of -1 is the last image.
570 %
571 %  If no such image exists at the specified offset a NULL image pointer is
572 %  returned.  This will only happen if index is less that the negative of
573 %  the list length, or larger than list length -1.  EG: ( -N to N-1 )
574 %
575 %  The format of the GetImageFromList method is:
576 %
577 %      Image *GetImageFromList(const Image *images,const ssize_t index)
578 %
579 %  A description of each parameter follows:
580 %
581 %    o images: the image list.
582 %
583 %    o index: the position within the list.
584 %
585 */
586 MagickExport Image *GetImageFromList(const Image *images,const ssize_t index)
587 {
588   register const Image
589     *p;
590
591   register ssize_t
592     i;
593
594   if (images == (Image *) NULL)
595     return((Image *) NULL);
596   assert(images->signature == MagickSignature);
597   if (images->debug != MagickFalse)
598     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
599
600   /*
601     Designed to efficiently find first image (index == 0), or last image
602     (index == -1) as appropriate, without to go through the whole image list.
603     That is it tries to avoid 'counting the whole list' to  handle the
604     most common image indexes.
605   */
606   if ( index < 0 )
607     {
608       p=GetLastImageInList(images);
609       for (i=-1; p != (Image *) NULL; p=p->previous)
610         if (i-- == index)
611           break;
612     }
613   else
614     {
615       p=GetFirstImageInList(images);
616       for (i=0; p != (Image *) NULL; p=p->next)
617         if (i++ == index)
618           break;
619     }
620   return((Image *) p);
621 }
622 \f
623 /*
624 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
625 %                                                                             %
626 %                                                                             %
627 %                                                                             %
628 %   G e t I m a g e I n d e x I n L i s t                                     %
629 %                                                                             %
630 %                                                                             %
631 %                                                                             %
632 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
633 %
634 %  GetImageIndexInList() returns the offset in the list of the specified image.
635 %
636 %  The format of the GetImageIndexInList method is:
637 %
638 %      ssize_t GetImageIndexInList(const Image *images)
639 %
640 %  A description of each parameter follows:
641 %
642 %    o images: the image list.
643 %
644 */
645 MagickExport ssize_t GetImageIndexInList(const Image *images)
646 {
647   register ssize_t
648     i;
649
650   if (images == (const Image *) NULL)
651     return(-1);
652   assert(images->signature == MagickSignature);
653   for (i=0; images->previous != (Image *) NULL; i++)
654     images=images->previous;
655   return(i);
656 }
657 \f
658 /*
659 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
660 %                                                                             %
661 %                                                                             %
662 %                                                                             %
663 %   G e t I m a g e L i s t L e n g t h                                       %
664 %                                                                             %
665 %                                                                             %
666 %                                                                             %
667 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
668 %
669 %  GetImageListLength() returns the length of the list (the number of images in
670 %  the list).
671 %
672 %  The format of the GetImageListLength method is:
673 %
674 %      size_t GetImageListLength(const Image *images)
675 %
676 %  A description of each parameter follows:
677 %
678 %    o images: the image list.
679 %
680 */
681 MagickExport size_t GetImageListLength(const Image *images)
682 {
683   register ssize_t
684     i;
685
686   if (images == (Image *) NULL)
687     return(0);
688   assert(images->signature == MagickSignature);
689   if (images->debug != MagickFalse)
690     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
691   images=GetLastImageInList(images);
692   for (i=0; images != (Image *) NULL; images=images->previous)
693     i++;
694   return((size_t) i);
695 }
696 \f
697 /*
698 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
699 %                                                                             %
700 %                                                                             %
701 %                                                                             %
702 %   G e t L a s t I m a g e I n L i s t                                       %
703 %                                                                             %
704 %                                                                             %
705 %                                                                             %
706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
707 %
708 %  GetLastImageInList() returns a pointer to the last image in the list.
709 %
710 %  The format of the GetLastImageInList method is:
711 %
712 %      Image *GetLastImageInList(const Image *images)
713 %
714 %  A description of each parameter follows:
715 %
716 %    o images: the image list.
717 %
718 */
719 MagickExport Image *GetLastImageInList(const Image *images)
720 {
721   register const Image
722     *p;
723
724   if (images == (Image *) NULL)
725     return((Image *) NULL);
726   assert(images->signature == MagickSignature);
727   for (p=images; p->next != (Image *) NULL; p=p->next) ;
728   return((Image *) p);
729 }
730 \f
731 /*
732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
733 %                                                                             %
734 %                                                                             %
735 %                                                                             %
736 %   G e t N e x t I m a g e I n L i s t                                       %
737 %                                                                             %
738 %                                                                             %
739 %                                                                             %
740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
741 %
742 %  GetNextImageInList() returns the next image in the list.
743 %
744 %  The format of the GetNextImageInList method is:
745 %
746 %      Image *GetNextImageInList(const Image *images)
747 %
748 %  A description of each parameter follows:
749 %
750 %    o images: the image list.
751 %
752 */
753 MagickExport Image *GetNextImageInList(const Image *images)
754 {
755   if (images == (Image *) NULL)
756     return((Image *) NULL);
757   assert(images->signature == MagickSignature);
758   if (images->debug != MagickFalse)
759     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
760   return(images->next);
761 }
762 \f
763 /*
764 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
765 %                                                                             %
766 %                                                                             %
767 %                                                                             %
768 %   G e t P r e v i o u s I m a g e I n L i s t                               %
769 %                                                                             %
770 %                                                                             %
771 %                                                                             %
772 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
773 %
774 %  GetPreviousImageInList() returns the previous image in the list.
775 %
776 %  The format of the GetPreviousImageInList method is:
777 %
778 %      Image *GetPreviousImageInList(const Image *images)
779 %
780 %  A description of each parameter follows:
781 %
782 %    o images: the image list.
783 %
784 */
785 MagickExport Image *GetPreviousImageInList(const Image *images)
786 {
787   if (images == (Image *) NULL)
788     return((Image *) NULL);
789   assert(images->signature == MagickSignature);
790   return(images->previous);
791 }
792 \f
793 /*
794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
795 %                                                                             %
796 %                                                                             %
797 %     I m a g e L i s t T o A r r a y                                         %
798 %                                                                             %
799 %                                                                             %
800 %                                                                             %
801 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
802 %
803 %  ImageListToArray() is a convenience method that converts an image list to
804 %  a sequential array, with a NULL image pointer at the end of the array.
805 %
806 %  The images remain part of the original image list, with the array providing
807 %  an alternative means of indexing the image array.
808 %
809 %    group = ImageListToArray(images, exception);
810 %    while (i = 0; group[i] != (Image *) NULL; i++)
811 %      printf("%s\n", group[i]->filename);
812 %    printf("%d images\n", i);
813 %    group = RelinquishMagickMemory(group);
814 %
815 %  The format of the ImageListToArray method is:
816 %
817 %      Image **ImageListToArray(const Image *images,ExceptionInfo *exception)
818 %
819 %  A description of each parameter follows:
820 %
821 %    o image: the image list.
822 %
823 %    o exception: return any errors or warnings in this structure.
824 %
825 */
826 MagickExport Image **ImageListToArray(const Image *images,
827   ExceptionInfo *exception)
828 {
829   Image
830     **group;
831
832   register ssize_t
833     i;
834
835   if (images == (Image *) NULL)
836     return((Image **) NULL);
837   assert(images->signature == MagickSignature);
838   if (images->debug != MagickFalse)
839     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
840   group=(Image **) AcquireQuantumMemory((size_t) GetImageListLength(images)+1UL,
841     sizeof(*group));
842   if (group == (Image **) NULL)
843     {
844       (void) ThrowMagickException(exception,GetMagickModule(),
845         ResourceLimitError,"MemoryAllocationFailed","'%s'",images->filename);
846       return((Image **) NULL);
847     }
848   images=GetFirstImageInList(images);
849   for (i=0; images != (Image *) NULL; images=images->next)
850     group[i++]=(Image *) images;
851   group[i]=(Image *) NULL;
852   return(group);
853 }
854 \f
855 /*
856 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
857 %                                                                             %
858 %                                                                             %
859 %                                                                             %
860 %   I n s e r t I m a g e I n L i s t                                         %
861 %                                                                             %
862 %                                                                             %
863 %                                                                             %
864 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
865 %
866 %  InsertImageInList() insert the given image or image list, into the first
867 %  image list, immediately AFTER the image pointed to.  The given image list
868 %  pointer is left unchanged unless previously empty.
869 %
870 %  The format of the InsertImageInList method is:
871 %
872 %      InsertImageInList(Image **images,Image *insert)
873 %
874 %  A description of each parameter follows:
875 %
876 %    o images: the image list to insert into.
877 %
878 %    o insert: the image list to insert.
879 %
880 */
881 MagickExport void InsertImageInList(Image **images,Image *insert)
882 {
883   Image
884     *split;
885
886   assert(images != (Image **) NULL);
887   assert(insert != (Image *) NULL);
888   assert(insert->signature == MagickSignature);
889   if (insert->debug != MagickFalse)
890     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",insert->filename);
891   if ((*images) == (Image *) NULL)
892     return;
893   assert((*images)->signature == MagickSignature);
894   split=SplitImageList(*images);
895   AppendImageToList(images,insert);
896   AppendImageToList(images,split);
897 }
898 \f
899 /*
900 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
901 %                                                                             %
902 %                                                                             %
903 %                                                                             %
904 %   N e w I m a g e L i s t                                                   %
905 %                                                                             %
906 %                                                                             %
907 %                                                                             %
908 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
909 %
910 %  NewImageList() creates an empty image list.
911 %
912 %  The format of the NewImageList method is:
913 %
914 %      Image *NewImageList(void)
915 %
916 */
917 MagickExport Image *NewImageList(void)
918 {
919   return((Image *) NULL);
920 }
921 \f
922 /*
923 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
924 %                                                                             %
925 %                                                                             %
926 %                                                                             %
927 %   P r e p e n d I m a g e T o L i s t                                       %
928 %                                                                             %
929 %                                                                             %
930 %                                                                             %
931 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
932 %
933 %  PrependImageToList() prepends the image to the beginning of the list.
934 %
935 %  The format of the PrependImageToList method is:
936 %
937 %      PrependImageToList(Image *images,Image *image)
938 %
939 %  A description of each parameter follows:
940 %
941 %    o images: the image list.
942 %
943 %    o image: the image.
944 %
945 */
946 MagickExport void PrependImageToList(Image **images,Image *prepend)
947 {
948   if (*images == (Image *) NULL)
949     {
950       *images=prepend;
951       return;
952     }
953   AppendImageToList(&prepend,*images);
954 }
955 \f
956 /*
957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
958 %                                                                             %
959 %                                                                             %
960 %                                                                             %
961 %   R e m o v e I m a g e F r o m L i s t                                     %
962 %                                                                             %
963 %                                                                             %
964 %                                                                             %
965 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
966 %
967 %  RemoveImageFromList() removes and returns the image pointed to.
968 %
969 %  The given image list pointer is set to point to the next image in list
970 %  if it exists, otherwise it is set to the previous image, or NULL if list
971 %  was emptied.
972 %
973 %  The format of the RemoveImageFromList method is:
974 %
975 %      Image *RemoveImageFromList(Image **images)
976 %
977 %  A description of each parameter follows:
978 %
979 %    o images: the image list.
980 %
981 */
982 MagickExport Image *RemoveImageFromList(Image **images)
983 {
984   register Image
985     *p;
986
987   assert(images != (Image **) NULL);
988   if ((*images) == (Image *) NULL)
989     return((Image *) NULL);
990   assert((*images)->signature == MagickSignature);
991   if ((*images)->debug != MagickFalse)
992     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
993       (*images)->filename);
994   p=(*images);
995   if ((p->previous == (Image *) NULL) && (p->next == (Image *) NULL))
996     *images=(Image *) NULL;
997   else
998     {
999       if (p->previous != (Image *) NULL)
1000         {
1001           p->previous->next=p->next;
1002           *images=p->previous;
1003         }
1004       if (p->next != (Image *) NULL)
1005         {
1006           p->next->previous=p->previous;
1007           *images=p->next;
1008         }
1009       p->previous=(Image *) NULL;
1010       p->next=(Image *) NULL;
1011     }
1012   return(p);
1013 }
1014 \f
1015 /*
1016 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1017 %                                                                             %
1018 %                                                                             %
1019 %                                                                             %
1020 %   R e m o v e F i r s t I m a g e F r o m L i s t                           %
1021 %                                                                             %
1022 %                                                                             %
1023 %                                                                             %
1024 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1025 %
1026 %  RemoveFirstImageFromList() removes and returns the first image in the list.
1027 %
1028 %  If the given image list pointer pointed to the removed first image, it is
1029 %  set to the new first image of list, or NULL if list was emptied, otherwise
1030 %  it is left as is.
1031 %
1032 %  The format of the RemoveFirstImageFromList method is:
1033 %
1034 %      Image *RemoveFirstImageFromList(Image **images)
1035 %
1036 %  A description of each parameter follows:
1037 %
1038 %    o images: the image list.
1039 %
1040 */
1041 MagickExport Image *RemoveFirstImageFromList(Image **images)
1042 {
1043   Image
1044     *image;
1045
1046   assert(images != (Image **) NULL);
1047   if ((*images) == (Image *) NULL)
1048     return((Image *) NULL);
1049   assert((*images)->signature == MagickSignature);
1050   if ((*images)->debug != MagickFalse)
1051     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1052       (*images)->filename);
1053   image=(*images);
1054   while (image->previous != (Image *) NULL)
1055     image=image->previous;
1056   if (image == *images)
1057     *images=(*images)->next;
1058   if (image->next != (Image *) NULL)
1059     {
1060       image->next->previous=(Image *) NULL;
1061       image->next=(Image *) NULL;
1062     }
1063   return(image);
1064 }
1065 \f
1066 /*
1067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1068 %                                                                             %
1069 %                                                                             %
1070 %                                                                             %
1071 %   R e m o v e L a s t I m a g e F r o m L i s t                             %
1072 %                                                                             %
1073 %                                                                             %
1074 %                                                                             %
1075 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1076 %
1077 %  RemoveLastImageFromList() removes and returns the last image from the list.
1078 %
1079 %  If the given image list pointer pointed to the removed last image, it is
1080 %  set to the new last image of list, or NULL if list was emptied, otherwise
1081 %  it is left as is.
1082 %
1083 %  The format of the RemoveLastImageFromList method is:
1084 %
1085 %      Image *RemoveLastImageFromList(Image **images)
1086 %
1087 %  A description of each parameter follows:
1088 %
1089 %    o images: the image list.
1090 %
1091 */
1092 MagickExport Image *RemoveLastImageFromList(Image **images)
1093 {
1094   Image
1095     *image;
1096
1097   assert(images != (Image **) NULL);
1098   if ((*images) == (Image *) NULL)
1099     return((Image *) NULL);
1100   assert((*images)->signature == MagickSignature);
1101   if ((*images)->debug != MagickFalse)
1102     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1103       (*images)->filename);
1104   image=(*images);
1105   while (image->next != (Image *) NULL)
1106     image=image->next;
1107   if (image == *images)
1108     *images=(*images)->previous;
1109   if (image->previous != (Image *) NULL)
1110     {
1111       image->previous->next=(Image *) NULL;
1112       image->previous=(Image *) NULL;
1113     }
1114   return(image);
1115 }
1116 \f
1117 /*
1118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1119 %                                                                             %
1120 %                                                                             %
1121 %                                                                             %
1122 %   R e p l a c e I m a g e I n L i s t                                       %
1123 %                                                                             %
1124 %                                                                             %
1125 %                                                                             %
1126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1127 %
1128 %  ReplaceImageInList() replaces an image in the list with the given image, or
1129 %  list of images.  Old image is destroyed.
1130 %
1131 %  The images list pointer is set to point to the first image of the inserted
1132 %  list of images.
1133 %
1134 %  The format of the ReplaceImageInList method is:
1135 %
1136 %      ReplaceImageInList(Image **images,Image *replace)
1137 %
1138 %  A description of each parameter follows:
1139 %
1140 %    o images: the list and pointer to image to replace
1141 %
1142 %    o replace: the image or image list replacing the original
1143 %
1144 */
1145 MagickExport void ReplaceImageInList(Image **images,Image *replace)
1146 {
1147   assert(images != (Image **) NULL);
1148   assert(replace != (Image *) NULL);
1149   assert(replace->signature == MagickSignature);
1150   if (replace->debug != MagickFalse)
1151     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",replace->filename);
1152   if ((*images) == (Image *) NULL)
1153     return;
1154   assert((*images)->signature == MagickSignature);
1155
1156   /* link next pointer */
1157   replace=GetLastImageInList(replace);
1158   replace->next=(*images)->next;
1159   if (replace->next != (Image *) NULL)
1160     replace->next->previous=replace;
1161
1162   /* link previous pointer - set images position to first replacement image */
1163   replace=GetFirstImageInList(replace);
1164   replace->previous=(*images)->previous;
1165   if (replace->previous != (Image *) NULL)
1166     replace->previous->next=replace;
1167
1168   /* destroy the replaced image that was in images */
1169   (void) DestroyImage(*images);
1170   (*images)=replace;
1171 }
1172 \f
1173 /*
1174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1175 %                                                                             %
1176 %                                                                             %
1177 %                                                                             %
1178 %   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                   %
1179 %                                                                             %
1180 %                                                                             %
1181 %                                                                             %
1182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1183 %
1184 %  ReplaceImageInListReturnLast() is exactly as ReplaceImageInList() except
1185 %  the images pointer is set to the last image in the list of replacemen
1186 %  images.
1187 %
1188 %  This allows you to simply use GetNextImageInList() to go to the image
1189 %  that follows the just replaced image, even if a list of replacement images
1190 %  was inserted.
1191 %
1192 %  The format of the ReplaceImageInList method is:
1193 %
1194 %      ReplaceImageInListReturnLast(Image **images,Image *replace)
1195 %
1196 %  A description of each parameter follows:
1197 %
1198 %    o images: the list and pointer to image to replace
1199 %
1200 %    o replace: the image or image list replacing the original
1201 %
1202 */
1203 MagickExport void ReplaceImageInListReturnLast(Image **images,Image *replace)
1204 {
1205   assert(images != (Image **) NULL);
1206   assert(replace != (Image *) NULL);
1207   assert(replace->signature == MagickSignature);
1208   if (replace->debug != MagickFalse)
1209     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",replace->filename);
1210   if ((*images) == (Image *) NULL)
1211     return;
1212   assert((*images)->signature == MagickSignature);
1213
1214   /* link previous pointer */
1215   replace=GetFirstImageInList(replace);
1216   replace->previous=(*images)->previous;
1217   if (replace->previous != (Image *) NULL)
1218     replace->previous->next=replace;
1219
1220   /* link next pointer - set images position to last replacement image */
1221   replace=GetLastImageInList(replace);
1222   replace->next=(*images)->next;
1223   if (replace->next != (Image *) NULL)
1224     replace->next->previous=replace;
1225
1226   /* destroy the replaced image that was in images */
1227   (void) DestroyImage(*images);
1228   (*images)=replace;
1229 }
1230 \f
1231 /*
1232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1233 %                                                                             %
1234 %                                                                             %
1235 %                                                                             %
1236 %   R e v e r s e I m a g e L i s t                                           %
1237 %                                                                             %
1238 %                                                                             %
1239 %                                                                             %
1240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1241 %
1242 %  ReverseImageList() reverses the order of an image list.
1243 %  The list pointer is reset to that start of the re-ordered list.
1244 %
1245 %  The format of the ReverseImageList method is:
1246 %
1247 %      void ReverseImageList(Image **images)
1248 %
1249 %  A description of each parameter follows:
1250 %
1251 %    o images: the image list.
1252 %
1253 */
1254 MagickExport void ReverseImageList(Image **images)
1255 {
1256   Image
1257     *next;
1258
1259   register Image
1260     *p;
1261
1262   assert(images != (Image **) NULL);
1263   if ((*images) == (Image *) NULL)
1264     return;
1265   assert((*images)->signature == MagickSignature);
1266   if ((*images)->debug != MagickFalse)
1267     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1268       (*images)->filename);
1269   for (p=(*images); p->next != (Image *) NULL; p=p->next) ;
1270   *images=p;
1271   for ( ; p != (Image *) NULL; p=p->next)
1272   {
1273     next=p->next;
1274     p->next=p->previous;
1275     p->previous=next;
1276   }
1277 }
1278 \f
1279 /*
1280 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1281 %                                                                             %
1282 %                                                                             %
1283 %                                                                             %
1284 %   S p l i c e I m a g e I n t o L i s t                                     %
1285 %                                                                             %
1286 %                                                                             %
1287 %                                                                             %
1288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1289 %
1290 %  SpliceImageIntoList() removes 'length' images from the list and replaces
1291 %  them with the specified splice. Removed images are returned.
1292 %
1293 %  The format of the SpliceImageIntoList method is:
1294 %
1295 %      SpliceImageIntoList(Image **images,const size_t,
1296 %        const Image *splice)
1297 %
1298 %  A description of each parameter follows:
1299 %
1300 %    o images: the image list.
1301 %
1302 %    o length: the length of the image list to remove.
1303 %
1304 %    o splice: Replace the removed image list with this list.
1305 %
1306 */
1307 MagickExport Image *SpliceImageIntoList(Image **images,
1308   const size_t length,const Image *splice)
1309 {
1310   Image
1311     *image,
1312     *split;
1313
1314   register size_t
1315     i;
1316
1317   assert(images != (Image **) NULL);
1318   assert(splice != (Image *) NULL);
1319   assert(splice->signature == MagickSignature);
1320   if ((*images) == (Image *) NULL)
1321     return((Image *) NULL);
1322   assert((*images)->signature == MagickSignature);
1323   if ((*images)->debug != MagickFalse)
1324     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1325       (*images)->filename);
1326   split=SplitImageList(*images);
1327   AppendImageToList(images,splice);
1328   image=(Image *) NULL;
1329   for (i=0; (i < length) && (split != (Image *) NULL); i++)
1330     AppendImageToList(&image,RemoveImageFromList(&split));
1331   AppendImageToList(images,split);
1332   return(image);
1333 }
1334 \f
1335 /*
1336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1337 %                                                                             %
1338 %                                                                             %
1339 %                                                                             %
1340 %   S p l i t I m a g e L i s t                                               %
1341 %                                                                             %
1342 %                                                                             %
1343 %                                                                             %
1344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1345 %
1346 %  SplitImageList() splits an image into two lists, after given image
1347 %  The list that was split off is returned, which may be empty.
1348 %
1349 %  The format of the SplitImageList method is:
1350 %
1351 %      Image *SplitImageList(Image *images)
1352 %
1353 %  A description of each parameter follows:
1354 %
1355 %    o images: the image list.
1356 %
1357 */
1358 MagickExport Image *SplitImageList(Image *images)
1359 {
1360   if ((images == (Image *) NULL) || (images->next == (Image *) NULL))
1361     return((Image *) NULL);
1362   images=images->next;
1363   images->previous->next=(Image *) NULL;
1364   images->previous=(Image *) NULL;
1365   return(images);
1366 }
1367 \f
1368 /*
1369 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1370 %                                                                             %
1371 %                                                                             %
1372 %                                                                             %
1373 +   S y n c I m a g e L i s t                                                 %
1374 %                                                                             %
1375 %                                                                             %
1376 %                                                                             %
1377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1378 %
1379 %  SyncImageList() synchronizes the scene numbers in an image list.
1380 %
1381 %  The format of the SyncImageList method is:
1382 %
1383 %      void SyncImageList(Image *images)
1384 %
1385 %  A description of each parameter follows:
1386 %
1387 %    o images: the image list.
1388 %
1389 */
1390 MagickExport void SyncImageList(Image *images)
1391 {
1392   register Image
1393     *p,
1394     *q;
1395
1396   if (images == (Image *) NULL)
1397     return;
1398   assert(images->signature == MagickSignature);
1399   for (p=images; p != (Image *) NULL; p=p->next)
1400   {
1401     for (q=p->next; q != (Image *) NULL; q=q->next)
1402       if (p->scene == q->scene)
1403         break;
1404     if (q != (Image *) NULL)
1405       break;
1406   }
1407   if (p == (Image *) NULL)
1408     return;
1409   for (p=images->next; p != (Image *) NULL; p=p->next)
1410     p->scene=p->previous->scene+1;
1411 }
1412 \f
1413 /*
1414 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1415 %                                                                             %
1416 %                                                                             %
1417 %                                                                             %
1418 +   S y n c N e x t I m a g e I n L i s t                                     %
1419 %                                                                             %
1420 %                                                                             %
1421 %                                                                             %
1422 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1423 %
1424 %  SyncNextImageInList() returns the next image in the list after the blob
1425 %  referenced is synchronized with the current image.
1426 %
1427 %  The format of the SyncNextImageInList method is:
1428 %
1429 %      Image *SyncNextImageInList(const Image *images)
1430 %
1431 %  A description of each parameter follows:
1432 %
1433 %    o images: the image list.
1434 %
1435 */
1436 MagickExport Image *SyncNextImageInList(const Image *images)
1437 {
1438   if (images == (Image *) NULL)
1439     return((Image *) NULL);
1440   assert(images->signature == MagickSignature);
1441   if (images->next == (Image *) NULL)
1442     return((Image *) NULL);
1443   if (images->blob != images->next->blob)
1444     {
1445       DestroyBlob(images->next);
1446       images->next->blob=ReferenceBlob(images->blob);
1447     }
1448   images->next->compression=images->compression;
1449   images->next->endian=images->endian;
1450   return(images->next);
1451 }