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