]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/pixel.c
(no commit message)
[imagemagick] / MagickCore / pixel.c
index 00f7beb7da8febbb55534255ece47c087cae76e7..a30d4facea50a1282fe801c7edeab1c33574c5bb 100644 (file)
@@ -88,7 +88,7 @@
     PixelChannel \
       channel; \
  \
-    switch (GetPixelChannelMapChannel(image,i)) \
+    switch (GetPixelChannelChannel(image,i)) \
     { \
       case RedPixelChannel: \
       { \
       default: \
         name="undefined"; \
     } \
-    channel=GetPixelChannelMapChannel(image,i); \
+    channel=GetPixelChannelChannel(image,i); \
     *traits='\0'; \
-    if ((GetPixelChannelMapTraits(image,channel) & UpdatePixelTrait) != 0) \
+    if ((GetPixelChannelTraits(image,channel) & UpdatePixelTrait) != 0) \
       (void) ConcatenateMagickString(traits,"update,",MaxTextExtent); \
-    if ((GetPixelChannelMapTraits(image,channel) & BlendPixelTrait) != 0) \
+    if ((GetPixelChannelTraits(image,channel) & BlendPixelTrait) != 0) \
       (void) ConcatenateMagickString(traits,"blend,",MaxTextExtent); \
-    if ((GetPixelChannelMapTraits(image,channel) & CopyPixelTrait) != 0) \
+    if ((GetPixelChannelTraits(image,channel) & CopyPixelTrait) != 0) \
       (void) ConcatenateMagickString(traits,"copy,",MaxTextExtent); \
     if (*traits == '\0') \
       (void) ConcatenateMagickString(traits,"undefined,",MaxTextExtent); \
@@ -2006,20 +2006,20 @@ MagickExport void GetPixelInfo(const Image *image,PixelInfo *pixel)
 {
   pixel->storage_class=DirectClass;
   pixel->colorspace=sRGBColorspace;
-  pixel->matte=MagickFalse;
+  pixel->alpha_trait=UndefinedPixelTrait;
   pixel->fuzz=0.0;
   pixel->depth=MAGICKCORE_QUANTUM_DEPTH;
   pixel->red=0.0;
   pixel->green=0.0;
   pixel->blue=0.0;
   pixel->black=0.0;
-  pixel->alpha=(MagickRealType) OpaqueAlpha;
+  pixel->alpha=(double) OpaqueAlpha;
   pixel->index=0.0;
   if (image == (const Image *) NULL)
     return;
   pixel->storage_class=image->storage_class;
   pixel->colorspace=image->colorspace;
-  pixel->matte=image->matte;
+  pixel->alpha_trait=image->alpha_trait;
   pixel->depth=image->depth;
   pixel->fuzz=image->fuzz;
 }
@@ -3736,7 +3736,7 @@ MagickExport MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
       case 'A':
       {
         quantum_map[i]=AlphaQuantum;
-        image->matte=MagickTrue;
+        image->alpha_trait=BlendPixelTrait;
         break;
       }
       case 'B':
@@ -3783,7 +3783,7 @@ MagickExport MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
       case 'o':
       {
         quantum_map[i]=OpacityQuantum;
-        image->matte=MagickTrue;
+        image->alpha_trait=BlendPixelTrait;
         break;
       }
       case 'P':
@@ -3910,37 +3910,37 @@ MagickExport void InitializePixelChannelMap(Image *image)
   (void) ResetMagickMemory(image->channel_map,0,MaxPixelChannels*
     sizeof(*image->channel_map));
   trait=UpdatePixelTrait;
-  if (image->matte != MagickFalse)
+  if (image->alpha_trait == BlendPixelTrait)
     trait=(PixelTrait) (trait | BlendPixelTrait);
   n=0;
   if (image->colorspace == GRAYColorspace)
     {
-      SetPixelChannelMap(image,BluePixelChannel,trait,n);
-      SetPixelChannelMap(image,GreenPixelChannel,trait,n);
-      SetPixelChannelMap(image,RedPixelChannel,trait,n++);
+      SetPixelChannelAttributes(image,BluePixelChannel,trait,n);
+      SetPixelChannelAttributes(image,GreenPixelChannel,trait,n);
+      SetPixelChannelAttributes(image,RedPixelChannel,trait,n++);
     }
   else
     {
-      SetPixelChannelMap(image,RedPixelChannel,trait,n++);
-      SetPixelChannelMap(image,GreenPixelChannel,trait,n++);
-      SetPixelChannelMap(image,BluePixelChannel,trait,n++);
+      SetPixelChannelAttributes(image,RedPixelChannel,trait,n++);
+      SetPixelChannelAttributes(image,GreenPixelChannel,trait,n++);
+      SetPixelChannelAttributes(image,BluePixelChannel,trait,n++);
     }
   if (image->colorspace == CMYKColorspace)
-    SetPixelChannelMap(image,BlackPixelChannel,trait,n++);
-  if (image->matte != MagickFalse)
-    SetPixelChannelMap(image,AlphaPixelChannel,CopyPixelTrait,n++);
+    SetPixelChannelAttributes(image,BlackPixelChannel,trait,n++);
+  if (image->alpha_trait != UndefinedPixelTrait)
+    SetPixelChannelAttributes(image,AlphaPixelChannel,CopyPixelTrait,n++);
   if (image->storage_class == PseudoClass)
-    SetPixelChannelMap(image,IndexPixelChannel,CopyPixelTrait,n++);
+    SetPixelChannelAttributes(image,IndexPixelChannel,CopyPixelTrait,n++);
   if (image->mask != MagickFalse)
-    SetPixelChannelMap(image,MaskPixelChannel,CopyPixelTrait,n++);
+    SetPixelChannelAttributes(image,MaskPixelChannel,CopyPixelTrait,n++);
   assert((n+image->number_meta_channels) < MaxPixelChannels);
   for (i=0; i < (ssize_t) image->number_meta_channels; i++)
-    SetPixelChannelMap(image,(PixelChannel) (MetaPixelChannel+i),CopyPixelTrait,
-      n++);
+    SetPixelChannelAttributes(image,(PixelChannel) (MetaPixelChannel+i),
+      CopyPixelTrait,n++);
   image->number_channels=(size_t) n;
   if (image->debug != MagickFalse)
     LogPixelChannels(image);
-  (void) SetPixelChannelMask(image,image->channel_mask);
+  (void) SetImageChannelMask(image,image->channel_mask);
 }
 \f
 /*
@@ -3985,45 +3985,46 @@ MagickExport void InitializePixelChannelMap(Image *image)
 %
 */
 
