Home | History | Annotate | Download | only in MagickCore
      1 /*
      2   Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization
      3   dedicated to making software imaging solutions freely available.
      4 
      5   You may not use this file except in compliance with the License.  You may
      6   obtain a copy of the License at
      7 
      8     https://imagemagick.org/script/license.php
      9 
     10   Unless required by applicable law or agreed to in writing, software
     11   distributed under the License is distributed on an "AS IS" BASIS,
     12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13   See the License for the specific language governing permissions and
     14   limitations under the License.
     15 
     16   MagickCore pixel accessor methods.
     17 */
     18 #ifndef MAGICKCORE_PIXEL_ACCESSOR_H
     19 #define MAGICKCORE_PIXEL_ACCESSOR_H
     20 
     21 #include <assert.h>
     22 #include "MagickCore/cache.h"
     23 #include "MagickCore/cache-view.h"
     24 #include "MagickCore/color.h"
     25 #include "MagickCore/colorspace.h"
     26 #include "MagickCore/gem.h"
     27 #include "MagickCore/image.h"
     28 #include "MagickCore/memory_.h"
     29 
     30 #if defined(__cplusplus) || defined(c_plusplus)
     31 extern "C" {
     32 #endif
     33 
     34 #undef index
     35 
     36 static inline Quantum ClampPixel(const MagickRealType pixel)
     37 {
     38   if (pixel < 0.0f)
     39     return((Quantum) 0);
     40   if (pixel >= (MagickRealType) QuantumRange)
     41     return((Quantum) QuantumRange);
     42 #if !defined(MAGICKCORE_HDRI_SUPPORT)
     43   return((Quantum) (pixel+0.5f));
     44 #else
     45   return((Quantum) pixel);
     46 #endif
     47 }
     48 
     49 static inline Quantum GetPixela(const Image *magick_restrict image,
     50   const Quantum *magick_restrict pixel)
     51 {
     52   return(pixel[image->channel_map[aPixelChannel].offset]);
     53 }
     54 
     55 static inline Quantum GetPixelAlpha(const Image *magick_restrict image,
     56   const Quantum *magick_restrict pixel)
     57 {
     58   if (image->channel_map[AlphaPixelChannel].traits == UndefinedPixelTrait)
     59     return(OpaqueAlpha);
     60   return(pixel[image->channel_map[AlphaPixelChannel].offset]);
     61 }
     62 
     63 static inline PixelTrait GetPixelAlphaTraits(
     64   const Image *magick_restrict image)
     65 {
     66   return(image->channel_map[AlphaPixelChannel].traits);
     67 }
     68 
     69 static inline Quantum GetPixelb(const Image *magick_restrict image,
     70   const Quantum *magick_restrict pixel)
     71 {
     72   return(pixel[image->channel_map[bPixelChannel].offset]);
     73 }
     74 
     75 static inline Quantum GetPixelBlack(const Image *magick_restrict image,
     76   const Quantum *magick_restrict pixel)
     77 {
     78   if (image->channel_map[BlackPixelChannel].traits == UndefinedPixelTrait)
     79     return((Quantum) 0);
     80   return(pixel[image->channel_map[BlackPixelChannel].offset]);
     81 }
     82 
     83 static inline PixelTrait GetPixelBlackTraits(
     84   const Image *magick_restrict image)
     85 {
     86   return(image->channel_map[BlackPixelChannel].traits);
     87 }
     88 
     89 static inline Quantum GetPixelBlue(const Image *magick_restrict image,
     90   const Quantum *magick_restrict pixel)
     91 {
     92   return(pixel[image->channel_map[BluePixelChannel].offset]);
     93 }
     94 
     95 static inline PixelTrait GetPixelBlueTraits(const Image *magick_restrict image)
     96 {
     97   return(image->channel_map[BluePixelChannel].traits);
     98 }
     99 
    100 static inline Quantum GetPixelCb(const Image *magick_restrict image,
    101   const Quantum *magick_restrict pixel)
    102 {
    103   return(pixel[image->channel_map[CbPixelChannel].offset]);
    104 }
    105 
    106 static inline PixelTrait GetPixelCbTraits(const Image *magick_restrict image)
    107 {
    108   return(image->channel_map[CbPixelChannel].traits);
    109 }
    110 
    111 static inline Quantum GetPixelChannel(const Image *magick_restrict image,
    112   const PixelChannel channel,const Quantum *magick_restrict pixel)
    113 {
    114   if (image->channel_map[channel].traits == UndefinedPixelTrait)
    115     return((Quantum) 0);
    116   return(pixel[image->channel_map[channel].offset]);
    117 }
    118 
    119 static inline PixelChannel GetPixelChannelChannel(
    120   const Image *magick_restrict image,const ssize_t offset)
    121 {
    122   return(image->channel_map[offset].channel);
    123 }
    124 
    125 static inline ssize_t GetPixelChannelOffset(const Image *magick_restrict image,
    126   const PixelChannel channel)
    127 {
    128   return(image->channel_map[channel].offset);
    129 }
    130 
    131 static inline PixelTrait GetPixelChannelTraits(
    132   const Image *magick_restrict image,const PixelChannel channel)
    133 {
    134   return(image->channel_map[channel].traits);
    135 }
    136 
    137 static inline size_t GetPixelChannels(const Image *magick_restrict image)
    138 {
    139   return(image->number_channels);
    140 }
    141 
    142 static inline Quantum GetPixelCompositeMask(const Image *magick_restrict image,
    143   const Quantum *magick_restrict pixel)
    144 {
    145   if (image->channel_map[CompositeMaskPixelChannel].traits == UndefinedPixelTrait)
    146     return((Quantum) QuantumRange);
    147   return(pixel[image->channel_map[CompositeMaskPixelChannel].offset]);
    148 }
    149 
    150 static inline Quantum GetPixelCr(const Image *magick_restrict image,
    151   const Quantum *magick_restrict pixel)
    152 {
    153   return(pixel[image->channel_map[CrPixelChannel].offset]);
    154 }
    155 
    156 static inline PixelTrait GetPixelCrTraits(const Image *magick_restrict image)
    157 {
    158   return(image->channel_map[CrPixelChannel].traits);
    159 }
    160 
    161 static inline Quantum GetPixelCyan(const Image *magick_restrict image,
    162   const Quantum *magick_restrict pixel)
    163 {
    164   return(pixel[image->channel_map[CyanPixelChannel].offset]);
    165 }
    166 
    167 static inline PixelTrait GetPixelCyanTraits(const Image *magick_restrict image)
    168 {
    169   return(image->channel_map[CyanPixelChannel].traits);
    170 }
    171 
    172 static inline Quantum GetPixelGray(const Image *magick_restrict image,
    173   const Quantum *magick_restrict pixel)
    174 {
    175   return(pixel[image->channel_map[GrayPixelChannel].offset]);
    176 }
    177 
    178 static inline PixelTrait GetPixelGrayTraits(const Image *magick_restrict image)
    179 {
    180   return(image->channel_map[GrayPixelChannel].traits);
    181 }
    182 
    183 static inline Quantum GetPixelGreen(const Image *magick_restrict image,
    184   const Quantum *magick_restrict pixel)
    185 {
    186   return(pixel[image->channel_map[GreenPixelChannel].offset]);
    187 }
    188 
    189 static inline PixelTrait GetPixelGreenTraits(
    190   const Image *magick_restrict image)
    191 {
    192   return(image->channel_map[GreenPixelChannel].traits);
    193 }
    194 
    195 static inline Quantum GetPixelIndex(const Image *magick_restrict image,
    196   const Quantum *magick_restrict pixel)
    197 {
    198   if (image->channel_map[IndexPixelChannel].traits == UndefinedPixelTrait)
    199     return((Quantum) 0);
    200   return(pixel[image->channel_map[IndexPixelChannel].offset]);
    201 }
    202 
    203 static inline PixelTrait GetPixelIndexTraits(
    204   const Image *magick_restrict image)
    205 {
    206   return(image->channel_map[IndexPixelChannel].traits);
    207 }
    208 
    209 static inline MagickRealType GetPixelInfoChannel(
    210   const PixelInfo *magick_restrict pixel_info,const PixelChannel channel)
    211 {
    212   switch (channel)
    213   {
    214     case RedPixelChannel: return(pixel_info->red);
    215     case GreenPixelChannel: return(pixel_info->green);
    216     case BluePixelChannel: return(pixel_info->blue);
    217     case BlackPixelChannel: return(pixel_info->black);
    218     case AlphaPixelChannel: return(pixel_info->alpha);
    219     case IndexPixelChannel: return(pixel_info->index);
    220     default: return((MagickRealType) 0.0);
    221   }
    222 }
    223 
    224 static inline double PerceptibleReciprocal(const double x)
    225 {
    226   double
    227     sign;
    228 
    229   /*
    230     Return 1/x where x is perceptible (not unlimited or infinitesimal).
    231   */
    232   sign=x < 0.0 ? -1.0 : 1.0;
    233   if ((sign*x) >= MagickEpsilon)
    234     return(1.0/x);
    235   return(sign/MagickEpsilon);
    236 }
    237 
    238 static inline MagickRealType GetPixelInfoLuma(
    239   const PixelInfo *magick_restrict pixel)
    240 {
    241   MagickRealType
    242     intensity;
    243 
    244   if (pixel->colorspace == sRGBColorspace)
    245     {
    246       intensity=(MagickRealType) (0.212656f*pixel->red+0.715158f*pixel->green+
    247         0.072186f*pixel->blue);
    248       return(intensity);
    249     }
    250   intensity=(MagickRealType) (0.212656f*EncodePixelGamma(pixel->red)+
    251     0.715158f*EncodePixelGamma(pixel->green)+
    252     0.072186f*EncodePixelGamma(pixel->blue));
    253   return(intensity);
    254 }
    255 
    256 static inline MagickRealType GetPixelInfoLuminance(
    257   const PixelInfo *magick_restrict pixel)
    258 {
    259   MagickRealType
    260     intensity;
    261 
    262   if (pixel->colorspace != sRGBColorspace)
    263     {
    264       intensity=(MagickRealType) (0.212656f*pixel->red+0.715158f*pixel->green+
    265         0.072186f*pixel->blue);
    266       return(intensity);
    267     }
    268   intensity=(MagickRealType) (0.212656f*DecodePixelGamma(pixel->red)+
    269     0.715158f*DecodePixelGamma(pixel->green)+
    270     0.072186f*DecodePixelGamma(pixel->blue));
    271   return(intensity);
    272 }
    273 
    274 static inline Quantum GetPixelL(const Image *magick_restrict image,
    275   const Quantum *magick_restrict pixel)
    276 {
    277   return(pixel[image->channel_map[LPixelChannel].offset]);
    278 }
    279 
    280 static inline ssize_t GetPixelLabel(const Image *magick_restrict image,
    281   const Quantum *magick_restrict pixel)
    282 {
    283   return((ssize_t) pixel[image->channel_map[LabelPixelChannel].offset]);
    284 }
    285 
    286 static inline MagickRealType GetPixelLuma(const Image *magick_restrict image,
    287   const Quantum *magick_restrict pixel)
    288 {
    289   MagickRealType
    290     intensity;
    291 
    292   intensity=(MagickRealType) (
    293     0.212656f*pixel[image->channel_map[RedPixelChannel].offset]+
    294     0.715158f*pixel[image->channel_map[GreenPixelChannel].offset]+
    295     0.072186f*pixel[image->channel_map[BluePixelChannel].offset]);
    296   return(intensity);
    297 }
    298 
    299 static inline MagickRealType GetPixelLuminance(
    300   const Image *magick_restrict image,const Quantum *magick_restrict pixel)
    301 {
    302   MagickRealType
    303     intensity;
    304 
    305   if (image->colorspace != sRGBColorspace)
    306     {
    307       intensity=(MagickRealType) (
    308         0.212656f*pixel[image->channel_map[RedPixelChannel].offset]+
    309         0.715158f*pixel[image->channel_map[GreenPixelChannel].offset]+
    310         0.072186f*pixel[image->channel_map[BluePixelChannel].offset]);
    311       return(intensity);
    312     }
    313   intensity=(MagickRealType) (0.212656f*DecodePixelGamma((MagickRealType)
    314     pixel[image->channel_map[RedPixelChannel].offset])+0.715158f*
    315     DecodePixelGamma((MagickRealType)
    316     pixel[image->channel_map[GreenPixelChannel].offset])+0.072186f*
    317     DecodePixelGamma((MagickRealType)
    318     pixel[image->channel_map[BluePixelChannel].offset]));
    319   return(intensity);
    320 }
    321 
    322 static inline Quantum GetPixelMagenta(const Image *magick_restrict image,
    323   const Quantum *magick_restrict pixel)
    324 {
    325   return(pixel[image->channel_map[MagentaPixelChannel].offset]);
    326 }
    327 
    328 static inline PixelTrait GetPixelMagentaTraits(
    329   const Image *magick_restrict image)
    330 {
    331   return(image->channel_map[MagentaPixelChannel].traits);
    332 }
    333 
    334 static inline Quantum GetPixelReadMask(const Image *magick_restrict image,
    335   const Quantum *magick_restrict pixel)
    336 {
    337   if (image->channel_map[ReadMaskPixelChannel].traits == UndefinedPixelTrait)
    338     return((Quantum) QuantumRange);
    339   return(pixel[image->channel_map[ReadMaskPixelChannel].offset]);
    340 }
    341 
    342 static inline Quantum GetPixelWriteMask(const Image *magick_restrict image,
    343   const Quantum *magick_restrict pixel)
    344 {
    345   if (image->channel_map[WriteMaskPixelChannel].traits == UndefinedPixelTrait)
    346     return((Quantum) QuantumRange);
    347   return(pixel[image->channel_map[WriteMaskPixelChannel].offset]);
    348 }
    349 
    350 static inline PixelTrait GetPixelReadMaskTraits(
    351   const Image *magick_restrict image)
    352 {
    353   return(image->channel_map[ReadMaskPixelChannel].traits);
    354 }
    355 
    356 static inline size_t GetPixelMetaChannels(const Image *magick_restrict image)
    357 {
    358   return(image->number_meta_channels);
    359 }
    360 
    361 static inline size_t GetPixelMetacontentExtent(
    362   const Image *magick_restrict image)
    363 {
    364   return(image->metacontent_extent);
    365 }
    366 
    367 static inline Quantum GetPixelOpacity(const Image *magick_restrict image,
    368   const Quantum *magick_restrict pixel)
    369 {
    370   if (image->channel_map[AlphaPixelChannel].traits != BlendPixelTrait)
    371     return(QuantumRange-OpaqueAlpha);
    372   return(QuantumRange-pixel[image->channel_map[AlphaPixelChannel].offset]);
    373 }
    374 
    375 static inline Quantum GetPixelRed(const Image *magick_restrict image,
    376   const Quantum *magick_restrict pixel)
    377 {
    378   return(pixel[image->channel_map[RedPixelChannel].offset]);
    379 }
    380 
    381 static inline PixelTrait GetPixelRedTraits(const Image *magick_restrict image)
    382 {
    383   return(image->channel_map[RedPixelChannel].traits);
    384 }
    385 
    386 static inline void GetPixelInfoPixel(const Image *magick_restrict image,
    387   const Quantum *magick_restrict pixel,PixelInfo *magick_restrict pixel_info)
    388 {
    389   (void) ResetMagickMemory(pixel_info,0,sizeof(*pixel_info));
    390   pixel_info->storage_class=DirectClass;
    391   pixel_info->colorspace=sRGBColorspace;
    392   pixel_info->depth=MAGICKCORE_QUANTUM_DEPTH;
    393   pixel_info->alpha_trait=UndefinedPixelTrait;
    394   pixel_info->alpha=(MagickRealType) OpaqueAlpha;
    395   if (image != (Image *) NULL)
    396     {
    397       pixel_info->storage_class=image->storage_class;
    398       pixel_info->colorspace=image->colorspace;
    399       pixel_info->fuzz=image->fuzz;
    400       pixel_info->depth=image->depth;
    401       pixel_info->alpha_trait=image->alpha_trait;
    402       if (pixel != (Quantum *) NULL)
    403         {
    404           pixel_info->red=(MagickRealType)
    405             pixel[image->channel_map[RedPixelChannel].offset];
    406           pixel_info->green=(MagickRealType)
    407             pixel[image->channel_map[GreenPixelChannel].offset];
    408           pixel_info->blue=(MagickRealType)
    409             pixel[image->channel_map[BluePixelChannel].offset];
    410           if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
    411             pixel_info->black=(MagickRealType)
    412               pixel[image->channel_map[BlackPixelChannel].offset];
    413           if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
    414             {
    415               pixel_info->alpha=(MagickRealType)
    416                 pixel[image->channel_map[AlphaPixelChannel].offset];
    417               pixel_info->alpha_trait=BlendPixelTrait;
    418             }
    419           if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
    420             pixel_info->index=(MagickRealType)
    421           pixel[image->channel_map[IndexPixelChannel].offset];
    422         }
    423     }
    424 }
    425 
    426 static inline PixelTrait GetPixelTraits(const Image *magick_restrict image,
    427   const PixelChannel channel)
    428 {
    429   return(image->channel_map[channel].traits);
    430 }
    431 
    432 static inline Quantum GetPixelY(const Image *magick_restrict image,
    433   const Quantum *magick_restrict pixel)
    434 {
    435   return(pixel[image->channel_map[YPixelChannel].offset]);
    436 }
    437 
    438 static inline PixelTrait GetPixelYTraits(const Image *magick_restrict image)
    439 {
    440   return(image->channel_map[YPixelChannel].traits);
    441 }
    442 
    443 static inline Quantum GetPixelYellow(const Image *magick_restrict image,
    444   const Quantum *magick_restrict pixel)
    445 {
    446   return(pixel[image->channel_map[YellowPixelChannel].offset]);
    447 }
    448 
    449 static inline PixelTrait GetPixelYellowTraits(
    450   const Image *magick_restrict image)
    451 {
    452   return(image->channel_map[YellowPixelChannel].traits);
    453 }
    454 
    455 static inline MagickRealType AbsolutePixelValue(const MagickRealType x)
    456 {
    457   return(x < 0.0f ? -x : x);
    458 }
    459 
    460 static inline MagickBooleanType IsPixelAtDepth(const Quantum pixel,
    461   const QuantumAny range)
    462 {
    463   Quantum
    464     quantum;
    465 
    466   if (range == 0)
    467     return(MagickTrue);
    468 #if !defined(MAGICKCORE_HDRI_SUPPORT)
    469   quantum=(Quantum) (((MagickRealType) QuantumRange*((QuantumAny)
    470     (((MagickRealType) range*pixel)/QuantumRange+0.5)))/range+0.5);
    471 #else
    472   quantum=(Quantum) (((MagickRealType) QuantumRange*((QuantumAny)
    473     (((MagickRealType) range*pixel)/QuantumRange+0.5)))/range);
    474 #endif
    475   return(pixel == quantum ? MagickTrue : MagickFalse);
    476 }
    477 
    478 static inline MagickBooleanType IsPixelEquivalent(
    479   const Image *magick_restrict image,const Quantum *magick_restrict p,
    480   const PixelInfo *magick_restrict q)
    481 {
    482   MagickRealType
    483     alpha,
    484     beta,
    485     color;
    486 
    487   color=(MagickRealType) p[image->channel_map[AlphaPixelChannel].offset];
    488   alpha=image->alpha_trait == UndefinedPixelTrait ? (MagickRealType)
    489     OpaqueAlpha : color;
    490   beta=q->alpha_trait == UndefinedPixelTrait ? (MagickRealType) OpaqueAlpha :
    491     q->alpha;
    492   if (AbsolutePixelValue(alpha-beta) >= MagickEpsilon)
    493     return(MagickFalse);
    494   if ((AbsolutePixelValue(alpha-TransparentAlpha) < MagickEpsilon) ||
    495       (AbsolutePixelValue(beta-TransparentAlpha) < MagickEpsilon))
    496     return(MagickTrue);  /* no color component if pixel is transparent */
    497   color=(MagickRealType) p[image->channel_map[RedPixelChannel].offset];
    498   if (AbsolutePixelValue(color-q->red) >= MagickEpsilon)
    499     return(MagickFalse);
    500   color=(MagickRealType) p[image->channel_map[GreenPixelChannel].offset];
    501   if (AbsolutePixelValue(color-q->green) >= MagickEpsilon)
    502     return(MagickFalse);
    503   color=(MagickRealType) p[image->channel_map[BluePixelChannel].offset];
    504   if (AbsolutePixelValue(color-q->blue) >= MagickEpsilon)
    505     return(MagickFalse);
    506   if (image->colorspace == CMYKColorspace)
    507     {
    508       color=(MagickRealType) p[image->channel_map[BlackPixelChannel].offset];
    509       if (AbsolutePixelValue(color-q->black) >= MagickEpsilon)
    510         return(MagickFalse);
    511     }
    512   return(MagickTrue);
    513 }
    514 
    515 static inline MagickBooleanType IsPixelGray(const Image *magick_restrict image,
    516   const Quantum *magick_restrict pixel)
    517 {
    518   MagickRealType
    519     green_blue,
    520     red_green;
    521 
    522   red_green=(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset]-
    523     pixel[image->channel_map[GreenPixelChannel].offset];
    524   green_blue=(MagickRealType)
    525     pixel[image->channel_map[GreenPixelChannel].offset]-
    526     pixel[image->channel_map[BluePixelChannel].offset];
    527   if ((AbsolutePixelValue(red_green) < MagickEpsilon) &&
    528       (AbsolutePixelValue(green_blue) < MagickEpsilon))
    529     return(MagickTrue);
    530   return(MagickFalse);
    531 }
    532 
    533 static inline MagickBooleanType IsPixelInfoEquivalent(
    534   const PixelInfo *magick_restrict p,const PixelInfo *magick_restrict q)
    535 {
    536   MagickRealType
    537     alpha,
    538     beta;
    539 
    540   alpha=p->alpha_trait == UndefinedPixelTrait ? (MagickRealType) OpaqueAlpha :
    541     p->alpha;
    542   beta=q->alpha_trait == UndefinedPixelTrait ? (MagickRealType) OpaqueAlpha :
    543     q->alpha;
    544   if (AbsolutePixelValue(alpha-beta) >= MagickEpsilon)
    545     return(MagickFalse);
    546   if ((AbsolutePixelValue(alpha-TransparentAlpha) < MagickEpsilon) ||
    547       (AbsolutePixelValue(beta-TransparentAlpha) < MagickEpsilon))
    548     return(MagickTrue);  /* no color component if pixel is transparent */
    549   if (AbsolutePixelValue(p->red-q->red) >= MagickEpsilon)
    550     return(MagickFalse);
    551   if (AbsolutePixelValue(p->green-q->green) >= MagickEpsilon)
    552     return(MagickFalse);
    553   if (AbsolutePixelValue(p->blue-q->blue) >= MagickEpsilon)
    554     return(MagickFalse);
    555   if (p->colorspace == CMYKColorspace)
    556     {
    557       if (AbsolutePixelValue(p->black-q->black) >= MagickEpsilon)
    558         return(MagickFalse);
    559     }
    560   return(MagickTrue);
    561 }
    562 
    563 static inline MagickBooleanType IsPixelMonochrome(
    564   const Image *magick_restrict image,const Quantum *magick_restrict pixel)
    565 {
    566   MagickRealType
    567     green_blue,
    568     red,
    569     red_green;
    570 
    571   red=(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset];
    572   if ((AbsolutePixelValue(red) >= MagickEpsilon) &&
    573       (AbsolutePixelValue(red-QuantumRange) >= MagickEpsilon))
    574     return(MagickFalse);
    575   red_green=(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset]-
    576     pixel[image->channel_map[GreenPixelChannel].offset];
    577   green_blue=(MagickRealType)
    578     pixel[image->channel_map[GreenPixelChannel].offset]-
    579     pixel[image->channel_map[BluePixelChannel].offset];
    580   if ((AbsolutePixelValue(red_green) < MagickEpsilon) &&
    581       (AbsolutePixelValue(green_blue) < MagickEpsilon))
    582     return(MagickTrue);
    583   return(MagickFalse);
    584 }
    585 
    586 static inline MagickBooleanType IsPixelInfoGray(
    587   const PixelInfo *magick_restrict pixel)
    588 {
    589   if ((AbsolutePixelValue(pixel->red-pixel->green) < MagickEpsilon) &&
    590       (AbsolutePixelValue(pixel->green-pixel->blue) < MagickEpsilon))
    591     return(MagickTrue);
    592   return(MagickFalse);
    593 }
    594 
    595 static inline MagickBooleanType IsPixelInfoMonochrome(
    596   const PixelInfo *magick_restrict pixel_info)
    597 {
    598   MagickRealType
    599     green_blue,
    600     red_green;
    601 
    602   if ((AbsolutePixelValue(pixel_info->red) >= MagickEpsilon) ||
    603       (AbsolutePixelValue(pixel_info->red-QuantumRange) >= MagickEpsilon))
    604     return(MagickFalse);
    605   red_green=pixel_info->red-pixel_info->green;
    606   green_blue=pixel_info->green-pixel_info->blue;
    607   if ((AbsolutePixelValue(red_green) < MagickEpsilon) &&
    608       (AbsolutePixelValue(green_blue) < MagickEpsilon))
    609     return(MagickTrue);
    610   return(MagickFalse);
    611 }
    612 
    613 static inline void SetPixela(const Image *magick_restrict image,
    614   const Quantum a,Quantum *magick_restrict pixel)
    615 {
    616   if (image->channel_map[aPixelChannel].traits != UndefinedPixelTrait)
    617     pixel[image->channel_map[aPixelChannel].offset]=a;
    618 }
    619 
    620 static inline void SetPixelAlpha(const Image *magick_restrict image,
    621   const Quantum alpha,Quantum *magick_restrict pixel)
    622 {
    623   if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
    624     pixel[image->channel_map[AlphaPixelChannel].offset]=alpha;
    625 }
    626 
    627 static inline void SetPixelAlphaTraits(Image *image,const PixelTrait traits)
    628 {
    629   image->channel_map[AlphaPixelChannel].traits=traits;
    630 }
    631 
    632 static inline void SetPixelb(const Image *magick_restrict image,
    633   const Quantum b,Quantum *magick_restrict pixel)
    634 {
    635   if (image->channel_map[bPixelChannel].traits != UndefinedPixelTrait)
    636     pixel[image->channel_map[bPixelChannel].offset]=b;
    637 }
    638 
    639 static inline void SetPixelBackgoundColor(const Image *magick_restrict image,
    640   Quantum *magick_restrict pixel)
    641 {
    642   ssize_t
    643     i;
    644 
    645   for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
    646     pixel[i]=(Quantum) 0;
    647   pixel[image->channel_map[RedPixelChannel].offset]=
    648     ClampToQuantum(image->background_color.red);
    649   pixel[image->channel_map[GreenPixelChannel].offset]=
    650     ClampToQuantum(image->background_color.green);
    651   pixel[image->channel_map[BluePixelChannel].offset]=
    652     ClampToQuantum(image->background_color.blue);
    653   if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
    654     pixel[image->channel_map[BlackPixelChannel].offset]=
    655       ClampToQuantum(image->background_color.black);
    656   if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
    657     pixel[image->channel_map[AlphaPixelChannel].offset]=
    658       image->background_color.alpha_trait == UndefinedPixelTrait ? OpaqueAlpha :
    659       ClampToQuantum(image->background_color.alpha);
    660 }
    661 
    662 static inline void SetPixelBlack(const Image *magick_restrict image,
    663   const Quantum black,Quantum *magick_restrict pixel)
    664 {
    665   if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
    666     pixel[image->channel_map[BlackPixelChannel].offset]=black;
    667 }
    668 
    669 static inline void SetPixelBlackTraits(Image *image,const PixelTrait traits)
    670 {
    671   image->channel_map[BlackPixelChannel].traits=traits;
    672 }
    673 
    674 static inline void SetPixelBlue(const Image *magick_restrict image,
    675   const Quantum blue,Quantum *magick_restrict pixel)
    676 {
    677   pixel[image->channel_map[BluePixelChannel].offset]=blue;
    678 }
    679 
    680 static inline void SetPixelBlueTraits(Image *image,const PixelTrait traits)
    681 {
    682   image->channel_map[BluePixelChannel].traits=traits;
    683 }
    684 
    685 static inline void SetPixelCb(const Image *magick_restrict image,
    686   const Quantum cb,Quantum *magick_restrict pixel)
    687 {
    688   pixel[image->channel_map[CbPixelChannel].offset]=cb;
    689 }
    690 
    691 static inline void SetPixelCbTraits(Image *image,const PixelTrait traits)
    692 {
    693   image->channel_map[CbPixelChannel].traits=traits;
    694 }
    695 
    696 static inline void SetPixelChannel(const Image *magick_restrict image,
    697   const PixelChannel channel,const Quantum quantum,
    698   Quantum *magick_restrict pixel)
    699 {
    700   if (image->channel_map[channel].traits != UndefinedPixelTrait)
    701     pixel[image->channel_map[channel].offset]=quantum;
    702 }
    703 
    704 static inline void SetPixelChannelAttributes(
    705   const Image *magick_restrict image,const PixelChannel channel,
    706   const PixelTrait traits,const ssize_t offset)
    707 {
    708   assert((ssize_t) channel < MaxPixelChannels);
    709   assert(offset < MaxPixelChannels);
    710   image->channel_map[offset].channel=channel;
    711   image->channel_map[channel].offset=offset;
    712   image->channel_map[channel].traits=traits;
    713 }
    714 
    715 static inline void SetPixelChannelChannel(const Image *magick_restrict image,
    716   const PixelChannel channel,const ssize_t offset)
    717 {
    718   image->channel_map[offset].channel=channel;
    719   image->channel_map[channel].offset=offset;
    720 }
    721 
    722 static inline void SetPixelChannels(Image *image,const size_t number_channels)
    723 {
    724   image->number_channels=number_channels;
    725 }
    726 
    727 static inline void SetPixelChannelTraits(Image *image,
    728   const PixelChannel channel,const PixelTrait traits)
    729 {
    730   image->channel_map[channel].traits=traits;
    731 }
    732 
    733 static inline void SetPixelCompositeMask(const Image *magick_restrict image,
    734   const Quantum mask,Quantum *magick_restrict pixel)
    735 {
    736   if (image->channel_map[CompositeMaskPixelChannel].traits != UndefinedPixelTrait)
    737     pixel[image->channel_map[CompositeMaskPixelChannel].offset]=mask;
    738 }
    739 
    740 static inline void SetPixelCr(const Image *magick_restrict image,
    741   const Quantum cr,Quantum *magick_restrict pixel)
    742 {
    743   pixel[image->channel_map[CrPixelChannel].offset]=cr;
    744 }
    745 
    746 static inline void SetPixelCrTraits(Image *image,const PixelTrait traits)
    747 {
    748   image->channel_map[CrPixelChannel].traits=traits;
    749 }
    750 
    751 static inline void SetPixelCyan(const Image *magick_restrict image,
    752   const Quantum cyan,Quantum *magick_restrict pixel)
    753 {
    754   pixel[image->channel_map[CyanPixelChannel].offset]=cyan;
    755 }
    756 
    757 static inline void SetPixelGray(const Image *magick_restrict image,
    758   const Quantum gray,Quantum *magick_restrict pixel)
    759 {
    760   pixel[image->channel_map[GrayPixelChannel].offset]=gray;
    761 }
    762 
    763 static inline void SetPixelGrayTraits(Image *image,const PixelTrait traits)
    764 {
    765   image->channel_map[GrayPixelChannel].traits=traits;
    766 }
    767 
    768 static inline void SetPixelGreen(const Image *magick_restrict image,
    769   const Quantum green,Quantum *magick_restrict pixel)
    770 {
    771   pixel[image->channel_map[GreenPixelChannel].offset]=green;
    772 }
    773 
    774 static inline void SetPixelGreenTraits(Image *image,const PixelTrait traits)
    775 {
    776   image->channel_map[GreenPixelChannel].traits=traits;
    777 }
    778 
    779 static inline void SetPixelIndex(const Image *magick_restrict image,
    780   const Quantum index,Quantum *magick_restrict pixel)
    781 {
    782   if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
    783     pixel[image->channel_map[IndexPixelChannel].offset]=index;
    784 }
    785 
    786 static inline void SetPixelIndexTraits(Image *image,const PixelTrait traits)
    787 {
    788   image->channel_map[IndexPixelChannel].traits=traits;
    789 }
    790 
    791 static inline void SetPixelViaPixelInfo(const Image *magick_restrict image,
    792   const PixelInfo *magick_restrict pixel_info,Quantum *magick_restrict pixel)
    793 {
    794   pixel[image->channel_map[RedPixelChannel].offset]=
    795     ClampToQuantum(pixel_info->red);
    796   pixel[image->channel_map[GreenPixelChannel].offset]=
    797     ClampToQuantum(pixel_info->green);
    798   pixel[image->channel_map[BluePixelChannel].offset]=
    799     ClampToQuantum(pixel_info->blue);
    800   if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
    801     pixel[image->channel_map[BlackPixelChannel].offset]=
    802       ClampToQuantum(pixel_info->black);
    803   if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
    804     pixel[image->channel_map[AlphaPixelChannel].offset]=
    805       pixel_info->alpha_trait == UndefinedPixelTrait ? OpaqueAlpha :
    806       ClampToQuantum(pixel_info->alpha);
    807 }
    808 
    809 static inline void SetPixelL(const Image *magick_restrict image,const Quantum L,
    810   Quantum *magick_restrict pixel)
    811 {
    812   if (image->channel_map[LPixelChannel].traits != UndefinedPixelTrait)
    813     pixel[image->channel_map[LPixelChannel].offset]=L;
    814 }
    815 
    816 static inline void SetPixelMagenta(const Image *magick_restrict image,
    817   const Quantum magenta,Quantum *magick_restrict pixel)
    818 {
    819   pixel[image->channel_map[MagentaPixelChannel].offset]=magenta;
    820 }
    821 
    822 static inline void SetPixelMagentaTraits(Image *image,const PixelTrait traits)
    823 {
    824   image->channel_map[MagentaPixelChannel].traits=traits;
    825 }
    826 
    827 static inline void SetPixelReadMask(const Image *magick_restrict image,
    828   const Quantum mask,Quantum *magick_restrict pixel)
    829 {
    830   if (image->channel_map[ReadMaskPixelChannel].traits != UndefinedPixelTrait)
    831     pixel[image->channel_map[ReadMaskPixelChannel].offset]=mask;
    832 }
    833 
    834 static inline void SetPixelWriteMask(const Image *magick_restrict image,
    835   const Quantum mask,Quantum *magick_restrict pixel)
    836 {
    837   if (image->channel_map[WriteMaskPixelChannel].traits != UndefinedPixelTrait)
    838     pixel[image->channel_map[WriteMaskPixelChannel].offset]=mask;
    839 }
    840 
    841 static inline void SetPixelMetacontentExtent(Image *image,const size_t extent)
    842 {
    843   image->metacontent_extent=extent;
    844 }
    845 
    846 static inline void SetPixelOpacity(const Image *magick_restrict image,
    847   const Quantum alpha,Quantum *magick_restrict pixel)
    848 {
    849   if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
    850     pixel[image->channel_map[AlphaPixelChannel].offset]=QuantumRange-alpha;
    851 }
    852 
    853 static inline void SetPixelRed(const Image *magick_restrict image,
    854   const Quantum red,Quantum *magick_restrict pixel)
    855 {
    856   pixel[image->channel_map[RedPixelChannel].offset]=red;
    857 }
    858 
    859 static inline void SetPixelRedTraits(Image *image,const PixelTrait traits)
    860 {
    861   image->channel_map[RedPixelChannel].traits=traits;
    862 }
    863 
    864 static inline void SetPixelYellow(const Image *magick_restrict image,
    865   const Quantum yellow,Quantum *magick_restrict pixel)
    866 {
    867   pixel[image->channel_map[YellowPixelChannel].offset]=yellow;
    868 }
    869 
    870 static inline void SetPixelYellowTraits(Image *image,const PixelTrait traits)
    871 {
    872   image->channel_map[YellowPixelChannel].traits=traits;
    873 }
    874 
    875 static inline void SetPixelY(const Image *magick_restrict image,
    876   const Quantum y,Quantum *magick_restrict pixel)
    877 {
    878   pixel[image->channel_map[YPixelChannel].offset]=y;
    879 }
    880 
    881 static inline void SetPixelYTraits(Image *image,const PixelTrait traits)
    882 {
    883   image->channel_map[YPixelChannel].traits=traits;
    884 }
    885 
    886 #if defined(__cplusplus) || defined(c_plusplus)
    887 }
    888 #endif
    889 
    890 #endif
    891