]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/pixel-accessor.h
Fix CLUT interpolation method
[imagemagick] / MagickCore / pixel-accessor.h
index f04822370f42189b0b7fd35a496e129a3de022ff..78d9bcc31f13c12775602145af4f56100abd878d 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  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.
@@ -23,139 +23,163 @@ extern "C" {
 #endif
 
 #include <math.h>
+#include <MagickCore/cache.h>
 #include <MagickCore/cache-view.h>
 #include <MagickCore/color.h>
 #include <MagickCore/image.h>
 
-static inline Quantum GetPixelAlpha(const Image *image,const Quantum *pixel)
+#undef index
+
+static inline Quantum GetPixelAlpha(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[image->map][AlphaPixelComponent].component]);
+  if (image->channel_map[AlphaPixelChannel].traits == UndefinedPixelTrait)
+    return(OpaqueAlpha);
+  return(pixel[image->channel_map[AlphaPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelAlphaTraits(const Image *image)
+static inline PixelTrait GetPixelAlphaTraits(const Image *restrict image)
 {
-  return(image->component_map[image->map][AlphaPixelComponent].traits);
+  return(image->channel_map[AlphaPixelChannel].traits);
 }
 
-static inline Quantum GetPixelBlack(const Image *image,const Quantum *pixel)
+static inline Quantum GetPixelBlack(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[image->map][BlackPixelComponent].component]);
+  if (image->channel_map[BlackPixelChannel].traits == UndefinedPixelTrait)
+    return(0);
+  return(pixel[image->channel_map[BlackPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelBlackTraits(const Image *image)
+static inline PixelTrait GetPixelBlackTraits(const Image *restrict image)
 {
-  return(image->component_map[image->map][BlackPixelComponent].traits);
+  return(image->channel_map[BlackPixelChannel].traits);
 }
 
-static inline Quantum GetPixelBlue(const Image *image,const Quantum *pixel)
+static inline Quantum GetPixelBlue(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[image->map][BluePixelComponent].component]);
+  return(pixel[image->channel_map[BluePixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelBlueTraits(const Image *image)
+static inline PixelTrait GetPixelBlueTraits(const Image *restrict image)
 {
-  return(image->component_map[image->map][BluePixelComponent].traits);
+  return(image->channel_map[BluePixelChannel].traits);
 }
 
-static inline Quantum GetPixelCb(const Image *image,const Quantum *pixel)
+static inline Quantum GetPixelCb(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[image->map][CbPixelComponent].component]);
+  return(pixel[image->channel_map[CbPixelChannel].offset]);
 }
 
-static inline Quantum GetPixelComponent(const Image *image,
-  const PixelComponent component,const Quantum *pixel)
+static inline PixelTrait GetPixelCbTraits(const Image *restrict image)
 {
-  return(pixel[image->component_map[image->map][component].component]);
+  return(image->channel_map[CbPixelChannel].traits);
 }
 
-static inline PixelTrait GetPixelComponentTraits(const Image *image,
-  const PixelComponent component)
+static inline Quantum GetPixelChannel(const Image *restrict image,
+  const PixelChannel channel,const Quantum *restrict pixel)
 {
-  return(image->component_map[image->map][component].traits);
+  if (image->channel_map[channel].traits == UndefinedPixelTrait)
+    return(0);
+  return(pixel[image->channel_map[channel].offset]);
 }
 
-static inline PixelTrait GetPixelCbTraits(const Image *image)
+static inline PixelChannel GetPixelChannelMapChannel(
+  const Image *restrict image,const ssize_t offset)
 {
-  return(image->component_map[image->map][CbPixelComponent].traits);
+  return(image->channel_map[offset].channel);
 }
 
-static inline Quantum GetPixelComponentMapComponent(const Image *image,
-  const PixelComponent component)
+static inline ssize_t GetPixelChannelMapOffset(const Image *restrict image,
+  const PixelChannel channel)
 {
-  return(image->component_map[image->map][component].component);
+  return(image->channel_map[channel].offset);
 }
 
-static inline PixelTrait GetPixelComponentMapTraits(const Image *image,
-  const PixelComponent component)
+static inline PixelTrait GetPixelChannelMapTraits(const Image *restrict image,
+  const PixelChannel channel)
 {
-  return(image->component_map[image->map][component].traits);
+  return(image->channel_map[channel].traits);
 }
 
-static inline size_t GetPixelComponents(const Image *image)
+static inline size_t GetPixelChannels(const Image *restrict image)
 {
-  return(image->pixel_components);
+  return(image->number_channels);
 }
 
-static inline Quantum GetPixelCr(const Image *image,const Quantum *pixel)
+static inline Quantum GetPixelCr(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[image->map][CrPixelComponent].component]);
+  return(pixel[image->channel_map[CrPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelCrTraits(const Image *image)
+static inline PixelTrait GetPixelCrTraits(const Image *restrict image)
 {
-  return(image->component_map[image->map][CrPixelComponent].traits);
+  return(image->channel_map[CrPixelChannel].traits);
 }
 
-static inline Quantum GetPixelCyan(const Image *image,const Quantum *pixel)
+static inline Quantum GetPixelCyan(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[image->map][CyanPixelComponent].component]);
+  return(pixel[image->channel_map[CyanPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelCyanTraits(const Image *image)
+static inline PixelTrait GetPixelCyanTraits(const Image *restrict image)
 {
-  return(image->component_map[image->map][CyanPixelComponent].traits);
+  return(image->channel_map[CyanPixelChannel].traits);
 }
 
-static inline Quantum GetPixelGray(const Image *image,const Quantum *pixel)
+static inline Quantum GetPixelGray(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[image->map][GrayPixelComponent].component]);
+  return(pixel[image->channel_map[GrayPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelGrayTraits(const Image *image)
+static inline PixelTrait GetPixelGrayTraits(const Image *restrict image)
 {
-  return(image->component_map[image->map][GrayPixelComponent].traits);
+  return(image->channel_map[GrayPixelChannel].traits);
 }
 
-static inline Quantum GetPixelGreen(const Image *image,const Quantum *pixel)
+static inline Quantum GetPixelGreen(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[image->map][GreenPixelComponent].component]);
+  return(pixel[image->channel_map[GreenPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelGreenTraits(const Image *image)
+static inline PixelTrait GetPixelGreenTraits(const Image *restrict image)
 {
-  return(image->component_map[image->map][GreenPixelComponent].traits);
+  return(image->channel_map[GreenPixelChannel].traits);
 }
 
-static inline Quantum GetPixelIndex(const Image *image,const Quantum *pixel)
+static inline Quantum GetPixelIndex(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[image->map][IndexPixelComponent].component]);
+  if (image->channel_map[IndexPixelChannel].traits == UndefinedPixelTrait)
+    return(0);
+  return(pixel[image->channel_map[IndexPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelIndexTraits(const Image *image)
+static inline PixelTrait GetPixelIndexTraits(const Image *restrict image)
 {
-  return(image->component_map[image->map][IndexPixelComponent].traits);
+  return(image->channel_map[IndexPixelChannel].traits);
 }
 
-static inline Quantum GetPixelInfoIntensity(const PixelInfo *pixel_info)
+static inline Quantum GetPixelInfoIntensity(
+  const PixelInfo *restrict pixel_info)
 {
 #if !defined(MAGICKCORE_HDRI_SUPPORT)
-  return((Quantum) (0.299*pixel_info->red+0.587*pixel_info->green+0.114*pixel_info->blue+0.5));
+  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));
+  return((Quantum) (0.299*pixel_info->red+0.587*pixel_info->green+0.114*
+    pixel_info->blue));
 #endif
 }
 
-static inline Quantum GetPixelInfoLuminance(const PixelInfo *pixel_info)
+static inline Quantum GetPixelInfoLuminance(
+  const PixelInfo *restrict pixel_info)
 {
   Quantum
     luminance;
@@ -170,105 +194,170 @@ static inline Quantum GetPixelInfoLuminance(const PixelInfo *pixel_info)
   return((Quantum) luminance);
 }
 
-static inline Quantum GetPixelMagenta(const Image *image,
-  const Quantum *pixel)
+static inline Quantum GetPixelIntensity(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[image->map][MagentaPixelComponent].component]);
+#if !defined(MAGICKCORE_HDRI_SUPPORT)
+  if (image->colorspace == GRAYColorspace)
+    return(pixel[image->channel_map[GrayPixelChannel].offset]);
+  return((Quantum) (0.299*pixel[image->channel_map[RedPixelChannel].offset]+
+    0.587*pixel[image->channel_map[GreenPixelChannel].offset]+0.114*
+    pixel[image->channel_map[BluePixelChannel].offset]+0.5));
+#else
+  {
+    double
+      alpha,
+      beta;
+
+    alpha=pixel[image->channel_map[RedPixelChannel].offset]-(double)
+      pixel[image->channel_map[GreenPixelChannel].offset];
+    beta=pixel[image->channel_map[GreenPixelChannel].offset]-(double)
+      pixel[image->channel_map[BluePixelChannel].offset];
+    if ((fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
+      return(pixel[image->channel_map[RedPixelChannel].offset]);
+    return((Quantum) (0.299*pixel[image->channel_map[RedPixelChannel].offset]+
+      0.587*pixel[image->channel_map[GreenPixelChannel].offset]+0.114*
+      pixel[image->channel_map[BluePixelChannel].offset]));
+  }
+#endif
 }
 
-static inline PixelTrait GetPixelMagentaTraits(const Image *image)
+static inline Quantum GetPixelLuminance(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(image->component_map[image->map][MagentaPixelComponent].traits);
+#if !defined(MAGICKCORE_HDRI_SUPPORT)
+  return((Quantum) (0.21267*pixel[image->channel_map[RedPixelChannel].offset]+
+    0.71516*pixel[image->channel_map[GreenPixelChannel].offset]+0.07217*
+    pixel[image->channel_map[BluePixelChannel].offset]+0.5));
+#else
+  return((Quantum) (0.21267*pixel[image->channel_map[RedPixelChannel].offset]+
+    0.71516*pixel[image->channel_map[GreenPixelChannel].offset]+0.07217*
+    pixel[image->channel_map[BluePixelChannel].offset]));
+#endif
 }
 
-static inline size_t GetPixelMetacontentExtent(const Image *image)
+static inline Quantum GetPixelMagenta(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(image->metacontent_extent);
+  return(pixel[image->channel_map[MagentaPixelChannel].offset]);
 }
 
-static inline Quantum GetPixelRed(const Image *image,const Quantum *pixel)
+static inline PixelTrait GetPixelMagentaTraits(const Image *restrict image)
 {
-  return(pixel[image->component_map[image->map][RedPixelComponent].component]);
+  return(image->channel_map[MagentaPixelChannel].traits);
 }
 
-static inline PixelTrait GetPixelRedTraits(const Image *image)
+static inline Quantum GetPixelMask(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(image->component_map[image->map][RedPixelComponent].traits);
+  if (image->channel_map[MaskPixelChannel].traits == UndefinedPixelTrait)
+    return(0);
+  return(pixel[image->channel_map[MaskPixelChannel].offset]);
 }
 
-static inline void GetPixelPacket(const Image *image,const Quantum *pixel,
-  PixelPacket *packet)
+static inline PixelTrait GetPixelMaskTraits(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[MaskPixelChannel].traits);
 }
 
-static inline Quantum GetPixelPacketIntensity(const PixelPacket *pixel)
+static inline size_t GetPixelMetaChannels(const Image *restrict image)
 {
-#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
-  {
-    double
-      alpha,
-      beta;
+  return(image->number_meta_channels);
+}
 
-    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));
-  }
-#endif
+static inline size_t GetPixelMetacontentExtent(const Image *restrict image)
+{
+  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;
+  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;
+  if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
+    pixel_info->index=(double)
+      pixel[image->channel_map[IndexPixelChannel].offset];
 }
 
-static inline PixelTrait GetPixelTraits(const Image *image,
-  const PixelComponent component)
+static inline PixelTrait GetPixelTraits(const Image *restrict image,
+  const PixelChannel channel)
 {
-  return(image->component_map[image->map][component].traits);
+  return(image->channel_map[channel].traits);
 }
 
-static inline Quantum GetPixelY(const Image *image,const Quantum *pixel)
+static inline Quantum GetPixelY(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[image->map][YPixelComponent].component]);
+  return(pixel[image->channel_map[YPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelYTraits(const Image *image)
+static inline PixelTrait GetPixelYTraits(const Image *restrict image)
 {
-  return(image->component_map[image->map][YPixelComponent].traits);
+  return(image->channel_map[YPixelChannel].traits);
 }
 
-static inline Quantum GetPixelYellow(const Image *image,
-  const Quantum *pixel)
+static inline Quantum GetPixelYellow(const Image *restrict image,
+  const Quantum *restrict pixel)
 {
-  return(pixel[image->component_map[image->map][YellowPixelComponent].component]);
+  return(pixel[image->channel_map[YellowPixelChannel].offset]);
 }
 
-static inline PixelTrait GetPixelYellowTraits(const Image *image)
+static inline PixelTrait GetPixelYellowTraits(const Image *restrict image)
 {
-  return(image->component_map[image->map][YellowPixelComponent].traits);
+  return(image->channel_map[YellowPixelChannel].traits);
 }
 
-static inline MagickBooleanType IsPixelEquivalent(const Image *image,
-  const Quantum *p,const PixelPacket *q)
+static inline MagickBooleanType IsPixelEquivalent(const Image *restrict image,
+  const Quantum *restrict p,const PixelInfo *restrict q)
 {
-  if ((GetPixelRed(image,p) == q->red) &&
-      (GetPixelGreen(image,p) == q->green) &&
-      (GetPixelBlue(image,p) == q->blue))
+  if (((double) p[image->channel_map[RedPixelChannel].offset] == q->red) &&
+      ((double) p[image->channel_map[GreenPixelChannel].offset] == q->green) &&
+      ((double) p[image->channel_map[BluePixelChannel].offset] == q->blue))
     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)))
+  if ((pixel[image->channel_map[RedPixelChannel].offset] ==
+       pixel[image->channel_map[GreenPixelChannel].offset]) &&
+      (pixel[image->channel_map[GreenPixelChannel].offset] ==
+       pixel[image->channel_map[BluePixelChannel].offset]))
     return(MagickTrue);
 #else
   {
@@ -276,8 +365,10 @@ static inline MagickBooleanType IsPixelGray(const Image *image,
       alpha,
       beta;
 
-    alpha=GetPixelRed(image,pixel)-(double) GetPixelGreen(image,pixel);
-    beta=GetPixelGreen(image,pixel)-(double) GetPixelBlue(image,pixel);
+    alpha=pixel[image->channel_map[RedPixelChannel].offset]-(double)
+      pixel[image->channel_map[GreenPixelChannel].offset];
+    beta=pixel[image->channel_map[GreenPixelChannel].offset]-(double)
+      pixel[image->channel_map[BluePixelChannel].offset];
     if ((fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
       return(MagickTrue);
   }
@@ -285,32 +376,9 @@ static inline MagickBooleanType IsPixelGray(const Image *image,
   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))
     return(MagickFalse);
@@ -332,18 +400,19 @@ static inline MagickBooleanType IsPixelInfoEquivalent(const PixelInfo *p,
     return(MagickFalse);
   if ((p->colorspace == CMYKColorspace) && (fabs(p->black-q->black) > 0.5))
     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)))
+  if (((pixel[image->channel_map[RedPixelChannel].offset] == 0) ||
+      (pixel[image->channel_map[RedPixelChannel].offset] == (Quantum) QuantumRange)) &&
+      (pixel[image->channel_map[RedPixelChannel].offset] ==
+       pixel[image->channel_map[GreenPixelChannel].offset]) &&
+      (pixel[image->channel_map[GreenPixelChannel].offset] ==
+       pixel[image->channel_map[BluePixelChannel].offset]))
     return(MagickTrue);
 #else
   {
@@ -351,10 +420,12 @@ static inline MagickBooleanType IsPixelMonochrome(const Image *image,
       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)) &&
+    alpha=pixel[image->channel_map[RedPixelChannel].offset]-(double)
+      pixel[image->channel_map[GreenPixelChannel].offset];
+    beta=pixel[image->channel_map[GreenPixelChannel].offset]-(double)
+      pixel[image->channel_map[BluePixelChannel].offset];
+    if (((fabs(pixel[image->channel_map[RedPixelChannel].offset]) <= MagickEpsilon) ||
+         (fabs(pixel[image->channel_map[RedPixelChannel].offset]-QuantumRange) <= MagickEpsilon)) &&
         (fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
       return(MagickTrue);
     }
@@ -362,18 +433,12 @@ static inline MagickBooleanType IsPixelMonochrome(const Image *image,
   return(MagickFalse);
 }
 
-static inline MagickBooleanType IsPixelPacketEquivalent(const PixelPacket *p,
-  const PixelPacket *q)
-{
-  if ((p->red == q->red) && (p->green == q->green) && (p->blue == q->blue))
-    return(MagickTrue);
-  return(MagickFalse);
-}
-
-static inline MagickBooleanType IsPixelPacketGray(const PixelPacket *pixel)
+static inline MagickBooleanType IsPixelInfoGray(
+  const PixelInfo *restrict pixel_info)
 {
 #if !defined(MAGICKCORE_HDRI_SUPPORT)
-  if ((pixel->red == pixel->green) && (pixel->green == pixel->blue))
+  if ((pixel_info->red == pixel_info->green) &&
+      (pixel_info->green == pixel_info->blue))
     return(MagickTrue);
 #else
   {
@@ -381,8 +446,8 @@ static inline MagickBooleanType IsPixelPacketGray(const PixelPacket *pixel)
       alpha,
       beta;
 
-    alpha=pixel->red-(double) pixel->green;
-    beta=pixel->green-(double) pixel->blue;
+    alpha=pixel_info->red-(double) pixel_info->green;
+    beta=pixel_info->green-(double) pixel_info->blue;
     if ((fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
       return(MagickTrue);
   }
@@ -390,12 +455,13 @@ static inline MagickBooleanType IsPixelPacketGray(const PixelPacket *pixel)
   return(MagickFalse);
 }
 
-static inline MagickBooleanType IsPixelPacketMonochrome(
-  const PixelPacket *pixel)
+static inline MagickBooleanType IsPixelInfoMonochrome(
+  const PixelInfo *restrict pixel_info)
 {
 #if !defined(MAGICKCORE_HDRI_SUPPORT)
-  if (((pixel->red == 0) || (pixel->red == (Quantum) QuantumRange)) &&
-      (pixel->red == pixel->green) && (pixel->green == pixel->blue))
+  if (((pixel_info->red == 0) || (pixel_info->red == (Quantum) QuantumRange)) &&
+      (pixel_info->red == pixel_info->green) &&
+      (pixel_info->green == pixel_info->blue))
     return(MagickTrue);
 #else
   {
@@ -403,10 +469,10 @@ static inline MagickBooleanType IsPixelPacketMonochrome(
       alpha,
       beta;
 
-    alpha=pixel->red-(double) pixel->green;
-    beta=pixel->green-(double) pixel->blue;
-    if (((fabs(pixel->red) <= MagickEpsilon) ||
-         (fabs(pixel->red-QuantumRange) <= MagickEpsilon)) &&
+    alpha=pixel_info->red-(double) pixel_info->green;
+    beta=pixel_info->green-(double) pixel_info->blue;
+    if (((fabs(pixel_info->red) <= MagickEpsilon) ||
+         (fabs(pixel_info->red-QuantumRange) <= MagickEpsilon)) &&
         (fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
       return(MagickTrue);
     }
@@ -414,191 +480,175 @@ static inline MagickBooleanType IsPixelPacketMonochrome(
   return(MagickFalse);
 }
 
-static inline void SetPacketPixelInfo(const Image *image,
-  const PixelInfo *pixel_info,PixelPacket *packet)
+static inline void SetPixelAlpha(const Image *restrict image,
+  const Quantum alpha,Quantum *restrict pixel)
 {
-  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);
-}
-
-static inline void SetPixelAlpha(const Image *image,const Quantum alpha,
-  Quantum *pixel)
-{
-  pixel[image->component_map[image->map][AlphaPixelComponent].component]=alpha;
+  if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[AlphaPixelChannel].offset]=alpha;
 }
 
 static inline void SetPixelAlphaTraits(Image *image,const PixelTrait traits)
 {
-  image->component_map[image->map][AlphaPixelComponent].traits=traits;
+  image->channel_map[AlphaPixelChannel].traits=traits;
 }
 
-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[image->map][BlackPixelComponent].component]=black;
+  if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[BlackPixelChannel].offset]=black;
 }
 
 static inline void SetPixelBlackTraits(Image *image,const PixelTrait traits)
 {
-  image->component_map[image->map][BlackPixelComponent].traits=traits;
+  image->channel_map[BlackPixelChannel].traits=traits;
 }
 
-static inline void SetPixelBlue(const Image *image,const Quantum blue,
-  Quantum *pixel)
+static inline void SetPixelBlue(const Image *restrict image,const Quantum blue,
+  Quantum *restrict pixel)
 {
-  pixel[image->component_map[image->map][BluePixelComponent].component]=blue;
+  pixel[image->channel_map[BluePixelChannel].offset]=blue;
 }
 
 static inline void SetPixelBlueTraits(Image *image,const PixelTrait traits)
 {
-  image->component_map[image->map][BluePixelComponent].traits=traits;
+  image->channel_map[BluePixelChannel].traits=traits;
 }
 
-static inline void SetPixelCb(const Image *image,const Quantum cb,
-  Quantum *pixel)
+static inline void SetPixelCb(const Image *restrict image,const Quantum cb,
+  Quantum *restrict pixel)
 {
-  pixel[image->component_map[image->map][CbPixelComponent].component]=cb;
+  pixel[image->channel_map[CbPixelChannel].offset]=cb;
 }
 
 static inline void SetPixelCbTraits(Image *image,const PixelTrait traits)
 {
-  image->component_map[image->map][CbPixelComponent].traits=traits;
+  image->channel_map[CbPixelChannel].traits=traits;
 }
 
-static inline void SetPixelComponent(const Image *image,
-  const PixelComponent component,const Quantum quantum,Quantum *pixel)
+static inline void SetPixelChannel(const Image *restrict image,
+  const PixelChannel channel,const Quantum quantum,Quantum *restrict pixel)
 {
-  pixel[image->component_map[image->map][component].component]=quantum;
+  if (image->channel_map[channel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[channel].offset]=quantum;
 }
 
-static inline void SetPixelComponentMapComponent(const Image *image,
-  const PixelComponent component,const PixelComponent components)
+static inline void SetPixelChannelMapChannel(const Image *restrict image,
+  const PixelChannel channel,const ssize_t offset)
 {
-  image->component_map[image->map][component].component=components;
+  image->channel_map[offset].channel=channel;
+  image->channel_map[channel].offset=offset;
 }
 
-static inline void SetPixelComponents(Image *image,const size_t channels)
+static inline void SetPixelChannelMap(const Image *restrict image,
+  const PixelChannel channel,const PixelTrait traits,const ssize_t offset)
 {
-  image->pixel_components=channels;
+  image->channel_map[offset].channel=channel;
+  image->channel_map[channel].offset=offset;
+  image->channel_map[channel].traits=traits;
 }
 
-static inline void SetPixelComponentTraits(Image *image,
-  const PixelComponent component,const PixelTrait traits)
+static inline void SetPixelChannels(Image *image,const size_t number_channels)
 {
-  image->component_map[image->map][component].traits=traits;
+  image->number_channels=number_channels;
 }
 
-static inline void SetPixelComponentMapTraits(Image *image,
-  const PixelComponent component,const PixelTrait traits)
+static inline void SetPixelChannelTraits(Image *image,
+  const PixelChannel channel,const PixelTrait traits)
 {
-  image->component_map[image->map][component].traits=traits;
+  image->channel_map[channel].traits=traits;
 }
 
-static inline void SetPixelCr(const Image *image,const Quantum cr,
-  Quantum *pixel)
+static inline void SetPixelChannelMapTraits(Image *image,
+  const PixelChannel channel,const PixelTrait traits)
 {
-  pixel[image->component_map[image->map][CrPixelComponent].component]=cr;
+  image->channel_map[channel].traits=traits;
+}
+
+static inline void SetPixelCr(const Image *restrict image,const Quantum cr,
+  Quantum *restrict pixel)
+{
+  pixel[image->channel_map[CrPixelChannel].offset]=cr;
 }
 
 static inline void SetPixelCrTraits(Image *image,const PixelTrait traits)
 {
-  image->component_map[image->map][CrPixelComponent].traits=traits;
+  image->channel_map[CrPixelChannel].traits=traits;
 }
 
-static inline void SetPixelCyan(const Image *image,const Quantum cyan,
-  Quantum *pixel)
+static inline void SetPixelCyan(const Image *restrict image,const Quantum cyan,
+  Quantum *restrict pixel)
 {
-  pixel[image->component_map[image->map][CyanPixelComponent].component]=cyan;
+  pixel[image->channel_map[CyanPixelChannel].offset]=cyan;
 }
 
-static inline void SetPixelGray(const Image *image,const Quantum gray,
-  Quantum *pixel)
+static inline void SetPixelGray(const Image *restrict image,const Quantum gray,
+  Quantum *restrict pixel)
 {
-  pixel[image->component_map[image->map][GrayPixelComponent].component]=gray;
+  pixel[image->channel_map[GrayPixelChannel].offset]=gray;
 }
 
 static inline void SetPixelGrayTraits(Image *image,const PixelTrait traits)
 {
-  image->component_map[image->map][GrayPixelComponent].traits=traits;
+  image->channel_map[GrayPixelChannel].traits=traits;
 }
 
-static inline void SetPixelGreen(const Image *image,const Quantum green,
-  Quantum *pixel)
+static inline void SetPixelGreen(const Image *restrict image,
+  const Quantum green,Quantum *restrict pixel)
 {
-  pixel[image->component_map[image->map][GreenPixelComponent].component]=green;
+  pixel[image->channel_map[GreenPixelChannel].offset]=green;
 }
 
 static inline void SetPixelGreenTraits(Image *image,const PixelTrait traits)
 {
-  image->component_map[image->map][GreenPixelComponent].traits=traits;
+  image->channel_map[GreenPixelChannel].traits=traits;
 }
 
-static inline void SetPixelIndex(const Image *image,const Quantum index,
-  Quantum *pixel)
+static inline void SetPixelIndex(const Image *restrict image,
+  const Quantum index,Quantum *restrict pixel)
 {
-  pixel[image->component_map[image->map][IndexPixelComponent].component]=index;
+  if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[IndexPixelChannel].offset]=index;
 }
 
 static inline void SetPixelIndexTraits(Image *image,const PixelTrait traits)
 {
-  image->component_map[image->map][IndexPixelComponent].traits=traits;
-}
-
-static inline void SetPixelInfo(const Image *image,const Quantum *pixel,
-  PixelInfo *pixel_info)
-{
-  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->channel_map[IndexPixelChannel].traits=traits;
 }
 
-static inline void SetPixelInfoBias(const Image *image,
-  PixelInfo *pixel_info)
+static inline void SetPixelInfoPixel(const Image *restrict image,
+  const PixelInfo *restrict pixel_info,Quantum *restrict pixel)
 {
-  /*
-    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;
+  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 SetPixelInfoPacket(const Image *image,
-  const PixelPacket *pixel,PixelInfo *pixel_info)
+static inline void SetPixelMagenta(const Image *restrict image,
+  const Quantum magenta,Quantum *restrict pixel)
 {
-  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;
+  pixel[image->channel_map[MagentaPixelChannel].offset]=magenta;
 }
 
-static inline void SetPixelMagenta(const Image *image,const Quantum magenta,
-  Quantum *pixel)
+static inline void SetPixelMagentaTraits(Image *image,const PixelTrait traits)
 {
-  pixel[image->component_map[image->map][MagentaPixelComponent].component]=
-    magenta;
+  image->channel_map[MagentaPixelChannel].traits=traits;
 }
 
-static inline void SetPixelMagentaTraits(Image *image,const PixelTrait traits)
+static inline void SetPixelMask(const Image *restrict image,
+  const Quantum mask,Quantum *restrict pixel)
 {
-  image->component_map[image->map][MagentaPixelComponent].traits=traits;
+  if (image->channel_map[MaskPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[MaskPixelChannel].offset]=mask;
 }
 
 static inline void SetPixelMetacontentExtent(Image *image,const size_t extent)
@@ -606,82 +656,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[image->map][RedPixelComponent].component]=red;
+  if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
+    pixel[image->channel_map[AlphaPixelChannel].offset]=QuantumRange-alpha;
 }
 
-static inline void SetPixelRedTraits(Image *image,const PixelTrait traits)
+static inline void SetPixelRed(const Image *restrict image,const Quantum red,
+  Quantum *restrict pixel)
 {
-  image->component_map[image->map][RedPixelComponent].traits=traits;
+  pixel[image->channel_map[RedPixelChannel].offset]=red;
 }
 
-static inline void SetPixelPacket(const Image *image,const PixelPacket *packet,
-  Quantum *pixel)
-{
-  SetPixelRed(image,packet->red,pixel);
-  SetPixelGreen(image,packet->green,pixel);
-  SetPixelBlue(image,packet->blue,pixel);
-  SetPixelAlpha(image,packet->alpha,pixel);
-}
-
-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[image->map][YellowPixelComponent].component]=
-    yellow;
+  pixel[image->channel_map[YellowPixelChannel].offset]=yellow;
 }
 
 static inline void SetPixelYellowTraits(Image *image,const PixelTrait traits)
 {
-  image->component_map[image->map][YellowPixelComponent].traits=traits;
+  image->channel_map[YellowPixelChannel].traits=traits;
 }
 
-static inline void SetPixelY(const Image *image,const Quantum y,Quantum *pixel)
+static inline void SetPixelY(const Image *restrict image,const Quantum y,
+  Quantum *restrict pixel)
 {
-  pixel[image->component_map[image->map][YPixelComponent].component]=y;
+  pixel[image->channel_map[YPixelChannel].offset]=y;
 }
 
 static inline void SetPixelYTraits(Image *image,const PixelTrait traits)
 {
-  image->component_map[image->map][YPixelComponent].traits=traits;
-}
-
-static inline Quantum GetPixelIntensity(const Image *image,
-  const Quantum *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
+  image->channel_map[YPixelChannel].traits=traits;
 }
 
 #if defined(__cplusplus) || defined(c_plusplus)