]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Sun, 11 Nov 2012 23:21:51 +0000 (23:21 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Sun, 11 Nov 2012 23:21:51 +0000 (23:21 +0000)
MagickCore/statistic.c

index 6ff118d24ea91e324cdbbcd47aa04de6677a7722..d0ecc256e7de88934db846979d9db0e4b578ffd0 100644 (file)
@@ -428,9 +428,6 @@ MagickExport Image *EvaluateImages(const Image *images,
   CacheView
     *evaluate_view;
 
-  const Image
-    *next;
-
   Image
     *image;
 
@@ -457,25 +454,12 @@ MagickExport Image *EvaluateImages(const Image *images,
     key;
 #endif
 
-  /*
-    Ensure the image are the same size.
-  */
   assert(images != (Image *) NULL);
   assert(images->signature == MagickSignature);
   if (images->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
-  for (next=images; next != (Image *) NULL; next=GetNextImageInList(next))
-    if ((next->columns != images->columns) || (next->rows != images->rows))
-      {
-        (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
-          "ImageWidthsOrHeightsDiffer","'%s'",images->filename);
-        return((Image *) NULL);
-      }
-  /*
-    Initialize evaluate next attributes.
-  */
   image=CloneImage(images,images->columns,images->rows,MagickTrue,
     exception);
   if (image == (Image *) NULL)
@@ -1764,12 +1748,12 @@ MagickExport ChannelStatistics *GetImageStatistics(const Image *image,
 %
 %  The format of the PolynomialImage method is:
 %
-%      Image *PolynomialImage(const Image *image,const size_t number_terms,
+%      Image *PolynomialImage(const Image *images,const size_t number_terms,
 %        const double *terms,ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
-%    o image: the image.
+%    o images: the image sequence.
 %
 %    o number_terms: the number of terms in the list.  The actual list length
 %      is 2 x number_terms + 1 (the constant).
@@ -1781,33 +1765,217 @@ MagickExport ChannelStatistics *GetImageStatistics(const Image *image,
 %
 */
 
-MagickExport Image *PolynomialImage(const Image *image,
+MagickExport Image *PolynomialImage(const Image *images,
   const size_t number_terms,const double *terms,ExceptionInfo *exception)
 {
+#define PolynomialImageTag  "Polynomial/Image"
+
+  CacheView
+    *polynomial_view;
+
   Image
-    *polynomial_image;
+    *image;
 
   MagickBooleanType
     status;
 
-  assert(image != (Image *) NULL);
-  assert(image->signature == MagickSignature);
-  if (image->debug != MagickFalse)
-    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
-  assert(terms != (double *) NULL);
+  MagickOffsetType
+    progress;
+
+  PixelChannels
+    **restrict polynomial_pixels;
+
+  size_t
+    number_images;
+
+  ssize_t
+    y;
+
+  assert(images != (Image *) NULL);
+  assert(images->signature == MagickSignature);
+  if (images->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
-  polynomial_image=CloneImage(image,image->columns,image->rows,MagickTrue,
+  image=CloneImage(images,images->columns,images->rows,MagickTrue,
     exception);
-  if (polynomial_image == (Image *) NULL)
+  if (image == (Image *) NULL)
     return((Image *) NULL);
-  status=SetImageStorageClass(polynomial_image,DirectClass,exception);
-  if (status == MagickFalse)
+  if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
+    {
+      image=DestroyImage(image);
+      return((Image *) NULL);
+    }
+  number_images=GetImageListLength(images);
+  polynomial_pixels=AcquirePixelThreadSet(images,number_images);
+  if (polynomial_pixels == (PixelChannels **) NULL)
     {
-      polynomial_image=DestroyImage(polynomial_image);
+      image=DestroyImage(image);
+      (void) ThrowMagickException(exception,GetMagickModule(),
+        ResourceLimitError,"MemoryAllocationFailed","'%s'",images->filename);
       return((Image *) NULL);
     }
-  return(polynomial_image);
+  /*
+    Polynomial image pixels.
+  */
+  status=MagickTrue;
+  progress=0;
+  polynomial_view=AcquireAuthenticCacheView(image,exception);
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+  #pragma omp parallel for schedule(static,4) shared(progress,status) \
+    dynamic_number_threads(image,image->columns,image->rows,1)
+#endif
+  for (y=0; y < (ssize_t) image->rows; y++)
+  {
+    CacheView
+      *image_view;
+
+    const Image
+      *next;
+
+    const int
+      id = GetOpenMPThreadId();
+
+    register ssize_t
+      i,
+      x;
+
+    register PixelChannels
+      *polynomial_pixel;
+
+    register Quantum
+      *restrict q;
+
+    ssize_t
+      j;
+
+    if (status == MagickFalse)
+      continue;
+    q=QueueCacheViewAuthenticPixels(polynomial_view,0,y,
+      image->columns,1,exception);
+    if (q == (Quantum *) NULL)
+      {
+        status=MagickFalse;
+        continue;
+      }
+    polynomial_pixel=polynomial_pixels[id];
+    for (j=0; j < (ssize_t) image->columns; j++)
+      for (i=0; i < MaxPixelChannels; i++)
+        polynomial_pixel[j].channel[i]=0.0;
+    next=images;
+    for (j=0; j < (ssize_t) number_images; j++)
+    {
+      register const Quantum
+        *p;
+
+      image_view=AcquireVirtualCacheView(next,exception);
+      p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
+      if (p == (const Quantum *) NULL)
+        {
+          image_view=DestroyCacheView(image_view);
+          break;
+        }
+      for (x=0; x < (ssize_t) next->columns; x++)
+      {
+        register ssize_t
+          i;
+
+        if (GetPixelMask(next,p) != 0)
+          {
+            p+=GetPixelChannels(next);
+            continue;
+          }
+        for (i=0; i < (ssize_t) GetPixelChannels(next); i++)
+        {
+          MagickRealType
+            coefficient,
+            degree;
+
+          PixelChannel
+            channel;
+
+          PixelTrait
+            polynomial_traits,
+            traits;
+
+          if ((i << 1) >= (ssize_t) number_terms)
+            continue;
+          channel=GetPixelChannelChannel(image,i);
+          traits=GetPixelChannelTraits(next,channel);
+          polynomial_traits=GetPixelChannelTraits(image,channel);
+          if ((traits == UndefinedPixelTrait) ||
+              (polynomial_traits == UndefinedPixelTrait))
+            continue;
+          if ((traits & UpdatePixelTrait) == 0)
+            continue;
+          coefficient=(MagickRealType) terms[2*i];
+          degree=(MagickRealType) terms[2*i+1];
+          polynomial_pixel[x].channel[i]+=coefficient*
+            pow(GetPixelChannel(image,channel,p),degree);
+        }
+        p+=GetPixelChannels(next);
+      }
+      image_view=DestroyCacheView(image_view);
+      next=GetNextImageInList(next);
+    }
+    for (x=0; x < (ssize_t) image->columns; x++)
+    {
+      MagickRealType
+        constant;
+
+      constant=(MagickRealType) terms[number_terms << 1];
+      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+        polynomial_pixel[x].channel[i]+=constant;
+    }
+    for (x=0; x < (ssize_t) image->columns; x++)
+    {
+      register ssize_t
+        i;
+
+      if (GetPixelMask(image,q) != 0)
+        {
+          q+=GetPixelChannels(image);
+          continue;
+        }
+      for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+      {
+        PixelChannel
+          channel;
+
+        PixelTrait
+          traits;
+
+        channel=GetPixelChannelChannel(image,i);
+        traits=GetPixelChannelTraits(image,channel);
+        if (traits == UndefinedPixelTrait)
+          continue;
+        if ((traits & UpdatePixelTrait) == 0)
+          continue;
+        q[i]=ClampToQuantum(polynomial_pixel[x].channel[i]);
+      }
+      q+=GetPixelChannels(image);
+    }
+    if (SyncCacheViewAuthenticPixels(polynomial_view,exception) == MagickFalse)
+      status=MagickFalse;
+    if (images->progress_monitor != (MagickProgressMonitor) NULL)
+      {
+        MagickBooleanType
+          proceed;
+
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+        #pragma omp critical (MagickCore_PolynomialImages)
+#endif
+        proceed=SetImageProgress(images,PolynomialImageTag,progress++,
+          image->rows);
+        if (proceed == MagickFalse)
+          status=MagickFalse;
+      }
+  }
+  polynomial_view=DestroyCacheView(polynomial_view);
+  polynomial_pixels=DestroyPixelThreadSet(polynomial_pixels);
+  if (status == MagickFalse)
+    image=DestroyImage(image);
+  return(image);
 }
 \f
 /*