-static inline double MagickMax(const MagickRealType x,const MagickRealType y)
+static inline double MagickMax(const double x,const double y)
 {
   if (x > y)
     return(x);
   return(y);
 }
 
-static inline void CatromWeights(const MagickRealType x,
-  MagickRealType (*weights)[4])
+static inline void CatromWeights(const double x,double (*weights)[4])
 {
-  /*
-    Nicolas Robidoux' 10 flops (4* + 5- + 1+) refactoring of the
-    computation of the standard four 1D Catmull-Rom weights. The
-    sampling location is assumed between the second and third input
-    pixel locations, and x is the position relative to the second
-    input pixel location. Formulas originally derived for the VIPS
-    (Virtual Image Processing System) library.
-  */
-  MagickRealType
+  double
     alpha,
     beta,
     gamma;
 
-  alpha=(MagickRealType) 1.0-x;
-  beta=(MagickRealType) (-0.5)*x*alpha;
+  /*
+    Nicolas Robidoux' 10 flops (4* + 5- + 1+) refactoring of the computation
+    of the standard four 1D Catmull-Rom weights. The sampling location is
+    assumed between the second and third input pixel locations, and x is the
+    position relative to the second input pixel location. Formulas originally
+    derived for the VIPS (Virtual Image Processing System) library.
+  */
+  alpha=(double) 1.0-x;
+  beta=(double) (-0.5)*x*alpha;
   (*weights)[0]=alpha*beta;
   (*weights)[3]=x*beta;
   /*
-    The following computation of the inner weights from the outer ones
-    works for all Keys cubics.
+    The following computation of the inner weights from the outer ones work
+    for all Keys cubics.
   */
   gamma=(*weights)[3]-(*weights)[0];
   (*weights)[1]=alpha-(*weights)[0]+gamma;
   (*weights)[2]=x-(*weights)[3]-gamma;
 }
 
