]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/pixel-accessor.h
(no commit message)
[imagemagick] / MagickCore / pixel-accessor.h
index a42b43b006e9493ec837bb4a8f79687dbce6370d..a53128ca23347eef2ae0c5d7ff29a7a047f55fd7 100644 (file)
@@ -1,12 +1,12 @@
 /*
-  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization
+  Copyright 1999-2012 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
-  
+
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,417 +23,680 @@ extern "C" {
 #endif
 
 #include <math.h>
+#include <MagickCore/cache.h>
 #include <MagickCore/cache-view.h>
 #include <MagickCore/color.h>
+#include <MagickCore/colorspace.h>
 #include <MagickCore/image.h>
 
-static inline Quantum GetPixelAlpha(const Image *image,const Quantum *pixel)
+#undef index
+
+static inline double InversesRGBCompandor(const double pixel)
 {
-  return(pixel[image->component_map[AlphaPixelComponent].component]);
+  if (pixel <= (0.04045*QuantumRange))
+    return(pixel/12.92);
+  return(QuantumRange*pow((QuantumScale*pixel+0.055)/1.055,2.4));
 }
 
-static inline Quantum GetPixelBlack(const Image *image,const Quantum *pixel)
+static inline double sRGBCompandor(const double pixel)
 {
-  return(pixel[image->component_map[BlackPixelComponent].component]);
+  if (pixel <= (0.0031308*QuantumRange))
+    return(12.92*pixel);
+  return(QuantumRange*(1.055*pow(QuantumScale*pixel,1.0/2.4)-0.055));
 }
 
-static inline Quantum GetPixelBlue(const Image *image,const Quantum *pixel)
+static inline Quantum GetPixela(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[BluePixelComponent].component]);
+  return(pixel[image->channel_map[aPixelChannel].offset]);
 }
 
-static inline Quantum GetPixelCb(const Image *image,const Quantum *pixel)
+static inline Quantum GetPixelAlpha(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[CbPixelComponent].component]);
+  if (image->channel_map[AlphaPixelChannel].traits == UndefinedPixelTrait)
+    return(OpaqueAlpha);
+  return(pixel[image->channel_map[AlphaPixelChannel].offset]);
 }
 
-static inline size_t GetPixelChannels(const Image *image)
+static inline PixelTrait GetPixelAlphaTraits(const Image *restrict image)
 {
-  return(image->pixel_channels);
+  return(image->channel_map[AlphaPixelChannel].traits);
 }
 
-static inline Quantum GetPixelCr(const Image *image,const Quantum *pixel)
+static inline Quantum GetPixelb(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[CrPixelComponent].component]);
+  return(pixel[image->channel_map[bPixelChannel].offset]);
 }
 
-static inline Quantum GetPixelCyan(const Image *image,const Quantum *pixel)
+static inline Quantum GetPixelBlack(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[CyanPixelComponent].component]);
+  if (image->channel_map[BlackPixelChannel].traits == UndefinedPixelTrait)
+    return((Quantum) 0);
+  return(pixel[image->channel_map[BlackPixelChannel].offset]);
 }
 
-static inline Quantum GetPixelGray(const Image *image,const Quantum *pixel)
+static inline PixelTrait GetPixelBlackTraits(const Image *restrict image)
 {
-  return(pixel[image->component_map[GrayPixelComponent].component]);
+  return(image->channel_map[BlackPixelChannel].traits);
 }
 
-static inline Quantum GetPixelGreen(const Image *image,const Quantum *pixel)
+static inline Quantum GetPixelBlue(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[GreenPixelComponent].component]);
+  return(pixel[image->channel_map[BluePixelChannel].offset]);
 }
 
-static inline Quantum GetPixelIndex(const Image *image,const Quantum *pixel)
+static inline PixelTrait GetPixelBlueTraits(const Image *restrict image)
 {
-  return(pixel[image->component_map[IndexPixelComponent].component]);
+  return(image->channel_map[BluePixelChannel].traits);
 }
 
-static inline Quantum GetPixelInfoIntensity(const PixelInfo *pixel_info)
+static inline Quantum GetPixelCb(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-#if !defined(MAGICKCORE_HDRI_SUPPORT)
-  return((Quantum) (0.299*pixel_info->red+0.587*pixel_info->green+0.114*pixel_info->blue+0.5));
-#else
-  return((Quantum) (0.299*pixel_info->red+0.587*pixel_info->green+0.114*pixel_info->blue));
-#endif
+  return(pixel[image->channel_map[CbPixelChannel].offset]);
 }
 
-static inline Quantum GetPixelInfoLuminance(const PixelInfo *pixel_info)
+static inline PixelTrait GetPixelCbTraits(const Image *restrict image)
 {
-  Quantum
-    luminance;
-  
-#if !defined(MAGICKCORE_HDRI_SUPPORT)
-  luminance=(Quantum) (0.21267*pixel_info->red+0.71516*pixel_info->green+
-    0.07217*pixel_info->blue+0.5);
-#else
-  luminance=(Quantum) (0.21267*pixel_info->red+0.71516*pixel_info->green+
-    0.07217*pixel_info->blue);
-#endif
-  return((Quantum) luminance);
+  return(image->channel_map[CbPixelChannel].traits);
 }
 
-static inline Quantum GetPixelMagenta(const Image *image,
-  const Quantum *pixel)
+static inline Quantum GetPixelChannel(const Image *restrict image,
+  const PixelChannel channel,const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[MagentaPixelComponent].component]);
+  if (image->channel_map[channel].traits == UndefinedPixelTrait)
+    return((Quantum) 0);
+  return(pixel[image->channel_map[channel].offset]);
 }
 
-static inline size_t GetPixelMetacontentExtent(const Image *image)
+static inline PixelChannel GetPixelChannelMapChannel(
+  const Image *restrict image,const ssize_t offset)
 {
-  return(image->metacontent_extent);
+  return(image->channel_map[offset].channel);
+}
+
+static inline ssize_t GetPixelChannelMapOffset(const Image *restrict image,
+  const PixelChannel channel)
+{
+  return(image->channel_map[channel].offset);
+}
+
+static inline PixelTrait GetPixelChannelMapTraits(const Image *restrict image,
+  const PixelChannel channel)
+{
+  return(image->channel_map[channel].traits);
+}
+
+static inline size_t GetPixelChannels(const Image *restrict image)
+{
+  return(image->number_channels);
+}
+
+static inline Quantum GetPixelCr(const Image *restrict image,
+  const Quantum *restrict pixel)
+{
+  return(pixel[image->channel_map[CrPixelChannel].offset]);
+}
+
+static inline PixelTrait GetPixelCrTraits(const Image *restrict image)
+{
+  return(image->channel_map[CrPixelChannel].traits);
+}
+
+static inline Quantum GetPixelCyan(const Image *restrict image,
+  const Quantum *restrict pixel)
+{
+  return(pixel[image->channel_map[CyanPixelChannel].offset]);
+}
+
+static inline PixelTrait GetPixelCyanTraits(const Image *restrict image)
+{
+  return(image->channel_map[CyanPixelChannel].traits);
+}
+
+static inline Quantum GetPixelGray(const Image *restrict image,
+  const Quantum *restrict pixel)
+{
+  return(pixel[image->channel_map[GrayPixelChannel].offset]);
+}
+
+static inline PixelTrait GetPixelGrayTraits(const Image *restrict image)
+{
+  return(image->channel_map[GrayPixelChannel].traits);
 }
 
-static inline Quantum GetPixelRed(const Image *image,const Quantum *pixel)
+static inline Quantum GetPixelGreen(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[RedPixelComponent].component]);
+  return(pixel[image->channel_map[GreenPixelChannel].offset]);
 }
 
-static inline void GetPixelPacket(const Image *image,const Quantum *pixel,
-  PixelPacket *packet)
+static inline PixelTrait GetPixelGreenTraits(const Image *restrict image)
 {
-  packet->red=GetPixelRed(image,pixel);
-  packet->green=GetPixelGreen(image,pixel);
-  packet->blue=GetPixelBlue(image,pixel);
-  packet->alpha=GetPixelAlpha(image,pixel);
+  return(image->channel_map[GreenPixelChannel].traits);
 }
 
-static inline Quantum GetPixelPacketIntensity(const PixelPacket *pixel)
+static inline Quantum GetPixelIndex(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-#if !defined(MAGICKCORE_HDRI_SUPPORT)
-  if ((pixel->red == pixel->green) && (pixel->green == pixel->blue))
-    return(pixel->red);
-  return((Quantum) (0.299*pixel->red+0.587*pixel->green+0.114*pixel->blue+0.5));
-#else
+  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)
+{
+  return(image->channel_map[IndexPixelChannel].traits);
+}
+
+static inline double GetPixelInfoChannel(const PixelInfo *restrict pixel_info,
+  const PixelChannel channel)
+{
+  switch (channel)
   {
-    double
-      alpha,
-      beta;
-
-    alpha=pixel->red-pixel->green;
-    beta=pixel->green-pixel->blue;
-    if ((fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
-      return(pixel->red);
-    return((Quantum) (0.299*pixel->red+0.587*pixel->green+0.114*pixel->blue));
+    case RedPixelChannel: return(pixel_info->red);
+    case GreenPixelChannel: return(pixel_info->green);
+    case BluePixelChannel: return(pixel_info->blue);
+    case BlackPixelChannel: return(pixel_info->black);
+    case AlphaPixelChannel: return(pixel_info->alpha);
+    case IndexPixelChannel: return(pixel_info->index);
+    default: return(0.0);
   }
-#endif
 }
 
-static inline Quantum GetPixelY(const Image *image,const Quantum *pixel)
+static inline double GetPixelInfoIntensity(const PixelInfo *restrict pixel_info)
+{
+  double
+    blue,
+    green,
+    red;
+
+  if (pixel_info->colorspace == GRAYColorspace)
+    return(pixel_info->red);
+  if (pixel_info->colorspace != sRGBColorspace)
+    return(0.298839*pixel_info->red+0.586811*pixel_info->green+
+      0.114350*pixel_info->blue);
+  red=InversesRGBCompandor(pixel_info->red);
+  green=InversesRGBCompandor(pixel_info->green);
+  blue=InversesRGBCompandor(pixel_info->blue);
+  return(0.298839*red+0.586811*green+0.114350*blue);
+}
+
+static inline double GetPixelInfoLuminance(const PixelInfo *restrict pixel_info)
+{
+  double
+    blue,
+    green,
+    red;
+
+  if (pixel_info->colorspace == GRAYColorspace)
+    return(pixel_info->red);
+  if (pixel_info->colorspace != sRGBColorspace)
+    return(0.21267*pixel_info->red+0.71516*pixel_info->green+
+      0.07217*pixel_info->blue);
+  red=InversesRGBCompandor(pixel_info->red);
+  green=InversesRGBCompandor(pixel_info->green);
+  blue=InversesRGBCompandor(pixel_info->blue);
+  return(0.21267*red+0.71516*green+0.07217*blue);
+}
+
+static inline double GetPixelIntensity(const Image *restrict image,
+  const Quantum *restrict pixel)
+{
+  double
+    blue,
+    green,
+    red;
+
+  if (image->colorspace == GRAYColorspace)
+    return((double) pixel[image->channel_map[GrayPixelChannel].offset]);
+  if (image->colorspace != sRGBColorspace)
+    return(0.298839*pixel[image->channel_map[RedPixelChannel].offset]+
+      0.586811*pixel[image->channel_map[GreenPixelChannel].offset]+
+      0.114350*pixel[image->channel_map[BluePixelChannel].offset]);
+  red=InversesRGBCompandor((double)
+    pixel[image->channel_map[RedPixelChannel].offset]);
+  green=InversesRGBCompandor((double)
+    pixel[image->channel_map[GreenPixelChannel].offset]);
+  blue=InversesRGBCompandor((double)
+    pixel[image->channel_map[BluePixelChannel].offset]);
+  return(0.298839*red+0.586811*green+0.114350*blue);
+}
+
+static inline Quantum GetPixelL(const Image *restrict image,
+  const Quantum *restrict pixel)
+{
+  return(pixel[image->channel_map[LPixelChannel].offset]);
+}
+
+static inline double GetPixelLuminance(const Image *restrict image,
+  const Quantum *restrict pixel)
+{
+  double
+    blue,
+    green,
+    red;
+
+  if (image->colorspace == GRAYColorspace)
+    return((double) pixel[image->channel_map[GrayPixelChannel].offset]);
+  if (image->colorspace != sRGBColorspace)
+    return(0.298839*pixel[image->channel_map[RedPixelChannel].offset]+
+      0.586811*pixel[image->channel_map[GreenPixelChannel].offset]+
+      0.114350*pixel[image->channel_map[BluePixelChannel].offset]);
+  red=InversesRGBCompandor((double)
+    pixel[image->channel_map[RedPixelChannel].offset]);
+  green=InversesRGBCompandor((double)
+    pixel[image->channel_map[GreenPixelChannel].offset]);
+  blue=InversesRGBCompandor((double)
+    pixel[image->channel_map[BluePixelChannel].offset]);
+  return(0.21267*red+0.71516*green+0.07217*blue);
+}
+
+static inline Quantum GetPixelMagenta(const Image *restrict image,
+  const Quantum *restrict pixel)
+{
+  return(pixel[image->channel_map[MagentaPixelChannel].offset]);
+}
+
+static inline PixelTrait GetPixelMagentaTraits(const Image *restrict image)
+{
+  return(image->channel_map[MagentaPixelChannel].traits);
+}
+
+static inline Quantum GetPixelMask(const Image *restrict image,
+  const Quantum *restrict pixel)
+{
+  if (image->channel_map[MaskPixelChannel].traits == UndefinedPixelTrait)
+    return((Quantum) 0);
+  return(pixel[image->channel_map[MaskPixelChannel].offset]);
+}
+
+static inline PixelTrait GetPixelMaskTraits(const Image *restrict image)
 {
-  return(pixel[image->component_map[YPixelComponent].component]);
+  return(image->channel_map[MaskPixelChannel].traits);
 }
 
-static inline Quantum GetPixelYellow(const Image *image,
-  const Quantum *pixel)
+static inline size_t GetPixelMetaChannels(const Image *restrict image)
 {
-  return(pixel[image->component_map[YellowPixelComponent].component]);
+  return(image->number_meta_channels);
 }
 
-static inline MagickBooleanType IsPixelEquivalent(const Image *image,
-  const Quantum *p,const PixelPacket *q)
+static inline size_t GetPixelMetacontentExtent(const Image *restrict image)
 {
-  if ((GetPixelRed(image,p) == q->red) &&
-      (GetPixelGreen(image,p) == q->green) &&
-      (GetPixelBlue(image,p) == q->blue))
+  return(image->metacontent_extent);
+}
+
+static inline Quantum GetPixelOpacity(const Image *restrict image,
+  const Quantum *restrict pixel)
+{
+  if (image->channel_map[AlphaPixelChannel].traits == UndefinedPixelTrait)
+    return(QuantumRange-OpaqueAlpha);
+  return(QuantumRange-pixel[image->channel_map[AlphaPixelChannel].offset]);
+}
+
+static inline Quantum GetPixelRed(const Image *restrict image,
+  const Quantum *restrict pixel)
+{
+  return(pixel[image->channel_map[RedPixelChannel].offset]);
+}
+
+static inline PixelTrait GetPixelRedTraits(const Image *restrict image)
+{
+  return(image->channel_map[RedPixelChannel].traits);
+}
+
+static inline void GetPixelInfoPixel(const Image *restrict image,
+  const Quantum *restrict pixel,PixelInfo *restrict pixel_info)
+{
+  pixel_info->red=(double)
+    pixel[image->channel_map[RedPixelChannel].offset];
+  pixel_info->green=(double)
+    pixel[image->channel_map[GreenPixelChannel].offset];
+  pixel_info->blue=(double)
+    pixel[image->channel_map[BluePixelChannel].offset];
+  pixel_info->black=0.0;
+  if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
+    pixel_info->black=(double)
+      pixel[image->channel_map[BlackPixelChannel].offset];
+  pixel_info->alpha=OpaqueAlpha;
+  if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
+    pixel_info->alpha=(double)
+      pixel[image->channel_map[AlphaPixelChannel].offset];
+  pixel_info->index=0.0;
+  if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
+    pixel_info->index=(double)
+      pixel[image->channel_map[IndexPixelChannel].offset];
+}
+
+static inline PixelTrait GetPixelTraits(const Image *restrict image,
+  const PixelChannel channel)
+{
+  return(image->channel_map[channel].traits);
+}
+
+static inline Quantum GetPixelY(const Image *restrict image,
+  const Quantum *restrict pixel)
+{
+  return(pixel[image->channel_map[YPixelChannel].offset]);
+}
+
+static inline PixelTrait GetPixelYTraits(const Image *restrict image)
+{
+  return(image->channel_map[YPixelChannel].traits);
+}
+
+static inline Quantum GetPixelYellow(const Image *restrict image,
+  const Quantum *restrict pixel)
+{
+  return(pixel[image->channel_map[YellowPixelChannel].offset]);
+}
+
+static inline PixelTrait GetPixelYellowTraits(const Image *restrict image)
+{
+  return(image->channel_map[YellowPixelChannel].traits);
+}
+
+static inline MagickBooleanType IsPixelEquivalent(const Image *restrict image,
+  const Quantum *restrict p,const PixelInfo *restrict q)
+{
+  double
+    blue,
+    green,
+    red;
+
+  red=(double) p[image->channel_map[RedPixelChannel].offset];
+  green=(double) p[image->channel_map[GreenPixelChannel].offset];
+  blue=(double) p[image->channel_map[BluePixelChannel].offset];
+  if ((fabs(red-q->red) < MagickEpsilon) &&
+      (fabs(green-q->green) < MagickEpsilon) &&
+      (fabs(blue-q->blue) < MagickEpsilon))
     return(MagickTrue);
   return(MagickFalse);
 }
 
-static inline MagickBooleanType IsPixelGray(const Image *image,
-  const Quantum *pixel)
+static inline MagickBooleanType IsPixelGray(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-#if !defined(MAGICKCORE_HDRI_SUPPORT)
-  if ((GetPixelRed(image,pixel) == GetPixelGreen(image,pixel)) &&
-      (GetPixelGreen(image,pixel) == GetPixelBlue(image,pixel)))
+  double
+    blue,
+    green,
+    red;
+
+  red=(double) pixel[image->channel_map[RedPixelChannel].offset];
+  green=(double) pixel[image->channel_map[GreenPixelChannel].offset];
+  blue=(double) pixel[image->channel_map[BluePixelChannel].offset];
+  if ((fabs(red-green) < MagickEpsilon) && (fabs(green-blue) < MagickEpsilon))
     return(MagickTrue);
-#else
-  {
-    double
-      alpha,
-      beta;
-
-    alpha=GetPixelRed(image,pixel)-(double) GetPixelGreen(image,pixel);
-    beta=GetPixelGreen(image,pixel)-(double) GetPixelBlue(image,pixel);
-    if ((fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
-      return(MagickTrue);
-  }
-#endif
   return(MagickFalse);
 }
 
-static inline MagickBooleanType IsPixelInfoEquivalent(const PixelInfo *p,
-  const PixelInfo *q)
+static inline MagickBooleanType IsPixelInfoEquivalent(
+  const PixelInfo *restrict p,const PixelInfo *restrict q)
 {
-#if !defined(MAGICKCORE_HDRI_SUPPORT)
-  if ((p->matte != MagickFalse) && (q->matte == MagickFalse) &&
-      (p->alpha != OpaqueAlpha))
-    return(MagickFalse);
-  if ((q->matte != MagickFalse) && (p->matte == MagickFalse) &&
-      (q->alpha != OpaqueAlpha))
-    return(MagickFalse);
-  if ((p->matte != MagickFalse) && (q->matte != MagickFalse))
-    {
-      if (p->alpha != q->alpha)
-        return(MagickFalse);
-      if (p->alpha == TransparentAlpha)
-        return(MagickTrue);
-    }
-  if (p->red != q->red)
-    return(MagickFalse);
-  if (p->green != q->green)
-    return(MagickFalse);
-  if (p->blue != q->blue)
-    return(MagickFalse);
-  if ((p->colorspace == CMYKColorspace) && (p->black != q->black))
-    return(MagickFalse);
-#else
   if ((p->matte != MagickFalse) && (q->matte == MagickFalse) &&
-      (fabs(p->alpha-OpaqueAlpha) > 0.5))
+      (fabs(p->alpha-OpaqueAlpha) >= MagickEpsilon))
     return(MagickFalse);
   if ((q->matte != MagickFalse) && (p->matte == MagickFalse) &&
-      (fabs(q->alpha-OpaqueAlpha)) > 0.5)
+      (fabs(q->alpha-OpaqueAlpha)) >= MagickEpsilon)
     return(MagickFalse);
   if ((p->matte != MagickFalse) && (q->matte != MagickFalse))
     {
-      if (fabs(p->alpha-q->alpha) > 0.5)
+      if (fabs(p->alpha-q->alpha) >= MagickEpsilon)
         return(MagickFalse);
-      if (fabs(p->alpha-TransparentAlpha) <= 0.5)
+      if (fabs(p->alpha-TransparentAlpha) < MagickEpsilon)
         return(MagickTrue);
     }
-  if (fabs(p->red-q->red) > 0.5)
+  if (fabs(p->red-q->red) >= MagickEpsilon)
     return(MagickFalse);
-  if (fabs(p->green-q->green) > 0.5)
+  if (fabs(p->green-q->green) >= MagickEpsilon)
     return(MagickFalse);
-  if (fabs(p->blue-q->blue) > 0.5)
+  if (fabs(p->blue-q->blue) >= MagickEpsilon)
     return(MagickFalse);
-  if ((p->colorspace == CMYKColorspace) && (fabs(p->black-q->black) > 0.5))
+  if ((p->colorspace == CMYKColorspace) &&
+      (fabs(p->black-q->black) >= MagickEpsilon))
     return(MagickFalse);
-#endif
   return(MagickTrue);
 }
 
-static inline MagickBooleanType IsPixelMonochrome(const Image *image,
-  const Quantum *pixel)
+static inline MagickBooleanType IsPixelMonochrome(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-#if !defined(MAGICKCORE_HDRI_SUPPORT)
-  if (((GetPixelRed(image,pixel) == 0) ||
-      (GetPixelRed(image,pixel) == (Quantum) QuantumRange)) &&
-      (GetPixelRed(image,pixel) == GetPixelGreen(image,pixel)) &&
-      (GetPixelGreen(image,pixel) == GetPixelBlue(image,pixel)))
+  double
+    blue,
+    green,
+    red;
+
+  red=(double) pixel[image->channel_map[RedPixelChannel].offset];
+  if ((fabs(red) >= MagickEpsilon) || (fabs(red-QuantumRange) >= MagickEpsilon))
+    return(MagickFalse);
+  green=(double) pixel[image->channel_map[GreenPixelChannel].offset];
+  blue=(double) pixel[image->channel_map[BluePixelChannel].offset];
+  if ((fabs(red-green) < MagickEpsilon) && (fabs(green-blue) < MagickEpsilon))
     return(MagickTrue);
-#else
-  {
-    double
-      alpha,
-      beta;
-
-    alpha=GetPixelRed(image,pixel)-(double) GetPixelGreen(image,pixel);
-    beta=GetPixelGreen(image,pixel)-(double) GetPixelBlue(image,pixel);
-    if (((fabs(GetPixelRed(image,pixel)) <= MagickEpsilon) ||
-         (fabs(GetPixelRed(image,pixel)-QuantumRange) <= MagickEpsilon)) &&
-        (fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
-      return(MagickTrue);
-    }
-#endif
   return(MagickFalse);
 }
 
-static inline MagickBooleanType IsPixelPacketEquivalent(const PixelPacket *p,
-  const PixelPacket *q)
+static inline MagickBooleanType IsPixelInfoGray(
+  const PixelInfo *restrict pixel_info)
 {
-  if ((p->red == q->red) && (p->green == q->green) && (p->blue == q->blue))
+  if ((pixel_info->colorspace != GRAYColorspace) &&
+      (pixel_info->colorspace != RGBColorspace))
+    return(MagickFalse);
+  if ((fabs(pixel_info->red-pixel_info->green) < MagickEpsilon) &&
+      (fabs(pixel_info->green-pixel_info->blue) < MagickEpsilon))
     return(MagickTrue);
   return(MagickFalse);
 }
 
-static inline MagickBooleanType IsPixelPacketGray(const PixelPacket *pixel)
+static inline MagickBooleanType IsPixelInfoMonochrome(
+  const PixelInfo *restrict pixel_info)
 {
-#if !defined(MAGICKCORE_HDRI_SUPPORT)
-  if ((pixel->red == pixel->green) && (pixel->green == pixel->blue))
+  if ((pixel_info->colorspace != GRAYColorspace) &&
+      (pixel_info->colorspace != RGBColorspace))
+    return(MagickFalse);
+  if ((fabs(pixel_info->red) >= MagickEpsilon) ||
+      (fabs(pixel_info->red-QuantumRange) >= MagickEpsilon))
+    return(MagickFalse);
+  if ((fabs(pixel_info->red-pixel_info->green) < MagickEpsilon) &&
+      (fabs(pixel_info->green-pixel_info->blue) < MagickEpsilon))
     return(MagickTrue);
-#else
-  {
-    double
-      alpha,
-      beta;
-
-    alpha=pixel->red-(double) pixel->green;
-    beta=pixel->green-(double) pixel->blue;
-    if ((fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
-      return(MagickTrue);
-  }
-#endif
   return(MagickFalse);
 }
 
-static inline MagickBooleanType IsPixelPacketMonochrome(
-  const PixelPacket *pixel)
+static inline void SetPixela(const Image *restrict image,
+  const Quantum a,Quantum *restrict pixel)
 {
-#if !defined(MAGICKCORE_HDRI_SUPPORT)
-  if (((pixel->red == 0) || (pixel->red == (Quantum) QuantumRange)) &&
-      (pixel->red == pixel->green) && (pixel->green == pixel->blue))
-    return(MagickTrue);
-#else
-  {
-    double
-      alpha,
-      beta;
-
-    alpha=pixel->red-(double) pixel->green;
-    beta=pixel->green-(double) pixel->blue;
-    if (((fabs(pixel->red) <= MagickEpsilon) ||
-         (fabs(pixel->red-QuantumRange) <= MagickEpsilon)) &&
-        (fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
-      return(MagickTrue);
-    }
-#endif
-  return(MagickFalse);
+  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)
+{
+  if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[AlphaPixelChannel].offset]=alpha;
 }
 
-static inline void SetPacketPixelInfo(const Image *image,
-  const PixelInfo *pixel_info,PixelPacket *packet)
+static inline void SetPixelAlphaTraits(Image *image,const PixelTrait traits)
 {
-  packet->red=ClampToQuantum(pixel_info->red);
-  packet->green=ClampToQuantum(pixel_info->green);
-  packet->blue=ClampToQuantum(pixel_info->blue);
-  packet->alpha=ClampToQuantum(pixel_info->alpha);
-  if (image->colorspace == CMYKColorspace)
-    packet->black=ClampToQuantum(pixel_info->black);
-  if (image->storage_class == PseudoClass)
-    packet->index=ClampToQuantum(pixel_info->index);
+  image->channel_map[AlphaPixelChannel].traits=traits;
 }
 
-static inline void SetPixelAlpha(const Image *image,const Quantum alpha,
-  Quantum *pixel)
+static inline void SetPixelb(const Image *restrict image,
+  const Quantum b,Quantum *restrict pixel)
 {
-  pixel[image->component_map[AlphaPixelComponent].component]=alpha;
+  if (image->channel_map[bPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[bPixelChannel].offset]=b;
 }
 
-static inline void SetPixelBlack(const Image *image,const Quantum black,
-  Quantum *pixel)
+static inline void SetPixelBlack(const Image *restrict image,
+  const Quantum black,Quantum *restrict pixel)
 {
-  pixel[image->component_map[BlackPixelComponent].component]=black;
+  if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[BlackPixelChannel].offset]=black;
 }
 
-static inline void SetPixelBlue(const Image *image,const Quantum blue,
-  Quantum *pixel)
+static inline void SetPixelBlackTraits(Image *image,const PixelTrait traits)
 {
-  pixel[image->component_map[BluePixelComponent].component]=blue;
+  image->channel_map[BlackPixelChannel].traits=traits;
 }
 
-static inline void SetPixelCb(const Image *image,const Quantum cb,
-  Quantum *pixel)
+static inline void SetPixelBlue(const Image *restrict image,const Quantum blue,
+  Quantum *restrict pixel)
 {
-  pixel[image->component_map[CbPixelComponent].component]=cb;
+  pixel[image->channel_map[BluePixelChannel].offset]=blue;
 }
 
-static inline void SetPixelChannels(Image *image,const size_t channels)
+static inline void SetPixelBlueTraits(Image *image,const PixelTrait traits)
 {
-  image->pixel_channels=channels;
+  image->channel_map[BluePixelChannel].traits=traits;
 }
 
-static inline void SetPixelCr(const Image *image,const Quantum cr,
-  Quantum *pixel)
+static inline void SetPixelCb(const Image *restrict image,const Quantum cb,
+  Quantum *restrict pixel)
 {
-  pixel[image->component_map[CrPixelComponent].component]=cr;
+  pixel[image->channel_map[CbPixelChannel].offset]=cb;
 }
 
-static inline void SetPixelCyan(const Image *image,const Quantum cyan,
-  Quantum *pixel)
+static inline void SetPixelCbTraits(Image *image,const PixelTrait traits)
 {
-  pixel[image->component_map[CyanPixelComponent].component]=cyan;
+  image->channel_map[CbPixelChannel].traits=traits;
 }
 
-static inline void SetPixelGray(const Image *image,const Quantum gray,
-  Quantum *pixel)
+static inline void SetPixelChannel(const Image *restrict image,
+  const PixelChannel channel,const Quantum quantum,Quantum *restrict pixel)
 {
-  pixel[image->component_map[GrayPixelComponent].component]=gray;
+  if (image->channel_map[channel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[channel].offset]=quantum;
 }
 
-static inline void SetPixelGreen(const Image *image,const Quantum green,
-  Quantum *pixel)
+static inline void SetPixelChannelMapChannel(const Image *restrict image,
+  const PixelChannel channel,const ssize_t offset)
 {
-  pixel[image->component_map[GreenPixelComponent].component]=green;
+  image->channel_map[offset].channel=channel;
+  image->channel_map[channel].offset=offset;
 }
 
-static inline void SetPixelIndex(const Image *image,const Quantum index,
-  Quantum *pixel)
+static inline void SetPixelChannelMap(const Image *restrict image,
+  const PixelChannel channel,const PixelTrait traits,const ssize_t offset)
 {
-  pixel[image->component_map[IndexPixelComponent].component]=index;
+  image->channel_map[offset].channel=channel;
+  image->channel_map[channel].offset=offset;
+  image->channel_map[channel].traits=traits;
 }
 
-static inline void SetPixelInfo(const Image *image,const Quantum *pixel,
-  PixelInfo *pixel_info)
+static inline void SetPixelChannels(Image *image,const size_t number_channels)
 {
-  pixel_info->red=(MagickRealType) GetPixelRed(image,pixel);
-  pixel_info->green=(MagickRealType) GetPixelGreen(image,pixel);
-  pixel_info->blue=(MagickRealType) GetPixelBlue(image,pixel);
-  pixel_info->alpha=(MagickRealType) GetPixelAlpha(image,pixel);
-  if (image->colorspace == CMYKColorspace)
-    pixel_info->black=(MagickRealType) GetPixelBlack(image,pixel);
-  if (image->storage_class == PseudoClass)
-    pixel_info->index=(MagickRealType) GetPixelIndex(image,pixel);
+  image->number_channels=number_channels;
 }
 
-static inline void SetPixelInfoBias(const Image *image,
-  PixelInfo *pixel_info)
+static inline void SetPixelChannelTraits(Image *image,
+  const PixelChannel channel,const PixelTrait traits)
 {
-  /*
-    Obsoleted by MorphologyApply().
-  */
-  pixel_info->red=image->bias;
-  pixel_info->green=image->bias;
-  pixel_info->blue=image->bias;
-  pixel_info->alpha=image->bias;
-  pixel_info->black=image->bias;
+  image->channel_map[channel].traits=traits;
 }
 
