2 Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization
3 dedicated to making software imaging solutions freely available.
5 You may not use this file except in compliance with the License.
6 obtain a copy of the License at
8 http://www.imagemagick.org/script/license.php
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.
16 MagickCore pixel accessor methods.
18 #ifndef _MAGICKCORE_PIXEL_ACCESSOR_H
19 #define _MAGICKCORE_PIXEL_ACCESSOR_H
21 #if defined(__cplusplus) || defined(c_plusplus)
26 #include <MagickCore/cache.h>
27 #include <MagickCore/cache-view.h>
28 #include <MagickCore/color.h>
29 #include <MagickCore/image.h>
33 static inline Quantum GetPixelAlpha(const Image *restrict image,
34 const Quantum *restrict pixel)
36 if (image->channel_map[AlphaPixelChannel].traits == UndefinedPixelTrait)
38 return(pixel[image->channel_map[AlphaPixelChannel].offset]);
41 static inline PixelTrait GetPixelAlphaTraits(const Image *restrict image)
43 return(image->channel_map[AlphaPixelChannel].traits);
46 static inline Quantum GetPixelBlack(const Image *restrict image,
47 const Quantum *restrict pixel)
49 if (image->channel_map[BlackPixelChannel].traits == UndefinedPixelTrait)
51 return(pixel[image->channel_map[BlackPixelChannel].offset]);
54 static inline PixelTrait GetPixelBlackTraits(const Image *restrict image)
56 return(image->channel_map[BlackPixelChannel].traits);
59 static inline Quantum GetPixelBlue(const Image *restrict image,
60 const Quantum *restrict pixel)
62 return(pixel[image->channel_map[BluePixelChannel].offset]);
65 static inline PixelTrait GetPixelBlueTraits(const Image *restrict image)
67 return(image->channel_map[BluePixelChannel].traits);
70 static inline Quantum GetPixelCb(const Image *restrict image,
71 const Quantum *restrict pixel)
73 return(pixel[image->channel_map[CbPixelChannel].offset]);
76 static inline PixelTrait GetPixelCbTraits(const Image *restrict image)
78 return(image->channel_map[CbPixelChannel].traits);
81 static inline Quantum GetPixelChannel(const Image *restrict image,
82 const PixelChannel channel,const Quantum *restrict pixel)
84 if (image->channel_map[channel].traits == UndefinedPixelTrait)
86 return(pixel[image->channel_map[channel].offset]);
89 static inline PixelChannel GetPixelChannelMapChannel(
90 const Image *restrict image,const ssize_t offset)
92 return(image->channel_map[offset].channel);
95 static inline ssize_t GetPixelChannelMapOffset(const Image *restrict image,
96 const PixelChannel channel)
98 return(image->channel_map[channel].offset);
101 static inline PixelTrait GetPixelChannelMapTraits(const Image *restrict image,
102 const PixelChannel channel)
104 return(image->channel_map[channel].traits);
107 static inline size_t GetPixelChannels(const Image *restrict image)
109 return(image->number_channels);
112 static inline Quantum GetPixelCr(const Image *restrict image,
113 const Quantum *restrict pixel)
115 return(pixel[image->channel_map[CrPixelChannel].offset]);
118 static inline PixelTrait GetPixelCrTraits(const Image *restrict image)
120 return(image->channel_map[CrPixelChannel].traits);
123 static inline Quantum GetPixelCyan(const Image *restrict image,
124 const Quantum *restrict pixel)
126 return(pixel[image->channel_map[CyanPixelChannel].offset]);
129 static inline PixelTrait GetPixelCyanTraits(const Image *restrict image)
131 return(image->channel_map[CyanPixelChannel].traits);
134 static inline Quantum GetPixelGray(const Image *restrict image,
135 const Quantum *restrict pixel)
137 return(pixel[image->channel_map[GrayPixelChannel].offset]);
140 static inline PixelTrait GetPixelGrayTraits(const Image *restrict image)
142 return(image->channel_map[GrayPixelChannel].traits);
145 static inline Quantum GetPixelGreen(const Image *restrict image,
146 const Quantum *restrict pixel)
148 return(pixel[image->channel_map[GreenPixelChannel].offset]);
151 static inline PixelTrait GetPixelGreenTraits(const Image *restrict image)
153 return(image->channel_map[GreenPixelChannel].traits);
156 static inline Quantum GetPixelIndex(const Image *restrict image,
157 const Quantum *restrict pixel)
159 if (image->channel_map[IndexPixelChannel].traits == UndefinedPixelTrait)
161 return(pixel[image->channel_map[IndexPixelChannel].offset]);
164 static inline PixelTrait GetPixelIndexTraits(const Image *restrict image)
166 return(image->channel_map[IndexPixelChannel].traits);
169 static inline Quantum GetPixelInfoIntensity(
170 const PixelInfo *restrict pixel_info)
172 #if !defined(MAGICKCORE_HDRI_SUPPORT)
173 return((Quantum) (0.299*pixel_info->red+0.587*pixel_info->green+0.114*
174 pixel_info->blue+0.5));
176 return((Quantum) (0.299*pixel_info->red+0.587*pixel_info->green+0.114*
181 static inline Quantum GetPixelInfoLuminance(
182 const PixelInfo *restrict pixel_info)
187 #if !defined(MAGICKCORE_HDRI_SUPPORT)
188 luminance=(Quantum) (0.21267*pixel_info->red+0.71516*pixel_info->green+
189 0.07217*pixel_info->blue+0.5);
191 luminance=(Quantum) (0.21267*pixel_info->red+0.71516*pixel_info->green+
192 0.07217*pixel_info->blue);
194 return((Quantum) luminance);
197 static inline Quantum GetPixelIntensity(const Image *restrict image,
198 const Quantum *restrict pixel)
200 #if !defined(MAGICKCORE_HDRI_SUPPORT)
201 if (image->colorspace == GRAYColorspace)
202 return(pixel[image->channel_map[GrayPixelChannel].offset]);
203 return((Quantum) (0.299*pixel[image->channel_map[RedPixelChannel].offset]+
204 0.587*pixel[image->channel_map[GreenPixelChannel].offset]+0.114*
205 pixel[image->channel_map[BluePixelChannel].offset]+0.5));
212 alpha=pixel[image->channel_map[RedPixelChannel].offset]-(double)
213 pixel[image->channel_map[GreenPixelChannel].offset];
214 beta=pixel[image->channel_map[GreenPixelChannel].offset]-(double)
215 pixel[image->channel_map[BluePixelChannel].offset];
216 if ((fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
217 return(pixel[image->channel_map[RedPixelChannel].offset]);
218 return((Quantum) (0.299*pixel[image->channel_map[RedPixelChannel].offset]+
219 0.587*pixel[image->channel_map[GreenPixelChannel].offset]+0.114*
220 pixel[image->channel_map[BluePixelChannel].offset]));
225 static inline Quantum GetPixelLuminance(const Image *restrict image,
226 const Quantum *restrict pixel)
228 #if !defined(MAGICKCORE_HDRI_SUPPORT)
229 return((Quantum) (0.21267*pixel[image->channel_map[RedPixelChannel].offset]+
230 0.71516*pixel[image->channel_map[GreenPixelChannel].offset]+0.07217*
231 pixel[image->channel_map[BluePixelChannel].offset]+0.5));
233 return((Quantum) (0.21267*pixel[image->channel_map[RedPixelChannel].offset]+
234 0.71516*pixel[image->channel_map[GreenPixelChannel].offset]+0.07217*
235 pixel[image->channel_map[BluePixelChannel].offset]));
239 static inline Quantum GetPixelMagenta(const Image *restrict image,
240 const Quantum *restrict pixel)
242 return(pixel[image->channel_map[MagentaPixelChannel].offset]);
245 static inline PixelTrait GetPixelMagentaTraits(const Image *restrict image)
247 return(image->channel_map[MagentaPixelChannel].traits);
250 static inline Quantum GetPixelMask(const Image *restrict image,
251 const Quantum *restrict pixel)
253 if (image->channel_map[MaskPixelChannel].traits == UndefinedPixelTrait)
255 return(pixel[image->channel_map[MaskPixelChannel].offset]);
258 static inline PixelTrait GetPixelMaskTraits(const Image *restrict image)
260 return(image->channel_map[MaskPixelChannel].traits);
263 static inline size_t GetPixelMetaChannels(const Image *restrict image)
265 return(image->number_meta_channels);
268 static inline size_t GetPixelMetacontentExtent(const Image *restrict image)
270 return(image->metacontent_extent);
273 static inline Quantum GetPixelOpacity(const Image *restrict image,
274 const Quantum *restrict pixel)
276 if (image->channel_map[AlphaPixelChannel].traits == UndefinedPixelTrait)
277 return(QuantumRange-OpaqueAlpha);
278 return(QuantumRange-pixel[image->channel_map[AlphaPixelChannel].offset]);
281 static inline Quantum GetPixelRed(const Image *restrict image,
282 const Quantum *restrict pixel)
284 return(pixel[image->channel_map[RedPixelChannel].offset]);
287 static inline PixelTrait GetPixelRedTraits(const Image *restrict image)
289 return(image->channel_map[RedPixelChannel].traits);
292 static inline void GetPixelInfoPixel(const Image *restrict image,
293 const Quantum *restrict pixel,PixelInfo *restrict pixel_info)
295 pixel_info->red=(double)
296 pixel[image->channel_map[RedPixelChannel].offset];
297 pixel_info->green=(double)
298 pixel[image->channel_map[GreenPixelChannel].offset];
299 pixel_info->blue=(double)
300 pixel[image->channel_map[BluePixelChannel].offset];
302 if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
303 pixel_info->black=(double)
304 pixel[image->channel_map[BlackPixelChannel].offset];
305 pixel_info->alpha=OpaqueAlpha;
306 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
307 pixel_info->alpha=(double)
308 pixel[image->channel_map[AlphaPixelChannel].offset];
310 if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
311 pixel_info->index=(double)
312 pixel[image->channel_map[IndexPixelChannel].offset];
315 static inline PixelTrait GetPixelTraits(const Image *restrict image,
316 const PixelChannel channel)
318 return(image->channel_map[channel].traits);
321 static inline Quantum GetPixelY(const Image *restrict image,
322 const Quantum *restrict pixel)
324 return(pixel[image->channel_map[YPixelChannel].offset]);
327 static inline PixelTrait GetPixelYTraits(const Image *restrict image)
329 return(image->channel_map[YPixelChannel].traits);
332 static inline Quantum GetPixelYellow(const Image *restrict image,
333 const Quantum *restrict pixel)
335 return(pixel[image->channel_map[YellowPixelChannel].offset]);
338 static inline PixelTrait GetPixelYellowTraits(const Image *restrict image)
340 return(image->channel_map[YellowPixelChannel].traits);
343 static inline MagickBooleanType IsPixelEquivalent(const Image *restrict image,
344 const Quantum *restrict p,const PixelInfo *restrict q)
346 if (((double) p[image->channel_map[RedPixelChannel].offset] == q->red) &&
347 ((double) p[image->channel_map[GreenPixelChannel].offset] == q->green) &&
348 ((double) p[image->channel_map[BluePixelChannel].offset] == q->blue))
353 static inline MagickBooleanType IsPixelGray(const Image *restrict image,
354 const Quantum *restrict pixel)
356 #if !defined(MAGICKCORE_HDRI_SUPPORT)
357 if ((pixel[image->channel_map[RedPixelChannel].offset] ==
358 pixel[image->channel_map[GreenPixelChannel].offset]) &&
359 (pixel[image->channel_map[GreenPixelChannel].offset] ==
360 pixel[image->channel_map[BluePixelChannel].offset]))
368 alpha=pixel[image->channel_map[RedPixelChannel].offset]-(double)
369 pixel[image->channel_map[GreenPixelChannel].offset];
370 beta=pixel[image->channel_map[GreenPixelChannel].offset]-(double)
371 pixel[image->channel_map[BluePixelChannel].offset];
372 if ((fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
379 static inline MagickBooleanType IsPixelInfoEquivalent(
380 const PixelInfo *restrict p,const PixelInfo *restrict q)
382 if ((p->matte != MagickFalse) && (q->matte == MagickFalse) &&
383 (fabs(p->alpha-OpaqueAlpha) > 0.5))
385 if ((q->matte != MagickFalse) && (p->matte == MagickFalse) &&
386 (fabs(q->alpha-OpaqueAlpha)) > 0.5)
388 if ((p->matte != MagickFalse) && (q->matte != MagickFalse))
390 if (fabs(p->alpha-q->alpha) > 0.5)
392 if (fabs(p->alpha-TransparentAlpha) <= 0.5)
395 if (fabs(p->red-q->red) > 0.5)
397 if (fabs(p->green-q->green) > 0.5)
399 if (fabs(p->blue-q->blue) > 0.5)
401 if ((p->colorspace == CMYKColorspace) && (fabs(p->black-q->black) > 0.5))
406 static inline MagickBooleanType IsPixelMonochrome(const Image *restrict image,
407 const Quantum *restrict pixel)
409 #if !defined(MAGICKCORE_HDRI_SUPPORT)
410 if (((pixel[image->channel_map[RedPixelChannel].offset] == 0) ||
411 (pixel[image->channel_map[RedPixelChannel].offset] == (Quantum) QuantumRange)) &&
412 (pixel[image->channel_map[RedPixelChannel].offset] ==
413 pixel[image->channel_map[GreenPixelChannel].offset]) &&
414 (pixel[image->channel_map[GreenPixelChannel].offset] ==
415 pixel[image->channel_map[BluePixelChannel].offset]))
423 alpha=pixel[image->channel_map[RedPixelChannel].offset]-(double)
424 pixel[image->channel_map[GreenPixelChannel].offset];
425 beta=pixel[image->channel_map[GreenPixelChannel].offset]-(double)
426 pixel[image->channel_map[BluePixelChannel].offset];
427 if (((fabs(pixel[image->channel_map[RedPixelChannel].offset]) <= MagickEpsilon) ||
428 (fabs(pixel[image->channel_map[RedPixelChannel].offset]-QuantumRange) <= MagickEpsilon)) &&
429 (fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
436 static inline MagickBooleanType IsPixelInfoGray(
437 const PixelInfo *restrict pixel_info)
439 #if !defined(MAGICKCORE_HDRI_SUPPORT)
440 if ((pixel_info->red == pixel_info->green) &&
441 (pixel_info->green == pixel_info->blue))
449 alpha=pixel_info->red-(double) pixel_info->green;
450 beta=pixel_info->green-(double) pixel_info->blue;
451 if ((fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
458 static inline MagickBooleanType IsPixelInfoMonochrome(
459 const PixelInfo *restrict pixel_info)
461 #if !defined(MAGICKCORE_HDRI_SUPPORT)
462 if (((pixel_info->red == 0) || (pixel_info->red == (Quantum) QuantumRange)) &&
463 (pixel_info->red == pixel_info->green) &&
464 (pixel_info->green == pixel_info->blue))
472 alpha=pixel_info->red-(double) pixel_info->green;
473 beta=pixel_info->green-(double) pixel_info->blue;
474 if (((fabs(pixel_info->red) <= MagickEpsilon) ||
475 (fabs(pixel_info->red-QuantumRange) <= MagickEpsilon)) &&
476 (fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
483 static inline void SetPixelAlpha(const Image *restrict image,
484 const Quantum alpha,Quantum *restrict pixel)
486 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
487 pixel[image->channel_map[AlphaPixelChannel].offset]=alpha;
490 static inline void SetPixelAlphaTraits(Image *image,const PixelTrait traits)
492 image->channel_map[AlphaPixelChannel].traits=traits;
495 static inline void SetPixelBlack(const Image *restrict image,
496 const Quantum black,Quantum *restrict pixel)
498 if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
499 pixel[image->channel_map[BlackPixelChannel].offset]=black;
502 static inline void SetPixelBlackTraits(Image *image,const PixelTrait traits)
504 image->channel_map[BlackPixelChannel].traits=traits;
507 static inline void SetPixelBlue(const Image *restrict image,const Quantum blue,
508 Quantum *restrict pixel)
510 pixel[image->channel_map[BluePixelChannel].offset]=blue;
513 static inline void SetPixelBlueTraits(Image *image,const PixelTrait traits)
515 image->channel_map[BluePixelChannel].traits=traits;
518 static inline void SetPixelCb(const Image *restrict image,const Quantum cb,
519 Quantum *restrict pixel)
521 pixel[image->channel_map[CbPixelChannel].offset]=cb;
524 static inline void SetPixelCbTraits(Image *image,const PixelTrait traits)
526 image->channel_map[CbPixelChannel].traits=traits;
529 static inline void SetPixelChannel(const Image *restrict image,
530 const PixelChannel channel,const Quantum quantum,Quantum *restrict pixel)
532 if (image->channel_map[channel].traits != UndefinedPixelTrait)
533 pixel[image->channel_map[channel].offset]=quantum;
536 static inline void SetPixelChannelMapChannel(const Image *restrict image,
537 const PixelChannel channel,const ssize_t offset)
539 image->channel_map[offset].channel=channel;
540 image->channel_map[channel].offset=offset;
543 static inline void SetPixelChannelMap(const Image *restrict image,
544 const PixelChannel channel,const PixelTrait traits,const ssize_t offset)
546 image->channel_map[offset].channel=channel;
547 image->channel_map[channel].offset=offset;
548 image->channel_map[channel].traits=traits;
551 static inline void SetPixelChannels(Image *image,const size_t number_channels)
553 image->number_channels=number_channels;
556 static inline void SetPixelChannelTraits(Image *image,
557 const PixelChannel channel,const PixelTrait traits)
559 image->channel_map[channel].traits=traits;
562 static inline void SetPixelChannelMapTraits(Image *image,
563 const PixelChannel channel,const PixelTrait traits)
565 image->channel_map[channel].traits=traits;
568 static inline void SetPixelCr(const Image *restrict image,const Quantum cr,
569 Quantum *restrict pixel)
571 pixel[image->channel_map[CrPixelChannel].offset]=cr;
574 static inline void SetPixelCrTraits(Image *image,const PixelTrait traits)
576 image->channel_map[CrPixelChannel].traits=traits;
579 static inline void SetPixelCyan(const Image *restrict image,const Quantum cyan,
580 Quantum *restrict pixel)
582 pixel[image->channel_map[CyanPixelChannel].offset]=cyan;
585 static inline void SetPixelGray(const Image *restrict image,const Quantum gray,
586 Quantum *restrict pixel)
588 pixel[image->channel_map[GrayPixelChannel].offset]=gray;
591 static inline void SetPixelGrayTraits(Image *image,const PixelTrait traits)
593 image->channel_map[GrayPixelChannel].traits=traits;
596 static inline void SetPixelGreen(const Image *restrict image,
597 const Quantum green,Quantum *restrict pixel)
599 pixel[image->channel_map[GreenPixelChannel].offset]=green;
602 static inline void SetPixelGreenTraits(Image *image,const PixelTrait traits)
604 image->channel_map[GreenPixelChannel].traits=traits;
607 static inline void SetPixelIndex(const Image *restrict image,
608 const Quantum index,Quantum *restrict pixel)
610 if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
611 pixel[image->channel_map[IndexPixelChannel].offset]=index;
614 static inline void SetPixelIndexTraits(Image *image,const PixelTrait traits)
616 image->channel_map[IndexPixelChannel].traits=traits;
619 static inline void SetPixelInfoPixel(const Image *restrict image,
620 const PixelInfo *restrict pixel_info,Quantum *restrict pixel)
622 pixel[image->channel_map[RedPixelChannel].offset]=
623 ClampToQuantum(pixel_info->red);
624 pixel[image->channel_map[GreenPixelChannel].offset]=
625 ClampToQuantum(pixel_info->green);
626 pixel[image->channel_map[BluePixelChannel].offset]=
627 ClampToQuantum(pixel_info->blue);
628 if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
629 pixel[image->channel_map[BlackPixelChannel].offset]=
630 ClampToQuantum(pixel_info->black);
631 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
632 pixel[image->channel_map[AlphaPixelChannel].offset]=pixel_info->matte ==
633 MagickFalse ? OpaqueAlpha : ClampToQuantum(pixel_info->alpha);
636 static inline void SetPixelMagenta(const Image *restrict image,
637 const Quantum magenta,Quantum *restrict pixel)
639 pixel[image->channel_map[MagentaPixelChannel].offset]=magenta;
642 static inline void SetPixelMagentaTraits(Image *image,const PixelTrait traits)
644 image->channel_map[MagentaPixelChannel].traits=traits;
647 static inline void SetPixelMask(const Image *restrict image,
648 const Quantum mask,Quantum *restrict pixel)
650 if (image->channel_map[MaskPixelChannel].traits != UndefinedPixelTrait)
651 pixel[image->channel_map[MaskPixelChannel].offset]=mask;
654 static inline void SetPixelMetacontentExtent(Image *image,const size_t extent)
656 image->metacontent_extent=extent;
659 static inline void SetPixelOpacity(const Image *restrict image,
660 const Quantum alpha,Quantum *restrict pixel)
662 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
663 pixel[image->channel_map[AlphaPixelChannel].offset]=QuantumRange-alpha;
666 static inline void SetPixelRed(const Image *restrict image,const Quantum red,
667 Quantum *restrict pixel)
669 pixel[image->channel_map[RedPixelChannel].offset]=red;
672 static inline void SetPixelRedTraits(Image *image,const PixelTrait traits)
674 image->channel_map[RedPixelChannel].traits=traits;
677 static inline void SetPixelYellow(const Image *restrict image,
678 const Quantum yellow,Quantum *restrict pixel)
680 pixel[image->channel_map[YellowPixelChannel].offset]=yellow;
683 static inline void SetPixelYellowTraits(Image *image,const PixelTrait traits)
685 image->channel_map[YellowPixelChannel].traits=traits;
688 static inline void SetPixelY(const Image *restrict image,const Quantum y,
689 Quantum *restrict pixel)
691 pixel[image->channel_map[YPixelChannel].offset]=y;
694 static inline void SetPixelYTraits(Image *image,const PixelTrait traits)
696 image->channel_map[YPixelChannel].traits=traits;
699 #if defined(__cplusplus) || defined(c_plusplus)