43 #include "magick/studio.h"
44 #include "magick/artifact.h"
45 #include "magick/blob.h"
46 #include "magick/blob-private.h"
47 #include "magick/exception.h"
48 #include "magick/exception-private.h"
49 #include "magick/image-private.h"
50 #include "magick/list.h"
51 #include "magick/memory_.h"
52 #include "magick/string_.h"
53 #include "magick/string-private.h"
80 MagickExport
void AppendImageToList(
Image **images,
const Image *append)
86 assert(images != (
Image **) NULL);
87 if (append == (
Image *) NULL)
89 assert(append->signature == MagickCoreSignature);
90 if (IsEventLogging() != MagickFalse)
91 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",append->filename);
92 if ((*images) == (
Image *) NULL)
94 *images=(
Image *) append;
97 assert((*images)->signature == MagickCoreSignature);
98 p=GetLastImageInList(*images);
99 q=GetFirstImageInList(append);
137 if (images == (
Image *) NULL)
138 return((
Image *) NULL);
139 assert(images->signature == MagickCoreSignature);
140 while (images->previous != (
Image *) NULL)
142 assert(images != images->previous);
143 images=images->previous;
145 image=(
Image *) NULL;
146 for (p=(
Image *) NULL; images != (
Image *) NULL; images=images->next)
148 assert(images != images->next);
149 clone=CloneImage(images,0,0,MagickTrue,exception);
150 if (clone == (
Image *) NULL)
152 if (image != (
Image *) NULL)
153 image=DestroyImageList(image);
154 return((
Image *) NULL);
156 if (image == (
Image *) NULL)
206 MagickExport
Image *CloneImages(
const Image *images,
const char *scenes,
233 assert(images != (
const Image *) NULL);
234 assert(images->signature == MagickCoreSignature);
235 assert(scenes != (
char *) NULL);
237 assert(exception->signature == MagickCoreSignature);
238 if (IsEventLogging() != MagickFalse)
239 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
240 clone_images=NewImageList();
241 images=GetFirstImageInList(images);
242 artifact=GetImageArtifact(images,
"frames:step");
243 length=GetImageListLength(images);
244 for (p=(
char *) scenes; *p !=
'\0';)
249 while ((isspace((
int) ((
unsigned char) *p)) != 0) || (*p ==
','))
251 first=(ssize_t) strtol(p,&p,10);
253 first+=(ssize_t) length;
255 if (first > (ssize_t) length)
256 first=(ssize_t) length;
257 first%=(length << 1);
259 while (isspace((
int) ((
unsigned char) *p)) != 0)
263 last=(ssize_t) strtol(p+1,&p,10);
265 last+=(ssize_t) length;
267 if (last > (ssize_t) length)
268 last=(ssize_t) length;
273 if (artifact != (
const char *) NULL)
275 step=(ssize_t) StringToLong(artifact);
279 step=(ssize_t) (first > last ? -step : step);
280 for ( ; step > 0 ? (last-first) >= 0 : (last-first) <= 0; first+=step)
283 for (next=images; next != (
Image *) NULL; next=GetNextImageInList(next))
285 if (i == (ssize_t) first)
287 image=CloneImage(next,0,0,MagickTrue,exception);
288 if (image == (
Image *) NULL)
290 AppendImageToList(&clone_images,image);
295 if (match == MagickFalse)
296 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
297 "InvalidImageIndex",
"`%s'",images->filename);
300 return(GetFirstImageInList(clone_images));
326 MagickExport
void DeleteImageFromList(
Image **images)
331 image=RemoveImageFromList(images);
332 if (image != (
Image *) NULL)
333 (void) DestroyImage(image);
372 MagickExport
void DeleteImages(
Image **images,
const char *scenes,
394 assert(images != (
Image **) NULL);
395 assert((*images)->signature == MagickCoreSignature);
396 assert(scenes != (
char *) NULL);
398 assert(exception->signature == MagickCoreSignature);
399 if (IsEventLogging() != MagickFalse)
400 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
401 (*images)->filename);
402 *images=GetFirstImageInList(*images);
403 length=GetImageListLength(*images);
404 delete_list=(MagickBooleanType *) AcquireQuantumMemory(length,
405 sizeof(*delete_list));
406 if (delete_list == (MagickBooleanType *) NULL)
408 (void) ThrowMagickException(exception,GetMagickModule(),
409 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",(*images)->filename);
413 for (i=0; i < (ssize_t) length; i++)
414 delete_list[i]=MagickFalse;
418 for (p=(
char *) scenes; *p !=
'\0';)
420 while ((isspace((
int) ((
unsigned char) *p)) != 0) || (*p ==
','))
422 first=strtol(p,&p,10);
424 first+=(long) length;
426 while (isspace((
int) ((
unsigned char) *p)) != 0)
430 last=strtol(p+1,&p,10);
436 for (i=(ssize_t) first; i <= (ssize_t) last; i++)
437 if ((i >= 0) && (i < (ssize_t) length))
438 delete_list[i]=MagickTrue;
444 for (i=0; i < (ssize_t) length; i++)
447 image=GetNextImageInList(image);
448 if (delete_list[i] != MagickFalse)
449 DeleteImageFromList(images);
451 (void) RelinquishMagickMemory(delete_list);
452 *images=GetFirstImageInList(*images);
477 MagickExport
Image *DestroyImageList(
Image *images)
479 if (images == (
Image *) NULL)
480 return((
Image *) NULL);
481 assert(images->signature == MagickCoreSignature);
482 if (IsEventLogging() != MagickFalse)
483 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
484 while (images != (
Image *) NULL)
485 DeleteImageFromList(&images);
486 return((
Image *) NULL);
525 MagickExport
Image *DuplicateImages(
Image *images,
526 const size_t number_duplicates,
const char *scenes,
ExceptionInfo *exception)
538 assert(images != (
Image *) NULL);
539 assert(images->signature == MagickCoreSignature);
540 assert(scenes != (
char *) NULL);
542 assert(exception->signature == MagickCoreSignature);
543 if (IsEventLogging() != MagickFalse)
544 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
545 duplicate_images=NewImageList();
546 for (i=0; i < (ssize_t) number_duplicates; i++)
548 clone_images=CloneImages(images,scenes,exception);
549 AppendImageToList(&duplicate_images,clone_images);
551 return(duplicate_images);
576 MagickExport
Image *GetFirstImageInList(
const Image *images)
581 if (images == (
Image *) NULL)
582 return((
Image *) NULL);
583 assert(images->signature == MagickCoreSignature);
584 for (p=images; p->previous != (
Image *) NULL; p=p->previous) ;
620 MagickExport
Image *GetImageFromList(
const Image *images,
const ssize_t index)
628 if (images == (
Image *) NULL)
629 return((
Image *) NULL);
630 assert(images->signature == MagickCoreSignature);
631 if (IsEventLogging() != MagickFalse)
632 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
635 p=GetLastImageInList(images);
636 for (i=(-1); p != (
Image *) NULL; p=p->previous)
642 p=GetFirstImageInList(images);
643 for (i=0; p != (
Image *) NULL; p=p->next)
672 MagickExport ssize_t GetImageIndexInList(
const Image *images)
677 if (images == (
const Image *) NULL)
679 assert(images->signature == MagickCoreSignature);
680 for (i=0; images->previous != (
Image *) NULL; i++)
682 assert(images != images->previous);
683 images=images->previous;
711 MagickExport
size_t GetImageListLength(
const Image *images)
716 if (images == (
Image *) NULL)
718 assert(images->signature == MagickCoreSignature);
719 if (IsEventLogging() != MagickFalse)
720 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
721 images=GetLastImageInList(images);
722 for (i=0; images != (
Image *) NULL; images=images->previous)
724 assert(images != images->previous);
752 MagickExport
Image *GetLastImageInList(
const Image *images)
757 if (images == (
Image *) NULL)
758 return((
Image *) NULL);
759 assert(images->signature == MagickCoreSignature);
760 for (p=images; p->next != (
Image *) NULL; p=p->next) ;
786 MagickExport
Image *GetNextImageInList(
const Image *images)
788 if (images == (
Image *) NULL)
789 return((
Image *) NULL);
790 assert(images->signature == MagickCoreSignature);
791 if (IsEventLogging() != MagickFalse)
792 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
793 return(images->next);
818 MagickExport
Image *GetPreviousImageInList(
const Image *images)
820 if (images == (
Image *) NULL)
821 return((
Image *) NULL);
822 assert(images->signature == MagickCoreSignature);
823 return(images->previous);
859 MagickExport
Image **ImageListToArray(
const Image *images,
868 if (images == (
Image *) NULL)
869 return((
Image **) NULL);
870 assert(images->signature == MagickCoreSignature);
871 if (IsEventLogging() != MagickFalse)
872 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
873 group=(
Image **) AcquireQuantumMemory((
size_t) GetImageListLength(images)+1UL,
875 if (group == (
Image **) NULL)
877 (void) ThrowMagickException(exception,GetMagickModule(),
878 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",images->filename);
879 return((
Image **) NULL);
881 images=GetFirstImageInList(images);
882 for (i=0; images != (
Image *) NULL; images=images->next)
884 assert(images != images->next);
885 group[i++]=(
Image *) images;
887 group[i]=(
Image *) NULL;
917 MagickExport
void InsertImageInList(
Image **images,
Image *insert)
922 assert(images != (
Image **) NULL);
923 assert(insert != (
Image *) NULL);
924 assert(insert->signature == MagickCoreSignature);
925 if (IsEventLogging() != MagickFalse)
926 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",insert->filename);
927 if ((*images) == (
Image *) NULL)
929 assert((*images)->signature == MagickCoreSignature);
930 split=SplitImageList(*images);
931 AppendImageToList(images,insert);
932 AppendImageToList(images,split);
953 MagickExport
Image *NewImageList(
void)
955 return((
Image *) NULL);
982 MagickExport
void PrependImageToList(
Image **images,
Image *image)
984 AppendImageToList(&image,*images);
1013 MagickExport
Image *RemoveImageFromList(
Image **images)
1018 assert(images != (
Image **) NULL);
1019 if ((*images) == (
Image *) NULL)
1020 return((
Image *) NULL);
1021 assert((*images)->signature == MagickCoreSignature);
1022 if (IsEventLogging() != MagickFalse)
1023 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
1024 (*images)->filename);
1026 if ((p->previous == (
Image *) NULL) && (p->next == (
Image *) NULL))
1027 *images=(
Image *) NULL;
1030 if (p->previous != (
Image *) NULL)
1032 p->previous->next=p->next;
1033 *images=p->previous;
1035 if (p->next != (
Image *) NULL)
1037 p->next->previous=p->previous;
1040 p->previous=(
Image *) NULL;
1041 p->next=(
Image *) NULL;
1072 MagickExport
Image *RemoveFirstImageFromList(
Image **images)
1077 assert(images != (
Image **) NULL);
1078 if ((*images) == (
Image *) NULL)
1079 return((
Image *) NULL);
1080 assert((*images)->signature == MagickCoreSignature);
1081 if (IsEventLogging() != MagickFalse)
1082 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
1083 (*images)->filename);
1085 while (image->previous != (
Image *) NULL)
1086 image=image->previous;
1087 if (image == *images)
1088 *images=(*images)->next;
1089 if (image->next != (
Image *) NULL)
1091 image->next->previous=(
Image *) NULL;
1092 image->next=(
Image *) NULL;
1123 MagickExport
Image *RemoveLastImageFromList(
Image **images)
1128 assert(images != (
Image **) NULL);
1129 if ((*images) == (
Image *) NULL)
1130 return((
Image *) NULL);
1131 assert((*images)->signature == MagickCoreSignature);
1132 if (IsEventLogging() != MagickFalse)
1133 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
1134 (*images)->filename);
1136 while (image->next != (
Image *) NULL)
1138 if (image == *images)
1139 *images=(*images)->previous;
1140 if (image->previous != (
Image *) NULL)
1142 image->previous->next=(
Image *) NULL;
1143 image->previous=(
Image *) NULL;
1176 MagickExport
void ReplaceImageInList(
Image **images,
Image *replace)
1178 assert(images != (
Image **) NULL);
1179 assert(replace != (
Image *) NULL);
1180 assert(replace->signature == MagickCoreSignature);
1181 if (IsEventLogging() != MagickFalse)
1182 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",replace->filename);
1183 if ((*images) == (
Image *) NULL)
1185 assert((*images)->signature == MagickCoreSignature);
1189 replace=GetLastImageInList(replace);
1190 replace->next=(*images)->next;
1191 if (replace->next != (
Image *) NULL)
1192 replace->next->previous=replace;
1196 replace=GetFirstImageInList(replace);
1197 replace->previous=(*images)->previous;
1198 if (replace->previous != (
Image *) NULL)
1199 replace->previous->next=replace;
1203 (void) DestroyImage(*images);
1237 MagickExport
void ReplaceImageInListReturnLast(
Image **images,
Image *replace)
1239 assert(images != (
Image **) NULL);
1240 assert(replace != (
Image *) NULL);
1241 assert(replace->signature == MagickCoreSignature);
1242 if (IsEventLogging() != MagickFalse)
1243 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",replace->filename);
1244 if ((*images) == (
Image *) NULL)
1246 assert((*images)->signature == MagickCoreSignature);
1250 replace=GetFirstImageInList(replace);
1251 replace->previous=(*images)->previous;
1252 if (replace->previous != (
Image *) NULL)
1253 replace->previous->next=replace;
1257 replace=GetLastImageInList(replace);
1258 replace->next=(*images)->next;
1259 if (replace->next != (
Image *) NULL)
1260 replace->next->previous=replace;
1264 (void) DestroyImage(*images);
1291 MagickExport
void ReverseImageList(
Image **images)
1299 assert(images != (
Image **) NULL);
1300 if ((*images) == (
Image *) NULL)
1302 assert((*images)->signature == MagickCoreSignature);
1303 if (IsEventLogging() != MagickFalse)
1304 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
1305 (*images)->filename);
1306 for (p=(*images); p->next != (
Image *) NULL; p=p->next) ;
1308 for ( ; p != (
Image *) NULL; p=p->next)
1311 p->next=p->previous;
1344 MagickExport
Image *SpliceImageIntoList(
Image **images,
1345 const size_t length,
const Image *splice)
1354 assert(images != (
Image **) NULL);
1355 assert(splice != (
Image *) NULL);
1356 assert(splice->signature == MagickCoreSignature);
1357 if ((*images) == (
Image *) NULL)
1358 return((
Image *) NULL);
1359 assert((*images)->signature == MagickCoreSignature);
1360 if (IsEventLogging() != MagickFalse)
1361 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
1362 (*images)->filename);
1363 split=SplitImageList(*images);
1364 AppendImageToList(images,splice);
1365 image=(
Image *) NULL;
1366 for (i=0; (i < length) && (split != (
Image *) NULL); i++)
1367 AppendImageToList(&image,RemoveImageFromList(&split));
1368 AppendImageToList(images,split);
1395 MagickExport
Image *SplitImageList(
Image *images)
1397 if ((images == (
Image *) NULL) || (images->next == (
Image *) NULL))
1398 return((
Image *) NULL);
1399 images=images->next;
1400 images->previous->next=(
Image *) NULL;
1401 images->previous=(
Image *) NULL;
1427 MagickExport
void SyncImageList(
Image *images)
1433 if (images == (
Image *) NULL)
1435 assert(images->signature == MagickCoreSignature);
1436 for (p=images; p != (
Image *) NULL; p=p->next)
1438 for (q=p->next; q != (
Image *) NULL; q=q->next)
1439 if (p->scene == q->scene)
1441 if (q != (
Image *) NULL)
1444 if (p == (
Image *) NULL)
1446 for (p=images->next; p != (
Image *) NULL; p=p->next)
1447 p->scene=p->previous->scene+1;
1473 MagickExport
Image *SyncNextImageInList(
const Image *images)
1475 if (images == (
Image *) NULL)
1476 return((
Image *) NULL);
1477 assert(images->signature == MagickCoreSignature);
1478 if (images->next == (
Image *) NULL)
1479 return((
Image *) NULL);
1480 if (images->blob != images->next->blob)
1482 DestroyBlob(images->next);
1483 images->next->blob=ReferenceBlob(images->blob);
1485 if (images->next->compression == UndefinedCompression)
1486 images->next->compression=images->compression;
1487 if (images->next->endian == UndefinedEndian)
1488 images->next->endian=images->endian;
1489 return(images->next);