-static inline void SetPixelInfoPacket(const Image *image,
-  const PixelPacket *pixel,PixelInfo *pixel_info)
+static inline void SetPixelChannelMapTraits(Image *image,
+  const PixelChannel channel,const PixelTrait traits)
 {
-  pixel_info->red=(MagickRealType) pixel->red;
-  pixel_info->green=(MagickRealType) pixel->green;
-  pixel_info->blue=(MagickRealType) pixel->blue;
-  pixel_info->alpha=(MagickRealType) pixel->alpha;
-  if (image->colorspace == CMYKColorspace)
-    pixel_info->black=(MagickRealType) pixel->black;
-  if (image->storage_class == PseudoClass)
-    pixel_info->index=(MagickRealType) pixel->index;
+  image->channel_map[channel].traits=traits;
 }
 
-static inline void SetPixelMagenta(const Image *image,const Quantum magenta,
-  Quantum *pixel)
+static inline void SetPixelCr(const Image *restrict image,const Quantum cr,
+  Quantum *restrict pixel)
 {
-  pixel[image->component_map[MagentaPixelComponent].component]=magenta;
+  pixel[image->channel_map[CrPixelChannel].offset]=cr;
+}
+
+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)
+{
+  pixel[image->channel_map[CyanPixelChannel].offset]=cyan;
+}
+
+static inline void SetPixelGray(const Image *restrict image,const Quantum gray,
+  Quantum *restrict pixel)
+{
+  pixel[image->channel_map[GrayPixelChannel].offset]=gray;
+}
+
+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)
+{
+  pixel[image->channel_map[GreenPixelChannel].offset]=green;
+}
+
+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)
+{
+  if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[IndexPixelChannel].offset]=index;
+}
+
+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)
+{
+  pixel[image->channel_map[RedPixelChannel].offset]=
+    ClampToQuantum(pixel_info->red);
+  pixel[image->channel_map[GreenPixelChannel].offset]=
+    ClampToQuantum(pixel_info->green);
+  pixel[image->channel_map[BluePixelChannel].offset]=
+    ClampToQuantum(pixel_info->blue);
+  if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[BlackPixelChannel].offset]=
+      ClampToQuantum(pixel_info->black);
+  if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[AlphaPixelChannel].offset]=pixel_info->matte ==
+      MagickFalse ? OpaqueAlpha : ClampToQuantum(pixel_info->alpha);
+}
+
+static inline void SetPixelL(const Image *restrict image,
+  const Quantum L,Quantum *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)
+{
+  pixel[image->channel_map[MagentaPixelChannel].offset]=magenta;
+}
+
+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)
+{
+  if (image->channel_map[MaskPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[MaskPixelChannel].offset]=mask;
 }
 
 static inline void SetPixelMetacontentExtent(Image *image,const size_t extent)
@@ -441,67 +704,44 @@ static inline void SetPixelMetacontentExtent(Image *image,const size_t extent)
   image->metacontent_extent=extent;
 }
 
