• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2   Copyright 1999-2021 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 
ClampPixel(const MagickRealType pixel)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 
GetPixela(const Image * magick_restrict image,const Quantum * magick_restrict pixel)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 
GetPixelAlpha(const Image * magick_restrict image,const Quantum * magick_restrict pixel)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 
GetPixelAlphaTraits(const Image * magick_restrict image)63 static inline PixelTrait GetPixelAlphaTraits(
64   const Image *magick_restrict image)
65 {
66   return(image->channel_map[AlphaPixelChannel].traits);
67 }
68 
GetPixelb(const Image * magick_restrict image,const Quantum * magick_restrict pixel)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 
GetPixelBlack(const Image * magick_restrict image,const Quantum * magick_restrict pixel)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 
GetPixelBlackTraits(const Image * magick_restrict image)83 static inline PixelTrait GetPixelBlackTraits(
84   const Image *magick_restrict image)
85 {
86   return(image->channel_map[BlackPixelChannel].traits);
87 }
88 
GetPixelBlue(const Image * magick_restrict image,const Quantum * magick_restrict pixel)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 
GetPixelBlueTraits(const Image * magick_restrict image)95 static inline PixelTrait GetPixelBlueTraits(const Image *magick_restrict image)
96 {
97   return(image->channel_map[BluePixelChannel].traits);
98 }
99 
GetPixelCb(const Image * magick_restrict image,const Quantum * magick_restrict pixel)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 
GetPixelCbTraits(const Image * magick_restrict image)106 static inline PixelTrait GetPixelCbTraits(const Image *magick_restrict image)
107 {
108   return(image->channel_map[CbPixelChannel].traits);
109 }
110 
GetPixelChannel(const Image * magick_restrict image,const PixelChannel channel,const Quantum * magick_restrict pixel)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 
GetPixelChannelChannel(const Image * magick_restrict image,const ssize_t offset)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 
GetPixelChannelOffset(const Image * magick_restrict image,const PixelChannel channel)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 
GetPixelChannelTraits(const Image * magick_restrict image,const PixelChannel channel)131 static inline PixelTrait GetPixelChannelTraits(
132   const Image *magick_restrict image,const PixelChannel channel)
133 {
134   return(image->channel_map[channel].traits);
135 }
136 
GetPixelChannels(const Image * magick_restrict image)137 static inline size_t GetPixelChannels(const Image *magick_restrict image)
138 {
139   return(image->number_channels);
140 }
141 
GetPixelCompositeMask(const Image * magick_restrict image,const Quantum * magick_restrict pixel)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 
GetPixelCr(const Image * magick_restrict image,const Quantum * magick_restrict pixel)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 
GetPixelCrTraits(const Image * magick_restrict image)156 static inline PixelTrait GetPixelCrTraits(const Image *magick_restrict image)
157 {
158   return(image->channel_map[CrPixelChannel].traits);
159 }
160 
GetPixelCyan(const Image * magick_restrict image,const Quantum * magick_restrict pixel)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 
GetPixelCyanTraits(const Image * magick_restrict image)167 static inline PixelTrait GetPixelCyanTraits(const Image *magick_restrict image)
168 {
169   return(image->channel_map[CyanPixelChannel].traits);
170 }
171 
GetPixelGray(const Image * magick_restrict image,const Quantum * magick_restrict pixel)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 
GetPixelGrayTraits(const Image * magick_restrict image)178 static inline PixelTrait GetPixelGrayTraits(const Image *magick_restrict image)
179 {
180   return(image->channel_map[GrayPixelChannel].traits);
181 }
182 
GetPixelGreen(const Image * magick_restrict image,const Quantum * magick_restrict pixel)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 
GetPixelGreenTraits(const Image * magick_restrict image)189 static inline PixelTrait GetPixelGreenTraits(
190   const Image *magick_restrict image)
191 {
192   return(image->channel_map[GreenPixelChannel].traits);
193 }
194 
GetPixelIndex(const Image * magick_restrict image,const Quantum * magick_restrict pixel)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 
GetPixelIndexTraits(const Image * magick_restrict image)203 static inline PixelTrait GetPixelIndexTraits(
204   const Image *magick_restrict image)
205 {
206   return(image->channel_map[IndexPixelChannel].traits);
207 }
208 
GetPixelInfoChannel(const PixelInfo * magick_restrict pixel_info,const PixelChannel channel)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:
218     {
219       if (pixel_info->colorspace != CMYKColorspace)
220         return(0.0);
221       return(pixel_info->black);
222     }
223     case AlphaPixelChannel:
224     {
225       if (pixel_info->alpha_trait == UndefinedPixelTrait)
226         return(OpaqueAlpha);
227       return(pixel_info->alpha);
228     }
229     case IndexPixelChannel: return(pixel_info->index);
230     default: return((MagickRealType) 0.0);
231   }
232 }
233 
PerceptibleReciprocal(const double x)234 static inline double PerceptibleReciprocal(const double x)
235 {
236   double
237     sign;
238 
239   /*
240     Return 1/x where x is perceptible (not unlimited or infinitesimal).
241   */
242   sign=x < 0.0 ? -1.0 : 1.0;
243   if ((sign*x) >= MagickEpsilon)
244     return(1.0/x);
245   return(sign/MagickEpsilon);
246 }
247 
GetPixelInfoLuma(const PixelInfo * magick_restrict pixel)248 static inline MagickRealType GetPixelInfoLuma(
249   const PixelInfo *magick_restrict pixel)
250 {
251   MagickRealType
252     intensity;
253 
254   if (pixel->colorspace == sRGBColorspace)
255     {
256       intensity=(MagickRealType) (0.212656f*pixel->red+0.715158f*pixel->green+
257         0.072186f*pixel->blue);
258       return(intensity);
259     }
260   intensity=(MagickRealType) (0.212656f*EncodePixelGamma(pixel->red)+
261     0.715158f*EncodePixelGamma(pixel->green)+
262     0.072186f*EncodePixelGamma(pixel->blue));
263   return(intensity);
264 }
265 
GetPixelInfoLuminance(const PixelInfo * magick_restrict pixel)266 static inline MagickRealType GetPixelInfoLuminance(
267   const PixelInfo *magick_restrict pixel)
268 {
269   MagickRealType
270     intensity;
271 
272   if (pixel->colorspace != sRGBColorspace)
273     {
274       intensity=(MagickRealType) (0.212656f*pixel->red+0.715158f*pixel->green+
275         0.072186f*pixel->blue);
276       return(intensity);
277     }
278   intensity=(MagickRealType) (0.212656f*DecodePixelGamma(pixel->red)+
279     0.715158f*DecodePixelGamma(pixel->green)+
280     0.072186f*DecodePixelGamma(pixel->blue));
281   return(intensity);
282 }
283 
GetPixelL(const Image * magick_restrict image,const Quantum * magick_restrict pixel)284 static inline Quantum GetPixelL(const Image *magick_restrict image,
285   const Quantum *magick_restrict pixel)
286 {
287   return(pixel[image->channel_map[LPixelChannel].offset]);
288 }
289 
GetPixelLabel(const Image * magick_restrict image,const Quantum * magick_restrict pixel)290 static inline ssize_t GetPixelLabel(const Image *magick_restrict image,
291   const Quantum *magick_restrict pixel)
292 {
293   return((ssize_t) pixel[image->channel_map[LabelPixelChannel].offset]);
294 }
295 
GetPixelLuma(const Image * magick_restrict image,const Quantum * magick_restrict pixel)296 static inline MagickRealType GetPixelLuma(const Image *magick_restrict image,
297   const Quantum *magick_restrict pixel)
298 {
299   MagickRealType
300     intensity;
301 
302   intensity=(MagickRealType) (
303     0.212656f*pixel[image->channel_map[RedPixelChannel].offset]+
304     0.715158f*pixel[image->channel_map[GreenPixelChannel].offset]+
305     0.072186f*pixel[image->channel_map[BluePixelChannel].offset]);
306   return(intensity);
307 }
308 
GetPixelLuminance(const Image * magick_restrict image,const Quantum * magick_restrict pixel)309 static inline MagickRealType GetPixelLuminance(
310   const Image *magick_restrict image,const Quantum *magick_restrict pixel)
311 {
312   MagickRealType
313     intensity;
314 
315   if (image->colorspace != sRGBColorspace)
316     {
317       intensity=(MagickRealType) (
318         0.212656f*pixel[image->channel_map[RedPixelChannel].offset]+
319         0.715158f*pixel[image->channel_map[GreenPixelChannel].offset]+
320         0.072186f*pixel[image->channel_map[BluePixelChannel].offset]);
321       return(intensity);
322     }
323   intensity=(MagickRealType) (0.212656f*DecodePixelGamma((MagickRealType)
324     pixel[image->channel_map[RedPixelChannel].offset])+0.715158f*
325     DecodePixelGamma((MagickRealType)
326     pixel[image->channel_map[GreenPixelChannel].offset])+0.072186f*
327     DecodePixelGamma((MagickRealType)
328     pixel[image->channel_map[BluePixelChannel].offset]));
329   return(intensity);
330 }
331 
GetPixelMagenta(const Image * magick_restrict image,const Quantum * magick_restrict pixel)332 static inline Quantum GetPixelMagenta(const Image *magick_restrict image,
333   const Quantum *magick_restrict pixel)
334 {
335   return(pixel[image->channel_map[MagentaPixelChannel].offset]);
336 }
337 
GetPixelMagentaTraits(const Image * magick_restrict image)338 static inline PixelTrait GetPixelMagentaTraits(
339   const Image *magick_restrict image)
340 {
341   return(image->channel_map[MagentaPixelChannel].traits);
342 }
343 
GetPixelReadMask(const Image * magick_restrict image,const Quantum * magick_restrict pixel)344 static inline Quantum GetPixelReadMask(const Image *magick_restrict image,
345   const Quantum *magick_restrict pixel)
346 {
347   if (image->channel_map[ReadMaskPixelChannel].traits == UndefinedPixelTrait)
348     return((Quantum) QuantumRange);
349   return(pixel[image->channel_map[ReadMaskPixelChannel].offset]);
350 }
351 
GetPixelWriteMask(const Image * magick_restrict image,const Quantum * magick_restrict pixel)352 static inline Quantum GetPixelWriteMask(const Image *magick_restrict image,
353   const Quantum *magick_restrict pixel)
354 {
355   if (image->channel_map[WriteMaskPixelChannel].traits == UndefinedPixelTrait)
356     return((Quantum) QuantumRange);
357   return(pixel[image->channel_map[WriteMaskPixelChannel].offset]);
358 }
359 
GetPixelReadMaskTraits(const Image * magick_restrict image)360 static inline PixelTrait GetPixelReadMaskTraits(
361   const Image *magick_restrict image)
362 {
363   return(image->channel_map[ReadMaskPixelChannel].traits);
364 }
365 
GetPixelMetaChannels(const Image * magick_restrict image)366 static inline size_t GetPixelMetaChannels(const Image *magick_restrict image)
367 {
368   return(image->number_meta_channels);
369 }
370 
GetPixelMetacontentExtent(const Image * magick_restrict image)371 static inline size_t GetPixelMetacontentExtent(
372   const Image *magick_restrict image)
373 {
374   return(image->metacontent_extent);
375 }
376 
GetPixelOpacity(const Image * magick_restrict image,const Quantum * magick_restrict pixel)377 static inline Quantum GetPixelOpacity(const Image *magick_restrict image,
378   const Quantum *magick_restrict pixel)
379 {
380   if (image->channel_map[AlphaPixelChannel].traits != BlendPixelTrait)
381     return(QuantumRange-OpaqueAlpha);
382   return(QuantumRange-pixel[image->channel_map[AlphaPixelChannel].offset]);
383 }
384 
GetPixelRed(const Image * magick_restrict image,const Quantum * magick_restrict pixel)385 static inline Quantum GetPixelRed(const Image *magick_restrict image,
386   const Quantum *magick_restrict pixel)
387 {
388   return(pixel[image->channel_map[RedPixelChannel].offset]);
389 }
390 
GetPixelRedTraits(const Image * magick_restrict image)391 static inline PixelTrait GetPixelRedTraits(const Image *magick_restrict image)
392 {
393   return(image->channel_map[RedPixelChannel].traits);
394 }
395 
GetPixelInfoPixel(const Image * magick_restrict image,const Quantum * magick_restrict pixel,PixelInfo * magick_restrict pixel_info)396 static inline void GetPixelInfoPixel(const Image *magick_restrict image,
397   const Quantum *magick_restrict pixel,PixelInfo *magick_restrict pixel_info)
398 {
399   (void) ResetMagickMemory(pixel_info,0,sizeof(*pixel_info));
400   pixel_info->storage_class=DirectClass;
401   pixel_info->colorspace=sRGBColorspace;
402   pixel_info->depth=MAGICKCORE_QUANTUM_DEPTH;
403   pixel_info->alpha_trait=UndefinedPixelTrait;
404   pixel_info->alpha=(MagickRealType) OpaqueAlpha;
405   if (image != (Image *) NULL)
406     {
407       pixel_info->storage_class=image->storage_class;
408       pixel_info->colorspace=image->colorspace;
409       pixel_info->fuzz=image->fuzz;
410       pixel_info->depth=image->depth;
411       pixel_info->alpha_trait=image->alpha_trait;
412       if (pixel != (Quantum *) NULL)
413         {
414           pixel_info->red=(MagickRealType)
415             pixel[image->channel_map[RedPixelChannel].offset];
416           pixel_info->green=(MagickRealType)
417             pixel[image->channel_map[GreenPixelChannel].offset];
418           pixel_info->blue=(MagickRealType)
419             pixel[image->channel_map[BluePixelChannel].offset];
420           if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
421             pixel_info->black=(MagickRealType)
422               pixel[image->channel_map[BlackPixelChannel].offset];
423           if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
424             pixel_info->alpha=(MagickRealType)
425               pixel[image->channel_map[AlphaPixelChannel].offset];
426           if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
427             pixel_info->index=(MagickRealType)
428               pixel[image->channel_map[IndexPixelChannel].offset];
429         }
430     }
431 }
432 
GetPixelTraits(const Image * magick_restrict image,const PixelChannel channel)433 static inline PixelTrait GetPixelTraits(const Image *magick_restrict image,
434   const PixelChannel channel)
435 {
436   return(image->channel_map[channel].traits);
437 }
438 
GetPixelY(const Image * magick_restrict image,const Quantum * magick_restrict pixel)439 static inline Quantum GetPixelY(const Image *magick_restrict image,
440   const Quantum *magick_restrict pixel)
441 {
442   return(pixel[image->channel_map[YPixelChannel].offset]);
443 }
444 
GetPixelYTraits(const Image * magick_restrict image)445 static inline PixelTrait GetPixelYTraits(const Image *magick_restrict image)
446 {
447   return(image->channel_map[YPixelChannel].traits);
448 }
449 
GetPixelYellow(const Image * magick_restrict image,const Quantum * magick_restrict pixel)450 static inline Quantum GetPixelYellow(const Image *magick_restrict image,
451   const Quantum *magick_restrict pixel)
452 {
453   return(pixel[image->channel_map[YellowPixelChannel].offset]);
454 }
455 
GetPixelYellowTraits(const Image * magick_restrict image)456 static inline PixelTrait GetPixelYellowTraits(
457   const Image *magick_restrict image)
458 {
459   return(image->channel_map[YellowPixelChannel].traits);
460 }
461 
AbsolutePixelValue(const MagickRealType x)462 static inline MagickRealType AbsolutePixelValue(const MagickRealType x)
463 {
464   return(x < 0.0f ? -x : x);
465 }
466 
IsPixelAtDepth(const Quantum pixel,const QuantumAny range)467 static inline MagickBooleanType IsPixelAtDepth(const Quantum pixel,
468   const QuantumAny range)
469 {
470   Quantum
471     quantum;
472 
473   if (range == 0)
474     return(MagickTrue);
475 #if !defined(MAGICKCORE_HDRI_SUPPORT)
476   quantum=(Quantum) (((MagickRealType) QuantumRange*((QuantumAny)
477     (((MagickRealType) range*pixel)/QuantumRange+0.5)))/range+0.5);
478 #else
479   quantum=(Quantum) (((MagickRealType) QuantumRange*((QuantumAny)
480     (((MagickRealType) range*pixel)/QuantumRange+0.5)))/range);
481 #endif
482   return(pixel == quantum ? MagickTrue : MagickFalse);
483 }
484 
IsPixelEquivalent(const Image * magick_restrict image,const Quantum * magick_restrict p,const PixelInfo * magick_restrict q)485 static inline MagickBooleanType IsPixelEquivalent(
486   const Image *magick_restrict image,const Quantum *magick_restrict p,
487   const PixelInfo *magick_restrict q)
488 {
489   MagickRealType
490     alpha,
491     beta,
492     color;
493 
494   color=(MagickRealType) p[image->channel_map[AlphaPixelChannel].offset];
495   alpha=image->alpha_trait == UndefinedPixelTrait ? (MagickRealType)
496     OpaqueAlpha : color;
497   beta=q->alpha_trait == UndefinedPixelTrait ? (MagickRealType) OpaqueAlpha :
498     q->alpha;
499   if (AbsolutePixelValue(alpha-beta) >= MagickEpsilon)
500     return(MagickFalse);
501   if ((AbsolutePixelValue(alpha-TransparentAlpha) < MagickEpsilon) ||
502       (AbsolutePixelValue(beta-TransparentAlpha) < MagickEpsilon))
503     return(MagickTrue);  /* no color component if pixel is transparent */
504   color=(MagickRealType) p[image->channel_map[RedPixelChannel].offset];
505   if (AbsolutePixelValue(color-q->red) >= MagickEpsilon)
506     return(MagickFalse);
507   color=(MagickRealType) p[image->channel_map[GreenPixelChannel].offset];
508   if (AbsolutePixelValue(color-q->green) >= MagickEpsilon)
509     return(MagickFalse);
510   color=(MagickRealType) p[image->channel_map[BluePixelChannel].offset];
511   if (AbsolutePixelValue(color-q->blue) >= MagickEpsilon)
512     return(MagickFalse);
513   if (image->colorspace == CMYKColorspace)
514     {
515       color=(MagickRealType) p[image->channel_map[BlackPixelChannel].offset];
516       if (AbsolutePixelValue(color-q->black) >= MagickEpsilon)
517         return(MagickFalse);
518     }
519   return(MagickTrue);
520 }
521 
IsPixelGray(const Image * magick_restrict image,const Quantum * magick_restrict pixel)522 static inline MagickBooleanType IsPixelGray(const Image *magick_restrict image,
523   const Quantum *magick_restrict pixel)
524 {
525   MagickRealType
526     green_blue,
527     red_green;
528 
529   red_green=(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset]-
530     pixel[image->channel_map[GreenPixelChannel].offset];
531   green_blue=(MagickRealType)
532     pixel[image->channel_map[GreenPixelChannel].offset]-
533     pixel[image->channel_map[BluePixelChannel].offset];
534   if ((AbsolutePixelValue(red_green) < MagickEpsilon) &&
535       (AbsolutePixelValue(green_blue) < MagickEpsilon))
536     return(MagickTrue);
537   return(MagickFalse);
538 }
539 
IsPixelInfoEquivalent(const PixelInfo * magick_restrict p,const PixelInfo * magick_restrict q)540 static inline MagickBooleanType IsPixelInfoEquivalent(
541   const PixelInfo *magick_restrict p,const PixelInfo *magick_restrict q)
542 {
543   MagickRealType
544     alpha,
545     beta;
546 
547   alpha=p->alpha_trait == UndefinedPixelTrait ? (MagickRealType) OpaqueAlpha :
548     p->alpha;
549   beta=q->alpha_trait == UndefinedPixelTrait ? (MagickRealType) OpaqueAlpha :
550     q->alpha;
551   if (AbsolutePixelValue(alpha-beta) >= MagickEpsilon)
552     return(MagickFalse);
553   if ((AbsolutePixelValue(alpha-TransparentAlpha) < MagickEpsilon) ||
554       (AbsolutePixelValue(beta-TransparentAlpha) < MagickEpsilon))
555     return(MagickTrue);  /* no color component if pixel is transparent */
556   if (AbsolutePixelValue(p->red-q->red) >= MagickEpsilon)
557     return(MagickFalse);
558   if (AbsolutePixelValue(p->green-q->green) >= MagickEpsilon)
559     return(MagickFalse);
560   if (AbsolutePixelValue(p->blue-q->blue) >= MagickEpsilon)
561     return(MagickFalse);
562   if (p->colorspace == CMYKColorspace)
563     {
564       if (AbsolutePixelValue(p->black-q->black) >= MagickEpsilon)
565         return(MagickFalse);
566     }
567   return(MagickTrue);
568 }
569 
IsPixelMonochrome(const Image * magick_restrict image,const Quantum * magick_restrict pixel)570 static inline MagickBooleanType IsPixelMonochrome(
571   const Image *magick_restrict image,const Quantum *magick_restrict pixel)
572 {
573   MagickRealType
574     green_blue,
575     red,
576     red_green;
577 
578   red=(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset];
579   if ((AbsolutePixelValue(red) >= MagickEpsilon) &&
580       (AbsolutePixelValue(red-QuantumRange) >= MagickEpsilon))
581     return(MagickFalse);
582   red_green=(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset]-
583     pixel[image->channel_map[GreenPixelChannel].offset];
584   green_blue=(MagickRealType)
585     pixel[image->channel_map[GreenPixelChannel].offset]-
586     pixel[image->channel_map[BluePixelChannel].offset];
587   if ((AbsolutePixelValue(red_green) < MagickEpsilon) &&
588       (AbsolutePixelValue(green_blue) < MagickEpsilon))
589     return(MagickTrue);
590   return(MagickFalse);
591 }
592 
IsPixelInfoGray(const PixelInfo * magick_restrict pixel)593 static inline MagickBooleanType IsPixelInfoGray(
594   const PixelInfo *magick_restrict pixel)
595 {
596   if ((AbsolutePixelValue(pixel->red-pixel->green) < MagickEpsilon) &&
597       (AbsolutePixelValue(pixel->green-pixel->blue) < MagickEpsilon))
598     return(MagickTrue);
599   return(MagickFalse);
600 }
601 
IsPixelInfoMonochrome(const PixelInfo * magick_restrict pixel_info)602 static inline MagickBooleanType IsPixelInfoMonochrome(
603   const PixelInfo *magick_restrict pixel_info)
604 {
605   MagickRealType
606     green_blue,
607     red_green;
608 
609   if ((AbsolutePixelValue(pixel_info->red) >= MagickEpsilon) ||
610       (AbsolutePixelValue(pixel_info->red-QuantumRange) >= MagickEpsilon))
611     return(MagickFalse);
612   red_green=pixel_info->red-pixel_info->green;
613   green_blue=pixel_info->green-pixel_info->blue;
614   if ((AbsolutePixelValue(red_green) < MagickEpsilon) &&
615       (AbsolutePixelValue(green_blue) < MagickEpsilon))
616     return(MagickTrue);
617   return(MagickFalse);
618 }
619 
SetPixela(const Image * magick_restrict image,const Quantum a,Quantum * magick_restrict pixel)620 static inline void SetPixela(const Image *magick_restrict image,
621   const Quantum a,Quantum *magick_restrict pixel)
622 {
623   if (image->channel_map[aPixelChannel].traits != UndefinedPixelTrait)
624     pixel[image->channel_map[aPixelChannel].offset]=a;
625 }
626 
SetPixelAlpha(const Image * magick_restrict image,const Quantum alpha,Quantum * magick_restrict pixel)627 static inline void SetPixelAlpha(const Image *magick_restrict image,
628   const Quantum alpha,Quantum *magick_restrict pixel)
629 {
630   if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
631     pixel[image->channel_map[AlphaPixelChannel].offset]=alpha;
632 }
633 
SetPixelAlphaTraits(Image * image,const PixelTrait traits)634 static inline void SetPixelAlphaTraits(Image *image,const PixelTrait traits)
635 {
636   image->channel_map[AlphaPixelChannel].traits=traits;
637 }
638 
SetPixelb(const Image * magick_restrict image,const Quantum b,Quantum * magick_restrict pixel)639 static inline void SetPixelb(const Image *magick_restrict image,
640   const Quantum b,Quantum *magick_restrict pixel)
641 {
642   if (image->channel_map[bPixelChannel].traits != UndefinedPixelTrait)
643     pixel[image->channel_map[bPixelChannel].offset]=b;
644 }
645 
SetPixelBackgoundColor(const Image * magick_restrict image,Quantum * magick_restrict pixel)646 static inline void SetPixelBackgoundColor(const Image *magick_restrict image,
647   Quantum *magick_restrict pixel)
648 {
649   ssize_t
650     i;
651 
652   for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
653     pixel[i]=(Quantum) 0;
654   pixel[image->channel_map[RedPixelChannel].offset]=
655     ClampToQuantum(image->background_color.red);
656   pixel[image->channel_map[GreenPixelChannel].offset]=
657     ClampToQuantum(image->background_color.green);
658   pixel[image->channel_map[BluePixelChannel].offset]=
659     ClampToQuantum(image->background_color.blue);
660   if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
661     pixel[image->channel_map[BlackPixelChannel].offset]=
662       ClampToQuantum(image->background_color.black);
663   if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
664     pixel[image->channel_map[AlphaPixelChannel].offset]=
665       image->background_color.alpha_trait == UndefinedPixelTrait ? OpaqueAlpha :
666       ClampToQuantum(image->background_color.alpha);
667 }
668 
SetPixelBlack(const Image * magick_restrict image,const Quantum black,Quantum * magick_restrict pixel)669 static inline void SetPixelBlack(const Image *magick_restrict image,
670   const Quantum black,Quantum *magick_restrict pixel)
671 {
672   if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
673     pixel[image->channel_map[BlackPixelChannel].offset]=black;
674 }
675 
SetPixelBlackTraits(Image * image,const PixelTrait traits)676 static inline void SetPixelBlackTraits(Image *image,const PixelTrait traits)
677 {
678   image->channel_map[BlackPixelChannel].traits=traits;
679 }
680 
SetPixelBlue(const Image * magick_restrict image,const Quantum blue,Quantum * magick_restrict pixel)681 static inline void SetPixelBlue(const Image *magick_restrict image,
682   const Quantum blue,Quantum *magick_restrict pixel)
683 {
684   pixel[image->channel_map[BluePixelChannel].offset]=blue;
685 }
686 
SetPixelBlueTraits(Image * image,const PixelTrait traits)687 static inline void SetPixelBlueTraits(Image *image,const PixelTrait traits)
688 {
689   image->channel_map[BluePixelChannel].traits=traits;
690 }
691 
SetPixelCb(const Image * magick_restrict image,const Quantum cb,Quantum * magick_restrict pixel)692 static inline void SetPixelCb(const Image *magick_restrict image,
693   const Quantum cb,Quantum *magick_restrict pixel)
694 {
695   pixel[image->channel_map[CbPixelChannel].offset]=cb;
696 }
697 
SetPixelCbTraits(Image * image,const PixelTrait traits)698 static inline void SetPixelCbTraits(Image *image,const PixelTrait traits)
699 {
700   image->channel_map[CbPixelChannel].traits=traits;
701 }
702 
SetPixelChannel(const Image * magick_restrict image,const PixelChannel channel,const Quantum quantum,Quantum * magick_restrict pixel)703 static inline void SetPixelChannel(const Image *magick_restrict image,
704   const PixelChannel channel,const Quantum quantum,
705   Quantum *magick_restrict pixel)
706 {
707   if (image->channel_map[channel].traits != UndefinedPixelTrait)
708     pixel[image->channel_map[channel].offset]=quantum;
709 }
710 
SetPixelChannelAttributes(const Image * magick_restrict image,const PixelChannel channel,const PixelTrait traits,const ssize_t offset)711 static inline void SetPixelChannelAttributes(
712   const Image *magick_restrict image,const PixelChannel channel,
713   const PixelTrait traits,const ssize_t offset)
714 {
715   assert((ssize_t) channel < MaxPixelChannels);
716   assert(offset < MaxPixelChannels);
717   image->channel_map[offset].channel=channel;
718   image->channel_map[channel].offset=offset;
719   image->channel_map[channel].traits=traits;
720 }
721 
SetPixelChannelChannel(const Image * magick_restrict image,const PixelChannel channel,const ssize_t offset)722 static inline void SetPixelChannelChannel(const Image *magick_restrict image,
723   const PixelChannel channel,const ssize_t offset)
724 {
725   image->channel_map[offset].channel=channel;
726   image->channel_map[channel].offset=offset;
727 }
728 
SetPixelChannels(Image * image,const size_t number_channels)729 static inline void SetPixelChannels(Image *image,const size_t number_channels)
730 {
731   image->number_channels=number_channels;
732 }
733 
SetPixelChannelTraits(Image * image,const PixelChannel channel,const PixelTrait traits)734 static inline void SetPixelChannelTraits(Image *image,
735   const PixelChannel channel,const PixelTrait traits)
736 {
737   image->channel_map[channel].traits=traits;
738 }
739 
SetPixelCompositeMask(const Image * magick_restrict image,const Quantum mask,Quantum * magick_restrict pixel)740 static inline void SetPixelCompositeMask(const Image *magick_restrict image,
741   const Quantum mask,Quantum *magick_restrict pixel)
742 {
743   if (image->channel_map[CompositeMaskPixelChannel].traits != UndefinedPixelTrait)
744     pixel[image->channel_map[CompositeMaskPixelChannel].offset]=mask;
745 }
746 
SetPixelCr(const Image * magick_restrict image,const Quantum cr,Quantum * magick_restrict pixel)747 static inline void SetPixelCr(const Image *magick_restrict image,
748   const Quantum cr,Quantum *magick_restrict pixel)
749 {
750   pixel[image->channel_map[CrPixelChannel].offset]=cr;
751 }
752 
SetPixelCrTraits(Image * image,const PixelTrait traits)753 static inline void SetPixelCrTraits(Image *image,const PixelTrait traits)
754 {
755   image->channel_map[CrPixelChannel].traits=traits;
756 }
757 
SetPixelCyan(const Image * magick_restrict image,const Quantum cyan,Quantum * magick_restrict pixel)758 static inline void SetPixelCyan(const Image *magick_restrict image,
759   const Quantum cyan,Quantum *magick_restrict pixel)
760 {
761   pixel[image->channel_map[CyanPixelChannel].offset]=cyan;
762 }
763 
SetPixelGray(const Image * magick_restrict image,const Quantum gray,Quantum * magick_restrict pixel)764 static inline void SetPixelGray(const Image *magick_restrict image,
765   const Quantum gray,Quantum *magick_restrict pixel)
766 {
767   pixel[image->channel_map[GrayPixelChannel].offset]=gray;
768 }
769 
SetPixelGrayTraits(Image * image,const PixelTrait traits)770 static inline void SetPixelGrayTraits(Image *image,const PixelTrait traits)
771 {
772   image->channel_map[GrayPixelChannel].traits=traits;
773 }
774 
SetPixelGreen(const Image * magick_restrict image,const Quantum green,Quantum * magick_restrict pixel)775 static inline void SetPixelGreen(const Image *magick_restrict image,
776   const Quantum green,Quantum *magick_restrict pixel)
777 {
778   pixel[image->channel_map[GreenPixelChannel].offset]=green;
779 }
780 
SetPixelGreenTraits(Image * image,const PixelTrait traits)781 static inline void SetPixelGreenTraits(Image *image,const PixelTrait traits)
782 {
783   image->channel_map[GreenPixelChannel].traits=traits;
784 }
785 
SetPixelIndex(const Image * magick_restrict image,const Quantum index,Quantum * magick_restrict pixel)786 static inline void SetPixelIndex(const Image *magick_restrict image,
787   const Quantum index,Quantum *magick_restrict pixel)
788 {
789   if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
790     pixel[image->channel_map[IndexPixelChannel].offset]=index;
791 }
792 
SetPixelIndexTraits(Image * image,const PixelTrait traits)793 static inline void SetPixelIndexTraits(Image *image,const PixelTrait traits)
794 {
795   image->channel_map[IndexPixelChannel].traits=traits;
796 }
797 
SetPixelViaPixelInfo(const Image * magick_restrict image,const PixelInfo * magick_restrict pixel_info,Quantum * magick_restrict pixel)798 static inline void SetPixelViaPixelInfo(const Image *magick_restrict image,
799   const PixelInfo *magick_restrict pixel_info,Quantum *magick_restrict pixel)
800 {
801   pixel[image->channel_map[RedPixelChannel].offset]=
802     ClampToQuantum(pixel_info->red);
803   pixel[image->channel_map[GreenPixelChannel].offset]=
804     ClampToQuantum(pixel_info->green);
805   pixel[image->channel_map[BluePixelChannel].offset]=
806     ClampToQuantum(pixel_info->blue);
807   if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
808     pixel[image->channel_map[BlackPixelChannel].offset]=
809       ClampToQuantum(pixel_info->black);
810   if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
811     pixel[image->channel_map[AlphaPixelChannel].offset]=
812       pixel_info->alpha_trait == UndefinedPixelTrait ? OpaqueAlpha :
813       ClampToQuantum(pixel_info->alpha);
814 }
815 
SetPixelL(const Image * magick_restrict image,const Quantum L,Quantum * magick_restrict pixel)816 static inline void SetPixelL(const Image *magick_restrict image,const Quantum L,
817   Quantum *magick_restrict pixel)
818 {
819   if (image->channel_map[LPixelChannel].traits != UndefinedPixelTrait)
820     pixel[image->channel_map[LPixelChannel].offset]=L;
821 }
822 
SetPixelMagenta(const Image * magick_restrict image,const Quantum magenta,Quantum * magick_restrict pixel)823 static inline void SetPixelMagenta(const Image *magick_restrict image,
824   const Quantum magenta,Quantum *magick_restrict pixel)
825 {
826   pixel[image->channel_map[MagentaPixelChannel].offset]=magenta;
827 }
828 
SetPixelMagentaTraits(Image * image,const PixelTrait traits)829 static inline void SetPixelMagentaTraits(Image *image,const PixelTrait traits)
830 {
831   image->channel_map[MagentaPixelChannel].traits=traits;
832 }
833 
SetPixelReadMask(const Image * magick_restrict image,const Quantum mask,Quantum * magick_restrict pixel)834 static inline void SetPixelReadMask(const Image *magick_restrict image,
835   const Quantum mask,Quantum *magick_restrict pixel)
836 {
837   if (image->channel_map[ReadMaskPixelChannel].traits != UndefinedPixelTrait)
838     pixel[image->channel_map[ReadMaskPixelChannel].offset]=mask;
839 }
840 
SetPixelWriteMask(const Image * magick_restrict image,const Quantum mask,Quantum * magick_restrict pixel)841 static inline void SetPixelWriteMask(const Image *magick_restrict image,
842   const Quantum mask,Quantum *magick_restrict pixel)
843 {
844   if (image->channel_map[WriteMaskPixelChannel].traits != UndefinedPixelTrait)
845     pixel[image->channel_map[WriteMaskPixelChannel].offset]=mask;
846 }
847 
SetPixelMetacontentExtent(Image * image,const size_t extent)848 static inline void SetPixelMetacontentExtent(Image *image,const size_t extent)
849 {
850   image->metacontent_extent=extent;
851 }
852 
SetPixelOpacity(const Image * magick_restrict image,const Quantum alpha,Quantum * magick_restrict pixel)853 static inline void SetPixelOpacity(const Image *magick_restrict image,
854   const Quantum alpha,Quantum *magick_restrict pixel)
855 {
856   if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
857     pixel[image->channel_map[AlphaPixelChannel].offset]=QuantumRange-alpha;
858 }
859 
SetPixelRed(const Image * magick_restrict image,const Quantum red,Quantum * magick_restrict pixel)860 static inline void SetPixelRed(const Image *magick_restrict image,
861   const Quantum red,Quantum *magick_restrict pixel)
862 {
863   pixel[image->channel_map[RedPixelChannel].offset]=red;
864 }
865 
SetPixelRedTraits(Image * image,const PixelTrait traits)866 static inline void SetPixelRedTraits(Image *image,const PixelTrait traits)
867 {
868   image->channel_map[RedPixelChannel].traits=traits;
869 }
870 
SetPixelYellow(const Image * magick_restrict image,const Quantum yellow,Quantum * magick_restrict pixel)871 static inline void SetPixelYellow(const Image *magick_restrict image,
872   const Quantum yellow,Quantum *magick_restrict pixel)
873 {
874   pixel[image->channel_map[YellowPixelChannel].offset]=yellow;
875 }
876 
SetPixelYellowTraits(Image * image,const PixelTrait traits)877 static inline void SetPixelYellowTraits(Image *image,const PixelTrait traits)
878 {
879   image->channel_map[YellowPixelChannel].traits=traits;
880 }
881 
SetPixelY(const Image * magick_restrict image,const Quantum y,Quantum * magick_restrict pixel)882 static inline void SetPixelY(const Image *magick_restrict image,
883   const Quantum y,Quantum *magick_restrict pixel)
884 {
885   pixel[image->channel_map[YPixelChannel].offset]=y;
886 }
887 
SetPixelYTraits(Image * image,const PixelTrait traits)888 static inline void SetPixelYTraits(Image *image,const PixelTrait traits)
889 {
890   image->channel_map[YPixelChannel].traits=traits;
891 }
892 
893 #if defined(__cplusplus) || defined(c_plusplus)
894 }
895 #endif
896 
897 #endif
898