blob: dd44cb15896ba2c565ed91db80ea37e4ba6f8162 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
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% John Cristy %
17% December 2002 %
18% %
19% %
cristy16af1cb2009-12-11 21:38:29 +000020% Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% 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% http://www.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/blob.h"
45#include "magick/blob-private.h"
46#include "magick/exception.h"
47#include "magick/exception-private.h"
48#include "magick/list.h"
49#include "magick/memory_.h"
50#include "magick/string_.h"
51
52/*
53%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54% %
55% %
56% %
57% A p p e n d I m a g e T o L i s t %
58% %
59% %
60% %
61%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62%
63% AppendImageToList() appends the second image list to the end of the first
64% list. The given image list pointer is left unchanged, unless it was empty.
65%
66% The format of the AppendImageToList method is:
67%
68% AppendImageToList(Image *images,const Image *image)
69%
70% A description of each parameter follows:
71%
72% o images: the image list to be appended to.
73%
74% o image: the appended image or image list.
75%
76*/
77MagickExport void AppendImageToList(Image **images,const Image *image)
78{
79 register Image
80 *p,
81 *q;
82
83 assert(images != (Image **) NULL);
84 if (image == (Image *) NULL)
85 return;
86 assert(image->signature == MagickSignature);
87 if (image->debug != MagickFalse)
88 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
89 if ((*images) == (Image *) NULL)
90 {
91 *images=(Image *) image;
92 return;
93 }
94 assert((*images)->signature == MagickSignature);
95 p=GetLastImageInList(*images);
96 q=GetFirstImageInList(image);
97 p->next=q;
98 q->previous=p;
cristy3ed852e2009-09-05 21:47:34 +000099}
100
101/*
102%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
103% %
104% %
105% %
106% C l o n e I m a g e L i s t %
107% %
108% %
109% %
110%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
111%
112% CloneImageList() returns a duplicate of the image list.
113%
114% The format of the CloneImageList method is:
115%
116% Image *CloneImageList(const Image *images,ExceptionInfo *exception)
117%
118% A description of each parameter follows:
119%
120% o images: the image list.
121%
122% o exception: return any errors or warnings in this structure.
123%
124*/
125MagickExport Image *CloneImageList(const Image *images,ExceptionInfo *exception)
126{
127 Image
128 *clone,
129 *image;
130
131 register Image
132 *p;
133
134 if (images == (Image *) NULL)
135 return((Image *) NULL);
136 assert(images->signature == MagickSignature);
137 while (images->previous != (Image *) NULL)
138 images=images->previous;
139 image=(Image *) NULL;
140 for (p=(Image *) NULL; images != (Image *) NULL; images=images->next)
141 {
142 clone=CloneImage(images,0,0,MagickTrue,exception);
143 if (clone == (Image *) NULL)
144 {
145 if (image != (Image *) NULL)
146 image=DestroyImageList(image);
147 return((Image *) NULL);
148 }
149 if (image == (Image *) NULL)
150 {
151 image=clone;
152 p=image;
153 continue;
154 }
155 p->next=clone;
156 clone->previous=p;
157 p=p->next;
158 }
159 return(image);
160}
161
162/*
163%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164% %
165% %
166% %
167% C l o n e I m a g e s %
168% %
169% %
170% %
171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172%
173% CloneImages() clones one or more images from an image sequence, using a
174% comma separated list of image numbers or ranges.
175%
176% The numbers start at 0 for the first image in the list, while negative
177% numbers refer to images starting counting from the end of the range. Images
178% may be refered to multiple times to clone them multiple times. Images
179% refered beyond the available number of images in list are ignored.
180%
181% Images referenced may be reversed, and results in a clone of those images
182% also being made with a reversed order.
183%
184% The format of the CloneImages method is:
185%
186% Image *CloneImages(const Image *images,const char *scenes,
187% ExceptionInfo *exception)
188%
189% A description of each parameter follows:
190%
191% o images: the image sequence.
192%
193% o scenes: This character string specifies which scenes to clone
194% (e.g. 1,3-5,7-3,2).
195%
196% o exception: return any errors or warnings in this structure.
197%
198*/
199MagickExport Image *CloneImages(const Image *images,const char *scenes,
200 ExceptionInfo *exception)
201{
202 char
203 *p;
204
205 const Image
206 *next;
207
208 Image
209 *clone_images,
210 *image;
211
cristycee97112010-05-28 00:44:52 +0000212 long
cristy3ed852e2009-09-05 21:47:34 +0000213 first,
214 last,
215 step;
216
cristybb503372010-05-27 20:51:26 +0000217 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000218 i;
219
220 size_t
221 length;
222
223 assert(images != (const Image *) NULL);
224 assert(images->signature == MagickSignature);
225 assert(scenes != (char *) NULL);
226 if (images->debug != MagickFalse)
227 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
228 assert(exception != (ExceptionInfo *) NULL);
229 assert(exception->signature == MagickSignature);
230 clone_images=NewImageList();
231 images=GetFirstImageInList(images);
232 length=GetImageListLength(images);
233 for (p=(char *) scenes; *p != '\0';)
234 {
235 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
236 p++;
237 first=strtol(p,&p,10);
238 if (first < 0)
cristy8891f9c2010-06-04 23:32:17 +0000239 first+=(long) length;
cristy3ed852e2009-09-05 21:47:34 +0000240 last=first;
241 while (isspace((int) ((unsigned char) *p)) != 0)
242 p++;
243 if (*p == '-')
244 {
245 last=strtol(p+1,&p,10);
246 if (last < 0)
cristy8891f9c2010-06-04 23:32:17 +0000247 last+=(long) length;
cristy3ed852e2009-09-05 21:47:34 +0000248 }
249 for (step=first > last ? -1 : 1; first != (last+step); first+=step)
250 {
251 i=0;
252 for (next=images; next != (Image *) NULL; next=GetNextImageInList(next))
253 {
cristycee97112010-05-28 00:44:52 +0000254 if (i == (ssize_t) first)
cristy3ed852e2009-09-05 21:47:34 +0000255 {
256 image=CloneImage(next,0,0,MagickTrue,exception);
257 if (image == (Image *) NULL)
258 break;
259 AppendImageToList(&clone_images,image);
260 }
261 i++;
262 }
263 }
264 }
265 return(GetFirstImageInList(clone_images));
266}
267
268/*
269%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
270% %
271% %
272% %
273% D e l e t e I m a g e F r o m L i s t %
274% %
275% %
276% %
277%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
278%
279% DeleteImageFromList() deletes an image from the list. List pointer
280% is moved to the next image, if one is present. See RemoveImageFromList().
281%
282% The format of the DeleteImageFromList method is:
283%
284% DeleteImageFromList(Image **images)
285%
286% A description of each parameter follows:
287%
288% o images: the image list.
289%
290*/
291MagickExport void DeleteImageFromList(Image **images)
292{
293 Image
294 *image;
295
296 image=RemoveImageFromList(images);
297 if (image != (Image *) NULL)
298 (void) DestroyImage(image);
299}
300
301/*
302%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
303% %
304% %
305% %
306% D e l e t e I m a g e s %
307% %
308% %
309% %
310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311%
312% DeleteImages() deletes one or more images from an image sequence, using a
313% comma separated list of image numbers or ranges.
314%
315% The numbers start at 0 for the first image, while negative numbers refer to
316% images starting counting from the end of the range. Images may be refered to
317% multiple times without problems. Image refered beyond the available number
318% of images in list are ignored.
319%
320% If the referenced images are in the reverse order, that range will be
321% completely ignored. Unlike CloneImages().
322%
323% The format of the DeleteImages method is:
324%
325% DeleteImages(Image **images,const char *scenes,ExceptionInfo *exception)
326%
327% A description of each parameter follows:
328%
329% o images: the image sequence.
330%
331% o scenes: This character string specifies which scenes to delete
332% (e.g. 1,3-5,-2-6,2).
333%
334% o exception: return any errors or warnings in this structure.
335%
336*/
337MagickExport void DeleteImages(Image **images,const char *scenes,
338 ExceptionInfo *exception)
339{
340 char
341 *p;
342
343 Image
344 *image;
345
cristycee97112010-05-28 00:44:52 +0000346 long
cristy3ed852e2009-09-05 21:47:34 +0000347 first,
348 last;
349
350 MagickBooleanType
351 *delete_list;
352
cristybb503372010-05-27 20:51:26 +0000353 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000354 i;
355
356 size_t
357 length;
358
359 assert(images != (Image **) NULL);
360 assert((*images)->signature == MagickSignature);
361 assert(scenes != (char *) NULL);
362 if ((*images)->debug != MagickFalse)
363 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
364 (*images)->filename);
365 assert(exception != (ExceptionInfo *) NULL);
366 assert(exception->signature == MagickSignature);
367 *images=GetFirstImageInList(*images);
368 length=GetImageListLength(*images);
369 delete_list=(MagickBooleanType *) AcquireQuantumMemory(length,
370 sizeof(*delete_list));
371 if (delete_list == (MagickBooleanType *) NULL)
372 {
373 (void) ThrowMagickException(exception,GetMagickModule(),
374 ResourceLimitError,"MemoryAllocationFailed","`%s'",(*images)->filename);
375 return;
376 }
377 image=(*images);
cristybb503372010-05-27 20:51:26 +0000378 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +0000379 delete_list[i]=MagickFalse;
380 /*
381 Note which images will be deleted, avoid duplicate deleted
382 */
383 for (p=(char *) scenes; *p != '\0';)
384 {
385 while ((isspace((int)*p) != 0) || (*p == ','))
386 p++;
387 first=strtol(p,&p,10);
388 if (first < 0)
cristy8891f9c2010-06-04 23:32:17 +0000389 first+=(long) length;
cristy3ed852e2009-09-05 21:47:34 +0000390 last=first;
391 while (isspace((int) ((unsigned char) *p)) != 0)
392 p++;
393 if (*p == '-')
394 {
395 last=strtol(p+1,&p,10);
396 if (last < 0)
cristy8891f9c2010-06-04 23:32:17 +0000397 last+=(long) length;
cristy3ed852e2009-09-05 21:47:34 +0000398 }
399 if (first > last)
400 continue;
cristycee97112010-05-28 00:44:52 +0000401 for (i=(ssize_t) first; i <= (ssize_t) last; i++)
cristybb503372010-05-27 20:51:26 +0000402 if ((i >= 0) && (i < (ssize_t) length))
cristy3ed852e2009-09-05 21:47:34 +0000403 delete_list[i]=MagickTrue;
404 }
405 /*
406 Delete images marked for deletion, once only
407 */
408 image=(*images);
cristybb503372010-05-27 20:51:26 +0000409 for (i=0; i < (ssize_t) length; i++)
cristy3ed852e2009-09-05 21:47:34 +0000410 {
411 *images=image;
412 image=GetNextImageInList(image);
413 if (delete_list[i] != MagickFalse)
414 DeleteImageFromList(images);
415
416 }
417 (void) RelinquishMagickMemory(delete_list);
418 *images=GetFirstImageInList(*images);
419}
420
421/*
422%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
423% %
424% %
425% %
426% D e s t r o y I m a g e L i s t %
427% %
428% %
429% %
430%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
431%
432% DestroyImageList() destroys an image list.
433%
434% The format of the DestroyImageList method is:
435%
436% Image *DestroyImageList(Image *image)
437%
438% A description of each parameter follows:
439%
440% o image: the image sequence.
441%
442*/
443MagickExport Image *DestroyImageList(Image *images)
444{
445 if (images == (Image *) NULL)
446 return((Image *) NULL);
447 assert(images->signature == MagickSignature);
448 if (images->debug != MagickFalse)
449 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
450 while (images != (Image *) NULL)
451 DeleteImageFromList(&images);
452 return((Image *) NULL);
453}
454
455/*
456%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
457% %
458% %
459% %
460% G e t F i r s t I m a g e I n L i s t %
461% %
462% %
463% %
464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465%
466% GetFirstImageInList() returns a pointer to the first image in the list.
467%
468% The format of the GetFirstImageInList method is:
469%
470% Image *GetFirstImageInList(const Image *images)
471%
472% A description of each parameter follows:
473%
474% o images: the image list.
475%
476*/
477MagickExport Image *GetFirstImageInList(const Image *images)
478{
479 register const Image
480 *p;
481
482 if (images == (Image *) NULL)
483 return((Image *) NULL);
484 assert(images->signature == MagickSignature);
485 for (p=images; p->previous != (Image *) NULL; p=p->previous) ;
486 return((Image *) p);
487}
488
489/*
490%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
491% %
492% %
493% %
494% G e t I m a g e F r o m L i s t %
495% %
496% %
497% %
498%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
499%
500% GetImageFromList() returns an image at the specified offset from the list.
501%
502% The format of the GetImageFromList method is:
503%
cristybb503372010-05-27 20:51:26 +0000504% Image *GetImageFromList(const Image *images,const ssize_t index)
cristy3ed852e2009-09-05 21:47:34 +0000505%
506% A description of each parameter follows:
507%
508% o images: the image list.
509%
510% o index: the position within the list.
511%
512*/
cristybb503372010-05-27 20:51:26 +0000513MagickExport Image *GetImageFromList(const Image *images,const ssize_t index)
cristy3ed852e2009-09-05 21:47:34 +0000514{
cristybb503372010-05-27 20:51:26 +0000515 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000516 offset;
517
518 register const Image
519 *p;
520
cristybb503372010-05-27 20:51:26 +0000521 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000522 i;
523
524 size_t
525 length;
526
527 if (images == (Image *) NULL)
528 return((Image *) NULL);
529 assert(images->signature == MagickSignature);
530 if (images->debug != MagickFalse)
531 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
532 for (p=images; p->previous != (Image *) NULL; p=p->previous) ;
533 length=GetImageListLength(images);
cristybb503372010-05-27 20:51:26 +0000534 for (offset=index; offset < 0; offset+=(ssize_t) length) ;
cristy3ed852e2009-09-05 21:47:34 +0000535 for (i=0; p != (Image *) NULL; p=p->next)
cristybb503372010-05-27 20:51:26 +0000536 if (i++ == (ssize_t) (offset % length))
cristy3ed852e2009-09-05 21:47:34 +0000537 break;
538 if (p == (Image *) NULL)
539 return((Image *) NULL);
540 return((Image *) p);
541}
542
543/*
544%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
545% %
546% %
547% %
548% G e t I m a g e I n d e x I n L i s t %
549% %
550% %
551% %
552%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
553%
554% GetImageIndexInList() returns the offset in the list of the specified image.
555%
556% The format of the GetImageIndexInList method is:
557%
cristybb503372010-05-27 20:51:26 +0000558% ssize_t GetImageIndexInList(const Image *images)
cristy3ed852e2009-09-05 21:47:34 +0000559%
560% A description of each parameter follows:
561%
562% o images: the image list.
563%
564*/
cristybb503372010-05-27 20:51:26 +0000565MagickExport ssize_t GetImageIndexInList(const Image *images)
cristy3ed852e2009-09-05 21:47:34 +0000566{
cristybb503372010-05-27 20:51:26 +0000567 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000568 i;
569
570 if (images == (const Image *) NULL)
571 return(-1);
572 assert(images->signature == MagickSignature);
573 for (i=0; images->previous != (Image *) NULL; i++)
574 images=images->previous;
575 return(i);
576}
577
578/*
579%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
580% %
581% %
582% %
583% G e t I m a g e L i s t L e n g t h %
584% %
585% %
586% %
587%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
588%
589% GetImageListLength() returns the length of the list (the number of images in
590% the list).
591%
592% The format of the GetImageListLength method is:
593%
cristybb503372010-05-27 20:51:26 +0000594% size_t GetImageListLength(const Image *images)
cristy3ed852e2009-09-05 21:47:34 +0000595%
596% A description of each parameter follows:
597%
598% o images: the image list.
599%
600*/
cristybb503372010-05-27 20:51:26 +0000601MagickExport size_t GetImageListLength(const Image *images)
cristy3ed852e2009-09-05 21:47:34 +0000602{
cristybb503372010-05-27 20:51:26 +0000603 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000604 i;
605
606 if (images == (Image *) NULL)
607 return(0);
608 assert(images->signature == MagickSignature);
609 if (images->debug != MagickFalse)
610 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
611 while (images->previous != (Image *) NULL)
612 images=images->previous;
613 for (i=0; images != (Image *) NULL; images=images->next)
614 i++;
cristybb503372010-05-27 20:51:26 +0000615 return((size_t) i);
cristy3ed852e2009-09-05 21:47:34 +0000616}
617
618/*
619%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
620% %
621% %
622% %
623% G e t L a s t I m a g e I n L i s t %
624% %
625% %
626% %
627%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
628%
629% GetLastImageInList() returns a pointer to the last image in the list.
630%
631% The format of the GetLastImageInList method is:
632%
633% Image *GetLastImageInList(const Image *images)
634%
635% A description of each parameter follows:
636%
637% o images: the image list.
638%
639*/
640MagickExport Image *GetLastImageInList(const Image *images)
641{
642 register const Image
643 *p;
644
645 if (images == (Image *) NULL)
646 return((Image *) NULL);
647 assert(images->signature == MagickSignature);
648 for (p=images; p->next != (Image *) NULL; p=p->next) ;
649 return((Image *) p);
650}
651
652/*
653%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
654% %
655% %
656% %
657% G e t N e x t I m a g e I n L i s t %
658% %
659% %
660% %
661%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
662%
663% GetNextImageInList() returns the next image in the list.
664%
665% The format of the GetNextImageInList method is:
666%
667% Image *GetNextImageInList(const Image *images)
668%
669% A description of each parameter follows:
670%
671% o images: the image list.
672%
673*/
674MagickExport Image *GetNextImageInList(const Image *images)
675{
676 if (images == (Image *) NULL)
677 return((Image *) NULL);
678 assert(images->signature == MagickSignature);
679 if (images->debug != MagickFalse)
680 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
681 return(images->next);
682}
683
684/*
685%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
686% %
687% %
688% %
689% G e t P r e v i o u s I m a g e I n L i s t %
690% %
691% %
692% %
693%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
694%
695% GetPreviousImageInList() returns the previous image in the list.
696%
697% The format of the GetPreviousImageInList method is:
698%
699% Image *GetPreviousImageInList(const Image *images)
700%
701% A description of each parameter follows:
702%
703% o images: the image list.
704%
705*/
706MagickExport Image *GetPreviousImageInList(const Image *images)
707{
708 if (images == (Image *) NULL)
709 return((Image *) NULL);
710 assert(images->signature == MagickSignature);
711 return(images->previous);
712}
713
714/*
715%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
716% %
717% %
718% I m a g e L i s t T o A r r a y %
719% %
720% %
721% %
722%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
723%
724% ImageListToArray() is a convenience method that converts an image list to
725% a sequential array. For example,
726%
727% group = ImageListToArray(images, exception);
728% while (i = 0; group[i] != (Image *) NULL; i++)
729% printf("%s\n", group[i]->filename);
730% printf("%d images\n", i);
731% group = RelinquishMagickMemory(group);
732%
733% The format of the ImageListToArray method is:
734%
735% Image **ImageListToArray(const Image *images,ExceptionInfo *exception)
736%
737% A description of each parameter follows:
738%
739% o image: the image list.
740%
741% o exception: return any errors or warnings in this structure.
742%
743*/
744MagickExport Image **ImageListToArray(const Image *images,
745 ExceptionInfo *exception)
746{
747 Image
748 **group;
749
cristybb503372010-05-27 20:51:26 +0000750 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000751 i;
752
753 if (images == (Image *) NULL)
754 return((Image **) NULL);
755 assert(images->signature == MagickSignature);
756 if (images->debug != MagickFalse)
757 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
758 group=(Image **) AcquireQuantumMemory((size_t) GetImageListLength(images)+1UL,
759 sizeof(*group));
760 if (group == (Image **) NULL)
761 {
762 (void) ThrowMagickException(exception,GetMagickModule(),
763 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
764 return((Image **) NULL);
765 }
766 images=GetFirstImageInList(images);
767 for (i=0; images != (Image *) NULL; images=images->next)
768 group[i++]=(Image *) images;
769 group[i]=(Image *) NULL;
770 return(group);
771}
772
773/*
774%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
775% %
776% %
777% %
778% I n s e r t I m a g e I n L i s t %
779% %
780% %
781% %
782%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
783%
784% InsertImageInList() inserts the second image or image list into the first
cristy7880d472010-08-22 20:57:24 +0000785% image list immediately after the image pointed to. The given image list
cristy3ed852e2009-09-05 21:47:34 +0000786% pointer is unchanged unless previously empty.
787%
788% The format of the InsertImageInList method is:
789%
790% InsertImageInList(Image **images,Image *image)
791%
792% A description of each parameter follows:
793%
794% o images: the image list to insert into.
795%
796% o image: the image list to insert.
797%
798*/
799MagickExport void InsertImageInList(Image **images,Image *image)
800{
801 Image
802 *split;
803
804 assert(images != (Image **) NULL);
805 assert(image != (Image *) NULL);
806 assert(image->signature == MagickSignature);
807 if (image->debug != MagickFalse)
808 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
809 if ((*images) == (Image *) NULL)
810 return;
811 assert((*images)->signature == MagickSignature);
812 split=SplitImageList(*images);
813 AppendImageToList(images,image);
814 AppendImageToList(images,split);
815}
816
817/*
818%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
819% %
820% %
821% %
822% N e w I m a g e L i s t %
823% %
824% %
825% %
826%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
827%
828% NewImageList() creates an empty image list.
829%
830% The format of the NewImageList method is:
831%
832% Image *NewImageList(void)
833%
834*/
835MagickExport Image *NewImageList(void)
836{
837 return((Image *) NULL);
838}
839
840/*
841%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
842% %
843% %
844% %
845% P r e p e n d I m a g e T o L i s t %
846% %
847% %
848% %
849%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
850%
851% PrependImageToList() prepends the image to the beginning of the list.
852%
853% The format of the PrependImageToList method is:
854%
855% PrependImageToList(Image *images,Image *image)
856%
857% A description of each parameter follows:
858%
859% o images: the image list.
860%
861% o image: the image.
862%
863*/
864MagickExport void PrependImageToList(Image **images,Image *image)
865{
866 AppendImageToList(&image,*images);
867}
868
869/*
870%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
871% %
872% %
873% %
874% R e m o v e I m a g e F r o m L i s t %
875% %
876% %
877% %
878%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
879%
880% RemoveImageFromList() removes and returns the image pointed to.
881%
882% The given image list pointer is set to point to the next image in list
883% if it exists, otherwise it is set to the previous image, or NULL if list
884% was emptied.
885%
886% The format of the RemoveImageFromList method is:
887%
888% Image *RemoveImageFromList(Image **images)
889%
890% A description of each parameter follows:
891%
892% o images: the image list.
893%
894*/
895MagickExport Image *RemoveImageFromList(Image **images)
896{
897 register Image
898 *p;
899
900 assert(images != (Image **) NULL);
901 if ((*images) == (Image *) NULL)
902 return((Image *) NULL);
903 assert((*images)->signature == MagickSignature);
904 if ((*images)->debug != MagickFalse)
905 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
906 (*images)->filename);
907 p=(*images);
908 if ((p->previous == (Image *) NULL) && (p->next == (Image *) NULL))
909 *images=(Image *) NULL;
910 else
911 {
912 if (p->previous != (Image *) NULL)
913 {
914 p->previous->next=p->next;
915 *images=p->previous;
916 }
917 if (p->next != (Image *) NULL)
918 {
919 p->next->previous=p->previous;
920 *images=p->next;
921 }
922 p->previous=(Image *) NULL;
923 p->next=(Image *) NULL;
924 }
925 return(p);
926}
927
928/*
929%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
930% %
931% %
932% %
933% R e m o v e F i r s t I m a g e F r o m L i s t %
934% %
935% %
936% %
937%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
938%
939% RemoveFirstImageFromList() removes and returns the first image in the list.
940%
941% If the given image list pointer pointed to the removed first image, it is
942% set to the new first image of list, or NULL if list was emptied, otherwise
943% it is left as is.
944%
945% The format of the RemoveFirstImageFromList method is:
946%
947% Image *RemoveFirstImageFromList(Image **images)
948%
949% A description of each parameter follows:
950%
951% o images: the image list.
952%
953*/
954MagickExport Image *RemoveFirstImageFromList(Image **images)
955{
956 Image
957 *image;
958
959 assert(images != (Image **) NULL);
960 if ((*images) == (Image *) NULL)
961 return((Image *) NULL);
962 assert((*images)->signature == MagickSignature);
963 if ((*images)->debug != MagickFalse)
964 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
965 (*images)->filename);
966 image=(*images);
967 while (image->previous != (Image *) NULL)
968 image=image->previous;
969 if (image == *images)
970 *images=(*images)->next;
971 if (image->next != (Image *) NULL)
972 {
973 image->next->previous=(Image *) NULL;
974 image->next=(Image *) NULL;
975 }
976 return(image);
977}
978
979/*
980%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
981% %
982% %
983% %
984% R e m o v e L a s t I m a g e F r o m L i s t %
985% %
986% %
987% %
988%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
989%
990% RemoveLastImageFromList() removes and returns the last image from the list.
991%
992% If the given image list pointer pointed to the removed last image, it is
993% set to the new last image of list, or NULL if list was emptied, otherwise
994% it is left as is.
995%
996% The format of the RemoveLastImageFromList method is:
997%
998% Image *RemoveLastImageFromList(Image **images)
999%
1000% A description of each parameter follows:
1001%
1002% o images: the image list.
1003%
1004*/
1005MagickExport Image *RemoveLastImageFromList(Image **images)
1006{
1007 Image
1008 *image;
1009
1010 assert(images != (Image **) NULL);
1011 if ((*images) == (Image *) NULL)
1012 return((Image *) NULL);
1013 assert((*images)->signature == MagickSignature);
1014 if ((*images)->debug != MagickFalse)
1015 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1016 (*images)->filename);
1017 image=(*images);
1018 while (image->next != (Image *) NULL)
1019 image=image->next;
1020 if (image == *images)
1021 *images=(*images)->previous;
1022 if (image->previous != (Image *) NULL)
1023 {
1024 image->previous->next=(Image *) NULL;
1025 image->previous=(Image *) NULL;
1026 }
1027 return(image);
1028}
1029
1030/*
1031%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1032% %
1033% %
1034% %
1035% R e p l a c e I m a g e I n L i s t %
1036% %
1037% %
1038% %
1039%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1040%
1041% ReplaceImageInList() replaces an image in the list. Old image is destroyed.
1042% The given image list pointer is set to point to the just inserted image.
1043%
1044% The format of the ReplaceImageInList method is:
1045%
1046% ReplaceImageInList(Image **images,Image *image)
1047%
1048% A description of each parameter follows:
1049%
1050% o images: the image list.
1051%
1052% o image: the image.
1053%
1054*/
1055MagickExport void ReplaceImageInList(Image **images,Image *image)
1056{
1057 assert(images != (Image **) NULL);
1058 assert(image != (Image *) NULL);
1059 assert(image->signature == MagickSignature);
1060 if (image->debug != MagickFalse)
1061 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1062 if ((*images) == (Image *) NULL)
1063 return;
1064 assert((*images)->signature == MagickSignature);
cristy7880d472010-08-22 20:57:24 +00001065 for ( ; image->next != (Image *) NULL; image=image->next) ;
cristy3ed852e2009-09-05 21:47:34 +00001066 image->next=(*images)->next;
1067 if (image->next != (Image *) NULL)
1068 image->next->previous=image;
cristy7880d472010-08-22 20:57:24 +00001069 for ( ; image->previous != (Image *) NULL; image=image->previous) ;
cristy3ed852e2009-09-05 21:47:34 +00001070 image->previous=(*images)->previous;
1071 if (image->previous != (Image *) NULL)
1072 image->previous->next=image;
1073 (void) DestroyImage(*images);
1074 (*images)=image;
1075}
1076
1077/*
1078%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1079% %
1080% %
1081% %
1082% R e v e r s e I m a g e L i s t %
1083% %
1084% %
1085% %
1086%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1087%
1088% ReverseImageList() reverses the order of an image list.
1089% The list pointer is reset to that start of the re-ordered list.
1090%
1091% The format of the ReverseImageList method is:
1092%
1093% void ReverseImageList(Image **images)
1094%
1095% A description of each parameter follows:
1096%
1097% o images: the image list.
1098%
1099*/
1100MagickExport void ReverseImageList(Image **images)
1101{
1102 Image
1103 *next;
1104
1105 register Image
1106 *p;
1107
1108 assert(images != (Image **) NULL);
1109 if ((*images) == (Image *) NULL)
1110 return;
1111 assert((*images)->signature == MagickSignature);
1112 if ((*images)->debug != MagickFalse)
1113 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1114 (*images)->filename);
1115 for (p=(*images); p->next != (Image *) NULL; p=p->next) ;
1116 *images=p;
1117 for ( ; p != (Image *) NULL; p=p->next)
1118 {
1119 next=p->next;
1120 p->next=p->previous;
1121 p->previous=next;
1122 }
1123}
1124
1125/*
1126%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1127% %
1128% %
1129% %
1130% S p l i c e I m a g e I n t o L i s t %
1131% %
1132% %
1133% %
1134%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1135%
1136% SpliceImageIntoList() removes 'length' images from the list and replaces
1137% them with the specified splice. Removed images are returned.
1138%
1139% The format of the SpliceImageIntoList method is:
1140%
cristybb503372010-05-27 20:51:26 +00001141% SpliceImageIntoList(Image **images,const size_t,
cristy3ed852e2009-09-05 21:47:34 +00001142% const Image *splice)
1143%
1144% A description of each parameter follows:
1145%
1146% o images: the image list.
1147%
1148% o length: the length of the image list to remove.
1149%
1150% o splice: Replace the removed image list with this list.
1151%
1152*/
1153MagickExport Image *SpliceImageIntoList(Image **images,
cristybb503372010-05-27 20:51:26 +00001154 const size_t length,const Image *splice)
cristy3ed852e2009-09-05 21:47:34 +00001155{
1156 Image
1157 *image,
1158 *split;
1159
cristybb503372010-05-27 20:51:26 +00001160 register size_t
cristy3ed852e2009-09-05 21:47:34 +00001161 i;
1162
1163 assert(images != (Image **) NULL);
1164 assert(splice != (Image *) NULL);
1165 assert(splice->signature == MagickSignature);
1166 if ((*images) == (Image *) NULL)
1167 return((Image *) NULL);
1168 assert((*images)->signature == MagickSignature);
1169 if ((*images)->debug != MagickFalse)
1170 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1171 (*images)->filename);
1172 split=SplitImageList(*images);
1173 AppendImageToList(images,splice);
1174 image=(Image *) NULL;
1175 for (i=0; (i < length) && (split != (Image *) NULL); i++)
1176 AppendImageToList(&image,RemoveImageFromList(&split));
1177 AppendImageToList(images,split);
1178 return(image);
1179}
1180
1181/*
1182%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1183% %
1184% %
1185% %
1186% S p l i t I m a g e L i s t %
1187% %
1188% %
1189% %
1190%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1191%
1192% SplitImageList() splits an image into two lists, after given image
1193% The list that was split off is returned, which may be empty.
1194%
1195% The format of the SplitImageList method is:
1196%
1197% Image *SplitImageList(Image *images)
1198%
1199% A description of each parameter follows:
1200%
1201% o images: the image list.
1202%
1203*/
1204MagickExport Image *SplitImageList(Image *images)
1205{
1206 if ((images == (Image *) NULL) || (images->next == (Image *) NULL))
1207 return((Image *) NULL);
1208 images=images->next;
1209 images->previous->next=(Image *) NULL;
1210 images->previous=(Image *) NULL;
1211 return(images);
1212}
1213
1214/*
1215%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1216% %
1217% %
1218% %
1219+ S y n c I m a g e L i s t %
1220% %
1221% %
1222% %
1223%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1224%
1225% SyncImageList() synchronizes the scene numbers in an image list.
1226%
1227% The format of the SyncImageList method is:
1228%
1229% void SyncImageList(Image *images)
1230%
1231% A description of each parameter follows:
1232%
1233% o images: the image list.
1234%
1235*/
1236MagickExport void SyncImageList(Image *images)
1237{
1238 register Image
1239 *p,
1240 *q;
1241
1242 if (images == (Image *) NULL)
1243 return;
1244 assert(images->signature == MagickSignature);
1245 for (p=images; p != (Image *) NULL; p=p->next)
1246 {
1247 for (q=p->next; q != (Image *) NULL; q=q->next)
1248 if (p->scene == q->scene)
1249 break;
1250 if (q != (Image *) NULL)
1251 break;
1252 }
1253 if (p == (Image *) NULL)
1254 return;
1255 for (p=images->next; p != (Image *) NULL; p=p->next)
1256 p->scene=p->previous->scene+1;
1257}
1258
1259/*
1260%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1261% %
1262% %
1263% %
1264+ S y n c N e x t I m a g e I n L i s t %
1265% %
1266% %
1267% %
1268%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1269%
1270% SyncNextImageInList() returns the next image in the list after the blob
1271% referenced is synchronized with the current image.
1272%
1273% The format of the SyncNextImageInList method is:
1274%
1275% Image *SyncNextImageInList(const Image *images)
1276%
1277% A description of each parameter follows:
1278%
1279% o images: the image list.
1280%
1281*/
1282MagickExport Image *SyncNextImageInList(const Image *images)
1283{
1284 if (images == (Image *) NULL)
1285 return((Image *) NULL);
1286 assert(images->signature == MagickSignature);
1287 if (images->next == (Image *) NULL)
1288 return((Image *) NULL);
1289 if (images->blob != images->next->blob)
1290 {
1291 DestroyBlob(images->next);
1292 images->next->blob=ReferenceBlob(images->blob);
1293 }
cristy2d3f0ea2010-03-19 17:24:36 +00001294 images->next->compression=images->compression;
cristy3ed852e2009-09-05 21:47:34 +00001295 images->next->endian=images->endian;
1296 return(images->next);
1297}