]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/list.c
(no commit message)
[imagemagick] / MagickCore / list.c
index 598eff10b4aa72fc0fcf50ef7caecb4337ebcd51..4240b2414a72e13591281a7bcb13a360c2678a44 100644 (file)
@@ -371,7 +371,7 @@ MagickExport void DeleteImages(Image **images,const char *scenes,
   if (delete_list == (MagickBooleanType *) NULL)
     {
       (void) ThrowMagickException(exception,GetMagickModule(),
-        ResourceLimitError,"MemoryAllocationFailed","`%s'",(*images)->filename);
+        ResourceLimitError,"MemoryAllocationFailed","'%s'",(*images)->filename);
       return;
     }
   image=(*images);
@@ -562,7 +562,15 @@ MagickExport Image *GetFirstImageInList(const Image *images)
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  GetImageFromList() returns an image at the specified offset from the list.
+%  GetImageFromList() returns an image at the specified index from the image
+%  list. Starting with 0 as the first image in the list.
+%
+%  A negative offset will return the image from the end of the list, such that
+%  an index of -1 is the last image.
+%
+%  If no such image exists at the specified offset a NULL image pointer is
+%  returned.  This will only happen if index is less that the negative of
+%  the list length, or larger than list length -1.  EG: ( -N to N-1 )
 %
 %  The format of the GetImageFromList method is:
 %
@@ -583,25 +591,32 @@ MagickExport Image *GetImageFromList(const Image *images,const ssize_t index)
   register ssize_t
     i;
 
-  size_t
-    length;
-
-  ssize_t
-    offset;
-
   if (images == (Image *) NULL)
     return((Image *) NULL);
   assert(images->signature == MagickSignature);
   if (images->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
-  for (p=images; p->previous != (Image *) NULL; p=p->previous) ;
-  length=GetImageListLength(images);
-  for (offset=index; offset < 0; offset+=(ssize_t) length) ;
-  for (i=0; p != (Image *) NULL; p=p->next)
-    if (i++ == (ssize_t) (offset % length))
-      break;
-  if (p == (Image *) NULL)
-    return((Image *) NULL);
+
+  /*
+    Designed to efficiently find first image (index == 0), or last image
+    (index == -1) as appropriate, without to go through the whole image list.
+    That is it tries to avoid 'counting the whole list' to  handle the
+    most common image indexes.
+  */
+  if ( index < 0 )
+    {
+      p=GetLastImageInList(images);
+      for (i=-1; p != (Image *) NULL; p=p->previous)
+        if (i-- == index)
+          break;
+    }
+  else
+    {
+      p=GetFirstImageInList(images);
+      for (i=0; p != (Image *) NULL; p=p->next)
+        if (i++ == index)
+          break;
+    }
   return((Image *) p);
 }
 \f
@@ -673,8 +688,7 @@ MagickExport size_t GetImageListLength(const Image *images)
   assert(images->signature == MagickSignature);
   if (images->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
-  while (images->next != (Image *) NULL)
-    images=images->next;
+  images=GetLastImageInList(images);
   for (i=0; images != (Image *) NULL; images=images->previous)
     i++;
   return((size_t) i);
@@ -828,7 +842,7 @@ MagickExport Image **ImageListToArray(const Image *images,
   if (group == (Image **) NULL)
     {
       (void) ThrowMagickException(exception,GetMagickModule(),
-        ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
+        ResourceLimitError,"MemoryAllocationFailed","'%s'",images->filename);
       return((Image **) NULL);
     }
   images=GetFirstImageInList(images);
@@ -929,10 +943,14 @@ MagickExport Image *NewImageList(void)
 %    o image: the image.
 %
 */
-MagickExport void PrependImageToList(Image **images,Image *image)
+MagickExport void PrependImageToList(Image **images,Image *prepend)
 {
-  /* prepend, append the two lists with order swapped! */
-  AppendImageToList(&image,*images);
+  if (*images == (Image *) NULL)
+    {
+      *images=prepend;
+      return;
+    }
+  AppendImageToList(&prepend,*images);
 }
 \f
 /*