2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % L IIIII SSSSS TTTTT %
10 % LLLLL IIIII SSSSS T %
13 % MagickCore Image List Methods %
20 % Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % https://www.imagemagick.org/script/license.php %
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. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 #include "MagickCore/studio.h"
44 #include "MagickCore/blob.h"
45 #include "MagickCore/blob-private.h"
46 #include "MagickCore/exception.h"
47 #include "MagickCore/exception-private.h"
48 #include "MagickCore/image-private.h"
49 #include "MagickCore/list.h"
50 #include "MagickCore/memory_.h"
51 #include "MagickCore/string_.h"
54 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58 % A p p e n d I m a g e T o L i s t %
62 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64 % AppendImageToList() appends the second image list to the end of the first
65 % list. The given image list pointer is left unchanged, unless it was empty.
67 % The format of the AppendImageToList method is:
69 % AppendImageToList(Image *images,const Image *image)
71 % A description of each parameter follows:
73 % o images: the image list to be appended to.
75 % o image: the appended image or image list.
78 MagickExport void AppendImageToList(Image **images,const Image *append)
84 assert(images != (Image **) NULL);
85 if (append == (Image *) NULL)
87 assert(append->signature == MagickCoreSignature);
88 if (append->debug != MagickFalse)
89 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",append->filename);
90 if ((*images) == (Image *) NULL)
92 *images=(Image *) append;
95 assert((*images)->signature == MagickCoreSignature);
96 p=GetLastImageInList(*images);
97 q=GetFirstImageInList(append);
103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
107 % C l o n e I m a g e L i s t %
111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113 % CloneImageList() returns a duplicate of the image list.
115 % The format of the CloneImageList method is:
117 % Image *CloneImageList(const Image *images,ExceptionInfo *exception)
119 % A description of each parameter follows:
121 % o images: the image list.
123 % o exception: return any errors or warnings in this structure.
126 MagickExport Image *CloneImageList(const Image *images,ExceptionInfo *exception)
135 if (images == (Image *) NULL)
136 return((Image *) NULL);
137 assert(images->signature == MagickCoreSignature);
138 while (images->previous != (Image *) NULL)
140 assert(images != images->previous);
141 images=images->previous;
143 image=(Image *) NULL;
144 for (p=(Image *) NULL; images != (Image *) NULL; images=images->next)
146 assert(images != images->next);
147 clone=CloneImage(images,0,0,MagickTrue,exception);
148 if (clone == (Image *) NULL)
150 if (image != (Image *) NULL)
151 image=DestroyImageList(image);
152 return((Image *) NULL);
154 if (image == (Image *) NULL)
168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172 % C l o n e I m a g e s %
176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
178 % CloneImages() clones one or more images from an image sequence, using a
179 % comma separated list of image numbers or ranges.
181 % The numbers start at 0 for the first image in the list, while negative
182 % numbers refer to images starting counting from the end of the range. Images
183 % may be referred to multiple times to clone them multiple times. Images
184 % referred beyond the available number of images in list are ignored.
186 % Images referenced may be reversed, and results in a clone of those images
187 % also being made with a reversed order.
189 % The format of the CloneImages method is:
191 % Image *CloneImages(const Image *images,const char *scenes,
192 % ExceptionInfo *exception)
194 % A description of each parameter follows:
196 % o images: the image sequence.
198 % o scenes: This character string specifies which scenes to clone
199 % (e.g. 1,3-5,7-3,2).
201 % o exception: return any errors or warnings in this structure.
204 MagickExport Image *CloneImages(const Image *images,const char *scenes,
205 ExceptionInfo *exception)
228 assert(images != (const Image *) NULL);
229 assert(images->signature == MagickCoreSignature);
230 assert(scenes != (char *) NULL);
231 if (images->debug != MagickFalse)
232 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
233 assert(exception != (ExceptionInfo *) NULL);
234 assert(exception->signature == MagickCoreSignature);
235 clone_images=NewImageList();
236 images=GetFirstImageInList(images);
237 length=GetImageListLength(images);
238 for (p=(char *) scenes; *p != '\0';)
240 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
242 first=(ssize_t) strtol(p,&p,10);
244 first+=(ssize_t) length;
246 if (first > (ssize_t) length)
247 first=(ssize_t) length;
249 while (isspace((int) ((unsigned char) *p)) != 0)
253 last=(ssize_t) strtol(p+1,&p,10);
255 last+=(ssize_t) length;
257 if (last > (ssize_t) length)
258 last=(ssize_t) length;
260 first=MagickMin(MagickMax(first,0),length);
261 last=MagickMin(MagickMax(last,0),length);
262 step=(ssize_t) (first > last ? -1 : 1);
263 for ( ; first != (last+step); first+=step)
266 for (next=images; next != (Image *) NULL; next=GetNextImageInList(next))
268 if (i == (ssize_t) first)
270 image=CloneImage(next,0,0,MagickTrue,exception);
271 if (image == (Image *) NULL)
273 AppendImageToList(&clone_images,image);
279 return(GetFirstImageInList(clone_images));
283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
287 % D e l e t e I m a g e F r o m L i s t %
291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
293 % DeleteImageFromList() deletes an image from the list. List pointer
294 % is moved to the next image, if one is present. See RemoveImageFromList().
296 % The format of the DeleteImageFromList method is:
298 % DeleteImageFromList(Image **images)
300 % A description of each parameter follows:
302 % o images: the image list.
305 MagickExport void DeleteImageFromList(Image **images)
310 image=RemoveImageFromList(images);
311 if (image != (Image *) NULL)
312 (void) DestroyImage(image);
316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
320 % D e l e t e I m a g e s %
324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
326 % DeleteImages() deletes one or more images from an image sequence, using a
327 % comma separated list of image numbers or ranges.
329 % The numbers start at 0 for the first image, while negative numbers refer to
330 % images starting counting from the end of the range. Images may be referred to
331 % multiple times without problems. Image referred beyond the available number
332 % of images in list are ignored.
334 % If the referenced images are in the reverse order, that range will be
335 % completely ignored, unlike CloneImages().
337 % The format of the DeleteImages method is:
339 % DeleteImages(Image **images,const char *scenes,ExceptionInfo *exception)
341 % A description of each parameter follows:
343 % o images: the image sequence.
345 % o scenes: This character string specifies which scenes to delete
346 % (e.g. 1,3-5,-2-6,2).
348 % o exception: return any errors or warnings in this structure.
351 MagickExport void DeleteImages(Image **images,const char *scenes,
352 ExceptionInfo *exception)
373 assert(images != (Image **) NULL);
374 assert((*images)->signature == MagickCoreSignature);
375 assert(scenes != (char *) NULL);
376 if ((*images)->debug != MagickFalse)
377 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
378 (*images)->filename);
379 assert(exception != (ExceptionInfo *) NULL);
380 assert(exception->signature == MagickCoreSignature);
381 *images=GetFirstImageInList(*images);
382 length=GetImageListLength(*images);
383 delete_list=(MagickBooleanType *) AcquireQuantumMemory(length,
384 sizeof(*delete_list));
385 if (delete_list == (MagickBooleanType *) NULL)
387 (void) ThrowMagickException(exception,GetMagickModule(),
388 ResourceLimitError,"MemoryAllocationFailed","`%s'",(*images)->filename);
392 for (i=0; i < (ssize_t) length; i++)
393 delete_list[i]=MagickFalse;
395 Note which images will be deleted, avoid duplicates.
397 for (p=(char *) scenes; *p != '\0';)
399 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
401 first=strtol(p,&p,10);
403 first+=(long) length;
405 while (isspace((int) ((unsigned char) *p)) != 0)
409 last=strtol(p+1,&p,10);
415 for (i=(ssize_t) first; i <= (ssize_t) last; i++)
416 if ((i >= 0) && (i < (ssize_t) length))
417 delete_list[i]=MagickTrue;
420 Delete images marked for deletion, once only.
423 for (i=0; i < (ssize_t) length; i++)
426 image=GetNextImageInList(image);
427 if (delete_list[i] != MagickFalse)
428 DeleteImageFromList(images);
430 (void) RelinquishMagickMemory(delete_list);
431 *images=GetFirstImageInList(*images);
435 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
439 % D e s t r o y I m a g e L i s t %
443 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
445 % DestroyImageList() destroys an image list.
447 % The format of the DestroyImageList method is:
449 % Image *DestroyImageList(Image *image)
451 % A description of each parameter follows:
453 % o image: the image sequence.
456 MagickExport Image *DestroyImageList(Image *images)
458 if (images == (Image *) NULL)
459 return((Image *) NULL);
460 assert(images->signature == MagickCoreSignature);
461 if (images->debug != MagickFalse)
462 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
463 while (images != (Image *) NULL)
464 DeleteImageFromList(&images);
465 return((Image *) NULL);
469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
473 % D u p l i c a t e I m a g e s %
477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
479 % DuplicateImages() duplicates one or more images from an image sequence,
480 % using a count and a comma separated list of image numbers or ranges.
482 % The numbers start at 0 for the first image, while negative numbers refer to
483 % images starting counting from the end of the range. Images may be referred to
484 % multiple times without problems. Image referred beyond the available number
485 % of images in list are ignored.
487 % The format of the DuplicateImages method is:
489 % Image *DuplicateImages(Image *images,const size_t number_duplicates,
490 % const char *scenes,ExceptionInfo *exception)
492 % A description of each parameter follows:
494 % o images: the image sequence.
496 % o number_duplicates: duplicate the image sequence this number of times.
498 % o scenes: This character string specifies which scenes to duplicate (e.g.
501 % o exception: return any errors or warnings in this structure.
504 MagickExport Image *DuplicateImages(Image *images,
505 const size_t number_duplicates,const char *scenes,ExceptionInfo *exception)
517 assert(images != (Image *) NULL);
518 assert(images->signature == MagickCoreSignature);
519 assert(scenes != (char *) NULL);
520 if (images->debug != MagickFalse)
521 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
522 assert(exception != (ExceptionInfo *) NULL);
523 assert(exception->signature == MagickCoreSignature);
524 duplicate_images=NewImageList();
525 for (i=0; i < (ssize_t) number_duplicates; i++)
527 clone_images=CloneImages(images,scenes,exception);
528 AppendImageToList(&duplicate_images,clone_images);
530 return(duplicate_images);
534 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
538 % G e t F i r s t I m a g e I n L i s t %
542 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
544 % GetFirstImageInList() returns a pointer to the first image in the list.
546 % The format of the GetFirstImageInList method is:
548 % Image *GetFirstImageInList(const Image *images)
550 % A description of each parameter follows:
552 % o images: the image list.
555 MagickExport Image *GetFirstImageInList(const Image *images)
560 if (images == (Image *) NULL)
561 return((Image *) NULL);
562 assert(images->signature == MagickCoreSignature);
563 for (p=images; p->previous != (Image *) NULL; p=p->previous) ;
568 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
572 % G e t I m a g e F r o m L i s t %
576 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
578 % GetImageFromList() returns an image at the specified index from the image
579 % list. Starting with 0 as the first image in the list.
581 % A negative offset will return the image from the end of the list, such that
582 % an index of -1 is the last image.
584 % If no such image exists at the specified offset a NULL image pointer is
585 % returned. This will only happen if index is less that the negative of
586 % the list length, or larger than list length -1. EG: ( -N to N-1 )
588 % The format of the GetImageFromList method is:
590 % Image *GetImageFromList(const Image *images,const ssize_t index)
592 % A description of each parameter follows:
594 % o images: the image list.
596 % o index: the position within the list.
599 MagickExport Image *GetImageFromList(const Image *images,const ssize_t index)
607 if (images == (Image *) NULL)
608 return((Image *) NULL);
609 assert(images->signature == MagickCoreSignature);
610 if (images->debug != MagickFalse)
611 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
614 p=GetLastImageInList(images);
615 for (i=(-1); p != (Image *) NULL; p=p->previous)
621 p=GetFirstImageInList(images);
622 for (i=0; p != (Image *) NULL; p=p->next)
630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
634 % G e t I m a g e I n d e x I n L i s t %
638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
640 % GetImageIndexInList() returns the offset in the list of the specified image.
642 % The format of the GetImageIndexInList method is:
644 % ssize_t GetImageIndexInList(const Image *images)
646 % A description of each parameter follows:
648 % o images: the image list.
651 MagickExport ssize_t GetImageIndexInList(const Image *images)
656 if (images == (const Image *) NULL)
658 assert(images->signature == MagickCoreSignature);
659 for (i=0; images->previous != (Image *) NULL; i++)
661 assert(images != images->previous);
662 images=images->previous;
668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
672 % G e t I m a g e L i s t L e n g t h %
676 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
678 % GetImageListLength() returns the length of the list (the number of images in
681 % The format of the GetImageListLength method is:
683 % size_t GetImageListLength(const Image *images)
685 % A description of each parameter follows:
687 % o images: the image list.
690 MagickExport size_t GetImageListLength(const Image *images)
695 if (images == (Image *) NULL)
697 assert(images->signature == MagickCoreSignature);
698 if (images->debug != MagickFalse)
699 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
700 images=GetLastImageInList(images);
701 for (i=0; images != (Image *) NULL; images=images->previous)
703 assert(images != images->previous);
710 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
714 % G e t L a s t I m a g e I n L i s t %
718 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
720 % GetLastImageInList() returns a pointer to the last image in the list.
722 % The format of the GetLastImageInList method is:
724 % Image *GetLastImageInList(const Image *images)
726 % A description of each parameter follows:
728 % o images: the image list.
731 MagickExport Image *GetLastImageInList(const Image *images)
736 if (images == (Image *) NULL)
737 return((Image *) NULL);
738 assert(images->signature == MagickCoreSignature);
739 for (p=images; p->next != (Image *) NULL; p=p->next) ;
744 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
748 % G e t N e x t I m a g e I n L i s t %
752 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
754 % GetNextImageInList() returns the next image in the list.
756 % The format of the GetNextImageInList method is:
758 % Image *GetNextImageInList(const Image *images)
760 % A description of each parameter follows:
762 % o images: the image list.
765 MagickExport Image *GetNextImageInList(const Image *images)
767 if (images == (Image *) NULL)
768 return((Image *) NULL);
769 assert(images->signature == MagickCoreSignature);
770 if (images->debug != MagickFalse)
771 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
772 return(images->next);
776 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
780 % G e t P r e v i o u s I m a g e I n L i s t %
784 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
786 % GetPreviousImageInList() returns the previous image in the list.
788 % The format of the GetPreviousImageInList method is:
790 % Image *GetPreviousImageInList(const Image *images)
792 % A description of each parameter follows:
794 % o images: the image list.
797 MagickExport Image *GetPreviousImageInList(const Image *images)
799 if (images == (Image *) NULL)
800 return((Image *) NULL);
801 assert(images->signature == MagickCoreSignature);
802 return(images->previous);
806 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
809 % I m a g e L i s t T o A r r a y %
813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
815 % ImageListToArray() is a convenience method that converts an image list to
816 % a sequential array, with a NULL image pointer at the end of the array.
818 % The images remain part of the original image list, with the array providing
819 % an alternative means of indexing the image array.
821 % group = ImageListToArray(images, exception);
822 % while (i = 0; group[i] != (Image *) NULL; i++)
823 % printf("%s\n", group[i]->filename);
824 % printf("%d images\n", i);
825 % group = RelinquishMagickMemory(group);
827 % The format of the ImageListToArray method is:
829 % Image **ImageListToArray(const Image *images,ExceptionInfo *exception)
831 % A description of each parameter follows:
833 % o image: the image list.
835 % o exception: return any errors or warnings in this structure.
838 MagickExport Image **ImageListToArray(const Image *images,
839 ExceptionInfo *exception)
847 if (images == (Image *) NULL)
848 return((Image **) NULL);
849 assert(images->signature == MagickCoreSignature);
850 if (images->debug != MagickFalse)
851 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
852 group=(Image **) AcquireQuantumMemory((size_t) GetImageListLength(images)+1UL,
854 if (group == (Image **) NULL)
856 (void) ThrowMagickException(exception,GetMagickModule(),
857 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
858 return((Image **) NULL);
860 images=GetFirstImageInList(images);
861 for (i=0; images != (Image *) NULL; images=images->next)
863 assert(images != images->next);
864 group[i++]=(Image *) images;
866 group[i]=(Image *) NULL;
871 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
875 % I n s e r t I m a g e I n L i s t %
879 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
881 % InsertImageInList() insert the given image or image list, into the first
882 % image list, immediately AFTER the image pointed to. The given image list
883 % pointer is left unchanged unless previously empty.
885 % The format of the InsertImageInList method is:
887 % InsertImageInList(Image **images,Image *insert)
889 % A description of each parameter follows:
891 % o images: the image list to insert into.
893 % o insert: the image list to insert.
896 MagickExport void InsertImageInList(Image **images,Image *insert)
901 assert(images != (Image **) NULL);
902 assert(insert != (Image *) NULL);
903 assert(insert->signature == MagickCoreSignature);
904 if (insert->debug != MagickFalse)
905 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",insert->filename);
906 if ((*images) == (Image *) NULL)
908 assert((*images)->signature == MagickCoreSignature);
909 split=SplitImageList(*images);
910 AppendImageToList(images,insert);
911 AppendImageToList(images,split);
915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
919 % N e w I m a g e L i s t %
923 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
925 % NewImageList() creates an empty image list.
927 % The format of the NewImageList method is:
929 % Image *NewImageList(void)
932 MagickExport Image *NewImageList(void)
934 return((Image *) NULL);
938 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
942 % P r e p e n d I m a g e T o L i s t %
946 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
948 % PrependImageToList() prepends the image to the beginning of the list.
950 % The format of the PrependImageToList method is:
952 % PrependImageToList(Image *images,Image *image)
954 % A description of each parameter follows:
956 % o images: the image list.
958 % o image: the image.
961 MagickExport void PrependImageToList(Image **images,Image *prepend)
963 if (*images == (Image *) NULL)
968 AppendImageToList(&prepend,*images);
972 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
976 % R e m o v e I m a g e F r o m L i s t %
980 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
982 % RemoveImageFromList() removes and returns the image pointed to.
984 % The given image list pointer is set to point to the next image in list
985 % if it exists, otherwise it is set to the previous image, or NULL if list
988 % The format of the RemoveImageFromList method is:
990 % Image *RemoveImageFromList(Image **images)
992 % A description of each parameter follows:
994 % o images: the image list.
997 MagickExport Image *RemoveImageFromList(Image **images)
1002 assert(images != (Image **) NULL);
1003 if ((*images) == (Image *) NULL)
1004 return((Image *) NULL);
1005 assert((*images)->signature == MagickCoreSignature);
1006 if ((*images)->debug != MagickFalse)
1007 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1008 (*images)->filename);
1010 if ((p->previous == (Image *) NULL) && (p->next == (Image *) NULL))
1011 *images=(Image *) NULL;
1014 if (p->previous != (Image *) NULL)
1016 p->previous->next=p->next;
1017 *images=p->previous;
1019 if (p->next != (Image *) NULL)
1021 p->next->previous=p->previous;
1024 p->previous=(Image *) NULL;
1025 p->next=(Image *) NULL;
1031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1035 % R e m o v e F i r s t I m a g e F r o m L i s t %
1039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1041 % RemoveFirstImageFromList() removes and returns the first image in the list.
1043 % If the given image list pointer pointed to the removed first image, it is
1044 % set to the new first image of list, or NULL if list was emptied, otherwise
1047 % The format of the RemoveFirstImageFromList method is:
1049 % Image *RemoveFirstImageFromList(Image **images)
1051 % A description of each parameter follows:
1053 % o images: the image list.
1056 MagickExport Image *RemoveFirstImageFromList(Image **images)
1061 assert(images != (Image **) NULL);
1062 if ((*images) == (Image *) NULL)
1063 return((Image *) NULL);
1064 assert((*images)->signature == MagickCoreSignature);
1065 if ((*images)->debug != MagickFalse)
1066 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1067 (*images)->filename);
1069 while (image->previous != (Image *) NULL)
1070 image=image->previous;
1071 if (image == *images)
1072 *images=(*images)->next;
1073 if (image->next != (Image *) NULL)
1075 image->next->previous=(Image *) NULL;
1076 image->next=(Image *) NULL;
1082 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1086 % R e m o v e L a s t I m a g e F r o m L i s t %
1090 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1092 % RemoveLastImageFromList() removes and returns the last image from the list.
1094 % If the given image list pointer pointed to the removed last image, it is
1095 % set to the new last image of list, or NULL if list was emptied, otherwise
1098 % The format of the RemoveLastImageFromList method is:
1100 % Image *RemoveLastImageFromList(Image **images)
1102 % A description of each parameter follows:
1104 % o images: the image list.
1107 MagickExport Image *RemoveLastImageFromList(Image **images)
1112 assert(images != (Image **) NULL);
1113 if ((*images) == (Image *) NULL)
1114 return((Image *) NULL);
1115 assert((*images)->signature == MagickCoreSignature);
1116 if ((*images)->debug != MagickFalse)
1117 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1118 (*images)->filename);
1120 while (image->next != (Image *) NULL)
1122 if (image == *images)
1123 *images=(*images)->previous;
1124 if (image->previous != (Image *) NULL)
1126 image->previous->next=(Image *) NULL;
1127 image->previous=(Image *) NULL;
1133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1137 % R e p l a c e I m a g e I n L i s t %
1141 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1143 % ReplaceImageInList() replaces an image in the list with the given image, or
1144 % list of images. Old image is destroyed.
1146 % The images list pointer is set to point to the first image of the inserted
1149 % The format of the ReplaceImageInList method is:
1151 % ReplaceImageInList(Image **images,Image *replace)
1153 % A description of each parameter follows:
1155 % o images: the list and pointer to image to replace
1157 % o replace: the image or image list replacing the original
1160 MagickExport void ReplaceImageInList(Image **images,Image *replace)
1162 assert(images != (Image **) NULL);
1163 assert(replace != (Image *) NULL);
1164 assert(replace->signature == MagickCoreSignature);
1165 if (replace->debug != MagickFalse)
1166 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",replace->filename);
1167 if ((*images) == (Image *) NULL)
1169 assert((*images)->signature == MagickCoreSignature);
1171 /* link next pointer */
1172 replace=GetLastImageInList(replace);
1173 replace->next=(*images)->next;
1174 if (replace->next != (Image *) NULL)
1175 replace->next->previous=replace;
1177 /* link previous pointer - set images position to first replacement image */
1178 replace=GetFirstImageInList(replace);
1179 replace->previous=(*images)->previous;
1180 if (replace->previous != (Image *) NULL)
1181 replace->previous->next=replace;
1183 /* destroy the replaced image that was in images */
1184 (void) DestroyImage(*images);
1189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1193 % R e p l a c e I m a g e I n L i s t R e t u r n L a s t %
1197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1199 % ReplaceImageInListReturnLast() is exactly as ReplaceImageInList() except
1200 % the images pointer is set to the last image in the list of replacement
1203 % This allows you to simply use GetNextImageInList() to go to the image
1204 % that follows the just replaced image, even if a list of replacement images
1207 % The format of the ReplaceImageInList method is:
1209 % ReplaceImageInListReturnLast(Image **images,Image *replace)
1211 % A description of each parameter follows:
1213 % o images: the list and pointer to image to replace
1215 % o replace: the image or image list replacing the original
1218 MagickExport void ReplaceImageInListReturnLast(Image **images,Image *replace)
1220 assert(images != (Image **) NULL);
1221 assert(replace != (Image *) NULL);
1222 assert(replace->signature == MagickCoreSignature);
1223 if (replace->debug != MagickFalse)
1224 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",replace->filename);
1225 if ((*images) == (Image *) NULL)
1227 assert((*images)->signature == MagickCoreSignature);
1229 /* link previous pointer */
1230 replace=GetFirstImageInList(replace);
1231 replace->previous=(*images)->previous;
1232 if (replace->previous != (Image *) NULL)
1233 replace->previous->next=replace;
1235 /* link next pointer - set images position to last replacement image */
1236 replace=GetLastImageInList(replace);
1237 replace->next=(*images)->next;
1238 if (replace->next != (Image *) NULL)
1239 replace->next->previous=replace;
1241 /* destroy the replaced image that was in images */
1242 (void) DestroyImage(*images);
1247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1251 % R e v e r s e I m a g e L i s t %
1255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1257 % ReverseImageList() reverses the order of an image list.
1258 % The list pointer is reset to that start of the re-ordered list.
1260 % The format of the ReverseImageList method is:
1262 % void ReverseImageList(Image **images)
1264 % A description of each parameter follows:
1266 % o images: the image list.
1269 MagickExport void ReverseImageList(Image **images)
1277 assert(images != (Image **) NULL);
1278 if ((*images) == (Image *) NULL)
1280 assert((*images)->signature == MagickCoreSignature);
1281 if ((*images)->debug != MagickFalse)
1282 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1283 (*images)->filename);
1284 for (p=(*images); p->next != (Image *) NULL; p=p->next) ;
1286 for ( ; p != (Image *) NULL; p=p->next)
1289 p->next=p->previous;
1295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1299 % S p l i c e I m a g e I n t o L i s t %
1303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1305 % SpliceImageIntoList() removes 'length' images from the list and replaces
1306 % them with the specified splice. Removed images are returned.
1308 % The format of the SpliceImageIntoList method is:
1310 % SpliceImageIntoList(Image **images,const size_t,
1311 % const Image *splice)
1313 % A description of each parameter follows:
1315 % o images: the image list.
1317 % o length: the length of the image list to remove.
1319 % o splice: Replace the removed image list with this list.
1322 MagickExport Image *SpliceImageIntoList(Image **images,
1323 const size_t length,const Image *splice)
1332 assert(images != (Image **) NULL);
1333 assert(splice != (Image *) NULL);
1334 assert(splice->signature == MagickCoreSignature);
1335 if ((*images) == (Image *) NULL)
1336 return((Image *) NULL);
1337 assert((*images)->signature == MagickCoreSignature);
1338 if ((*images)->debug != MagickFalse)
1339 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1340 (*images)->filename);
1341 split=SplitImageList(*images);
1342 AppendImageToList(images,splice);
1343 image=(Image *) NULL;
1344 for (i=0; (i < length) && (split != (Image *) NULL); i++)
1345 AppendImageToList(&image,RemoveImageFromList(&split));
1346 AppendImageToList(images,split);
1351 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1355 % S p l i t I m a g e L i s t %
1359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1361 % SplitImageList() splits an image into two lists, after given image
1362 % The list that was split off is returned, which may be empty.
1364 % The format of the SplitImageList method is:
1366 % Image *SplitImageList(Image *images)
1368 % A description of each parameter follows:
1370 % o images: the image list.
1373 MagickExport Image *SplitImageList(Image *images)
1375 if ((images == (Image *) NULL) || (images->next == (Image *) NULL))
1376 return((Image *) NULL);
1377 images=images->next;
1378 images->previous->next=(Image *) NULL;
1379 images->previous=(Image *) NULL;
1384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1388 + S y n c I m a g e L i s t %
1392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1394 % SyncImageList() synchronizes the scene numbers in an image list.
1396 % The format of the SyncImageList method is:
1398 % void SyncImageList(Image *images)
1400 % A description of each parameter follows:
1402 % o images: the image list.
1405 MagickExport void SyncImageList(Image *images)
1411 if (images == (Image *) NULL)
1413 assert(images->signature == MagickCoreSignature);
1414 for (p=images; p != (Image *) NULL; p=p->next)
1416 for (q=p->next; q != (Image *) NULL; q=q->next)
1417 if (p->scene == q->scene)
1419 if (q != (Image *) NULL)
1422 if (p == (Image *) NULL)
1424 for (p=images->next; p != (Image *) NULL; p=p->next)
1425 p->scene=p->previous->scene+1;
1429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1433 + S y n c N e x t I m a g e I n L i s t %
1437 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1439 % SyncNextImageInList() returns the next image in the list after the blob
1440 % referenced is synchronized with the current image.
1442 % The format of the SyncNextImageInList method is:
1444 % Image *SyncNextImageInList(const Image *images)
1446 % A description of each parameter follows:
1448 % o images: the image list.
1451 MagickExport Image *SyncNextImageInList(const Image *images)
1453 if (images == (Image *) NULL)
1454 return((Image *) NULL);
1455 assert(images->signature == MagickCoreSignature);
1456 if (images->next == (Image *) NULL)
1457 return((Image *) NULL);
1458 if (images->blob != images->next->blob)
1460 DestroyBlob(images->next);
1461 images->next->blob=ReferenceBlob(images->blob);
1463 if (images->next->compression == UndefinedCompression)
1464 images->next->compression=images->compression;
1465 if (images->next->endian == UndefinedEndian)
1466 images->next->endian=images->endian;
1467 return(images->next);