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