• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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