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"
80MagickExport
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)
206MagickExport
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));
326MagickExport
void DeleteImageFromList(
Image **images)
331 image=RemoveImageFromList(images);
332 if (image != (
Image *) NULL)
333 (void) DestroyImage(image);
372MagickExport
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'; )
423 while ((isspace((
int) ((
unsigned char) *p)) != 0) || (*p ==
','))
425 first=strtol(p,&q,10);
430 first+=(long) length;
432 while (isspace((
int) ((
unsigned char) *p)) != 0)
436 last=strtol(p+1,&q,10);
445 for (i=(ssize_t) first; i <= (ssize_t) last; i++)
446 if ((i >= 0) && (i < (ssize_t) length))
447 delete_list[i]=MagickTrue;
453 for (i=0; i < (ssize_t) length; i++)
456 image=GetNextImageInList(image);
457 if (delete_list[i] != MagickFalse)
458 DeleteImageFromList(images);
460 (void) RelinquishMagickMemory(delete_list);
461 *images=GetFirstImageInList(*images);
486MagickExport
Image *DestroyImageList(
Image *images)
488 if (images == (
Image *) NULL)
489 return((
Image *) NULL);
490 assert(images->signature == MagickCoreSignature);
491 if (IsEventLogging() != MagickFalse)
492 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
493 while (images != (
Image *) NULL)
494 DeleteImageFromList(&images);
495 return((
Image *) NULL);
534MagickExport
Image *DuplicateImages(
Image *images,
535 const size_t number_duplicates,
const char *scenes,
ExceptionInfo *exception)
547 assert(images != (
Image *) NULL);
548 assert(images->signature == MagickCoreSignature);
549 assert(scenes != (
char *) NULL);
551 assert(exception->signature == MagickCoreSignature);
552 if (IsEventLogging() != MagickFalse)
553 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
554 duplicate_images=NewImageList();
555 for (i=0; i < (ssize_t) number_duplicates; i++)
557 clone_images=CloneImages(images,scenes,exception);
558 AppendImageToList(&duplicate_images,clone_images);
560 return(duplicate_images);
585MagickExport
Image *GetFirstImageInList(
const Image *images)
590 if (images == (
Image *) NULL)
591 return((
Image *) NULL);
592 assert(images->signature == MagickCoreSignature);
593 for (p=images; p->previous != (
Image *) NULL; p=p->previous) ;
629MagickExport
Image *GetImageFromList(
const Image *images,
const ssize_t index)
637 if (images == (
Image *) NULL)
638 return((
Image *) NULL);
639 assert(images->signature == MagickCoreSignature);
640 if (IsEventLogging() != MagickFalse)
641 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
644 p=GetLastImageInList(images);
645 for (i=(-1); p != (
Image *) NULL; p=p->previous)
651 p=GetFirstImageInList(images);
652 for (i=0; p != (
Image *) NULL; p=p->next)
681MagickExport ssize_t GetImageIndexInList(
const Image *images)
686 if (images == (
const Image *) NULL)
688 assert(images->signature == MagickCoreSignature);
689 for (i=0; images->previous != (
Image *) NULL; i++)
691 assert(images != images->previous);
692 images=images->previous;
720MagickExport
size_t GetImageListLength(
const Image *images)
725 if (images == (
Image *) NULL)
727 assert(images->signature == MagickCoreSignature);
728 if (IsEventLogging() != MagickFalse)
729 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
730 images=GetLastImageInList(images);
731 for (i=0; images != (
Image *) NULL; images=images->previous)
733 assert(images != images->previous);
761MagickExport
Image *GetLastImageInList(
const Image *images)
766 if (images == (
Image *) NULL)
767 return((
Image *) NULL);
768 assert(images->signature == MagickCoreSignature);
769 for (p=images; p->next != (
Image *) NULL; p=p->next) ;
795MagickExport
Image *GetNextImageInList(
const Image *images)
797 if (images == (
Image *) NULL)
798 return((
Image *) NULL);
799 assert(images->signature == MagickCoreSignature);
800 if (IsEventLogging() != MagickFalse)
801 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
802 return(images->next);
827MagickExport
Image *GetPreviousImageInList(
const Image *images)
829 if (images == (
Image *) NULL)
830 return((
Image *) NULL);
831 assert(images->signature == MagickCoreSignature);
832 return(images->previous);
868MagickExport
Image **ImageListToArray(
const Image *images,
877 if (images == (
Image *) NULL)
878 return((
Image **) NULL);
879 assert(images->signature == MagickCoreSignature);
880 if (IsEventLogging() != MagickFalse)
881 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
882 group=(
Image **) AcquireQuantumMemory((
size_t) GetImageListLength(images)+1UL,
884 if (group == (
Image **) NULL)
886 (void) ThrowMagickException(exception,GetMagickModule(),
887 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",images->filename);
888 return((
Image **) NULL);
890 images=GetFirstImageInList(images);
891 for (i=0; images != (
Image *) NULL; images=images->next)
893 assert(images != images->next);
894 group[i++]=(
Image *) images;
896 group[i]=(
Image *) NULL;
926MagickExport
void InsertImageInList(
Image **images,
Image *insert)
931 assert(images != (
Image **) NULL);
932 assert(insert != (
Image *) NULL);
933 assert(insert->signature == MagickCoreSignature);
934 if (IsEventLogging() != MagickFalse)
935 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",insert->filename);
936 if ((*images) == (
Image *) NULL)
938 assert((*images)->signature == MagickCoreSignature);
939 split=SplitImageList(*images);
940 AppendImageToList(images,insert);
941 AppendImageToList(images,split);
962MagickExport
Image *NewImageList(
void)
964 return((
Image *) NULL);
991MagickExport
void PrependImageToList(
Image **images,
Image *image)
993 AppendImageToList(&image,*images);
1022MagickExport
Image *RemoveImageFromList(
Image **images)
1027 assert(images != (
Image **) NULL);
1028 if ((*images) == (
Image *) NULL)
1029 return((
Image *) NULL);
1030 assert((*images)->signature == MagickCoreSignature);
1031 if (IsEventLogging() != MagickFalse)
1032 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
1033 (*images)->filename);
1035 if ((p->previous == (
Image *) NULL) && (p->next == (
Image *) NULL))
1036 *images=(
Image *) NULL;
1039 if (p->previous != (
Image *) NULL)
1041 p->previous->next=p->next;
1042 *images=p->previous;
1044 if (p->next != (
Image *) NULL)
1046 p->next->previous=p->previous;
1049 p->previous=(
Image *) NULL;
1050 p->next=(
Image *) NULL;
1081MagickExport
Image *RemoveFirstImageFromList(
Image **images)
1086 assert(images != (
Image **) NULL);
1087 if ((*images) == (
Image *) NULL)
1088 return((
Image *) NULL);
1089 assert((*images)->signature == MagickCoreSignature);
1090 if (IsEventLogging() != MagickFalse)
1091 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
1092 (*images)->filename);
1094 while (image->previous != (
Image *) NULL)
1095 image=image->previous;
1096 if (image == *images)
1097 *images=(*images)->next;
1098 if (image->next != (
Image *) NULL)
1100 image->next->previous=(
Image *) NULL;
1101 image->next=(
Image *) NULL;
1132MagickExport
Image *RemoveLastImageFromList(
Image **images)
1137 assert(images != (
Image **) NULL);
1138 if ((*images) == (
Image *) NULL)
1139 return((
Image *) NULL);
1140 assert((*images)->signature == MagickCoreSignature);
1141 if (IsEventLogging() != MagickFalse)
1142 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
1143 (*images)->filename);
1145 while (image->next != (
Image *) NULL)
1147 if (image == *images)
1148 *images=(*images)->previous;
1149 if (image->previous != (
Image *) NULL)
1151 image->previous->next=(
Image *) NULL;
1152 image->previous=(
Image *) NULL;
1185MagickExport
void ReplaceImageInList(
Image **images,
Image *replace)
1187 assert(images != (
Image **) NULL);
1188 assert(replace != (
Image *) NULL);
1189 assert(replace->signature == MagickCoreSignature);
1190 if (IsEventLogging() != MagickFalse)
1191 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",replace->filename);
1192 if ((*images) == (
Image *) NULL)
1194 assert((*images)->signature == MagickCoreSignature);
1198 replace=GetLastImageInList(replace);
1199 replace->next=(*images)->next;
1200 if (replace->next != (
Image *) NULL)
1201 replace->next->previous=replace;
1205 replace=GetFirstImageInList(replace);
1206 replace->previous=(*images)->previous;
1207 if (replace->previous != (
Image *) NULL)
1208 replace->previous->next=replace;
1212 (void) DestroyImage(*images);
1246MagickExport
void ReplaceImageInListReturnLast(
Image **images,
Image *replace)
1248 assert(images != (
Image **) NULL);
1249 assert(replace != (
Image *) NULL);
1250 assert(replace->signature == MagickCoreSignature);
1251 if (IsEventLogging() != MagickFalse)
1252 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",replace->filename);
1253 if ((*images) == (
Image *) NULL)
1255 assert((*images)->signature == MagickCoreSignature);
1259 replace=GetFirstImageInList(replace);
1260 replace->previous=(*images)->previous;
1261 if (replace->previous != (
Image *) NULL)
1262 replace->previous->next=replace;
1266 replace=GetLastImageInList(replace);
1267 replace->next=(*images)->next;
1268 if (replace->next != (
Image *) NULL)
1269 replace->next->previous=replace;
1273 (void) DestroyImage(*images);
1300MagickExport
void ReverseImageList(
Image **images)
1308 assert(images != (
Image **) NULL);
1309 if ((*images) == (
Image *) NULL)
1311 assert((*images)->signature == MagickCoreSignature);
1312 if (IsEventLogging() != MagickFalse)
1313 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
1314 (*images)->filename);
1315 for (p=(*images); p->next != (
Image *) NULL; p=p->next) ;
1317 for ( ; p != (
Image *) NULL; p=p->next)
1320 p->next=p->previous;
1353MagickExport
Image *SpliceImageIntoList(
Image **images,
1354 const size_t length,
const Image *splice)
1363 assert(images != (
Image **) NULL);
1364 assert(splice != (
Image *) NULL);
1365 assert(splice->signature == MagickCoreSignature);
1366 if ((*images) == (
Image *) NULL)
1367 return((
Image *) NULL);
1368 assert((*images)->signature == MagickCoreSignature);
1369 if (IsEventLogging() != MagickFalse)
1370 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
1371 (*images)->filename);
1372 split=SplitImageList(*images);
1373 AppendImageToList(images,splice);
1374 image=(
Image *) NULL;
1375 for (i=0; (i < length) && (split != (
Image *) NULL); i++)
1376 AppendImageToList(&image,RemoveImageFromList(&split));
1377 AppendImageToList(images,split);
1404MagickExport
Image *SplitImageList(
Image *images)
1406 if ((images == (
Image *) NULL) || (images->next == (
Image *) NULL))
1407 return((
Image *) NULL);
1408 images=images->next;
1409 images->previous->next=(
Image *) NULL;
1410 images->previous=(
Image *) NULL;
1436MagickExport
void SyncImageList(
Image *images)
1442 if (images == (
Image *) NULL)
1444 assert(images->signature == MagickCoreSignature);
1445 for (p=images; p != (
Image *) NULL; p=p->next)
1447 for (q=p->next; q != (
Image *) NULL; q=q->next)
1448 if (p->scene == q->scene)
1450 if (q != (
Image *) NULL)
1453 if (p == (
Image *) NULL)
1455 for (p=images->next; p != (
Image *) NULL; p=p->next)
1456 p->scene=p->previous->scene+1;
1482MagickExport
Image *SyncNextImageInList(
const Image *images)
1484 if (images == (
Image *) NULL)
1485 return((
Image *) NULL);
1486 assert(images->signature == MagickCoreSignature);
1487 if (images->next == (
Image *) NULL)
1488 return((
Image *) NULL);
1489 if (images->blob != images->next->blob)
1491 DestroyBlob(images->next);
1492 images->next->blob=ReferenceBlob(images->blob);
1494 if (images->next->compression == UndefinedCompression)
1495 images->next->compression=images->compression;
1496 if (images->next->endian == UndefinedEndian)
1497 images->next->endian=images->endian;
1498 return(images->next);