]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/list.c
(no commit message)
[imagemagick] / MagickCore / list.c
index 19e4b0374a6d991fab1c0163ad139cd99709b46d..6c140b1703e3d867d07de75bc91eb377062155b2 100644 (file)
 %                        MagickCore Image List Methods                        %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                               December 2002                                 %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
 %    o image: the appended image or image list.
 %
 */
-MagickExport void AppendImageToList(Image **images,const Image *image)
+MagickExport void AppendImageToList(Image **images,const Image *append)
 {
   register Image
     *p,
     *q;
 
   assert(images != (Image **) NULL);
-  if (image == (Image *) NULL)
+  if (append == (Image *) NULL)
     return;
-  assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
-    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
+  assert(append->signature == MagickSignature);
+  if (append->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",append->filename);
   if ((*images) == (Image *) NULL)
     {
-      *images=(Image *) image;
+      *images=(Image *) append;
       return;
     }
   assert((*images)->signature == MagickSignature);
   p=GetLastImageInList(*images);
-  q=GetFirstImageInList(image);
+  q=GetFirstImageInList(append);
   p->next=q;
   q->previous=p;
 }
@@ -382,7 +382,7 @@ MagickExport void DeleteImages(Image **images,const char *scenes,
   */
   for (p=(char *) scenes; *p != '\0';)
   {
-    while ((isspace((int) *p) != 0) || (*p == ','))
+    while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
       p++;
     first=strtol(p,&p,10);
     if (first < 0)
@@ -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,9 +688,8 @@ MagickExport size_t GetImageListLength(const Image *images)
   assert(images->signature == MagickSignature);
   if (images->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
-  while (images->previous != (Image *) NULL)
-    images=images->previous;
-  for (i=0; images != (Image *) NULL; images=images->next)
+  images=GetLastImageInList(images);
+  for (i=0; images != (Image *) NULL; images=images->previous)
     i++;
   return((size_t) i);
 }
@@ -787,7 +801,10 @@ MagickExport Image *GetPreviousImageInList(const Image *images)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %  ImageListToArray() is a convenience method that converts an image list to
-%  a sequential array.  For example,
+%  a sequential array, with a NULL image pointer at the end of the array.
+%
+%  The images remain part of the original image list, with the array providing
+%  an alternative means of indexing the image array.
 %
 %    group = ImageListToArray(images, exception);
 %    while (i = 0; group[i] != (Image *) NULL; i++)
@@ -846,36 +863,36 @@ MagickExport Image **ImageListToArray(const Image *images,
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  InsertImageInList() insert second given image or image list, into the first
+%  InsertImageInList() insert the given image or image list, into the first
 %  image list, immediately AFTER the image pointed to.  The given image list
 %  pointer is left unchanged unless previously empty.
 %
 %  The format of the InsertImageInList method is:
 %
-%      InsertImageInList(Image **images,Image *image)
+%      InsertImageInList(Image **images,Image *insert)
 %
 %  A description of each parameter follows:
 %
 %    o images: the image list to insert into.
 %
-%    o image: the image list to insert.
+%    o insert: the image list to insert.
 %
 */
-MagickExport void InsertImageInList(Image **images,Image *image)
+MagickExport void InsertImageInList(Image **images,Image *insert)
 {
   Image
     *split;
 
   assert(images != (Image **) NULL);
-  assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
-    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
+  assert(insert != (Image *) NULL);
+  assert(insert->signature == MagickSignature);
+  if (insert->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",insert->filename);
   if ((*images) == (Image *) NULL)
     return;
   assert((*images)->signature == MagickSignature);
   split=SplitImageList(*images);
-  AppendImageToList(images,image);
+  AppendImageToList(images,insert);
   AppendImageToList(images,split);
 }
 \f
@@ -926,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
 /*
@@ -1105,46 +1126,48 @@ MagickExport Image *RemoveLastImageFromList(Image **images)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %  ReplaceImageInList() replaces an image in the list with the given image, or
-%  list of images.  Old image is destroyed.  The image list pointer is set to
-%  point to the first image of the inserted list of images.
+%  list of images.  Old image is destroyed.
+%
+%  The images list pointer is set to point to the first image of the inserted
+%  list of images.
 %
 %  The format of the ReplaceImageInList method is:
 %
-%      ReplaceImageInList(Image **images,Image *image)
+%      ReplaceImageInList(Image **images,Image *replace)
 %
 %  A description of each parameter follows:
 %
 %    o images: the list and pointer to image to replace
 %
-%    o image: the image or image list replacing the original
+%    o replace: the image or image list replacing the original
 %
 */
-MagickExport void ReplaceImageInList(Image **images,Image *image)
+MagickExport void ReplaceImageInList(Image **images,Image *replace)
 {
   assert(images != (Image **) NULL);
-  assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
-    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
+  assert(replace != (Image *) NULL);
+  assert(replace->signature == MagickSignature);
+  if (replace->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",replace->filename);
   if ((*images) == (Image *) NULL)
     return;
   assert((*images)->signature == MagickSignature);
 
   /* link next pointer */
-  image=GetLastImageInList(image);
-  image->next=(*images)->next;
-  if (image->next != (Image *) NULL)
-    image->next->previous=image;
+  replace=GetLastImageInList(replace);
+  replace->next=(*images)->next;
+  if (replace->next != (Image *) NULL)
+    replace->next->previous=replace;
 
-  /* link previous pointer - set image position to first replacement image */
-  image=GetFirstImageInList(image);
-  image->previous=(*images)->previous;
-  if (image->previous != (Image *) NULL)
-    image->previous->next=image;
+  /* link previous pointer - set images position to first replacement image */
+  replace=GetFirstImageInList(replace);
+  replace->previous=(*images)->previous;
+  if (replace->previous != (Image *) NULL)
+    replace->previous->next=replace;
 
-  /* destroy replaced image */
+  /* destroy the replaced image that was in images */
   (void) DestroyImage(*images);
-  (*images)=image;
+  (*images)=replace;
 }
 \f
 /*
@@ -1159,48 +1182,50 @@ MagickExport void ReplaceImageInList(Image **images,Image *image)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %  ReplaceImageInListReturnLast() is exactly as ReplaceImageInList() except
-%  the image pointer is set to the last image in the list.
+%  the images pointer is set to the last image in the list of replacemen
+%  images.
 %
-%  This allows you to simply use 'next' to go to the image that follows the
-%  just replaced image.
+%  This allows you to simply use GetNextImageInList() to go to the image
+%  that follows the just replaced image, even if a list of replacement images
+%  was inserted.
 %
 %  The format of the ReplaceImageInList method is:
 %
-%      ReplaceImageInListReturnLast(Image **images,Image *image)
+%      ReplaceImageInListReturnLast(Image **images,Image *replace)
 %
 %  A description of each parameter follows:
 %
 %    o images: the list and pointer to image to replace
 %
-%    o image: the image or image list replacing the original
+%    o replace: the image or image list replacing the original
 %
 */
-MagickExport void ReplaceImageInListReturnLast(Image **images,Image *image)
+MagickExport void ReplaceImageInListReturnLast(Image **images,Image *replace)
 {
   assert(images != (Image **) NULL);
-  assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
-    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
+  assert(replace != (Image *) NULL);
+  assert(replace->signature == MagickSignature);
+  if (replace->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",replace->filename);
   if ((*images) == (Image *) NULL)
     return;
   assert((*images)->signature == MagickSignature);
 
   /* link previous pointer */
-  image=GetFirstImageInList(image);
-  image->previous=(*images)->previous;
-  if (image->previous != (Image *) NULL)
-    image->previous->next=image;
+  replace=GetFirstImageInList(replace);
+  replace->previous=(*images)->previous;
+  if (replace->previous != (Image *) NULL)
+    replace->previous->next=replace;
 
-  /* link next pointer - set image position to last replacement image */
-  image=GetLastImageInList(image);
-  image->next=(*images)->next;
-  if (image->next != (Image *) NULL)
-    image->next->previous=image;
+  /* link next pointer - set images position to last replacement image */
+  replace=GetLastImageInList(replace);
+  replace->next=(*images)->next;
+  if (replace->next != (Image *) NULL)
+    replace->next->previous=replace;
 
-  /* destroy replaced image */
+  /* destroy the replaced image that was in images */
   (void) DestroyImage(*images);
-  (*images)=image;
+  (*images)=replace;
 }
 \f
 /*