-static inline void SetPixelRed(const Image *image,const Quantum red,
-  Quantum *pixel)
+static inline void SetPixelOpacity(const Image *restrict image,
+  const Quantum alpha,Quantum *restrict pixel)
 {
-  pixel[image->component_map[RedPixelComponent].component]=red;
+  if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[AlphaPixelChannel].offset]=QuantumRange-alpha;
 }
 
-static inline void SetPixelPacket(const Image *image,const PixelPacket *packet,
-  Quantum *pixel)
+static inline void SetPixelRed(const Image *restrict image,const Quantum red,
+  Quantum *restrict pixel)
 {
-  SetPixelRed(image,packet->red,pixel);
-  SetPixelGreen(image,packet->green,pixel);
-  SetPixelBlue(image,packet->blue,pixel);
-  SetPixelAlpha(image,packet->alpha,pixel);
+  pixel[image->channel_map[RedPixelChannel].offset]=red;
 }
 
-static inline void SetPixelPixelInfo(const Image *image,
-  const PixelInfo *pixel_info,Quantum *packet)
+static inline void SetPixelRedTraits(Image *image,const PixelTrait traits)
 {
-  SetPixelRed(image,ClampToQuantum(pixel_info->red),packet);
-  SetPixelGreen(image,ClampToQuantum(pixel_info->green),packet);
-  SetPixelBlue(image,ClampToQuantum(pixel_info->blue),packet);
-  SetPixelAlpha(image,ClampToQuantum(pixel_info->alpha),packet);
-  if (image->colorspace == CMYKColorspace)
-    SetPixelBlack(image,ClampToQuantum(pixel_info->black),packet);
+  image->channel_map[RedPixelChannel].traits=traits;
 }
 
