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