-static inline void SplineWeights(const MagickRealType x,
-  MagickRealType (*weights)[4])
+static inline void SplineWeights(const double x,double (*weights)[4])
 {
+  double
+    alpha,
+    beta;
+
   /*
     Nicolas Robidoux' 12 flops (6* + 5- + 1+) refactoring of the
     computation of the standard four 1D cubic B-spline smoothing
@@ -4031,13 +4032,9 @@ static inline void SplineWeights(const MagickRealType x,
     third input pixel locations, and x is the position relative to the
     second input pixel location.
   */
-  MagickRealType
-    alpha,
-    beta;
-
-  alpha=(MagickRealType) 1.0-x;
-  (*weights)[3]=(MagickRealType) (1.0/6.0)*x*x*x;
-  (*weights)[0]=(MagickRealType) (1.0/6.0)*alpha*alpha*alpha;
+  alpha=(double) 1.0-x;
+  (*weights)[3]=(double) (1.0/6.0)*x*x*x;
+  (*weights)[0]=(double) (1.0/6.0)*alpha*alpha*alpha;
   beta=(*weights)[3]-(*weights)[0];
   (*weights)[1]=alpha-(*weights)[0]+beta;
   (*weights)[2]=x-(*weights)[3]-beta;
@@ -4050,7 +4047,7 @@ static inline double MeshInterpolate(const PointInfo *delta,const double p,
 }
 
 /*
-static inline ssize_t NearestNeighbor(const MagickRealType x)
+static inline ssize_t NearestNeighbor(const double x)
 {
   if (x >= 0.0)
     return((ssize_t) (x+0.5));
@@ -4066,7 +4063,7 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
   MagickBooleanType
     status;
 
-  MagickRealType
+  double
     alpha[16],
     gamma,
     pixels[16];
@@ -4093,7 +4090,7 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
   assert(image_view != (CacheView *) NULL);
   status=MagickTrue;
   *pixel=0.0;
-  traits=GetPixelChannelMapTraits(image,channel);
+  traits=GetPixelChannelTraits(image,channel);
   x_offset=(ssize_t) floor(x);
   y_offset=(ssize_t) floor(y);
   interpolate = method;
@@ -4133,7 +4130,7 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
         for (i=0; i < (ssize_t) count; i++)
         {
           alpha[i]=1.0;
-          pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
+          pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
         }
       else
         for (i=0; i < (ssize_t) count; i++)
@@ -4166,7 +4163,7 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
         for (i=0; i < 4; i++)
         {
           alpha[i]=1.0;
-          pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
+          pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
         }
       else
         for (i=0; i < 4; i++)
@@ -4186,9 +4183,58 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
         (epsilon.x*pixels[2]+delta.x*pixels[3]));
       break;
     }
+    case BlendInterpolatePixel:
+    {
+      p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
+      if (p == (const Quantum *) NULL)
+        {
+          status=MagickFalse;
+          break;
+        }
+      if ((traits & BlendPixelTrait) == 0)
+        for (i=0; i < 4; i++)
+        {
+          alpha[i]=1.0;
+          pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
+        }
+      else
+        for (i=0; i < 4; i++)
+        {
+          alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
+            GetPixelChannels(image));
+          pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
+        }
+      gamma=1.0;    /* number of pixels blended together (its variable) */
+      for (i=0; i <= 1L; i++) {
+        if ( y-y_offset >= 0.75 ) { /* take right pixels */
+          alpha[i]  = alpha[i+2];
+          pixels[i] = pixels[i+2];
+        }
+        else if ( y-y_offset > 0.25 ) {
+          gamma = 2.0;              /* blend both pixels in row */
+          alpha[i]  += alpha[i+2];  /* add up alpha weights */
+          pixels[i] += pixels[i+2];
+        }
+      }
+      if ( x-x_offset >= 0.75 ) {   /* take bottom row blend */
+        alpha[0]  = alpha[1];
+        pixels[0] = pixels[1];
+      }
+      else if ( x-x_offset > 0.25 ) {
+        gamma *= 2.0;               /* blend both rows */
+        alpha[0]  += alpha[1];      /* add up alpha weights */
+        pixels[0] += pixels[1];
+      }
+      if (channel != AlphaPixelChannel)
+        gamma=MagickEpsilonReciprocal(alpha[0]); /* (color) 1/alpha_weights */
+      else
+        gamma=MagickEpsilonReciprocal(gamma); /* (alpha) 1/number_of_pixels */
+      *pixel=gamma*pixels[0];
+      break;
+    }
     case CatromInterpolatePixel:
     {
-      MagickRealType
+      double
         cx[4],
         cy[4];
 
@@ -4203,7 +4249,7 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
         for (i=0; i < 16; i++)
         {
           alpha[i]=1.0;
-          pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
+          pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
         }
       else
         for (i=0; i < 16; i++)
@@ -4212,9 +4258,9 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
             GetPixelChannels(image));
           pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
         }
-      CatromWeights((MagickRealType) (x-x_offset),&cx);
-      CatromWeights((MagickRealType) (y-y_offset),&cy);
-      gamma=(channel == AlphaPixelChannel ? (MagickRealType) 1.0 :
+      CatromWeights((double) (x-x_offset),&cx);
+      CatromWeights((double) (y-y_offset),&cy);
+      gamma=(channel == AlphaPixelChannel ? (double) 1.0 :
         MagickEpsilonReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
         alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
         alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
@@ -4306,7 +4352,7 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
         for (i=0; i < 4; i++)
         {
           alpha[i]=1.0;
-          pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
+          pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
         }
       else
         for (i=0; i < 4; i++)
@@ -4381,7 +4427,7 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
     }
     case SplineInterpolatePixel:
     {
-      MagickRealType
+      double
         cx[4],
         cy[4];
 
@@ -4396,7 +4442,7 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
         for (i=0; i < 16; i++)
         {
           alpha[i]=1.0;
-          pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
+          pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
         }
       else
         for (i=0; i < 16; i++)
@@ -4405,9 +4451,9 @@ MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
             GetPixelChannels(image));
           pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
         }
