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