43#include "MagickCore/studio.h"
44#include "MagickCore/artifact.h"
45#include "MagickCore/blob.h"
46#include "MagickCore/blob-private.h"
47#include "MagickCore/exception.h"
48#include "MagickCore/exception-private.h"
49#include "MagickCore/image-private.h"
50#include "MagickCore/list.h"
51#include "MagickCore/memory_.h"
52#include "MagickCore/string_.h"
53#include "MagickCore/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,
232 assert(images != (
const Image *) NULL);
233 assert(images->signature == MagickCoreSignature);
234 assert(scenes != (
char *) NULL);
236 assert(exception->signature == MagickCoreSignature);
237 if (IsEventLogging() != MagickFalse)
238 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
239 clone_images=NewImageList();
240 images=GetFirstImageInList(images);
241 artifact=GetImageArtifact(images,
"frames:step");
242 length=GetImageListLength(images);
243 for (p=(
char *) scenes; *p !=
'\0';)
248 while ((isspace((
int) ((
unsigned char) *p)) != 0) || (*p ==
','))
250 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%=(ssize_t) (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;
270 last%=(ssize_t) (length << 1);
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",
"%g `%s'",(
double) offset,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 *prepend)
993 if (*images == (
Image *) NULL)
998 AppendImageToList(&prepend,*images);
1027MagickExport
Image *RemoveImageFromList(
Image **images)
1032 assert(images != (
Image **) NULL);
1033 if ((*images) == (
Image *) NULL)
1034 return((
Image *) NULL);
1035 assert((*images)->signature == MagickCoreSignature);
1036 if (IsEventLogging() != MagickFalse)
1037 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
1038 (*images)->filename);
1040 if ((p->previous == (
Image *) NULL) && (p->next == (
Image *) NULL))
1041 *images=(
Image *) NULL;
1044 if (p->previous != (
Image *) NULL)
1046 p->previous->next=p->next;
1047 *images=p->previous;
1049 if (p->next != (
Image *) NULL)
1051 p->next->previous=p->previous;
1054 p->previous=(
Image *) NULL;
1055 p->next=(
Image *) NULL;
1086MagickExport
Image *RemoveFirstImageFromList(
Image **images)
1091 assert(images != (
Image **) NULL);
1092 if ((*images) == (
Image *) NULL)
1093 return((
Image *) NULL);
1094 assert((*images)->signature == MagickCoreSignature);
1095 if (IsEventLogging() != MagickFalse)
1096 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
1097 (*images)->filename);
1099 while (image->previous != (
Image *) NULL)
1100 image=image->previous;
1101 if (image == *images)
1102 *images=(*images)->next;
1103 if (image->next != (
Image *) NULL)
1105 image->next->previous=(
Image *) NULL;
1106 image->next=(
Image *) NULL;
1137MagickExport
Image *RemoveLastImageFromList(
Image **images)
1142 assert(images != (
Image **) NULL);
1143 if ((*images) == (
Image *) NULL)
1144 return((
Image *) NULL);
1145 assert((*images)->signature == MagickCoreSignature);
1146 if (IsEventLogging() != MagickFalse)
1147 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
1148 (*images)->filename);
1150 while (image->next != (
Image *) NULL)
1152 if (image == *images)
1153 *images=(*images)->previous;
1154 if (image->previous != (
Image *) NULL)
1156 image->previous->next=(
Image *) NULL;
1157 image->previous=(
Image *) NULL;
1190MagickExport
void ReplaceImageInList(
Image **images,
Image *replace)
1192 assert(images != (
Image **) NULL);
1193 assert(replace != (
Image *) NULL);
1194 assert(replace->signature == MagickCoreSignature);
1195 if (IsEventLogging() != MagickFalse)
1196 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",replace->filename);
1197 if ((*images) == (
Image *) NULL)
1199 assert((*images)->signature == MagickCoreSignature);
1203 replace=GetLastImageInList(replace);
1204 replace->next=(*images)->next;
1205 if (replace->next != (
Image *) NULL)
1206 replace->next->previous=replace;
1210 replace=GetFirstImageInList(replace);
1211 replace->previous=(*images)->previous;
1212 if (replace->previous != (
Image *) NULL)
1213 replace->previous->next=replace;
1217 (void) DestroyImage(*images);
1251MagickExport
void ReplaceImageInListReturnLast(
Image **images,
Image *replace)
1253 assert(images != (
Image **) NULL);
1254 assert(replace != (
Image *) NULL);
1255 assert(replace->signature == MagickCoreSignature);
1256 if (IsEventLogging() != MagickFalse)
1257 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",replace->filename);
1258 if ((*images) == (
Image *) NULL)
1260 assert((*images)->signature == MagickCoreSignature);
1264 replace=GetFirstImageInList(replace);
1265 replace->previous=(*images)->previous;
1266 if (replace->previous != (
Image *) NULL)
1267 replace->previous->next=replace;
1271 replace=GetLastImageInList(replace);
1272 replace->next=(*images)->next;
1273 if (replace->next != (
Image *) NULL)
1274 replace->next->previous=replace;
1278 (void) DestroyImage(*images);
1305MagickExport
void ReverseImageList(
Image **images)
1313 assert(images != (
Image **) NULL);
1314 if ((*images) == (
Image *) NULL)
1316 assert((*images)->signature == MagickCoreSignature);
1317 if (IsEventLogging() != MagickFalse)
1318 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
1319 (*images)->filename);
1320 for (p=(*images); p->next != (
Image *) NULL; p=p->next) ;
1322 for ( ; p != (
Image *) NULL; p=p->next)
1325 p->next=p->previous;
1358MagickExport
Image *SpliceImageIntoList(
Image **images,
1359 const size_t length,
const Image *splice)
1368 assert(images != (
Image **) NULL);
1369 assert(splice != (
Image *) NULL);
1370 assert(splice->signature == MagickCoreSignature);
1371 if ((*images) == (
Image *) NULL)
1372 return((
Image *) NULL);
1373 assert((*images)->signature == MagickCoreSignature);
1374 if (IsEventLogging() != MagickFalse)
1375 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",
1376 (*images)->filename);
1377 split=SplitImageList(*images);
1378 AppendImageToList(images,splice);
1379 image=(
Image *) NULL;
1380 for (i=0; (i < length) && (split != (
Image *) NULL); i++)
1381 AppendImageToList(&image,RemoveImageFromList(&split));
1382 AppendImageToList(images,split);
1409MagickExport
Image *SplitImageList(
Image *images)
1411 if ((images == (
Image *) NULL) || (images->next == (
Image *) NULL))
1412 return((
Image *) NULL);
1413 images=images->next;
1414 images->previous->next=(
Image *) NULL;
1415 images->previous=(
Image *) NULL;
1441MagickExport
void SyncImageList(
Image *images)
1447 if (images == (
Image *) NULL)
1449 assert(images->signature == MagickCoreSignature);
1450 for (p=images; p != (
Image *) NULL; p=p->next)
1452 for (q=p->next; q != (
Image *) NULL; q=q->next)
1453 if (p->scene == q->scene)
1455 if (q != (
Image *) NULL)
1458 if (p == (
Image *) NULL)
1460 for (p=images->next; p != (
Image *) NULL; p=p->next)
1461 p->scene=p->previous->scene+1;
1487MagickExport
Image *SyncNextImageInList(
const Image *images)
1489 if (images == (
Image *) NULL)
1490 return((
Image *) NULL);
1491 assert(images->signature == MagickCoreSignature);
1492 if (images->next == (
Image *) NULL)
1493 return((
Image *) NULL);
1494 if (images->blob != images->next->blob)
1496 DestroyBlob(images->next);
1497 images->next->blob=ReferenceBlob(images->blob);
1499 if (images->next->compression == UndefinedCompression)
1500 images->next->compression=images->compression;
1501 if (images->next->endian == UndefinedEndian)
1502 images->next->endian=images->endian;
1503 return(images->next);