• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2   Copyright 1999-2020 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             {
425               pixel_info->alpha=(MagickRealType)
426                 pixel[image->channel_map[AlphaPixelChannel].offset];
427               pixel_info->alpha_trait=BlendPixelTrait;
428             }
429           if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
430             pixel_info->index=(MagickRealType)
431           pixel[image->channel_map[IndexPixelChannel].offset];
432         }
433     }
434 }
435 
GetPixelTraits(const Image * magick_restrict image,const PixelChannel channel)436 static inline PixelTrait GetPixelTraits(const Image *magick_restrict image,
437   const PixelChannel channel)
438 {
439   return(image->channel_map[channel].traits);
440 }
441 
GetPixelY(const Image * magick_restrict image,const Quantum * magick_restrict pixel)442 static inline Quantum GetPixelY(const Image *magick_restrict image,
443   const Quantum *magick_restrict pixel)
444 {
445   return(pixel[image->channel_map[YPixelChannel].offset]);
446 }
447 
GetPixelYTraits(const Image * magick_restrict image)448 static inline PixelTrait GetPixelYTraits(const Image *magick_restrict image)
449 {
450   return(image->channel_map[YPixelChannel].traits);
451 }
452 
GetPixelYellow(const Image * magick_restrict image,const Quantum * magick_restrict pixel)453 static inline Quantum GetPixelYellow(const Image *magick_restrict image,
454   const Quantum *magick_restrict pixel)
455 {
456   return(pixel[image->channel_map[YellowPixelChannel].offset]);
457 }
458 
GetPixelYellowTraits(const Image * magick_restrict image)459 static inline PixelTrait GetPixelYellowTraits(
460   const Image *magick_restrict image)
461 {
462   return(image->channel_map[YellowPixelChannel].traits);
463 }
464 
AbsolutePixelValue(const MagickRealType x)465 static inline MagickRealType AbsolutePixelValue(const MagickRealType x)
466 {
467   return(x < 0.0f ? -x : x);
468 }
469 
IsPixelAtDepth(const Quantum pixel,const QuantumAny range)470 static inline MagickBooleanType IsPixelAtDepth(const Quantum pixel,
471   const QuantumAny range)
472 {
473   Quantum
474     quantum;
475 
476   if (range == 0)
477     return(MagickTrue);
478 #if !defined(MAGICKCORE_HDRI_SUPPORT)
479   quantum=(Quantum) (((MagickRealType) QuantumRange*((QuantumAny)
480     (((MagickRealType) range*pixel)/QuantumRange+0.5)))/range+0.5);
481 #else
482   quantum=(Quantum) (((MagickRealType) QuantumRange*((QuantumAny)
483     (((MagickRealType) range*pixel)/QuantumRange+0.5)))/range);
484 #endif
485   return(pixel == quantum ? MagickTrue : MagickFalse);
486 }
487 
IsPixelEquivalent(const Image * magick_restrict image,const Quantum * magick_restrict p,const PixelInfo * magick_restrict q)488 static inline MagickBooleanType IsPixelEquivalent(
489   const Image *magick_restrict image,const Quantum *magick_restrict p,
490   const PixelInfo *magick_restrict q)
491 {
492   MagickRealType
493     alpha,
494     beta,
495     color;
496 
497   color=(MagickRealType) p[image->channel_map[AlphaPixelChannel].offset];
498   alpha=image->alpha_trait == UndefinedPixelTrait ? (MagickRealType)
499     OpaqueAlpha : color;
500   beta=q->alpha_trait == UndefinedPixelTrait ? (MagickRealType) OpaqueAlpha :
501     q->alpha;
502   if (AbsolutePixelValue(alpha-beta) >= MagickEpsilon)
503     return(MagickFalse);
504   if ((AbsolutePixelValue(alpha-TransparentAlpha) < MagickEpsilon) ||
505       (AbsolutePixelValue(beta-TransparentAlpha) < MagickEpsilon))
506     return(MagickTrue);  /* no color component if pixel is transparent */
507   color=(MagickRealType) p[image->channel_map[RedPixelChannel].offset];
508   if (AbsolutePixelValue(color-q->red) >= MagickEpsilon)
509     return(MagickFalse);
510   color=(MagickRealType) p[image->channel_map[GreenPixelChannel].offset];
511   if (AbsolutePixelValue(color-q->green) >= MagickEpsilon)
512     return(MagickFalse);
513   color=(MagickRealType) p[image->channel_map[BluePixelChannel].offset];
514   if (AbsolutePixelValue(color-q->blue) >= MagickEpsilon)
515     return(MagickFalse);
516   if (image->colorspace == CMYKColorspace)
517     {
518       color=(MagickRealType) p[image->channel_map[BlackPixelChannel].offset];
519       if (AbsolutePixelValue(color-q->black) >= MagickEpsilon)
520         return(MagickFalse);
521     }
522   return(MagickTrue);
523 }
524 
IsPixelGray(const Image * magick_restrict image,const Quantum * magick_restrict pixel)525 static inline MagickBooleanType IsPixelGray(const Image *magick_restrict image,
526   const Quantum *magick_restrict pixel)
527 {
528   MagickRealType
529     green_blue,
530     red_green;
531 
532   red_green=(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset]-
533     pixel[image->channel_map[GreenPixelChannel].offset];
534   green_blue=(MagickRealType)
535     pixel[image->channel_map[GreenPixelChannel].offset]-
536     pixel[image->channel_map[BluePixelChannel].offset];
537   if ((AbsolutePixelValue(red_green) < MagickEpsilon) &&
538       (AbsolutePixelValue(green_blue) < MagickEpsilon))
539     return(MagickTrue);
540   return(MagickFalse);
541 }
542 
IsPixelInfoEquivalent(const PixelInfo * magick_restrict p,const PixelInfo * magick_restrict q)543 static inline MagickBooleanType IsPixelInfoEquivalent(
544   const PixelInfo *magick_restrict p,const PixelInfo *magick_restrict q)
545 {
546   MagickRealType
547     alpha,
548     beta;
549 
550   alpha=p->alpha_trait == UndefinedPixelTrait ? (MagickRealType) OpaqueAlpha :
551     p->alpha;
552   beta=q->alpha_trait == UndefinedPixelTrait ? (MagickRealType) OpaqueAlpha :
553     q->alpha;
554   if (AbsolutePixelValue(alpha-beta) >= MagickEpsilon)
555     return(MagickFalse);
556   if ((AbsolutePixelValue(alpha-TransparentAlpha) < MagickEpsilon) ||
557       (AbsolutePixelValue(beta-TransparentAlpha) < MagickEpsilon))
558     return(MagickTrue);  /* no color component if pixel is transparent */
559   if (AbsolutePixelValue(p->red-q->red) >= MagickEpsilon)
560     return(MagickFalse);
561   if (AbsolutePixelValue(p->green-q->green) >= MagickEpsilon)
562     return(MagickFalse);
563   if (AbsolutePixelValue(p->blue-q->blue) >= MagickEpsilon)
564     return(MagickFalse);
565   if (p->colorspace == CMYKColorspace)
566     {
567       if (AbsolutePixelValue(p->black-q->black) >= MagickEpsilon)
568         return(MagickFalse);
569     }
570   return(MagickTrue);
571 }
572 
IsPixelMonochrome(const Image * magick_restrict image,const Quantum * magick_restrict pixel)573 static inline MagickBooleanType IsPixelMonochrome(
574   const Image *magick_restrict image,const Quantum *magick_restrict pixel)
575 {
576   MagickRealType
577     green_blue,
578     red,
579     red_green;
580 
581   red=(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset];
582   if ((AbsolutePixelValue(red) >= MagickEpsilon) &&
583       (AbsolutePixelValue(red-QuantumRange) >= MagickEpsilon))
584     return(MagickFalse);
585   red_green=(MagickRealType) pixel[image->channel_map[RedPixelChannel].offset]-
586     pixel[image->channel_map[GreenPixelChannel].offset];
587   green_blue=(MagickRealType)
588     pixel[image->channel_map[GreenPixelChannel].offset]-
589     pixel[image->channel_map[BluePixelChannel].offset];
590   if ((AbsolutePixelValue(red_green) < MagickEpsilon) &&
591       (AbsolutePixelValue(green_blue) < MagickEpsilon))
592     return(MagickTrue);
593   return(MagickFalse);
594 }
595 
IsPixelInfoGray(const PixelInfo * magick_restrict pixel)596 static inline MagickBooleanType IsPixelInfoGray(
597   const PixelInfo *magick_restrict pixel)
598 {
599   if ((AbsolutePixelValue(pixel->red-pixel->green) < MagickEpsilon) &&
600       (AbsolutePixelValue(pixel->green-pixel->blue) < MagickEpsilon))
601     return(MagickTrue);
602   return(MagickFalse);
603 }
604 
IsPixelInfoMonochrome(const PixelInfo * magick_restrict pixel_info)605 static inline MagickBooleanType IsPixelInfoMonochrome(
606   const PixelInfo *magick_restrict pixel_info)
607 {
608   MagickRealType
609     green_blue,
610     red_green;
611 
612   if ((AbsolutePixelValue(pixel_info->red) >= MagickEpsilon) ||
613       (AbsolutePixelValue(pixel_info->red-QuantumRange) >= MagickEpsilon))
614     return(MagickFalse);
615   red_green=pixel_info->red-pixel_info->green;
616   green_blue=pixel_info->green-pixel_info->blue;
617   if ((AbsolutePixelValue(red_green) < MagickEpsilon) &&
618       (AbsolutePixelValue(green_blue) < MagickEpsilon))
619     return(MagickTrue);
620   return(MagickFalse);
621 }
622 
SetPixela(const Image * magick_restrict image,const Quantum a,Quantum * magick_restrict pixel)623 static inline void SetPixela(const Image *magick_restrict image,
624   const Quantum a,Quantum *magick_restrict pixel)
625 {
626   if (image->channel_map[aPixelChannel].traits != UndefinedPixelTrait)
627     pixel[image->channel_map[aPixelChannel].offset]=a;
628 }
629 
SetPixelAlpha(const Image * magick_restrict image,const Quantum alpha,Quantum * magick_restrict pixel)630 static inline void SetPixelAlpha(const Image *magick_restrict image,
631   const Quantum alpha,Quantum *magick_restrict pixel)
632 {
633   if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
634     pixel[image->channel_map[AlphaPixelChannel].offset]=alpha;
635 }
636 
SetPixelAlphaTraits(Image * image,const PixelTrait traits)637 static inline void SetPixelAlphaTraits(Image *image,const PixelTrait traits)
638 {
639   image->channel_map[AlphaPixelChannel].traits=traits;
640 }
641 
SetPixelb(const Image * magick_restrict image,const Quantum b,Quantum * magick_restrict pixel)642 static inline void SetPixelb(const Image *magick_restrict image,
643   const Quantum b,Quantum *magick_restrict pixel)
644 {
645   if (image->channel_map[bPixelChannel].traits != UndefinedPixelTrait)
646     pixel[image->channel_map[bPixelChannel].offset]=b;
647 }
648 
SetPixelBackgoundColor(const Image * magick_restrict image,Quantum * magick_restrict pixel)649 static inline void SetPixelBackgoundColor(const Image *magick_restrict image,
650   Quantum *magick_restrict pixel)
651 {
652   ssize_t
653     i;
654 
655   for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
656     pixel[i]=(Quantum) 0;
657   pixel[image->channel_map[RedPixelChannel].offset]=
658     ClampToQuantum(image->background_color.red);
659   pixel[image->channel_map[GreenPixelChannel].offset]=
660     ClampToQuantum(image->background_color.green);
661   pixel[image->channel_map[BluePixelChannel].offset]=
662     ClampToQuantum(image->background_color.blue);
663   if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
664     pixel[image->channel_map[BlackPixelChannel].offset]=
665       ClampToQuantum(image->background_color.black);
666   if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
667     pixel[image->channel_map[AlphaPixelChannel].offset]=
668       image->background_color.alpha_trait == UndefinedPixelTrait ? OpaqueAlpha :
669       ClampToQuantum(image->background_color.alpha);
670 }
671 
SetPixelBlack(const Image * magick_restrict image,const Quantum black,Quantum * magick_restrict pixel)672 static inline void SetPixelBlack(const Image *magick_restrict image,
673   const Quantum black,Quantum *magick_restrict pixel)
674 {
675   if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
676     pixel[image->channel_map[BlackPixelChannel].offset]=black;
677 }
678 
SetPixelBlackTraits(Image * image,const PixelTrait traits)679 static inline void SetPixelBlackTraits(Image *image,const PixelTrait traits)
680 {
681   image->channel_map[BlackPixelChannel].traits=traits;
682 }
683 
SetPixelBlue(const Image * magick_restrict image,const Quantum blue,Quantum * magick_restrict pixel)684 static inline void SetPixelBlue(const Image *magick_restrict image,
685   const Quantum blue,Quantum *magick_restrict pixel)
686 {
687   pixel[image->channel_map[BluePixelChannel].offset]=blue;
688 }
689 
SetPixelBlueTraits(Image * image,const PixelTrait traits)690 static inline void SetPixelBlueTraits(Image *image,const PixelTrait traits)
691 {
692   image->channel_map[BluePixelChannel].traits=traits;
693 }
694 
SetPixelCb(const Image * magick_restrict image,const Quantum cb,Quantum * magick_restrict pixel)695 static inline void SetPixelCb(const Image *magick_restrict image,
696   const Quantum cb,Quantum *magick_restrict pixel)
697 {
698   pixel[image->channel_map[CbPixelChannel].offset]=cb;
699 }
700 
SetPixelCbTraits(Image * image,const PixelTrait traits)701 static inline void SetPixelCbTraits(Image *image,const PixelTrait traits)
702 {
703   image->channel_map[CbPixelChannel].traits=traits;
704 }
705 
SetPixelChannel(const Image * magick_restrict image,const PixelChannel channel,const Quantum quantum,Quantum * magick_restrict pixel)706 static inline void SetPixelChannel(const Image *magick_restrict image,
707   const PixelChannel channel,const Quantum quantum,
708   Quantum *magick_restrict pixel)
709 {
710   if (image->channel_map[channel].traits != UndefinedPixelTrait)
711     pixel[image->channel_map[channel].offset]=quantum;
712 }
713 
SetPixelChannelAttributes(const Image * magick_restrict image,const PixelChannel channel,const PixelTrait traits,const ssize_t offset)714 static inline void SetPixelChannelAttributes(
715   const Image *magick_restrict image,const PixelChannel channel,
716   const PixelTrait traits,const ssize_t offset)
717 {
718   assert((ssize_t) channel < MaxPixelChannels);
719   assert(offset < MaxPixelChannels);
720   image->channel_map[offset].channel=channel;
721   image->channel_map[channel].offset=offset;
722   image->channel_map[channel].traits=traits;
723 }
724 
SetPixelChannelChannel(const Image * magick_restrict image,const PixelChannel channel,const ssize_t offset)725 static inline void SetPixelChannelChannel(const Image *magick_restrict image,
726   const PixelChannel channel,const ssize_t offset)
727 {
728   image->channel_map[offset].channel=channel;
729   image->channel_map[channel].offset=offset;
730 }
731 
SetPixelChannels(Image * image,const size_t number_channels)732 static inline void SetPixelChannels(Image *image,const size_t number_channels)
733 {
734   image->number_channels=number_channels;
735 }
736 
SetPixelChannelTraits(Image * image,const PixelChannel channel,const PixelTrait traits)737 static inline void SetPixelChannelTraits(Image *image,
738   const PixelChannel channel,const PixelTrait traits)
739 {
740   image->channel_map[channel].traits=traits;
741 }
742 
SetPixelCompositeMask(const Image * magick_restrict image,const Quantum mask,Quantum * magick_restrict pixel)743 static inline void SetPixelCompositeMask(const Image *magick_restrict image,
744   const Quantum mask,Quantum *magick_restrict pixel)
745 {
746   if (image->channel_map[CompositeMaskPixelChannel].traits != UndefinedPixelTrait)
747     pixel[image->channel_map[CompositeMaskPixelChannel].offset]=mask;
748 }
749 
SetPixelCr(const Image * magick_restrict image,const Quantum cr,Quantum * magick_restrict pixel)750 static inline void SetPixelCr(const Image *magick_restrict image,
751   const Quantum cr,Quantum *magick_restrict pixel)
752 {
753   pixel[image->channel_map[CrPixelChannel].offset]=cr;
754 }
755 
SetPixelCrTraits(Image * image,const PixelTrait traits)756 static inline void SetPixelCrTraits(Image *image,const PixelTrait traits)
757 {
758   image->channel_map[CrPixelChannel].traits=traits;
759 }
760 
SetPixelCyan(const Image * magick_restrict image,const Quantum cyan,Quantum * magick_restrict pixel)761 static inline void SetPixelCyan(const Image *magick_restrict image,
762   const Quantum cyan,Quantum *magick_restrict pixel)
763 {
764   pixel[image->channel_map[CyanPixelChannel].offset]=cyan;
765 }
766 
SetPixelGray(const Image * magick_restrict image,const Quantum gray,Quantum * magick_restrict pixel)767 static inline void SetPixelGray(const Image *magick_restrict image,
768   const Quantum gray,Quantum *magick_restrict pixel)
769 {
770   pixel[image->channel_map[GrayPixelChannel].offset]=gray;
771 }
772 
SetPixelGrayTraits(Image * image,const PixelTrait traits)773 static inline void SetPixelGrayTraits(Image *image,const PixelTrait traits)
774 {
775   image->channel_map[GrayPixelChannel].traits=traits;
776 }
777 
SetPixelGreen(const Image * magick_restrict image,const Quantum green,Quantum * magick_restrict pixel)778 static inline void SetPixelGreen(const Image *magick_restrict image,
779   const Quantum green,Quantum *magick_restrict pixel)
780 {
781   pixel[image->channel_map[GreenPixelChannel].offset]=green;
782 }
783 
SetPixelGreenTraits(Image * image,const PixelTrait traits)784 static inline void SetPixelGreenTraits(Image *image,const PixelTrait traits)
785 {
786   image->channel_map[GreenPixelChannel].traits=traits;
787 }
788 
SetPixelIndex(const Image * magick_restrict image,const Quantum index,Quantum * magick_restrict pixel)789 static inline void SetPixelIndex(const Image *magick_restrict image,
790   const Quantum index,Quantum *magick_restrict pixel)
791 {
792   if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
793     pixel[image->channel_map[IndexPixelChannel].offset]=index;
794 }
795 
SetPixelIndexTraits(Image * image,const PixelTrait traits)796 static inline void SetPixelIndexTraits(Image *image,const PixelTrait traits)
797 {
798   image->channel_map[IndexPixelChannel].traits=traits;
799 }
800 
SetPixelViaPixelInfo(const Image * magick_restrict image,const PixelInfo * magick_restrict pixel_info,Quantum * magick_restrict pixel)801 static inline void SetPixelViaPixelInfo(const Image *magick_restrict image,
802   const PixelInfo *magick_restrict pixel_info,Quantum *magick_restrict pixel)
803 {
804   pixel[image->channel_map[RedPixelChannel].offset]=
805     ClampToQuantum(pixel_info->red);
806   pixel[image->channel_map[GreenPixelChannel].offset]=
807     ClampToQuantum(pixel_info->green);
808   pixel[image->channel_map[BluePixelChannel].offset]=
809     ClampToQuantum(pixel_info->blue);
810   if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
811     pixel[image->channel_map[BlackPixelChannel].offset]=
812       ClampToQuantum(pixel_info->black);
813   if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
814     pixel[image->channel_map[AlphaPixelChannel].offset]=
815       pixel_info->alpha_trait == UndefinedPixelTrait ? OpaqueAlpha :
816       ClampToQuantum(pixel_info->alpha);
817 }
818 
SetPixelL(const Image * magick_restrict image,const Quantum L,Quantum * magick_restrict pixel)819 static inline void SetPixelL(const Image *magick_restrict image,const Quantum L,
820   Quantum *magick_restrict pixel)
821 {
822   if (image->channel_map[LPixelChannel].traits != UndefinedPixelTrait)
823     pixel[image->channel_map[LPixelChannel].offset]=L;
824 }
825 
SetPixelMagenta(const Image * magick_restrict image,const Quantum magenta,Quantum * magick_restrict pixel)826 static inline void SetPixelMagenta(const Image *magick_restrict image,
827   const Quantum magenta,Quantum *magick_restrict pixel)
828 {
829   pixel[image->channel_map[MagentaPixelChannel].offset]=magenta;
830 }
831 
SetPixelMagentaTraits(Image * image,const PixelTrait traits)832 static inline void SetPixelMagentaTraits(Image *image,const PixelTrait traits)
833 {
834   image->channel_map[MagentaPixelChannel].traits=traits;
835 }
836 
SetPixelReadMask(const Image * magick_restrict image,const Quantum mask,Quantum * magick_restrict pixel)837 static inline void SetPixelReadMask(const Image *magick_restrict image,
838   const Quantum mask,Quantum *magick_restrict pixel)
839 {
840   if (image->channel_map[ReadMaskPixelChannel].traits != UndefinedPixelTrait)
841     pixel[image->channel_map[ReadMaskPixelChannel].offset]=mask;
842 }
843 
SetPixelWriteMask(const Image * magick_restrict image,const Quantum mask,Quantum * magick_restrict pixel)844 static inline void SetPixelWriteMask(const Image *magick_restrict image,
845   const Quantum mask,Quantum *magick_restrict pixel)
846 {
847   if (image->channel_map[WriteMaskPixelChannel].traits != UndefinedPixelTrait)
848     pixel[image->channel_map[WriteMaskPixelChannel].offset]=mask;
849 }
850 
SetPixelMetacontentExtent(Image * image,const size_t extent)851 static inline void SetPixelMetacontentExtent(Image *image,const size_t extent)
852 {
853   image->metacontent_extent=extent;
854 }
855 
SetPixelOpacity(const Image * magick_restrict image,const Quantum alpha,Quantum * magick_restrict pixel)856 static inline void SetPixelOpacity(const Image *magick_restrict image,
857   const Quantum alpha,Quantum *magick_restrict pixel)
858 {
859   if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
860     pixel[image->channel_map[AlphaPixelChannel].offset]=QuantumRange-alpha;
861 }
862 
SetPixelRed(const Image * magick_restrict image,const Quantum red,Quantum * magick_restrict pixel)863 static inline void SetPixelRed(const Image *magick_restrict image,
864   const Quantum red,Quantum *magick_restrict pixel)
865 {
866   pixel[image->channel_map[RedPixelChannel].offset]=red;
867 }
868 
SetPixelRedTraits(Image * image,const PixelTrait traits)869 static inline void SetPixelRedTraits(Image *image,const PixelTrait traits)
870 {
871   image->channel_map[RedPixelChannel].traits=traits;
872 }
873 
SetPixelYellow(const Image * magick_restrict image,const Quantum yellow,Quantum * magick_restrict pixel)874 static inline void SetPixelYellow(const Image *magick_restrict image,
875   const Quantum yellow,Quantum *magick_restrict pixel)
876 {
877   pixel[image->channel_map[YellowPixelChannel].offset]=yellow;
878 }
879 
SetPixelYellowTraits(Image * image,const PixelTrait traits)880 static inline void SetPixelYellowTraits(Image *image,const PixelTrait traits)
881 {
882   image->channel_map[YellowPixelChannel].traits=traits;
883 }
884 
SetPixelY(const Image * magick_restrict image,const Quantum y,Quantum * magick_restrict pixel)885 static inline void SetPixelY(const Image *magick_restrict image,
886   const Quantum y,Quantum *magick_restrict pixel)
887 {
888   pixel[image->channel_map[YPixelChannel].offset]=y;
889 }
890 
SetPixelYTraits(Image * image,const PixelTrait traits)891 static inline void SetPixelYTraits(Image *image,const PixelTrait traits)
892 {
893   image->channel_map[YPixelChannel].traits=traits;
894 }
895 
896 #if defined(__cplusplus) || defined(c_plusplus)
897 }
898 #endif
899 
900 #endif
901