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