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