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