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