-      SplineWeights((MagickRealType) (x-x_offset),&cx);
-      SplineWeights((MagickRealType) (y-y_offset),&cy);
-      gamma=(channel == AlphaPixelChannel ? (MagickRealType) 1.0 :
+      SplineWeights((double) (x-x_offset),&cx);
+      SplineWeights((double) (y-y_offset),&cy);
+      gamma=(channel == AlphaPixelChannel ? (double) 1.0 :
         MagickEpsilonReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
         alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
         alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
@@ -4474,7 +4520,7 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
   MagickBooleanType
     status;
 
-  MagickRealType
+  double
     alpha[16],
     gamma,
     pixels[16];
@@ -4546,14 +4592,14 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
         register ssize_t
           j;
 
-        channel=GetPixelChannelMapChannel(source,i);
-        traits=GetPixelChannelMapTraits(source,channel);
-        destination_traits=GetPixelChannelMapTraits(destination,channel);
+        channel=GetPixelChannelChannel(source,i);
+        traits=GetPixelChannelTraits(source,channel);
+        destination_traits=GetPixelChannelTraits(destination,channel);
         if ((traits == UndefinedPixelTrait) ||
             (destination_traits == UndefinedPixelTrait))
           continue;
         for (j=0; j < (ssize_t) count; j++)
-          pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
+          pixels[j]=(double) p[j*GetPixelChannels(source)+i];
         sum=0.0;
         if ((traits & BlendPixelTrait) == 0)
           {
@@ -4591,9 +4637,9 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
           delta,
           epsilon;
 
-        channel=GetPixelChannelMapChannel(source,i);
-        traits=GetPixelChannelMapTraits(source,channel);
-        destination_traits=GetPixelChannelMapTraits(destination,channel);
+        channel=GetPixelChannelChannel(source,i);
+        traits=GetPixelChannelTraits(source,channel);
+        destination_traits=GetPixelChannelTraits(destination,channel);
         if ((traits == UndefinedPixelTrait) ||
             (destination_traits == UndefinedPixelTrait))
           continue;
@@ -4601,10 +4647,10 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
         delta.y=y-y_offset;
         epsilon.x=1.0-delta.x;
         epsilon.y=1.0-delta.y;
-        pixels[0]=(MagickRealType) p[i];
-        pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
-        pixels[2]=(MagickRealType) p[2*GetPixelChannels(source)+i];
-        pixels[3]=(MagickRealType) p[3*GetPixelChannels(source)+i];
+        pixels[0]=(double) p[i];
+        pixels[1]=(double) p[GetPixelChannels(source)+i];
+        pixels[2]=(double) p[2*GetPixelChannels(source)+i];
+        pixels[3]=(double) p[3*GetPixelChannels(source)+i];
         if ((traits & BlendPixelTrait) == 0)
           {
             gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
@@ -4633,9 +4679,71 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
       }
       break;
     }
+    case BlendInterpolatePixel:
+    {
+      p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
+      if (p == (const Quantum *) NULL)
+        {
+          status=MagickFalse;
+          break;
+        }
+      for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
+      {
+        register ssize_t
+          j;
+
+        channel=GetPixelChannelChannel(source,i);
+        traits=GetPixelChannelTraits(source,channel);
+        destination_traits=GetPixelChannelTraits(destination,channel);
+        if ((traits == UndefinedPixelTrait) ||
+            (destination_traits == UndefinedPixelTrait))
+          continue;
+        if ((traits & BlendPixelTrait) == 0)
+          for (j=0; j < 4; j++)
+          {
+            alpha[j]=1.0;
+            pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+channel];
+          }
+        else
+          for (j=0; j < 4; j++)
+          {
+            alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
+              GetPixelChannels(source));
+            pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+channel];
+          }
+        gamma=1.0;    /* number of pixels blended together (its variable) */
+        for (j=0; j <= 1L; j++) {
+          if ( y-y_offset >= 0.75 ) { /* take right pixels */
+            alpha[j]  = alpha[j+2];
+            pixels[j] = pixels[j+2];
+          }
+          else if ( y-y_offset > 0.25 ) {
+            gamma = 2.0;              /* blend both pixels in row */
+            alpha[j]  += alpha[j+2];  /* add up alpha weights */
+            pixels[j] += pixels[j+2];
+          }
+        }
+        if ( x-x_offset >= 0.75 ) {   /* take bottom row blend */
+          alpha[0]  = alpha[1];
+          pixels[0] = pixels[1];
+        }
+        else if ( x-x_offset > 0.25 ) {
+          gamma *= 2.0;               /* blend both rows */
+          alpha[0]  += alpha[1];      /* add up alpha weights */
+          pixels[0] += pixels[1];
+        }
+        if ((traits & BlendPixelTrait) == 0)
+          gamma=MagickEpsilonReciprocal(alpha[0]); /* (color) 1/alpha_weights */
+        else
+          gamma=MagickEpsilonReciprocal(gamma); /* (alpha) 1/number_of_pixels */
+        SetPixelChannel(destination,channel,ClampToQuantum(gamma*pixels[0]),
+             pixel);
+      }
+      break;
+    }
     case CatromInterpolatePixel:
     {
-      MagickRealType
+      double
         cx[4],
         cy[4];
 
@@ -4651,9 +4759,9 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
         register ssize_t
           j;
 
-        channel=GetPixelChannelMapChannel(source,i);
-        traits=GetPixelChannelMapTraits(source,channel);
-        destination_traits=GetPixelChannelMapTraits(destination,channel);
+        channel=GetPixelChannelChannel(source,i);
+        traits=GetPixelChannelTraits(source,channel);
+        destination_traits=GetPixelChannelTraits(destination,channel);
         if ((traits == UndefinedPixelTrait) ||
             (destination_traits == UndefinedPixelTrait))
           continue;
@@ -4661,7 +4769,7 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
           for (j=0; j < 16; j++)
           {
             alpha[j]=1.0;
-            pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
+            pixels[j]=(double) p[j*GetPixelChannels(source)+i];
           }
         else
           for (j=0; j < 16; j++)
@@ -4670,9 +4778,9 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
               GetPixelChannels(source));
             pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
           }
