]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/pixel-accessor.h
https://github.com/ImageMagick/ImageMagick/issues/539
[imagemagick] / MagickCore / pixel-accessor.h
index 4aec80823cdd000dc4a201ce10ffcd4850c1016b..6c4623696228bc27b038dee261788d76808e316f 100644 (file)
@@ -1,11 +1,11 @@
 /*
-  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization
+  Copyright 1999-2017 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.
   obtain a copy of the License at
 
-    http://www.imagemagick.org/script/license.php
+    https://www.imagemagick.org/script/license.php
 
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
 
   MagickCore pixel accessor methods.
 */
-#ifndef _MAGICKCORE_PIXEL_ACCESSOR_H
-#define _MAGICKCORE_PIXEL_ACCESSOR_H
+#ifndef MAGICKCORE_PIXEL_ACCESSOR_H
+#define MAGICKCORE_PIXEL_ACCESSOR_H
 
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-#include <math.h>
+#include <assert.h>
 #include "MagickCore/cache.h"
 #include "MagickCore/cache-view.h"
 #include "MagickCore/color.h"
@@ -30,158 +26,179 @@ extern "C" {
 #include "MagickCore/gem.h"
 #include "MagickCore/image.h"
 
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
 #undef index
 
-static inline Quantum GetPixela(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum ClampPixel(const MagickRealType value)
+{ 
+  if (value < 0.0f)
+    return((Quantum) 0); 
+  if (value >= (MagickRealType) QuantumRange)
+    return((Quantum) QuantumRange);
+#if !defined(MAGICKCORE_HDRI_SUPPORT)
+  return((Quantum) (value+0.5f));
+#else
+  return((Quantum) value);
+#endif
+}
+
+static inline Quantum GetPixela(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   return(pixel[image->channel_map[aPixelChannel].offset]);
 }
 
-static inline Quantum GetPixelAlpha(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelAlpha(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   if (image->channel_map[AlphaPixelChannel].traits == UndefinedPixelTrait)
     return(OpaqueAlpha);
   return(pixel[image->channel_map[AlphaPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelAlphaTraits(const Image *restrict image)
+static inline PixelTrait GetPixelAlphaTraits(
+  const Image *magick_restrict image)
 {
   return(image->channel_map[AlphaPixelChannel].traits);
 }
 
-static inline Quantum GetPixelb(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelb(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   return(pixel[image->channel_map[bPixelChannel].offset]);
 }
 
-static inline Quantum GetPixelBlack(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelBlack(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   if (image->channel_map[BlackPixelChannel].traits == UndefinedPixelTrait)
     return((Quantum) 0);
   return(pixel[image->channel_map[BlackPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelBlackTraits(const Image *restrict image)
+static inline PixelTrait GetPixelBlackTraits(
+  const Image *magick_restrict image)
 {
   return(image->channel_map[BlackPixelChannel].traits);
 }
 
-static inline Quantum GetPixelBlue(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelBlue(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   return(pixel[image->channel_map[BluePixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelBlueTraits(const Image *restrict image)
+static inline PixelTrait GetPixelBlueTraits(const Image *magick_restrict image)
 {
   return(image->channel_map[BluePixelChannel].traits);
 }
 
-static inline Quantum GetPixelCb(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelCb(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   return(pixel[image->channel_map[CbPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelCbTraits(const Image *restrict image)
+static inline PixelTrait GetPixelCbTraits(const Image *magick_restrict image)
 {
   return(image->channel_map[CbPixelChannel].traits);
 }
 
-static inline Quantum GetPixelChannel(const Image *restrict image,
-  const PixelChannel channel,const Quantum *restrict pixel)
+static inline Quantum GetPixelChannel(const Image *magick_restrict image,
+  const PixelChannel channel,const Quantum *magick_restrict pixel)
 {
   if (image->channel_map[channel].traits == UndefinedPixelTrait)
     return((Quantum) 0);
   return(pixel[image->channel_map[channel].offset]);
 }
 
-static inline PixelChannel GetPixelChannelChannel(const Image *restrict image,
-  const ssize_t offset)
+static inline PixelChannel GetPixelChannelChannel(
+  const Image *magick_restrict image,const ssize_t offset)
 {
   return(image->channel_map[offset].channel);
 }
 
-static inline ssize_t GetPixelChannelOffset(const Image *restrict image,
+static inline ssize_t GetPixelChannelOffset(const Image *magick_restrict image,
   const PixelChannel channel)
 {
   return(image->channel_map[channel].offset);
 }
 
-static inline PixelTrait GetPixelChannelTraits(const Image *restrict image,
-  const PixelChannel channel)
+static inline PixelTrait GetPixelChannelTraits(
+  const Image *magick_restrict image,const PixelChannel channel)
 {
   return(image->channel_map[channel].traits);
 }
 
-static inline size_t GetPixelChannels(const Image *restrict image)
+static inline size_t GetPixelChannels(const Image *magick_restrict image)
 {
   return(image->number_channels);
 }
 
-static inline Quantum GetPixelCr(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelCr(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   return(pixel[image->channel_map[CrPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelCrTraits(const Image *restrict image)
+static inline PixelTrait GetPixelCrTraits(const Image *magick_restrict image)
 {
   return(image->channel_map[CrPixelChannel].traits);
 }
 
-static inline Quantum GetPixelCyan(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelCyan(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   return(pixel[image->channel_map[CyanPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelCyanTraits(const Image *restrict image)
+static inline PixelTrait GetPixelCyanTraits(const Image *magick_restrict image)
 {
   return(image->channel_map[CyanPixelChannel].traits);
 }
 
-static inline Quantum GetPixelGray(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelGray(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   return(pixel[image->channel_map[GrayPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelGrayTraits(const Image *restrict image)
+static inline PixelTrait GetPixelGrayTraits(const Image *magick_restrict image)
 {
   return(image->channel_map[GrayPixelChannel].traits);
 }
 
-static inline Quantum GetPixelGreen(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelGreen(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   return(pixel[image->channel_map[GreenPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelGreenTraits(const Image *restrict image)
+static inline PixelTrait GetPixelGreenTraits(
+  const Image *magick_restrict image)
 {
   return(image->channel_map[GreenPixelChannel].traits);
 }
 
-static inline Quantum GetPixelIndex(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelIndex(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   if (image->channel_map[IndexPixelChannel].traits == UndefinedPixelTrait)
     return((Quantum) 0);
   return(pixel[image->channel_map[IndexPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelIndexTraits(const Image *restrict image)
+static inline PixelTrait GetPixelIndexTraits(
+  const Image *magick_restrict image)
 {
   return(image->channel_map[IndexPixelChannel].traits);
 }
 
 static inline MagickRealType GetPixelInfoChannel(
-  const PixelInfo *restrict pixel_info,const PixelChannel channel)
+  const PixelInfo *magick_restrict pixel_info,const PixelChannel channel)
 {
   switch (channel)
   {
@@ -195,129 +212,175 @@ static inline MagickRealType GetPixelInfoChannel(
   }
 }
 
-static inline MagickRealType GetPixelInfoIntensity(
-  const PixelInfo *restrict pixel_info)
+static inline double PerceptibleReciprocal(const double x)
+{
+  double
+    sign;
+
+  /*
+    Return 1/x where x is perceptible (not unlimited or infinitesimal).
+  */
+  sign=x < 0.0 ? -1.0 : 1.0;
+  if ((sign*x) >= MagickEpsilon)
+    return(1.0/x);
+  return(sign/MagickEpsilon);
+}
+
+static inline MagickRealType GetPixelInfoLuma(
+  const PixelInfo *magick_restrict pixel)
 {
   MagickRealType
-    blue,
-    green,
-    red;
+    intensity;
 
-  if (pixel_info->colorspace == GRAYColorspace)
-    return(pixel_info->red);
-  if (pixel_info->colorspace != sRGBColorspace)
-    return(0.298839f*pixel_info->red+0.586811f*pixel_info->green+
-      0.114350f*pixel_info->blue);
-  red=DecodePixelGamma(pixel_info->red);
-  green=DecodePixelGamma(pixel_info->green);
-  blue=DecodePixelGamma(pixel_info->blue);
-  return(0.298839f*red+0.586811f*green+0.114350f*blue);
+  if (pixel->colorspace == sRGBColorspace)
+    {
+      intensity=(MagickRealType) (0.212656f*pixel->red+0.715158f*pixel->green+
+        0.072186f*pixel->blue);
+      return(intensity);
+    }
+  intensity=(MagickRealType) (0.212656f*EncodePixelGamma(pixel->red)+
+    0.715158f*EncodePixelGamma(pixel->green)+
+    0.072186f*EncodePixelGamma(pixel->blue));
+  return(intensity);
 }
 
 static inline MagickRealType GetPixelInfoLuminance(
-  const PixelInfo *restrict pixel_info)
+  const PixelInfo *magick_restrict pixel)
 {
   MagickRealType
-    blue,
-    green,
-    red;
+    intensity;
 
-  if (pixel_info->colorspace == GRAYColorspace)
-    return(pixel_info->red);
-  if (pixel_info->colorspace != sRGBColorspace)
-    return(0.21267f*pixel_info->red+0.71516f*pixel_info->green+
-      0.07217f*pixel_info->blue);
-  red=DecodePixelGamma(pixel_info->red);
-  green=DecodePixelGamma(pixel_info->green);
-  blue=DecodePixelGamma(pixel_info->blue);
-  return(0.21267f*red+0.71516f*green+0.07217f*blue);
+  if (pixel->colorspace != sRGBColorspace)
+    {
+      intensity=(MagickRealType) (0.212656f*pixel->red+0.715158f*pixel->green+
+        0.072186f*pixel->blue);
+      return(intensity);
+    }
+  intensity=(MagickRealType) (0.212656f*DecodePixelGamma(pixel->red)+
+    0.715158f*DecodePixelGamma(pixel->green)+
+    0.072186f*DecodePixelGamma(pixel->blue));
+  return(intensity);
 }
 
-static inline Quantum GetPixelL(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelL(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   return(pixel[image->channel_map[LPixelChannel].offset]);
 }
 
-static inline MagickRealType GetPixelLuminance(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline ssize_t GetPixelLabel(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
+{
+  return((ssize_t) pixel[image->channel_map[LabelPixelChannel].offset]);
+}
+
+static inline MagickRealType GetPixelLuma(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   MagickRealType
-    blue,
-    green,
-    red;
+    intensity;
+
+  intensity=(MagickRealType) (
+    0.212656f*pixel[image->channel_map[RedPixelChannel].offset]+
+    0.715158f*pixel[image->channel_map[GreenPixelChannel].offset]+
+    0.072186f*pixel[image->channel_map[BluePixelChannel].offset]);
+  return(intensity);
+}
+
+static inline MagickRealType GetPixelLuminance(
+  const Image *magick_restrict image,const Quantum *magick_restrict pixel)
+{
+  MagickRealType
+    intensity;
 
-  if (image->colorspace == GRAYColorspace)
-    return((MagickRealType) pixel[image->channel_map[GrayPixelChannel].offset]);
   if (image->colorspace != sRGBColorspace)
-    return(0.298839f*pixel[image->channel_map[RedPixelChannel].offset]+
-      0.586811f*pixel[image->channel_map[GreenPixelChannel].offset]+
-      0.114350f*pixel[image->channel_map[BluePixelChannel].offset]);
-  red=DecodePixelGamma((MagickRealType)
-    pixel[image->channel_map[RedPixelChannel].offset]);
-  green=DecodePixelGamma((MagickRealType)
-    pixel[image->channel_map[GreenPixelChannel].offset]);
-  blue=DecodePixelGamma((MagickRealType)
-    pixel[image->channel_map[BluePixelChannel].offset]);
-  return(0.21267f*red+0.71516f*green+0.07217f*blue);
+    {
+      intensity=(MagickRealType) (
+        0.212656f*pixel[image->channel_map[RedPixelChannel].offset]+
+        0.715158f*pixel[image->channel_map[GreenPixelChannel].offset]+
+        0.072186f*pixel[image->channel_map[BluePixelChannel].offset]);
+      return(intensity);
+    }
+  intensity=(MagickRealType) (0.212656f*DecodePixelGamma((MagickRealType)
+    pixel[image->channel_map[RedPixelChannel].offset])+0.715158f*
+    DecodePixelGamma((MagickRealType)
+    pixel[image->channel_map[GreenPixelChannel].offset])+0.072186f*
+    DecodePixelGamma((MagickRealType)
+    pixel[image->channel_map[BluePixelChannel].offset]));
+  return(intensity);
 }
 
-static inline Quantum GetPixelMagenta(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelMagenta(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   return(pixel[image->channel_map[MagentaPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelMagentaTraits(const Image *restrict image)
+static inline PixelTrait GetPixelMagentaTraits(
+  const Image *magick_restrict image)
 {
   return(image->channel_map[MagentaPixelChannel].traits);
 }
 
-static inline Quantum GetPixelMask(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelReadMask(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
-  if (image->channel_map[MaskPixelChannel].traits == UndefinedPixelTrait)
+  if (image->channel_map[ReadMaskPixelChannel].traits == UndefinedPixelTrait)
     return((Quantum) QuantumRange);
-  return(pixel[image->channel_map[MaskPixelChannel].offset]);
+  return(pixel[image->channel_map[ReadMaskPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelMaskTraits(const Image *restrict image)
+static inline Quantum GetPixelWriteMask(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
-  return(image->channel_map[MaskPixelChannel].traits);
+  if (image->channel_map[WriteMaskPixelChannel].traits == UndefinedPixelTrait)
+    return((Quantum) QuantumRange);
+  return(pixel[image->channel_map[WriteMaskPixelChannel].offset]);
 }
 
-static inline size_t GetPixelMetaChannels(const Image *restrict image)
+static inline PixelTrait GetPixelReadMaskTraits(
+  const Image *magick_restrict image)
+{
+  return(image->channel_map[ReadMaskPixelChannel].traits);
+}
+
+static inline size_t GetPixelMetaChannels(const Image *magick_restrict image)
 {
   return(image->number_meta_channels);
 }
 
-static inline size_t GetPixelMetacontentExtent(const Image *restrict image)
+static inline size_t GetPixelMetacontentExtent(
+  const Image *magick_restrict image)
 {
   return(image->metacontent_extent);
 }
 
-static inline Quantum GetPixelOpacity(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelOpacity(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
-  if (image->channel_map[AlphaPixelChannel].traits == UndefinedPixelTrait)
+  if (image->channel_map[AlphaPixelChannel].traits != BlendPixelTrait)
     return(QuantumRange-OpaqueAlpha);
   return(QuantumRange-pixel[image->channel_map[AlphaPixelChannel].offset]);
 }
 
-static inline Quantum GetPixelRed(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelRed(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   return(pixel[image->channel_map[RedPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelRedTraits(const Image *restrict image)
+static inline PixelTrait GetPixelRedTraits(const Image *magick_restrict image)
 {
   return(image->channel_map[RedPixelChannel].traits);
 }
 
-static inline void GetPixelInfoPixel(const Image *restrict image,
-  const Quantum *restrict pixel,PixelInfo *restrict pixel_info)
+static inline void GetPixelInfoPixel(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel,PixelInfo *magick_restrict pixel_info)
 {
+  pixel_info->storage_class=image->storage_class;
+  pixel_info->colorspace=image->colorspace;
+  pixel_info->fuzz=image->fuzz;
+  pixel_info->depth=image->depth;
   pixel_info->red=(MagickRealType)
     pixel[image->channel_map[RedPixelChannel].offset];
   pixel_info->green=(MagickRealType)
@@ -329,39 +392,45 @@ static inline void GetPixelInfoPixel(const Image *restrict image,
     pixel_info->black=(MagickRealType)
       pixel[image->channel_map[BlackPixelChannel].offset];
   pixel_info->alpha=(MagickRealType) OpaqueAlpha;
+  pixel_info->alpha_trait=UndefinedPixelTrait;
   if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
-    pixel_info->alpha=(MagickRealType)
-      pixel[image->channel_map[AlphaPixelChannel].offset];
+    {
+      pixel_info->alpha=(MagickRealType)
+        pixel[image->channel_map[AlphaPixelChannel].offset];
+      pixel_info->alpha_trait=BlendPixelTrait;
+    }
   pixel_info->index=0.0f;
   if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
     pixel_info->index=(MagickRealType)
       pixel[image->channel_map[IndexPixelChannel].offset];
+  pixel_info->count=0;
 }
 
-static inline PixelTrait GetPixelTraits(const Image *restrict image,
+static inline PixelTrait GetPixelTraits(const Image *magick_restrict image,
   const PixelChannel channel)
 {
   return(image->channel_map[channel].traits);
 }
 
-static inline Quantum GetPixelY(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelY(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   return(pixel[image->channel_map[YPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelYTraits(const Image *restrict image)
+static inline PixelTrait GetPixelYTraits(const Image *magick_restrict image)
 {
   return(image->channel_map[YPixelChannel].traits);
 }
 
-static inline Quantum GetPixelYellow(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline Quantum GetPixelYellow(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   return(pixel[image->channel_map[YellowPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelYellowTraits(const Image *restrict image)
+static inline PixelTrait GetPixelYellowTraits(
+  const Image *magick_restrict image)
 {
   return(image->channel_map[YellowPixelChannel].traits);
 }
@@ -371,54 +440,95 @@ static inline MagickRealType AbsolutePixelValue(const MagickRealType x)
   return(x < 0.0f ? -x : x);
 }
 
-static inline MagickBooleanType IsPixelEquivalent(const Image *restrict image,
-  const Quantum *restrict p,const PixelInfo *restrict q)
+static inline MagickBooleanType IsPixelAtDepth(const Quantum pixel,
+  const QuantumAny range)
+{
+  Quantum
+    quantum;
+
+#if !defined(MAGICKCORE_HDRI_SUPPORT)
+  quantum=(Quantum) (((MagickRealType) QuantumRange*((QuantumAny) 
+    (((MagickRealType) range*pixel)/QuantumRange+0.5)))/range+0.5);
+#else
+  quantum=(Quantum) (((MagickRealType) QuantumRange*((QuantumAny) 
+    (((MagickRealType) range*pixel)/QuantumRange+0.5)))/range);
+#endif
+  return(pixel == quantum ? MagickTrue : MagickFalse);
+}
+
+static inline MagickBooleanType IsPixelEquivalent(
+  const Image *magick_restrict image,const Quantum *magick_restrict p,
+  const PixelInfo *magick_restrict q)
 {
   MagickRealType
-    blue,
-    green,
-    red;
-
-  red=(MagickRealType) p[image->channel_map[RedPixelChannel].offset];
-  green=(MagickRealType) p[image->channel_map[GreenPixelChannel].offset];
-  blue=(MagickRealType) p[image->channel_map[BluePixelChannel].offset];
-  if ((AbsolutePixelValue(red-q->red) < MagickEpsilon) &&
-      (AbsolutePixelValue(green-q->green) < MagickEpsilon) &&
-      (AbsolutePixelValue(blue-q->blue) < MagickEpsilon))
-    return(MagickTrue);
-  return(MagickFalse);
+    value;
+
+  value=(MagickRealType) p[image->channel_map[AlphaPixelChannel].offset];
+  if ((image->alpha_trait != UndefinedPixelTrait) &&
+      (q->alpha_trait == UndefinedPixelTrait) &&
+      (AbsolutePixelValue(value-OpaqueAlpha) >= MagickEpsilon))
+    return(MagickFalse);
+  if ((q->alpha_trait != UndefinedPixelTrait) &&
+      (image->alpha_trait == UndefinedPixelTrait) &&
+      (AbsolutePixelValue(q->alpha-OpaqueAlpha)) >= MagickEpsilon)
+    return(MagickFalse);
+  if ((image->alpha_trait != UndefinedPixelTrait) &&
+      (q->alpha_trait != UndefinedPixelTrait))
+    {
+      if (AbsolutePixelValue(value-q->alpha) >= MagickEpsilon)
+        return(MagickFalse);
+      if (AbsolutePixelValue(value-TransparentAlpha) < MagickEpsilon)
+        return(MagickTrue);
+    }
+  value=(MagickRealType) p[image->channel_map[RedPixelChannel].offset];
+  if (AbsolutePixelValue(value-q->red) >= MagickEpsilon)
+    return(MagickFalse);
+  value=(MagickRealType) p[image->channel_map[GreenPixelChannel].offset];
+  if (AbsolutePixelValue(value-q->green) >= MagickEpsilon)
+    return(MagickFalse);
+  value=(MagickRealType) p[image->channel_map[BluePixelChannel].offset];
+  if (AbsolutePixelValue(value-q->blue) >= MagickEpsilon)
+    return(MagickFalse);
+  if (image->colorspace == CMYKColorspace)
+    {
+      value=(MagickRealType) p[image->channel_map[BlackPixelChannel].offset];
+      if (AbsolutePixelValue(value-q->black) >= MagickEpsilon)
+        return(MagickFalse);
+    }
+  return(MagickTrue);
 }
 
-static inline MagickBooleanType IsPixelGray(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline MagickBooleanType IsPixelGray(const Image *magick_restrict image,
+  const Quantum *magick_restrict pixel)
 {
   MagickRealType
-    blue,
-    green,
-    red;
+    green_blue,
+    red_green;
 
-  red=(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset];
-  green=(MagickRealType) pixel[image->channel_map[GreenPixelChannel].offset];
-  blue=(MagickRealType) pixel[image->channel_map[BluePixelChannel].offset];
-  if ((AbsolutePixelValue(red-green) < MagickEpsilon) &&
-      (AbsolutePixelValue(green-blue) < MagickEpsilon))
+  red_green=(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset]-
+    pixel[image->channel_map[GreenPixelChannel].offset];
+  green_blue=(MagickRealType)
+    pixel[image->channel_map[GreenPixelChannel].offset]-
+    pixel[image->channel_map[BluePixelChannel].offset];
+  if ((AbsolutePixelValue(red_green) < MagickEpsilon) &&
+      (AbsolutePixelValue(green_blue) < MagickEpsilon))
     return(MagickTrue);
   return(MagickFalse);
 }
 
 static inline MagickBooleanType IsPixelInfoEquivalent(
-  const PixelInfo *restrict p,const PixelInfo *restrict q)
+  const PixelInfo *magick_restrict p,const PixelInfo *magick_restrict q)
 {
-  if ((p->alpha_trait == BlendPixelTrait) &&
-      (q->alpha_trait != BlendPixelTrait) &&
+  if ((p->alpha_trait != UndefinedPixelTrait) &&
+      (q->alpha_trait == UndefinedPixelTrait) &&
       (AbsolutePixelValue(p->alpha-OpaqueAlpha) >= MagickEpsilon))
     return(MagickFalse);
-  if ((q->alpha_trait == BlendPixelTrait) &&
-      (p->alpha_trait != BlendPixelTrait) &&
+  if ((q->alpha_trait != UndefinedPixelTrait) &&
+      (p->alpha_trait == UndefinedPixelTrait) &&
       (AbsolutePixelValue(q->alpha-OpaqueAlpha)) >= MagickEpsilon)
     return(MagickFalse);
-  if ((p->alpha_trait == BlendPixelTrait) &&
-      (q->alpha_trait == BlendPixelTrait))
+  if ((p->alpha_trait != UndefinedPixelTrait) &&
+      (q->alpha_trait != UndefinedPixelTrait))
     {
       if (AbsolutePixelValue(p->alpha-q->alpha) >= MagickEpsilon)
         return(MagickFalse);
@@ -437,62 +547,65 @@ static inline MagickBooleanType IsPixelInfoEquivalent(
   return(MagickTrue);
 }
 
-static inline MagickBooleanType IsPixelMonochrome(const Image *restrict image,
-  const Quantum *restrict pixel)
+static inline MagickBooleanType IsPixelMonochrome(
+  const Image *magick_restrict image,const Quantum *magick_restrict pixel)
 {
   MagickRealType
-    blue,
-    green,
-    red;
+    green_blue,
+    red,
+    red_green;
 
   red=(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset];
-  if ((AbsolutePixelValue(red) >= MagickEpsilon) ||
+  if ((AbsolutePixelValue(red) >= MagickEpsilon) &&
       (AbsolutePixelValue(red-QuantumRange) >= MagickEpsilon))
     return(MagickFalse);
-  green=(MagickRealType) pixel[image->channel_map[GreenPixelChannel].offset];
-  blue=(MagickRealType) pixel[image->channel_map[BluePixelChannel].offset];
-  if ((AbsolutePixelValue(red-green) < MagickEpsilon) &&
-      (AbsolutePixelValue(green-blue) < MagickEpsilon))
+  red_green=(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset]-
+    pixel[image->channel_map[GreenPixelChannel].offset];
+  green_blue=(MagickRealType)
+    pixel[image->channel_map[GreenPixelChannel].offset]-
+    pixel[image->channel_map[BluePixelChannel].offset];
+  if ((AbsolutePixelValue(red_green) < MagickEpsilon) &&
+      (AbsolutePixelValue(green_blue) < MagickEpsilon))
     return(MagickTrue);
   return(MagickFalse);
 }
 
 static inline MagickBooleanType IsPixelInfoGray(
-  const PixelInfo *restrict pixel_info)
+  const PixelInfo *magick_restrict pixel)
 {
-  if ((pixel_info->colorspace != GRAYColorspace) &&
-      (pixel_info->colorspace != RGBColorspace))
-    return(MagickFalse);
-  if ((AbsolutePixelValue(pixel_info->red-pixel_info->green) < MagickEpsilon) &&
-      (AbsolutePixelValue(pixel_info->green-pixel_info->blue) < MagickEpsilon))
+  if ((AbsolutePixelValue(pixel->red-pixel->green) < MagickEpsilon) &&
+      (AbsolutePixelValue(pixel->green-pixel->blue) < MagickEpsilon))
     return(MagickTrue);
   return(MagickFalse);
 }
 
 static inline MagickBooleanType IsPixelInfoMonochrome(
-  const PixelInfo *restrict pixel_info)
+  const PixelInfo *magick_restrict pixel_info)
 {
-  if ((pixel_info->colorspace != GRAYColorspace) &&
-      (pixel_info->colorspace != RGBColorspace))
-    return(MagickFalse);
+  MagickRealType
+    green_blue,
+    red_green;
+
   if ((AbsolutePixelValue(pixel_info->red) >= MagickEpsilon) ||
       (AbsolutePixelValue(pixel_info->red-QuantumRange) >= MagickEpsilon))
     return(MagickFalse);
-  if ((AbsolutePixelValue(pixel_info->red-pixel_info->green) < MagickEpsilon) &&
-      (AbsolutePixelValue(pixel_info->green-pixel_info->blue) < MagickEpsilon))
+  red_green=pixel_info->red-pixel_info->green;
+  green_blue=pixel_info->green-pixel_info->blue;
+  if ((AbsolutePixelValue(red_green) < MagickEpsilon) &&
+      (AbsolutePixelValue(green_blue) < MagickEpsilon))
     return(MagickTrue);
   return(MagickFalse);
 }
 
-static inline void SetPixela(const Image *restrict image,
-  const Quantum a,Quantum *restrict pixel)
+static inline void SetPixela(const Image *magick_restrict image,
+  const Quantum a,Quantum *magick_restrict pixel)
 {
   if (image->channel_map[aPixelChannel].traits != UndefinedPixelTrait)
     pixel[image->channel_map[aPixelChannel].offset]=a;
 }
 
-static inline void SetPixelAlpha(const Image *restrict image,
-  const Quantum alpha,Quantum *restrict pixel)
+static inline void SetPixelAlpha(const Image *magick_restrict image,
+  const Quantum alpha,Quantum *magick_restrict pixel)
 {
   if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
     pixel[image->channel_map[AlphaPixelChannel].offset]=alpha;
@@ -503,15 +616,38 @@ static inline void SetPixelAlphaTraits(Image *image,const PixelTrait traits)
   image->channel_map[AlphaPixelChannel].traits=traits;
 }
 
-static inline void SetPixelb(const Image *restrict image,
-  const Quantum b,Quantum *restrict pixel)
+static inline void SetPixelb(const Image *magick_restrict image,
+  const Quantum b,Quantum *magick_restrict pixel)
 {
   if (image->channel_map[bPixelChannel].traits != UndefinedPixelTrait)
     pixel[image->channel_map[bPixelChannel].offset]=b;
 }
 
-static inline void SetPixelBlack(const Image *restrict image,
-  const Quantum black,Quantum *restrict pixel)
+static inline void SetPixelBackgoundColor(const Image *magick_restrict image,
+  Quantum *magick_restrict pixel)
+{
+  register ssize_t
+    i;
+
+  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+    pixel[i]=(Quantum) 0;
+  pixel[image->channel_map[RedPixelChannel].offset]=
+    ClampToQuantum(image->background_color.red);
+  pixel[image->channel_map[GreenPixelChannel].offset]=
+    ClampToQuantum(image->background_color.green);
+  pixel[image->channel_map[BluePixelChannel].offset]=
+    ClampToQuantum(image->background_color.blue);
+  if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[BlackPixelChannel].offset]=
+      ClampToQuantum(image->background_color.black);
+  if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[AlphaPixelChannel].offset]=
+      image->background_color.alpha_trait == UndefinedPixelTrait ? OpaqueAlpha :
+      ClampToQuantum(image->background_color.alpha);
+}
+
+static inline void SetPixelBlack(const Image *magick_restrict image,
+  const Quantum black,Quantum *magick_restrict pixel)
 {
   if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
     pixel[image->channel_map[BlackPixelChannel].offset]=black;
@@ -522,8 +658,8 @@ static inline void SetPixelBlackTraits(Image *image,const PixelTrait traits)
   image->channel_map[BlackPixelChannel].traits=traits;
 }
 
-static inline void SetPixelBlue(const Image *restrict image,const Quantum blue,
-  Quantum *restrict pixel)
+static inline void SetPixelBlue(const Image *magick_restrict image,
+  const Quantum blue,Quantum *magick_restrict pixel)
 {
   pixel[image->channel_map[BluePixelChannel].offset]=blue;
 }
@@ -533,8 +669,8 @@ static inline void SetPixelBlueTraits(Image *image,const PixelTrait traits)
   image->channel_map[BluePixelChannel].traits=traits;
 }
 
-static inline void SetPixelCb(const Image *restrict image,const Quantum cb,
-  Quantum *restrict pixel)
+static inline void SetPixelCb(const Image *magick_restrict image,
+  const Quantum cb,Quantum *magick_restrict pixel)
 {
   pixel[image->channel_map[CbPixelChannel].offset]=cb;
 }
@@ -544,22 +680,26 @@ static inline void SetPixelCbTraits(Image *image,const PixelTrait traits)
   image->channel_map[CbPixelChannel].traits=traits;
 }
 
-static inline void SetPixelChannel(const Image *restrict image,
-  const PixelChannel channel,const Quantum quantum,Quantum *restrict pixel)
+static inline void SetPixelChannel(const Image *magick_restrict image,
+  const PixelChannel channel,const Quantum quantum,
+  Quantum *magick_restrict pixel)
 {
   if (image->channel_map[channel].traits != UndefinedPixelTrait)
     pixel[image->channel_map[channel].offset]=quantum;
 }
 
-static inline void SetPixelChannelAttributes(const Image *restrict image,
-  const PixelChannel channel,const PixelTrait traits,const ssize_t offset)
+static inline void SetPixelChannelAttributes(
+  const Image *magick_restrict image,const PixelChannel channel,
+  const PixelTrait traits,const ssize_t offset)
 {
+  assert((ssize_t) channel < MaxPixelChannels);
+  assert(offset < MaxPixelChannels);
   image->channel_map[offset].channel=channel;
   image->channel_map[channel].offset=offset;
   image->channel_map[channel].traits=traits;
 }
 
-static inline void SetPixelChannelChannel(const Image *restrict image,
+static inline void SetPixelChannelChannel(const Image *magick_restrict image,
   const PixelChannel channel,const ssize_t offset)
 {
   image->channel_map[offset].channel=channel;
@@ -577,8 +717,8 @@ static inline void SetPixelChannelTraits(Image *image,
   image->channel_map[channel].traits=traits;
 }
 
-static inline void SetPixelCr(const Image *restrict image,const Quantum cr,
-  Quantum *restrict pixel)
+static inline void SetPixelCr(const Image *magick_restrict image,
+  const Quantum cr,Quantum *magick_restrict pixel)
 {
   pixel[image->channel_map[CrPixelChannel].offset]=cr;
 }
@@ -588,14 +728,14 @@ static inline void SetPixelCrTraits(Image *image,const PixelTrait traits)
   image->channel_map[CrPixelChannel].traits=traits;
 }
 
-static inline void SetPixelCyan(const Image *restrict image,const Quantum cyan,
-  Quantum *restrict pixel)
+static inline void SetPixelCyan(const Image *magick_restrict image,
+  const Quantum cyan,Quantum *magick_restrict pixel)
 {
   pixel[image->channel_map[CyanPixelChannel].offset]=cyan;
 }
 
-static inline void SetPixelGray(const Image *restrict image,const Quantum gray,
-  Quantum *restrict pixel)
+static inline void SetPixelGray(const Image *magick_restrict image,
+  const Quantum gray,Quantum *magick_restrict pixel)
 {
   pixel[image->channel_map[GrayPixelChannel].offset]=gray;
 }
@@ -605,8 +745,8 @@ static inline void SetPixelGrayTraits(Image *image,const PixelTrait traits)
   image->channel_map[GrayPixelChannel].traits=traits;
 }
 
-static inline void SetPixelGreen(const Image *restrict image,
-  const Quantum green,Quantum *restrict pixel)
+static inline void SetPixelGreen(const Image *magick_restrict image,
+  const Quantum green,Quantum *magick_restrict pixel)
 {
   pixel[image->channel_map[GreenPixelChannel].offset]=green;
 }
@@ -616,8 +756,8 @@ static inline void SetPixelGreenTraits(Image *image,const PixelTrait traits)
   image->channel_map[GreenPixelChannel].traits=traits;
 }
 
-static inline void SetPixelIndex(const Image *restrict image,
-  const Quantum index,Quantum *restrict pixel)
+static inline void SetPixelIndex(const Image *magick_restrict image,
+  const Quantum index,Quantum *magick_restrict pixel)
 {
   if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
     pixel[image->channel_map[IndexPixelChannel].offset]=index;
@@ -628,8 +768,8 @@ static inline void SetPixelIndexTraits(Image *image,const PixelTrait traits)
   image->channel_map[IndexPixelChannel].traits=traits;
 }
 
-static inline void SetPixelInfoPixel(const Image *restrict image,
-  const PixelInfo *restrict pixel_info,Quantum *restrict pixel)
+static inline void SetPixelViaPixelInfo(const Image *magick_restrict image,
+  const PixelInfo *magick_restrict pixel_info,Quantum *magick_restrict pixel)
 {
   pixel[image->channel_map[RedPixelChannel].offset]=
     ClampToQuantum(pixel_info->red);
@@ -642,19 +782,19 @@ static inline void SetPixelInfoPixel(const Image *restrict image,
       ClampToQuantum(pixel_info->black);
   if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
     pixel[image->channel_map[AlphaPixelChannel].offset]=
-      pixel_info->alpha_trait != BlendPixelTrait ? OpaqueAlpha :
+      pixel_info->alpha_trait == UndefinedPixelTrait ? OpaqueAlpha :
       ClampToQuantum(pixel_info->alpha);
 }
 
-static inline void SetPixelL(const Image *restrict image,const Quantum L,
-  Quantum *restrict pixel)
+static inline void SetPixelL(const Image *magick_restrict image,const Quantum L,
+  Quantum *magick_restrict pixel)
 {
   if (image->channel_map[LPixelChannel].traits != UndefinedPixelTrait)
     pixel[image->channel_map[LPixelChannel].offset]=L;
 }
 
-static inline void SetPixelMagenta(const Image *restrict image,
-  const Quantum magenta,Quantum *restrict pixel)
+static inline void SetPixelMagenta(const Image *magick_restrict image,
+  const Quantum magenta,Quantum *magick_restrict pixel)
 {
   pixel[image->channel_map[MagentaPixelChannel].offset]=magenta;
 }
@@ -664,11 +804,18 @@ static inline void SetPixelMagentaTraits(Image *image,const PixelTrait traits)
   image->channel_map[MagentaPixelChannel].traits=traits;
 }
 
-static inline void SetPixelMask(const Image *restrict image,
-  const Quantum mask,Quantum *restrict pixel)
+static inline void SetPixelReadMask(const Image *magick_restrict image,
+  const Quantum mask,Quantum *magick_restrict pixel)
+{
+  if (image->channel_map[ReadMaskPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[ReadMaskPixelChannel].offset]=mask;
+}
+
+static inline void SetPixelWriteMask(const Image *magick_restrict image,
+  const Quantum mask,Quantum *magick_restrict pixel)
 {
-  if (image->channel_map[MaskPixelChannel].traits != UndefinedPixelTrait)
-    pixel[image->channel_map[MaskPixelChannel].offset]=mask;
+  if (image->channel_map[WriteMaskPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[WriteMaskPixelChannel].offset]=mask;
 }
 
 static inline void SetPixelMetacontentExtent(Image *image,const size_t extent)
@@ -676,15 +823,15 @@ static inline void SetPixelMetacontentExtent(Image *image,const size_t extent)
   image->metacontent_extent=extent;
 }
 
-static inline void SetPixelOpacity(const Image *restrict image,
-  const Quantum alpha,Quantum *restrict pixel)
+static inline void SetPixelOpacity(const Image *magick_restrict image,
+  const Quantum alpha,Quantum *magick_restrict pixel)
 {
   if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
     pixel[image->channel_map[AlphaPixelChannel].offset]=QuantumRange-alpha;
 }
 
-static inline void SetPixelRed(const Image *restrict image,const Quantum red,
-  Quantum *restrict pixel)
+static inline void SetPixelRed(const Image *magick_restrict image,
+  const Quantum red,Quantum *magick_restrict pixel)
 {
   pixel[image->channel_map[RedPixelChannel].offset]=red;
 }
@@ -694,8 +841,8 @@ static inline void SetPixelRedTraits(Image *image,const PixelTrait traits)
   image->channel_map[RedPixelChannel].traits=traits;
 }
 
-static inline void SetPixelYellow(const Image *restrict image,
-  const Quantum yellow,Quantum *restrict pixel)
+static inline void SetPixelYellow(const Image *magick_restrict image,
+  const Quantum yellow,Quantum *magick_restrict pixel)
 {
   pixel[image->channel_map[YellowPixelChannel].offset]=yellow;
 }
@@ -705,8 +852,8 @@ static inline void SetPixelYellowTraits(Image *image,const PixelTrait traits)
   image->channel_map[YellowPixelChannel].traits=traits;
 }
 
-static inline void SetPixelY(const Image *restrict image,const Quantum y,
-  Quantum *restrict pixel)
+static inline void SetPixelY(const Image *magick_restrict image,
+  const Quantum y,Quantum *magick_restrict pixel)
 {
   pixel[image->channel_map[YPixelChannel].offset]=y;
 }