2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % L IIIII SSSSS TTTTT %
10 % LLLLL IIIII SSSSS T %
13 % MagickCore Image List Methods %
20 % Copyright 1999-2017 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/list.h"
49 #include "MagickCore/memory_.h"
50 #include "MagickCore/string_.h"
53 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57 % A p p e n d I m a g e T o L i s t %
61 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
66 % The format of the AppendImageToList method is:
68 % AppendImageToList(Image *images,const Image *image)
70 % A description of each parameter follows:
72 % o images: the image list to be appended to.
74 % o image: the appended image or image list.
77 MagickExport void AppendImageToList(Image **images,const Image *append)
83 assert(images != (Image **) NULL);
84 if (append == (Image *) NULL)
86 assert(append->signature == MagickCoreSignature);
87 if (append->debug != MagickFalse)
88 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",append->filename);
89 if ((*images) == (Image *) NULL)
91 *images=(Image *) append;
94 assert((*images)->signature == MagickCoreSignature);
95 p=GetLastImageInList(*images);
96 q=GetFirstImageInList(append);
102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106 % C l o n e I m a g e L i s t %
110 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
112 % CloneImageList() returns a duplicate of the image list.
114 % The format of the CloneImageList method is:
116 % Image *CloneImageList(const Image *images,ExceptionInfo *exception)
118 % A description of each parameter follows:
120 % o images: the image list.
122 % o exception: return any errors or warnings in this structure.
125 MagickExport Image *CloneImageList(const Image *images,ExceptionInfo *exception)
134 if (images == (Image *) NULL)
135 return((Image *) NULL);
136 assert(images->signature == MagickCoreSignature);
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)
142 clone=CloneImage(images,0,0,MagickTrue,exception);
143 if (clone == (Image *) NULL)
145 if (image != (Image *) NULL)
146 image=DestroyImageList(image);
147 return((Image *) NULL);
149 if (image == (Image *) NULL)
163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
167 % C l o n e I m a g e s %
171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173 % CloneImages() clones one or more images from an image sequence, using a
174 % comma separated list of image numbers or ranges.
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.
181 % Images referenced may be reversed, and results in a clone of those images
182 % also being made with a reversed order.
184 % The format of the CloneImages method is:
186 % Image *CloneImages(const Image *images,const char *scenes,
187 % ExceptionInfo *exception)
189 % A description of each parameter follows:
191 % o images: the image sequence.
193 % o scenes: This character string specifies which scenes to clone
194 % (e.g. 1,3-5,7-3,2).
196 % o exception: return any errors or warnings in this structure.
199 MagickExport Image *CloneImages(const Image *images,const char *scenes,
200 ExceptionInfo *exception)
223 assert(images != (const Image *) NULL);
224 assert(images->signature == MagickCoreSignature);
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 == MagickCoreSignature);
230 clone_images=NewImageList();
231 images=GetFirstImageInList(images);
232 length=GetImageListLength(images);
233 for (p=(char *) scenes; *p != '\0';)
235 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
237 first=strtol(p,&p,10);
239 first+=(long) length;
241 while (isspace((int) ((unsigned char) *p)) != 0)
245 last=strtol(p+1,&p,10);
249 for (step=first > last ? -1 : 1; first != (last+step); first+=step)
252 for (next=images; next != (Image *) NULL; next=GetNextImageInList(next))
254 if (i == (ssize_t) first)
256 image=CloneImage(next,0,0,MagickTrue,exception);
257 if (image == (Image *) NULL)
259 AppendImageToList(&clone_images,image);
265 return(GetFirstImageInList(clone_images));
269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
273 % D e l e t e I m a g e F r o m L i s t %
277 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279 % DeleteImageFromList() deletes an image from the list. List pointer
280 % is moved to the next image, if one is present. See RemoveImageFromList().
282 % The format of the DeleteImageFromList method is:
284 % DeleteImageFromList(Image **images)
286 % A description of each parameter follows:
288 % o images: the image list.
291 MagickExport void DeleteImageFromList(Image **images)
296 image=RemoveImageFromList(images);
297 if (image != (Image *) NULL)
298 (void) DestroyImage(image);
302 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
306 % D e l e t e I m a g e s %
310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
312 % DeleteImages() deletes one or more images from an image sequence, using a
313 % comma separated list of image numbers or ranges.
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.
320 % If the referenced images are in the reverse order, that range will be
321 % completely ignored, unlike CloneImages().
323 % The format of the DeleteImages method is:
325 % DeleteImages(Image **images,const char *scenes,ExceptionInfo *exception)
327 % A description of each parameter follows:
329 % o images: the image sequence.
331 % o scenes: This character string specifies which scenes to delete
332 % (e.g. 1,3-5,-2-6,2).
334 % o exception: return any errors or warnings in this structure.
337 MagickExport void DeleteImages(Image **images,const char *scenes,
338 ExceptionInfo *exception)
359 assert(images != (Image **) NULL);
360 assert((*images)->signature == MagickCoreSignature);
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 == MagickCoreSignature);
367 *images=GetFirstImageInList(*images);
368 length=GetImageListLength(*images);
369 delete_list=(MagickBooleanType *) AcquireQuantumMemory(length,
370 sizeof(*delete_list));
371 if (delete_list == (MagickBooleanType *) NULL)
373 (void) ThrowMagickException(exception,GetMagickModule(),
374 ResourceLimitError,"MemoryAllocationFailed","`%s'",(*images)->filename);
378 for (i=0; i < (ssize_t) length; i++)
379 delete_list[i]=MagickFalse;
381 Note which images will be deleted, avoid duplicates.
383 for (p=(char *) scenes; *p != '\0';)
385 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
387 first=strtol(p,&p,10);
389 first+=(long) length;
391 while (isspace((int) ((unsigned char) *p)) != 0)
395 last=strtol(p+1,&p,10);
401 for (i=(ssize_t) first; i <= (ssize_t) last; i++)
402 if ((i >= 0) && (i < (ssize_t) length))
403 delete_list[i]=MagickTrue;
406 Delete images marked for deletion, once only.
409 for (i=0; i < (ssize_t) length; i++)
412 image=GetNextImageInList(image);
413 if (delete_list[i] != MagickFalse)
414 DeleteImageFromList(images);
416 (void) RelinquishMagickMemory(delete_list);
417 *images=GetFirstImageInList(*images);
421 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
425 % D e s t r o y I m a g e L i s t %
429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
431 % DestroyImageList() destroys an image list.
433 % The format of the DestroyImageList method is:
435 % Image *DestroyImageList(Image *image)
437 % A description of each parameter follows:
439 % o image: the image sequence.
442 MagickExport Image *DestroyImageList(Image *images)
444 if (images == (Image *) NULL)
445 return((Image *) NULL);
446 assert(images->signature == MagickCoreSignature);
447 if (images->debug != MagickFalse)
448 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
449 while (images != (Image *) NULL)
450 DeleteImageFromList(&images);
451 return((Image *) NULL);
455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
459 % D u p l i c a t e I m a g e s %
463 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465 % DuplicateImages() duplicates one or more images from an image sequence,
466 % using a count and a comma separated list of image numbers or ranges.
468 % The numbers start at 0 for the first image, while negative numbers refer to
469 % images starting counting from the end of the range. Images may be refered to
470 % multiple times without problems. Image refered beyond the available number
471 % of images in list are ignored.
473 % The format of the DuplicateImages method is:
475 % Image *DuplicateImages(Image *images,const size_t number_duplicates,
476 % const char *scenes,ExceptionInfo *exception)
478 % A description of each parameter follows:
480 % o images: the image sequence.
482 % o number_duplicates: duplicate the image sequence this number of times.
484 % o scenes: This character string specifies which scenes to duplicate (e.g.
487 % o exception: return any errors or warnings in this structure.
490 MagickExport Image *DuplicateImages(Image *images,
491 const size_t number_duplicates,const char *scenes,ExceptionInfo *exception)
503 assert(images != (Image *) NULL);
504 assert(images->signature == MagickCoreSignature);
505 assert(scenes != (char *) NULL);
506 if (images->debug != MagickFalse)
507 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
508 assert(exception != (ExceptionInfo *) NULL);
509 assert(exception->signature == MagickCoreSignature);
510 duplicate_images=NewImageList();
511 for (i=0; i < (ssize_t) number_duplicates; i++)
513 clone_images=CloneImages(images,scenes,exception);
514 AppendImageToList(&duplicate_images,clone_images);
516 return(duplicate_images);
520 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
524 % G e t F i r s t I m a g e I n L i s t %
528 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
530 % GetFirstImageInList() returns a pointer to the first image in the list.
532 % The format of the GetFirstImageInList method is:
534 % Image *GetFirstImageInList(const Image *images)
536 % A description of each parameter follows:
538 % o images: the image list.
541 MagickExport Image *GetFirstImageInList(const Image *images)
546 if (images == (Image *) NULL)
547 return((Image *) NULL);
548 assert(images->signature == MagickCoreSignature);
549 for (p=images; p->previous != (Image *) NULL; p=p->previous) ;
554 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
558 % G e t I m a g e F r o m L i s t %
562 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
564 % GetImageFromList() returns an image at the specified index from the image
565 % list. Starting with 0 as the first image in the list.
567 % A negative offset will return the image from the end of the list, such that
568 % an index of -1 is the last image.
570 % If no such image exists at the specified offset a NULL image pointer is
571 % returned. This will only happen if index is less that the negative of
572 % the list length, or larger than list length -1. EG: ( -N to N-1 )
574 % The format of the GetImageFromList method is:
576 % Image *GetImageFromList(const Image *images,const ssize_t index)
578 % A description of each parameter follows:
580 % o images: the image list.
582 % o index: the position within the list.
585 MagickExport Image *GetImageFromList(const Image *images,const ssize_t index)
593 if (images == (Image *) NULL)
594 return((Image *) NULL);
595 assert(images->signature == MagickCoreSignature);
596 if (images->debug != MagickFalse)
597 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
600 Designed to efficiently find first image (index == 0), or last image
601 (index == -1) as appropriate, without to go through the whole image list.
602 That is it tries to avoid 'counting the whole list' to handle the
603 most common image indexes.
607 p=GetLastImageInList(images);
608 for (i=-1; p != (Image *) NULL; p=p->previous)
614 p=GetFirstImageInList(images);
615 for (i=0; p != (Image *) NULL; p=p->next)
623 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
627 % G e t I m a g e I n d e x I n L i s t %
631 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
633 % GetImageIndexInList() returns the offset in the list of the specified image.
635 % The format of the GetImageIndexInList method is:
637 % ssize_t GetImageIndexInList(const Image *images)
639 % A description of each parameter follows:
641 % o images: the image list.
644 MagickExport ssize_t GetImageIndexInList(const Image *images)
649 if (images == (const Image *) NULL)
651 assert(images->signature == MagickCoreSignature);
652 for (i=0; images->previous != (Image *) NULL; i++)
653 images=images->previous;
658 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
662 % G e t I m a g e L i s t L e n g t h %
666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
668 % GetImageListLength() returns the length of the list (the number of images in
671 % The format of the GetImageListLength method is:
673 % size_t GetImageListLength(const Image *images)
675 % A description of each parameter follows:
677 % o images: the image list.
680 MagickExport size_t GetImageListLength(const Image *images)
685 if (images == (Image *) NULL)
687 assert(images->signature == MagickCoreSignature);
688 if (images->debug != MagickFalse)
689 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
690 images=GetLastImageInList(images);
691 for (i=0; images != (Image *) NULL; images=images->previous)
697 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
701 % G e t L a s t I m a g e I n L i s t %
705 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
707 % GetLastImageInList() returns a pointer to the last image in the list.
709 % The format of the GetLastImageInList method is:
711 % Image *GetLastImageInList(const Image *images)
713 % A description of each parameter follows:
715 % o images: the image list.
718 MagickExport Image *GetLastImageInList(const Image *images)
723 if (images == (Image *) NULL)
724 return((Image *) NULL);
725 assert(images->signature == MagickCoreSignature);
726 for (p=images; p->next != (Image *) NULL; p=p->next) ;
731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
735 % G e t N e x t I m a g e I n L i s t %
739 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
741 % GetNextImageInList() returns the next image in the list.
743 % The format of the GetNextImageInList method is:
745 % Image *GetNextImageInList(const Image *images)
747 % A description of each parameter follows:
749 % o images: the image list.
752 MagickExport Image *GetNextImageInList(const Image *images)
754 if (images == (Image *) NULL)
755 return((Image *) NULL);
756 assert(images->signature == MagickCoreSignature);
757 if (images->debug != MagickFalse)
758 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
759 return(images->next);
763 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
767 % G e t P r e v i o u s I m a g e I n L i s t %
771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
773 % GetPreviousImageInList() returns the previous image in the list.
775 % The format of the GetPreviousImageInList method is:
777 % Image *GetPreviousImageInList(const Image *images)
779 % A description of each parameter follows:
781 % o images: the image list.
784 MagickExport Image *GetPreviousImageInList(const Image *images)
786 if (images == (Image *) NULL)
787 return((Image *) NULL);
788 assert(images->signature == MagickCoreSignature);
789 return(images->previous);
793 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
796 % I m a g e L i s t T o A r r a y %
800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
802 % ImageListToArray() is a convenience method that converts an image list to
803 % a sequential array, with a NULL image pointer at the end of the array.
805 % The images remain part of the original image list, with the array providing
806 % an alternative means of indexing the image array.
808 % group = ImageListToArray(images, exception);
809 % while (i = 0; group[i] != (Image *) NULL; i++)
810 % printf("%s\n", group[i]->filename);
811 % printf("%d images\n", i);
812 % group = RelinquishMagickMemory(group);
814 % The format of the ImageListToArray method is:
816 % Image **ImageListToArray(const Image *images,ExceptionInfo *exception)
818 % A description of each parameter follows:
820 % o image: the image list.
822 % o exception: return any errors or warnings in this structure.
825 MagickExport Image **ImageListToArray(const Image *images,
826 ExceptionInfo *exception)
834 if (images == (Image *) NULL)
835 return((Image **) NULL);
836 assert(images->signature == MagickCoreSignature);
837 if (images->debug != MagickFalse)
838 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
839 group=(Image **) AcquireQuantumMemory((size_t) GetImageListLength(images)+1UL,
841 if (group == (Image **) NULL)
843 (void) ThrowMagickException(exception,GetMagickModule(),
844 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
845 return((Image **) NULL);
847 images=GetFirstImageInList(images);
848 for (i=0; images != (Image *) NULL; images=images->next)
849 group[i++]=(Image *) images;
850 group[i]=(Image *) NULL;
855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
859 % I n s e r t I m a g e I n L i s t %
863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
865 % InsertImageInList() insert the given image or image list, into the first
866 % image list, immediately AFTER the image pointed to. The given image list
867 % pointer is left unchanged unless previously empty.
869 % The format of the InsertImageInList method is:
871 % InsertImageInList(Image **images,Image *insert)
873 % A description of each parameter follows:
875 % o images: the image list to insert into.
877 % o insert: the image list to insert.
880 MagickExport void InsertImageInList(Image **images,Image *insert)
885 assert(images != (Image **) NULL);
886 assert(insert != (Image *) NULL);
887 assert(insert->signature == MagickCoreSignature);
888 if (insert->debug != MagickFalse)
889 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",insert->filename);
890 if ((*images) == (Image *) NULL)
892 assert((*images)->signature == MagickCoreSignature);
893 split=SplitImageList(*images);
894 AppendImageToList(images,insert);
895 AppendImageToList(images,split);
899 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
903 % N e w I m a g e L i s t %
907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
909 % NewImageList() creates an empty image list.
911 % The format of the NewImageList method is:
913 % Image *NewImageList(void)
916 MagickExport Image *NewImageList(void)
918 return((Image *) NULL);
922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
926 % P r e p e n d I m a g e T o L i s t %
930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
932 % PrependImageToList() prepends the image to the beginning of the list.
934 % The format of the PrependImageToList method is:
936 % PrependImageToList(Image *images,Image *image)
938 % A description of each parameter follows:
940 % o images: the image list.
942 % o image: the image.
945 MagickExport void PrependImageToList(Image **images,Image *prepend)
947 if (*images == (Image *) NULL)
952 AppendImageToList(&prepend,*images);
956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
960 % R e m o v e I m a g e F r o m L i s t %
964 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
966 % RemoveImageFromList() removes and returns the image pointed to.
968 % The given image list pointer is set to point to the next image in list
969 % if it exists, otherwise it is set to the previous image, or NULL if list
972 % The format of the RemoveImageFromList method is:
974 % Image *RemoveImageFromList(Image **images)
976 % A description of each parameter follows:
978 % o images: the image list.
981 MagickExport Image *RemoveImageFromList(Image **images)
986 assert(images != (Image **) NULL);
987 if ((*images) == (Image *) NULL)
988 return((Image *) NULL);
989 assert((*images)->signature == MagickCoreSignature);
990 if ((*images)->debug != MagickFalse)
991 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
992 (*images)->filename);
994 if ((p->previous == (Image *) NULL) && (p->next == (Image *) NULL))
995 *images=(Image *) NULL;
998 if (p->previous != (Image *) NULL)
1000 p->previous->next=p->next;
1001 *images=p->previous;
1003 if (p->next != (Image *) NULL)
1005 p->next->previous=p->previous;
1008 p->previous=(Image *) NULL;
1009 p->next=(Image *) NULL;
1015 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1019 % R e m o v e F i r s t I m a g e F r o m L i s t %
1023 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1025 % RemoveFirstImageFromList() removes and returns the first image in the list.
1027 % If the given image list pointer pointed to the removed first image, it is
1028 % set to the new first image of list, or NULL if list was emptied, otherwise
1031 % The format of the RemoveFirstImageFromList method is:
1033 % Image *RemoveFirstImageFromList(Image **images)
1035 % A description of each parameter follows:
1037 % o images: the image list.
1040 MagickExport Image *RemoveFirstImageFromList(Image **images)
1045 assert(images != (Image **) NULL);
1046 if ((*images) == (Image *) NULL)
1047 return((Image *) NULL);
1048 assert((*images)->signature == MagickCoreSignature);
1049 if ((*images)->debug != MagickFalse)
1050 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1051 (*images)->filename);
1053 while (image->previous != (Image *) NULL)
1054 image=image->previous;
1055 if (image == *images)
1056 *images=(*images)->next;
1057 if (image->next != (Image *) NULL)
1059 image->next->previous=(Image *) NULL;
1060 image->next=(Image *) NULL;
1066 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1070 % R e m o v e L a s t I m a g e F r o m L i s t %
1074 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1076 % RemoveLastImageFromList() removes and returns the last image from the list.
1078 % If the given image list pointer pointed to the removed last image, it is
1079 % set to the new last image of list, or NULL if list was emptied, otherwise
1082 % The format of the RemoveLastImageFromList method is:
1084 % Image *RemoveLastImageFromList(Image **images)
1086 % A description of each parameter follows:
1088 % o images: the image list.
1091 MagickExport Image *RemoveLastImageFromList(Image **images)
1096 assert(images != (Image **) NULL);
1097 if ((*images) == (Image *) NULL)
1098 return((Image *) NULL);
1099 assert((*images)->signature == MagickCoreSignature);
1100 if ((*images)->debug != MagickFalse)
1101 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1102 (*images)->filename);
1104 while (image->next != (Image *) NULL)
1106 if (image == *images)
1107 *images=(*images)->previous;
1108 if (image->previous != (Image *) NULL)
1110 image->previous->next=(Image *) NULL;
1111 image->previous=(Image *) NULL;
1117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1121 % R e p l a c e I m a g e I n L i s t %
1125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1127 % ReplaceImageInList() replaces an image in the list with the given image, or
1128 % list of images. Old image is destroyed.
1130 % The images list pointer is set to point to the first image of the inserted
1133 % The format of the ReplaceImageInList method is:
1135 % ReplaceImageInList(Image **images,Image *replace)
1137 % A description of each parameter follows:
1139 % o images: the list and pointer to image to replace
1141 % o replace: the image or image list replacing the original
1144 MagickExport void ReplaceImageInList(Image **images,Image *replace)
1146 assert(images != (Image **) NULL);
1147 assert(replace != (Image *) NULL);
1148 assert(replace->signature == MagickCoreSignature);
1149 if (replace->debug != MagickFalse)
1150 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",replace->filename);
1151 if ((*images) == (Image *) NULL)
1153 assert((*images)->signature == MagickCoreSignature);
1155 /* link next pointer */
1156 replace=GetLastImageInList(replace);
1157 replace->next=(*images)->next;
1158 if (replace->next != (Image *) NULL)
1159 replace->next->previous=replace;
1161 /* link previous pointer - set images position to first replacement image */
1162 replace=GetFirstImageInList(replace);
1163 replace->previous=(*images)->previous;
1164 if (replace->previous != (Image *) NULL)
1165 replace->previous->next=replace;
1167 /* destroy the replaced image that was in images */
1168 (void) DestroyImage(*images);
1173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1177 % 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 %
1181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1183 % ReplaceImageInListReturnLast() is exactly as ReplaceImageInList() except
1184 % the images pointer is set to the last image in the list of replacement
1187 % This allows you to simply use GetNextImageInList() to go to the image
1188 % that follows the just replaced image, even if a list of replacement images
1191 % The format of the ReplaceImageInList method is:
1193 % ReplaceImageInListReturnLast(Image **images,Image *replace)
1195 % A description of each parameter follows:
1197 % o images: the list and pointer to image to replace
1199 % o replace: the image or image list replacing the original
1202 MagickExport void ReplaceImageInListReturnLast(Image **images,Image *replace)
1204 assert(images != (Image **) NULL);
1205 assert(replace != (Image *) NULL);
1206 assert(replace->signature == MagickCoreSignature);
1207 if (replace->debug != MagickFalse)
1208 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",replace->filename);
1209 if ((*images) == (Image *) NULL)
1211 assert((*images)->signature == MagickCoreSignature);
1213 /* link previous pointer */
1214 replace=GetFirstImageInList(replace);
1215 replace->previous=(*images)->previous;
1216 if (replace->previous != (Image *) NULL)
1217 replace->previous->next=replace;
1219 /* link next pointer - set images position to last replacement image */
1220 replace=GetLastImageInList(replace);
1221 replace->next=(*images)->next;
1222 if (replace->next != (Image *) NULL)
1223 replace->next->previous=replace;
1225 /* destroy the replaced image that was in images */
1226 (void) DestroyImage(*images);
1231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1235 % R e v e r s e I m a g e L i s t %
1239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1241 % ReverseImageList() reverses the order of an image list.
1242 % The list pointer is reset to that start of the re-ordered list.
1244 % The format of the ReverseImageList method is:
1246 % void ReverseImageList(Image **images)
1248 % A description of each parameter follows:
1250 % o images: the image list.
1253 MagickExport void ReverseImageList(Image **images)
1261 assert(images != (Image **) NULL);
1262 if ((*images) == (Image *) NULL)
1264 assert((*images)->signature == MagickCoreSignature);
1265 if ((*images)->debug != MagickFalse)
1266 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1267 (*images)->filename);
1268 for (p=(*images); p->next != (Image *) NULL; p=p->next) ;
1270 for ( ; p != (Image *) NULL; p=p->next)
1273 p->next=p->previous;
1279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1283 % S p l i c e I m a g e I n t o L i s t %
1287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1289 % SpliceImageIntoList() removes 'length' images from the list and replaces
1290 % them with the specified splice. Removed images are returned.
1292 % The format of the SpliceImageIntoList method is:
1294 % SpliceImageIntoList(Image **images,const size_t,
1295 % const Image *splice)
1297 % A description of each parameter follows:
1299 % o images: the image list.
1301 % o length: the length of the image list to remove.
1303 % o splice: Replace the removed image list with this list.
1306 MagickExport Image *SpliceImageIntoList(Image **images,
1307 const size_t length,const Image *splice)
1316 assert(images != (Image **) NULL);
1317 assert(splice != (Image *) NULL);
1318 assert(splice->signature == MagickCoreSignature);
1319 if ((*images) == (Image *) NULL)
1320 return((Image *) NULL);
1321 assert((*images)->signature == MagickCoreSignature);
1322 if ((*images)->debug != MagickFalse)
1323 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1324 (*images)->filename);
1325 split=SplitImageList(*images);
1326 AppendImageToList(images,splice);
1327 image=(Image *) NULL;
1328 for (i=0; (i < length) && (split != (Image *) NULL); i++)
1329 AppendImageToList(&image,RemoveImageFromList(&split));
1330 AppendImageToList(images,split);
1335 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1339 % S p l i t I m a g e L i s t %
1343 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1345 % SplitImageList() splits an image into two lists, after given image
1346 % The list that was split off is returned, which may be empty.
1348 % The format of the SplitImageList method is:
1350 % Image *SplitImageList(Image *images)
1352 % A description of each parameter follows:
1354 % o images: the image list.
1357 MagickExport Image *SplitImageList(Image *images)
1359 if ((images == (Image *) NULL) || (images->next == (Image *) NULL))
1360 return((Image *) NULL);
1361 images=images->next;
1362 images->previous->next=(Image *) NULL;
1363 images->previous=(Image *) NULL;
1368 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1372 + S y n c I m a g e L i s t %
1376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1378 % SyncImageList() synchronizes the scene numbers in an image list.
1380 % The format of the SyncImageList method is:
1382 % void SyncImageList(Image *images)
1384 % A description of each parameter follows:
1386 % o images: the image list.
1389 MagickExport void SyncImageList(Image *images)
1395 if (images == (Image *) NULL)
1397 assert(images->signature == MagickCoreSignature);
1398 for (p=images; p != (Image *) NULL; p=p->next)
1400 for (q=p->next; q != (Image *) NULL; q=q->next)
1401 if (p->scene == q->scene)
1403 if (q != (Image *) NULL)
1406 if (p == (Image *) NULL)
1408 for (p=images->next; p != (Image *) NULL; p=p->next)
1409 p->scene=p->previous->scene+1;
1413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1417 + S y n c N e x t I m a g e I n L i s t %
1421 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1423 % SyncNextImageInList() returns the next image in the list after the blob
1424 % referenced is synchronized with the current image.
1426 % The format of the SyncNextImageInList method is:
1428 % Image *SyncNextImageInList(const Image *images)
1430 % A description of each parameter follows:
1432 % o images: the image list.
1435 MagickExport Image *SyncNextImageInList(const Image *images)
1437 if (images == (Image *) NULL)
1438 return((Image *) NULL);
1439 assert(images->signature == MagickCoreSignature);
1440 if (images->next == (Image *) NULL)
1441 return((Image *) NULL);
1442 if (images->blob != images->next->blob)
1444 DestroyBlob(images->next);
1445 images->next->blob=ReferenceBlob(images->blob);
1447 images->next->compression=images->compression;
1448 images->next->endian=images->endian;
1449 return(images->next);