-        CatromWeights((MagickRealType) (x-x_offset),&cx);
-        CatromWeights((MagickRealType) (y-y_offset),&cy);
-        gamma=((traits & BlendPixelTrait) ? (MagickRealType) (1.0) :
+        CatromWeights((double) (x-x_offset),&cx);
+        CatromWeights((double) (y-y_offset),&cy);
+        gamma=((traits & BlendPixelTrait) ? (double) (1.0) :
           MagickEpsilonReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
           alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
           alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
@@ -4703,9 +4811,9 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
         RectangleInfo
           geometry;
 
-        channel=GetPixelChannelMapChannel(source,i);
-        traits=GetPixelChannelMapTraits(source,channel);
-        destination_traits=GetPixelChannelMapTraits(destination,channel);
+        channel=GetPixelChannelChannel(source,i);
+        traits=GetPixelChannelTraits(source,channel);
+        destination_traits=GetPixelChannelTraits(destination,channel);
         if ((traits == UndefinedPixelTrait) ||
             (destination_traits == UndefinedPixelTrait))
           continue;
@@ -4747,9 +4855,9 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
         }
       for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
       {
-        channel=GetPixelChannelMapChannel(source,i);
-        traits=GetPixelChannelMapTraits(source,channel);
-        destination_traits=GetPixelChannelMapTraits(destination,channel);
+        channel=GetPixelChannelChannel(source,i);
+        traits=GetPixelChannelTraits(source,channel);
+        destination_traits=GetPixelChannelTraits(destination,channel);
         if ((traits == UndefinedPixelTrait) ||
             (destination_traits == UndefinedPixelTrait))
           continue;
@@ -4769,9 +4877,9 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
         }
       for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
       {
-        channel=GetPixelChannelMapChannel(source,i);
-        traits=GetPixelChannelMapTraits(source,channel);
-        destination_traits=GetPixelChannelMapTraits(destination,channel);
+        channel=GetPixelChannelChannel(source,i);
+        traits=GetPixelChannelTraits(source,channel);
+        destination_traits=GetPixelChannelTraits(destination,channel);
         if ((traits == UndefinedPixelTrait) ||
             (destination_traits == UndefinedPixelTrait))
           continue;
@@ -4793,16 +4901,16 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
           delta,
           luminance;
 
-        channel=GetPixelChannelMapChannel(source,i);
-        traits=GetPixelChannelMapTraits(source,channel);
-        destination_traits=GetPixelChannelMapTraits(destination,channel);
+        channel=GetPixelChannelChannel(source,i);
+        traits=GetPixelChannelTraits(source,channel);
+        destination_traits=GetPixelChannelTraits(destination,channel);
         if ((traits == UndefinedPixelTrait) ||
             (destination_traits == UndefinedPixelTrait))
           continue;
-        pixels[0]=(MagickRealType) p[i];
-        pixels[1]=(MagickRealType) p[GetPixelChannels(source)+i];
-        pixels[2]=(MagickRealType) p[2*GetPixelChannels(source)+i];
-        pixels[3]=(MagickRealType) p[3*GetPixelChannels(source)+i];
+        pixels[0]=(double) p[i];
+        pixels[1]=(double) p[GetPixelChannels(source)+i];
+        pixels[2]=(double) p[2*GetPixelChannels(source)+i];
+        pixels[3]=(double) p[3*GetPixelChannels(source)+i];
         if ((traits & BlendPixelTrait) == 0)
           {
             alpha[0]=1.0;
@@ -4889,7 +4997,7 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
     }
     case SplineInterpolatePixel:
     {
-      MagickRealType
+      double
         cx[4],
         cy[4];
 
@@ -4905,9 +5013,9 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
         register ssize_t
           j;
 
-        channel=GetPixelChannelMapChannel(source,i);
-        traits=GetPixelChannelMapTraits(source,channel);
-        destination_traits=GetPixelChannelMapTraits(destination,channel);
+        channel=GetPixelChannelChannel(source,i);
+        traits=GetPixelChannelTraits(source,channel);
+        destination_traits=GetPixelChannelTraits(destination,channel);
         if ((traits == UndefinedPixelTrait) ||
             (destination_traits == UndefinedPixelTrait))
           continue;
@@ -4915,7 +5023,7 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
           for (j=0; j < 16; j++)
           {
             alpha[j]=1.0;
-            pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+i];
+            pixels[j]=(double) p[j*GetPixelChannels(source)+i];
           }
         else
           for (j=0; j < 16; j++)
@@ -4924,9 +5032,9 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
               GetPixelChannels(source));
             pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
           }
