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