-static inline void SetPixelYellow(const Image *image,const Quantum yellow,
-  Quantum *pixel)
+static inline void SetPixelYellow(const Image *restrict image,
+  const Quantum yellow,Quantum *restrict pixel)
 {
-  pixel[image->component_map[YellowPixelComponent].component]=yellow;
+  pixel[image->channel_map[YellowPixelChannel].offset]=yellow;
 }
 
-static inline void SetPixelY(const Image *image,const Quantum y,
-  Quantum *pixel)
+static inline void SetPixelYellowTraits(Image *image,const PixelTrait traits)
 {
-  pixel[image->component_map[YPixelComponent].component]=y;
+  image->channel_map[YellowPixelChannel].traits=traits;
 }
 
-static inline Quantum GetPixelIntensity(const Image *image,
-  const Quantum *pixel)
+static inline void SetPixelY(const Image *restrict image,const Quantum y,
+  Quantum *restrict pixel)
 {
-#if !defined(MAGICKCORE_HDRI_SUPPORT)
-  if ((GetPixelRed(image,pixel) == GetPixelGreen(image,pixel)) &&
-      (GetPixelGreen(image,pixel) == GetPixelBlue(image,pixel)))
-    return(GetPixelRed(image,pixel));
-  return((Quantum) (0.299*GetPixelRed(image,pixel)+0.587*
-    GetPixelGreen(image,pixel)+0.114*GetPixelBlue(image,pixel)+0.5));
-#else
-  {
-    double
-      alpha,
-      beta;
-
-    alpha=GetPixelRed(image,pixel)-(double) GetPixelGreen(image,pixel);
-    beta=GetPixelGreen(image,pixel)-(double) GetPixelBlue(image,pixel);
-    if ((fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
-      return(GetPixelRed(image,pixel));
-    return((Quantum) (0.299*GetPixelRed(image,pixel)+0.587*
-      GetPixelGreen(image,pixel)+0.114*GetPixelBlue(image,pixel)));
-  }
-#endif
+  pixel[image->channel_map[YPixelChannel].offset]=y;
+}
+
+static inline void SetPixelYTraits(Image *image,const PixelTrait traits)
+{
+  image->channel_map[YPixelChannel].traits=traits;
 }
 
 #if defined(__cplusplus) || defined(c_plusplus)