-        SplineWeights((MagickRealType) (x-x_offset),&cx);
-        SplineWeights((MagickRealType) (y-y_offset),&cy);
-        gamma=((traits & BlendPixelTrait) ? (MagickRealType) (1.0) :
+        SplineWeights((double) (x-x_offset),&cx);
+        SplineWeights((double) (y-y_offset),&cy);
+        gamma=((traits & BlendPixelTrait) ? (double) (1.0) :
           MagickEpsilonReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
           alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
           alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
@@ -4986,18 +5094,18 @@ MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
 */
 
 static inline void AlphaBlendPixelInfo(const Image *image,
-  const Quantum *pixel,PixelInfo *pixel_info,MagickRealType *alpha)
+  const Quantum *pixel,PixelInfo *pixel_info,double *alpha)
 {
-  if (image->matte == MagickFalse)
+  if (image->alpha_trait != BlendPixelTrait)
     {
       *alpha=1.0;
-      pixel_info->red=(MagickRealType) GetPixelRed(image,pixel);
-      pixel_info->green=(MagickRealType) GetPixelGreen(image,pixel);
-      pixel_info->blue=(MagickRealType) GetPixelBlue(image,pixel);
+      pixel_info->red=(double) GetPixelRed(image,pixel);
+      pixel_info->green=(double) GetPixelGreen(image,pixel);
+      pixel_info->blue=(double) GetPixelBlue(image,pixel);
       pixel_info->black=0.0;
       if (image->colorspace == CMYKColorspace)
-        pixel_info->black=(MagickRealType) GetPixelBlack(image,pixel);
-      pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
+        pixel_info->black=(double) GetPixelBlack(image,pixel);
+      pixel_info->alpha=(double) GetPixelAlpha(image,pixel);
       return;
     }
   *alpha=QuantumScale*GetPixelAlpha(image,pixel);
@@ -5007,7 +5115,7 @@ static inline void AlphaBlendPixelInfo(const Image *image,
   pixel_info->black=0.0;
   if (image->colorspace == CMYKColorspace)
     pixel_info->black=(*alpha*GetPixelBlack(image,pixel));
-  pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
+  pixel_info->alpha=(double) GetPixelAlpha(image,pixel);
 }
 
 MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
@@ -5017,7 +5125,7 @@ MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
   MagickBooleanType
     status;
 
-  MagickRealType
+  double
     alpha[16],
     gamma;
 
@@ -5155,14 +5263,14 @@ MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
         }
       for (i=0; i < 4L; i++)
         AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
-      gamma=1.0;       /* number of pixels blended together */
+      gamma=1.0;    /* number of pixels blended together (its variable) */
       for (i=0; i <= 1L; i++) {
-        if ( y-y_offset >= 0.75 ) {
+        if ( y-y_offset >= 0.75 ) {       /* take right pixels */
           alpha[i]  = alpha[i+2];
           pixels[i] = pixels[i+2];
         }
         else if ( y-y_offset > 0.25 ) {
-          gamma = 2.0;             /* each y pixels have been blended */
+          gamma = 2.0;                    /* blend both pixels in row */
           alpha[i]        += alpha[i+2];  /* add up alpha weights */
           pixels[i].red   += pixels[i+2].red;
           pixels[i].green += pixels[i+2].green;
@@ -5176,8 +5284,8 @@ MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
         pixels[0] = pixels[1];
       }
       else if ( x-x_offset > 0.25 ) {
-        gamma *= 2.0;          /* double number of pixels blended */
-        alpha[0]        += alpha[1];  /* add up alpha weights */
+        gamma *= 2.0;                     /* blend both rows */
+        alpha[0]        += alpha[1];      /* add up alpha weights */
         pixels[0].red   += pixels[1].red;
         pixels[0].green += pixels[1].green;
         pixels[0].blue  += pixels[1].blue;
@@ -5195,7 +5303,7 @@ MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
     }
     case CatromInterpolatePixel:
     {
-      MagickRealType
+      double
         cx[4],
         cy[4];
 
@@ -5208,8 +5316,8 @@ MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
         }
       for (i=0; i < 16L; i++)
         AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
-      CatromWeights((MagickRealType) (x-x_offset),&cx);
-      CatromWeights((MagickRealType) (y-y_offset),&cy);
+      CatromWeights((double) (x-x_offset),&cx);
+      CatromWeights((double) (y-y_offset),&cy);
       pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*
         pixels[1].red+cx[2]*pixels[2].red+cx[3]*
         pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
@@ -5436,7 +5544,7 @@ MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
     }
     case SplineInterpolatePixel:
     {
-      MagickRealType
+      double
         cx[4],
         cy[4];
 
@@ -5449,8 +5557,8 @@ MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
         }
       for (i=0; i < 16L; i++)
         AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
-      SplineWeights((MagickRealType) (x-x_offset),&cx);
-      SplineWeights((MagickRealType) (y-y_offset),&cy);
+      SplineWeights((double) (x-x_offset),&cx);
+      SplineWeights((double) (y-y_offset),&cy);
       pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*
         pixels[1].red+cx[2]*pixels[2].red+cx[3]*
         pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
@@ -5532,24 +5640,24 @@ MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
 MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source,
   const Quantum *p,const Image *destination,const Quantum *q)
 {
-  MagickRealType
+  double
     fuzz,
     pixel;
 
-  register MagickRealType
+  register double
     distance,
     scale;
 
-  fuzz=MagickMax(source->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(
-    destination->fuzz,(MagickRealType) MagickSQ1_2);
+  fuzz=MagickMax(source->fuzz,(double) MagickSQ1_2)*MagickMax(
+    destination->fuzz,(double) MagickSQ1_2);
   scale=1.0;
   distance=0.0;
-  if (source->matte != MagickFalse)
+  if (source->alpha_trait == BlendPixelTrait)
     {
       /*
         Transparencies are involved - set alpha distance
       */
-      pixel=GetPixelAlpha(source,p)-(MagickRealType)
+      pixel=GetPixelAlpha(source,p)-(double)
         GetPixelAlpha(destination,q);
       distance=pixel*pixel;
       if (distance > fuzz)
@@ -5568,7 +5676,7 @@ MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source,
   */
   distance*=3.0;  /* rescale appropriately */
   fuzz*=3.0;
-  pixel=GetPixelRed(source,p)-(MagickRealType) GetPixelRed(destination,q);
+  pixel=GetPixelRed(source,p)-(double) GetPixelRed(destination,q);
   if ((source->colorspace == HSLColorspace) ||
       (source->colorspace == HSBColorspace) ||
       (source->colorspace == HWBColorspace))
@@ -5584,11 +5692,11 @@ MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source,
   distance+=scale*pixel*pixel;
   if (distance > fuzz)
     return(MagickFalse);
-  pixel=GetPixelGreen(source,p)-(MagickRealType) GetPixelGreen(destination,q);
+  pixel=GetPixelGreen(source,p)-(double) GetPixelGreen(destination,q);
   distance+=scale*pixel*pixel;
   if (distance > fuzz)
     return(MagickFalse);
-  pixel=GetPixelBlue(source,p)-(MagickRealType) GetPixelBlue(destination,q);
+  pixel=GetPixelBlue(source,p)-(double) GetPixelBlue(destination,q);
   distance+=scale*pixel*pixel;
   if (distance > fuzz)
     return(MagickFalse);
@@ -5642,34 +5750,34 @@ MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source,
 MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
   const PixelInfo *q)
 {
-  MagickRealType
+  double
     fuzz,
     pixel;
 
-  register MagickRealType
+  register double
     scale,
     distance;
 
   if ((p->fuzz == 0.0) && (q->fuzz == 0.0))
     return(IsPixelInfoEquivalent(p,q));
   if (p->fuzz == 0.0)
-    fuzz=MagickMax(q->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(q->fuzz,
-      (MagickRealType) MagickSQ1_2);
+    fuzz=MagickMax(q->fuzz,(double) MagickSQ1_2)*MagickMax(q->fuzz,
+      (double) MagickSQ1_2);
   else if (q->fuzz == 0.0)
-    fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(p->fuzz,
-      (MagickRealType) MagickSQ1_2);
+    fuzz=MagickMax(p->fuzz,(double) MagickSQ1_2)*MagickMax(p->fuzz,
+      (double) MagickSQ1_2);
   else
-    fuzz=MagickMax(p->fuzz,(MagickRealType) MagickSQ1_2)*MagickMax(q->fuzz,
-      (MagickRealType) MagickSQ1_2);
+    fuzz=MagickMax(p->fuzz,(double) MagickSQ1_2)*MagickMax(q->fuzz,
+      (double) MagickSQ1_2);
   scale=1.0;
   distance=0.0;
-  if ((p->matte != MagickFalse) || (q->matte != MagickFalse))
+  if ((p->alpha_trait == BlendPixelTrait) || (q->alpha_trait == BlendPixelTrait))
     {
       /*
         Transparencies are involved - set alpha distance.
       */
-      pixel=(p->matte != MagickFalse ? p->alpha : OpaqueAlpha)-
-        (q->matte != MagickFalse ? q->alpha : OpaqueAlpha);
+      pixel=(p->alpha_trait == BlendPixelTrait ? p->alpha : OpaqueAlpha)-
+        (q->alpha_trait == BlendPixelTrait ? q->alpha : OpaqueAlpha);
       distance=pixel*pixel;
       if (distance > fuzz)
         return(MagickFalse);
@@ -5677,9 +5785,9 @@ MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
         Generate a alpha scaling factor to generate a 4D cone on colorspace.
         If one color is transparent, distance has no color component.
       */
-      if (p->matte != MagickFalse)
+      if (p->alpha_trait == BlendPixelTrait)
         scale=(QuantumScale*p->alpha);
-      if (q->matte != MagickFalse)
+      if (q->alpha_trait == BlendPixelTrait)
         scale*=(QuantumScale*q->alpha);
       if (scale <= MagickEpsilon )
         return(MagickTrue);
@@ -5693,8 +5801,8 @@ MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
       distance+=pixel*pixel*scale;
       if (distance > fuzz)
         return(MagickFalse);
-      scale*=(MagickRealType) (QuantumScale*(QuantumRange-p->black));
-      scale*=(MagickRealType) (QuantumScale*(QuantumRange-q->black));
+      scale*=(double) (QuantumScale*(QuantumRange-p->black));
+      scale*=(double) (QuantumScale*(QuantumRange-q->black));
     }
   /*
     RGB or CMY color cube.
@@ -5739,12 +5847,12 @@ MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  SetPixelChannelMapMask() sets the pixel channel map from the specified
+%  SetPixelChannelMask() sets the pixel channel map from the specified
 %  channel mask.
 %
-%  The format of the SetPixelChannelMapMask method is:
+%  The format of the SetPixelChannelMask method is:
 %
-%      void SetPixelChannelMapMask(Image *image,const ChannelType channel_mask)
+%      void SetPixelChannelMask(Image *image,const ChannelType channel_mask)
 %
 %  A description of each parameter follows:
 %
@@ -5753,7 +5861,7 @@ MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
 %    o channel_mask: the channel mask.
 %
 */
-MagickExport void SetPixelChannelMapMask(Image *image,
+MagickExport void SetPixelChannelMask(Image *image,
   const ChannelType channel_mask)
 {
 #define GetChannelBit(mask,bit)  (((size_t) (mask) >> (size_t) (bit)) & 0x01)
@@ -5770,16 +5878,16 @@ MagickExport void SetPixelChannelMapMask(Image *image,
     PixelChannel
       channel;
 
-    channel=GetPixelChannelMapChannel(image,i);
-    SetPixelChannelMapTraits(image,channel,
+    channel=GetPixelChannelChannel(image,i);
+    SetPixelChannelTraits(image,channel,
       GetChannelBit(channel_mask,channel) == 0 ? CopyPixelTrait :
-      image->matte == MagickFalse || (channel == AlphaPixelChannel) ?
-      UpdatePixelTrait : (PixelTrait) (UpdatePixelTrait | BlendPixelTrait));
+      image->alpha_trait != BlendPixelTrait || (channel == AlphaPixelChannel) ?
+      UpdatePixelTrait : (PixelTrait) (UpdatePixelTrait | image->alpha_trait));
   }
   if (image->storage_class == PseudoClass)
-    SetPixelChannelMapTraits(image,IndexPixelChannel,CopyPixelTrait);
+    SetPixelChannelTraits(image,IndexPixelChannel,CopyPixelTrait);
   if (image->mask != MagickFalse)
-    SetPixelChannelMapTraits(image,MaskPixelChannel,CopyPixelTrait);
+    SetPixelChannelTraits(image,MaskPixelChannel,CopyPixelTrait);
   if (image->debug != MagickFalse)
     LogPixelChannels(image);
 }
@@ -5789,44 +5897,6 @@ MagickExport void SetPixelChannelMapMask(Image *image,
 %                                                                             %
 %                                                                             %
 %                                                                             %
-%   S e t P i x e l C h a n n e l M a s k                                     %
-%                                                                             %
-%                                                                             %
-%                                                                             %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%  SetPixelChannelMask() sets the pixel channel mask from the specified channel
-%  mask.
-%
-%  The format of the SetPixelChannelMask method is:
-%
-%      ChannelType SetPixelChannelMask(Image *image,
-%        const ChannelType channel_mask)
-%
-%  A description of each parameter follows:
-%
-%    o image: the image.
-%
-%    o channel_mask: the channel mask.
-%
-*/
-MagickExport ChannelType SetPixelChannelMask(Image *image,
-  const ChannelType channel_mask)
-{
-  ChannelType
-    mask;
-
-  mask=image->channel_mask;
-  image->channel_mask=channel_mask;
-  SetPixelChannelMapMask(image,channel_mask);
-  return(mask);
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%                                                                             %
-%                                                                             %
-%                                                                             %
 %   S e t P i x e l M e t a C h a n n e l s                                   %
 %                                                                             %
 %                                                                             %