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/colorspace.h>
30 #include <MagickCore/image.h>
34 static inline double InversesRGBCompandor(const double pixel)
36 if (pixel <= (0.04045*QuantumRange))
38 return(QuantumRange*pow((QuantumScale*pixel+0.055)/1.055,2.4));
41 static inline double sRGBCompandor(const double pixel)
43 if (pixel <= (0.0031308*QuantumRange))
45 return(QuantumRange*(1.055*pow(QuantumScale*pixel,1.0/2.4)-0.055));
48 static inline Quantum GetPixela(const Image *restrict image,
49 const Quantum *restrict pixel)
51 return(pixel[image->channel_map[aPixelChannel].offset]);
54 static inline Quantum GetPixelAlpha(const Image *restrict image,
55 const Quantum *restrict pixel)
57 if (image->channel_map[AlphaPixelChannel].traits == UndefinedPixelTrait)
59 return(pixel[image->channel_map[AlphaPixelChannel].offset]);
62 static inline PixelTrait GetPixelAlphaTraits(const Image *restrict image)
64 return(image->channel_map[AlphaPixelChannel].traits);
67 static inline Quantum GetPixelb(const Image *restrict image,
68 const Quantum *restrict pixel)
70 return(pixel[image->channel_map[bPixelChannel].offset]);
73 static inline Quantum GetPixelBlack(const Image *restrict image,
74 const Quantum *restrict pixel)
76 if (image->channel_map[BlackPixelChannel].traits == UndefinedPixelTrait)
78 return(pixel[image->channel_map[BlackPixelChannel].offset]);
81 static inline PixelTrait GetPixelBlackTraits(const Image *restrict image)
83 return(image->channel_map[BlackPixelChannel].traits);
86 static inline Quantum GetPixelBlue(const Image *restrict image,
87 const Quantum *restrict pixel)
89 return(pixel[image->channel_map[BluePixelChannel].offset]);
92 static inline PixelTrait GetPixelBlueTraits(const Image *restrict image)
94 return(image->channel_map[BluePixelChannel].traits);
97 static inline Quantum GetPixelCb(const Image *restrict image,
98 const Quantum *restrict pixel)
100 return(pixel[image->channel_map[CbPixelChannel].offset]);
103 static inline PixelTrait GetPixelCbTraits(const Image *restrict image)
105 return(image->channel_map[CbPixelChannel].traits);
108 static inline Quantum GetPixelChannel(const Image *restrict image,
109 const PixelChannel channel,const Quantum *restrict pixel)
111 if (image->channel_map[channel].traits == UndefinedPixelTrait)
113 return(pixel[image->channel_map[channel].offset]);
116 static inline PixelChannel GetPixelChannelMapChannel(
117 const Image *restrict image,const ssize_t offset)
119 return(image->channel_map[offset].channel);
122 static inline ssize_t GetPixelChannelMapOffset(const Image *restrict image,
123 const PixelChannel channel)
125 return(image->channel_map[channel].offset);
128 static inline PixelTrait GetPixelChannelMapTraits(const Image *restrict image,
129 const PixelChannel channel)
131 return(image->channel_map[channel].traits);
134 static inline size_t GetPixelChannels(const Image *restrict image)
136 return(image->number_channels);
139 static inline Quantum GetPixelCr(const Image *restrict image,
140 const Quantum *restrict pixel)
142 return(pixel[image->channel_map[CrPixelChannel].offset]);
145 static inline PixelTrait GetPixelCrTraits(const Image *restrict image)
147 return(image->channel_map[CrPixelChannel].traits);
150 static inline Quantum GetPixelCyan(const Image *restrict image,
151 const Quantum *restrict pixel)
153 return(pixel[image->channel_map[CyanPixelChannel].offset]);
156 static inline PixelTrait GetPixelCyanTraits(const Image *restrict image)
158 return(image->channel_map[CyanPixelChannel].traits);
161 static inline Quantum GetPixelGray(const Image *restrict image,
162 const Quantum *restrict pixel)
164 return(pixel[image->channel_map[GrayPixelChannel].offset]);
167 static inline PixelTrait GetPixelGrayTraits(const Image *restrict image)
169 return(image->channel_map[GrayPixelChannel].traits);
172 static inline Quantum GetPixelGreen(const Image *restrict image,
173 const Quantum *restrict pixel)
175 return(pixel[image->channel_map[GreenPixelChannel].offset]);
178 static inline PixelTrait GetPixelGreenTraits(const Image *restrict image)
180 return(image->channel_map[GreenPixelChannel].traits);
183 static inline Quantum GetPixelIndex(const Image *restrict image,
184 const Quantum *restrict pixel)
186 if (image->channel_map[IndexPixelChannel].traits == UndefinedPixelTrait)
188 return(pixel[image->channel_map[IndexPixelChannel].offset]);
191 static inline PixelTrait GetPixelIndexTraits(const Image *restrict image)
193 return(image->channel_map[IndexPixelChannel].traits);
196 static inline double GetPixelInfoChannel(const PixelInfo *restrict pixel_info,
197 const PixelChannel channel)
201 case RedPixelChannel: return(pixel_info->red);
202 case GreenPixelChannel: return(pixel_info->green);
203 case BluePixelChannel: return(pixel_info->blue);
204 case BlackPixelChannel: return(pixel_info->black);
205 case AlphaPixelChannel: return(pixel_info->alpha);
206 case IndexPixelChannel: return(pixel_info->index);
207 default: return(0.0);
211 static inline double GetPixelInfoIntensity(const PixelInfo *restrict pixel_info)
218 if (pixel_info->colorspace == GRAYColorspace)
219 return(pixel_info->red);
220 if (pixel_info->colorspace != sRGBColorspace)
221 return(0.298839*pixel_info->red+0.586811*pixel_info->green+
222 0.114350*pixel_info->blue);
223 red=InversesRGBCompandor(pixel_info->red);
224 green=InversesRGBCompandor(pixel_info->green);
225 blue=InversesRGBCompandor(pixel_info->blue);
226 return(0.298839*red+0.586811*green+0.114350*blue);
229 static inline double GetPixelInfoLuminance(const PixelInfo *restrict pixel_info)
236 if (pixel_info->colorspace == GRAYColorspace)
237 return(pixel_info->red);
238 if (pixel_info->colorspace != sRGBColorspace)
239 return(0.21267*pixel_info->red+0.71516*pixel_info->green+
240 0.07217*pixel_info->blue);
241 red=InversesRGBCompandor(pixel_info->red);
242 green=InversesRGBCompandor(pixel_info->green);
243 blue=InversesRGBCompandor(pixel_info->blue);
244 return(0.21267*red+0.71516*green+0.07217*blue);
247 static inline double GetPixelIntensity(const Image *restrict image,
248 const Quantum *restrict pixel)
255 if (image->colorspace == GRAYColorspace)
256 return((double) pixel[image->channel_map[GrayPixelChannel].offset]);
257 if (image->colorspace != sRGBColorspace)
258 return(0.298839*pixel[image->channel_map[RedPixelChannel].offset]+
259 0.586811*pixel[image->channel_map[GreenPixelChannel].offset]+
260 0.114350*pixel[image->channel_map[BluePixelChannel].offset]);
261 red=InversesRGBCompandor((double)
262 pixel[image->channel_map[RedPixelChannel].offset]);
263 green=InversesRGBCompandor((double)
264 pixel[image->channel_map[GreenPixelChannel].offset]);
265 blue=InversesRGBCompandor((double)
266 pixel[image->channel_map[BluePixelChannel].offset]);
267 return(0.298839*red+0.586811*green+0.114350*blue);
270 static inline Quantum GetPixelL(const Image *restrict image,
271 const Quantum *restrict pixel)
273 return(pixel[image->channel_map[LPixelChannel].offset]);
276 static inline double GetPixelLuminance(const Image *restrict image,
277 const Quantum *restrict pixel)
284 if (image->colorspace == GRAYColorspace)
285 return((double) pixel[image->channel_map[GrayPixelChannel].offset]);
286 if (image->colorspace != sRGBColorspace)
287 return(0.298839*pixel[image->channel_map[RedPixelChannel].offset]+
288 0.586811*pixel[image->channel_map[GreenPixelChannel].offset]+
289 0.114350*pixel[image->channel_map[BluePixelChannel].offset]);
290 red=InversesRGBCompandor((double)
291 pixel[image->channel_map[RedPixelChannel].offset]);
292 green=InversesRGBCompandor((double)
293 pixel[image->channel_map[GreenPixelChannel].offset]);
294 blue=InversesRGBCompandor((double)
295 pixel[image->channel_map[BluePixelChannel].offset]);
296 return(0.21267*red+0.71516*green+0.07217*blue);
299 static inline Quantum GetPixelMagenta(const Image *restrict image,
300 const Quantum *restrict pixel)
302 return(pixel[image->channel_map[MagentaPixelChannel].offset]);
305 static inline PixelTrait GetPixelMagentaTraits(const Image *restrict image)
307 return(image->channel_map[MagentaPixelChannel].traits);
310 static inline Quantum GetPixelMask(const Image *restrict image,
311 const Quantum *restrict pixel)
313 if (image->channel_map[MaskPixelChannel].traits == UndefinedPixelTrait)
315 return(pixel[image->channel_map[MaskPixelChannel].offset]);
318 static inline PixelTrait GetPixelMaskTraits(const Image *restrict image)
320 return(image->channel_map[MaskPixelChannel].traits);
323 static inline size_t GetPixelMetaChannels(const Image *restrict image)
325 return(image->number_meta_channels);
328 static inline size_t GetPixelMetacontentExtent(const Image *restrict image)
330 return(image->metacontent_extent);
333 static inline Quantum GetPixelOpacity(const Image *restrict image,
334 const Quantum *restrict pixel)
336 if (image->channel_map[AlphaPixelChannel].traits == UndefinedPixelTrait)
337 return(QuantumRange-OpaqueAlpha);
338 return(QuantumRange-pixel[image->channel_map[AlphaPixelChannel].offset]);
341 static inline Quantum GetPixelRed(const Image *restrict image,
342 const Quantum *restrict pixel)
344 return(pixel[image->channel_map[RedPixelChannel].offset]);
347 static inline PixelTrait GetPixelRedTraits(const Image *restrict image)
349 return(image->channel_map[RedPixelChannel].traits);
352 static inline void GetPixelInfoPixel(const Image *restrict image,
353 const Quantum *restrict pixel,PixelInfo *restrict pixel_info)
355 pixel_info->red=(double)
356 pixel[image->channel_map[RedPixelChannel].offset];
357 pixel_info->green=(double)
358 pixel[image->channel_map[GreenPixelChannel].offset];
359 pixel_info->blue=(double)
360 pixel[image->channel_map[BluePixelChannel].offset];
361 pixel_info->black=0.0;
362 if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
363 pixel_info->black=(double)
364 pixel[image->channel_map[BlackPixelChannel].offset];
365 pixel_info->alpha=OpaqueAlpha;
366 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
367 pixel_info->alpha=(double)
368 pixel[image->channel_map[AlphaPixelChannel].offset];
369 pixel_info->index=0.0;
370 if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
371 pixel_info->index=(double)
372 pixel[image->channel_map[IndexPixelChannel].offset];
375 static inline PixelTrait GetPixelTraits(const Image *restrict image,
376 const PixelChannel channel)
378 return(image->channel_map[channel].traits);
381 static inline Quantum GetPixelY(const Image *restrict image,
382 const Quantum *restrict pixel)
384 return(pixel[image->channel_map[YPixelChannel].offset]);
387 static inline PixelTrait GetPixelYTraits(const Image *restrict image)
389 return(image->channel_map[YPixelChannel].traits);
392 static inline Quantum GetPixelYellow(const Image *restrict image,
393 const Quantum *restrict pixel)
395 return(pixel[image->channel_map[YellowPixelChannel].offset]);
398 static inline PixelTrait GetPixelYellowTraits(const Image *restrict image)
400 return(image->channel_map[YellowPixelChannel].traits);
403 static inline MagickBooleanType IsPixelEquivalent(const Image *restrict image,
404 const Quantum *restrict p,const PixelInfo *restrict q)
411 red=(double) p[image->channel_map[RedPixelChannel].offset];
412 green=(double) p[image->channel_map[GreenPixelChannel].offset];
413 blue=(double) p[image->channel_map[BluePixelChannel].offset];
414 if ((fabs(red-q->red) < MagickEpsilon) &&
415 (fabs(green-q->green) < MagickEpsilon) &&
416 (fabs(blue-q->blue) < MagickEpsilon))
421 static inline MagickBooleanType IsPixelGray(const Image *restrict image,
422 const Quantum *restrict pixel)
429 red=(double) pixel[image->channel_map[RedPixelChannel].offset];
430 green=(double) pixel[image->channel_map[GreenPixelChannel].offset];
431 blue=(double) pixel[image->channel_map[BluePixelChannel].offset];
432 if ((fabs(red-green) < MagickEpsilon) && (fabs(green-blue) < MagickEpsilon))
437 static inline MagickBooleanType IsPixelInfoEquivalent(
438 const PixelInfo *restrict p,const PixelInfo *restrict q)
440 if ((p->matte != MagickFalse) && (q->matte == MagickFalse) &&
441 (fabs(p->alpha-OpaqueAlpha) >= MagickEpsilon))
443 if ((q->matte != MagickFalse) && (p->matte == MagickFalse) &&
444 (fabs(q->alpha-OpaqueAlpha)) >= MagickEpsilon)
446 if ((p->matte != MagickFalse) && (q->matte != MagickFalse))
448 if (fabs(p->alpha-q->alpha) >= MagickEpsilon)
450 if (fabs(p->alpha-TransparentAlpha) < MagickEpsilon)
453 if (fabs(p->red-q->red) >= MagickEpsilon)
455 if (fabs(p->green-q->green) >= MagickEpsilon)
457 if (fabs(p->blue-q->blue) >= MagickEpsilon)
459 if ((p->colorspace == CMYKColorspace) &&
460 (fabs(p->black-q->black) >= MagickEpsilon))
465 static inline MagickBooleanType IsPixelMonochrome(const Image *restrict image,
466 const Quantum *restrict pixel)
473 red=(double) pixel[image->channel_map[RedPixelChannel].offset];
474 if ((fabs(red) >= MagickEpsilon) || (fabs(red-QuantumRange) >= MagickEpsilon))
476 green=(double) pixel[image->channel_map[GreenPixelChannel].offset];
477 blue=(double) pixel[image->channel_map[BluePixelChannel].offset];
478 if ((fabs(red-green) < MagickEpsilon) && (fabs(green-blue) < MagickEpsilon))
483 static inline MagickBooleanType IsPixelInfoGray(
484 const PixelInfo *restrict pixel_info)
486 if ((pixel_info->colorspace != GRAYColorspace) &&
487 (pixel_info->colorspace != RGBColorspace))
489 if ((fabs(pixel_info->red-pixel_info->green) < MagickEpsilon) &&
490 (fabs(pixel_info->green-pixel_info->blue) < MagickEpsilon))
495 static inline MagickBooleanType IsPixelInfoMonochrome(
496 const PixelInfo *restrict pixel_info)
498 if ((pixel_info->colorspace != GRAYColorspace) &&
499 (pixel_info->colorspace != RGBColorspace))
501 if ((fabs(pixel_info->red) >= MagickEpsilon) ||
502 (fabs(pixel_info->red-QuantumRange) >= MagickEpsilon))
504 if ((fabs(pixel_info->red-pixel_info->green) < MagickEpsilon) &&
505 (fabs(pixel_info->green-pixel_info->blue) < MagickEpsilon))
510 static inline void SetPixela(const Image *restrict image,
511 const Quantum a,Quantum *restrict pixel)
513 if (image->channel_map[aPixelChannel].traits != UndefinedPixelTrait)
514 pixel[image->channel_map[aPixelChannel].offset]=a;
517 static inline void SetPixelAlpha(const Image *restrict image,
518 const Quantum alpha,Quantum *restrict pixel)
520 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
521 pixel[image->channel_map[AlphaPixelChannel].offset]=alpha;
524 static inline void SetPixelAlphaTraits(Image *image,const PixelTrait traits)
526 image->channel_map[AlphaPixelChannel].traits=traits;
529 static inline void SetPixelb(const Image *restrict image,
530 const Quantum b,Quantum *restrict pixel)
532 if (image->channel_map[bPixelChannel].traits != UndefinedPixelTrait)
533 pixel[image->channel_map[bPixelChannel].offset]=b;
536 static inline void SetPixelBlack(const Image *restrict image,
537 const Quantum black,Quantum *restrict pixel)
539 if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
540 pixel[image->channel_map[BlackPixelChannel].offset]=black;
543 static inline void SetPixelBlackTraits(Image *image,const PixelTrait traits)
545 image->channel_map[BlackPixelChannel].traits=traits;
548 static inline void SetPixelBlue(const Image *restrict image,const Quantum blue,
549 Quantum *restrict pixel)
551 pixel[image->channel_map[BluePixelChannel].offset]=blue;
554 static inline void SetPixelBlueTraits(Image *image,const PixelTrait traits)
556 image->channel_map[BluePixelChannel].traits=traits;
559 static inline void SetPixelCb(const Image *restrict image,const Quantum cb,
560 Quantum *restrict pixel)
562 pixel[image->channel_map[CbPixelChannel].offset]=cb;
565 static inline void SetPixelCbTraits(Image *image,const PixelTrait traits)
567 image->channel_map[CbPixelChannel].traits=traits;
570 static inline void SetPixelChannel(const Image *restrict image,
571 const PixelChannel channel,const Quantum quantum,Quantum *restrict pixel)
573 if (image->channel_map[channel].traits != UndefinedPixelTrait)
574 pixel[image->channel_map[channel].offset]=quantum;
577 static inline void SetPixelChannelMapChannel(const Image *restrict image,
578 const PixelChannel channel,const ssize_t offset)
580 image->channel_map[offset].channel=channel;
581 image->channel_map[channel].offset=offset;
584 static inline void SetPixelChannelMap(const Image *restrict image,
585 const PixelChannel channel,const PixelTrait traits,const ssize_t offset)
587 image->channel_map[offset].channel=channel;
588 image->channel_map[channel].offset=offset;
589 image->channel_map[channel].traits=traits;
592 static inline void SetPixelChannels(Image *image,const size_t number_channels)
594 image->number_channels=number_channels;
597 static inline void SetPixelChannelTraits(Image *image,
598 const PixelChannel channel,const PixelTrait traits)
600 image->channel_map[channel].traits=traits;
603 static inline void SetPixelChannelMapTraits(Image *image,
604 const PixelChannel channel,const PixelTrait traits)
606 image->channel_map[channel].traits=traits;
609 static inline void SetPixelCr(const Image *restrict image,const Quantum cr,
610 Quantum *restrict pixel)
612 pixel[image->channel_map[CrPixelChannel].offset]=cr;
615 static inline void SetPixelCrTraits(Image *image,const PixelTrait traits)
617 image->channel_map[CrPixelChannel].traits=traits;
620 static inline void SetPixelCyan(const Image *restrict image,const Quantum cyan,
621 Quantum *restrict pixel)
623 pixel[image->channel_map[CyanPixelChannel].offset]=cyan;
626 static inline void SetPixelGray(const Image *restrict image,const Quantum gray,
627 Quantum *restrict pixel)
629 pixel[image->channel_map[GrayPixelChannel].offset]=gray;
632 static inline void SetPixelGrayTraits(Image *image,const PixelTrait traits)
634 image->channel_map[GrayPixelChannel].traits=traits;
637 static inline void SetPixelGreen(const Image *restrict image,
638 const Quantum green,Quantum *restrict pixel)
640 pixel[image->channel_map[GreenPixelChannel].offset]=green;
643 static inline void SetPixelGreenTraits(Image *image,const PixelTrait traits)
645 image->channel_map[GreenPixelChannel].traits=traits;
648 static inline void SetPixelIndex(const Image *restrict image,
649 const Quantum index,Quantum *restrict pixel)
651 if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
652 pixel[image->channel_map[IndexPixelChannel].offset]=index;
655 static inline void SetPixelIndexTraits(Image *image,const PixelTrait traits)
657 image->channel_map[IndexPixelChannel].traits=traits;
660 static inline void SetPixelInfoPixel(const Image *restrict image,
661 const PixelInfo *restrict pixel_info,Quantum *restrict pixel)
663 pixel[image->channel_map[RedPixelChannel].offset]=
664 ClampToQuantum(pixel_info->red);
665 pixel[image->channel_map[GreenPixelChannel].offset]=
666 ClampToQuantum(pixel_info->green);
667 pixel[image->channel_map[BluePixelChannel].offset]=
668 ClampToQuantum(pixel_info->blue);
669 if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
670 pixel[image->channel_map[BlackPixelChannel].offset]=
671 ClampToQuantum(pixel_info->black);
672 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
673 pixel[image->channel_map[AlphaPixelChannel].offset]=pixel_info->matte ==
674 MagickFalse ? OpaqueAlpha : ClampToQuantum(pixel_info->alpha);
677 static inline void SetPixelL(const Image *restrict image,
678 const Quantum L,Quantum *restrict pixel)
680 if (image->channel_map[LPixelChannel].traits != UndefinedPixelTrait)
681 pixel[image->channel_map[LPixelChannel].offset]=L;
684 static inline void SetPixelMagenta(const Image *restrict image,
685 const Quantum magenta,Quantum *restrict pixel)
687 pixel[image->channel_map[MagentaPixelChannel].offset]=magenta;
690 static inline void SetPixelMagentaTraits(Image *image,const PixelTrait traits)
692 image->channel_map[MagentaPixelChannel].traits=traits;
695 static inline void SetPixelMask(const Image *restrict image,
696 const Quantum mask,Quantum *restrict pixel)
698 if (image->channel_map[MaskPixelChannel].traits != UndefinedPixelTrait)
699 pixel[image->channel_map[MaskPixelChannel].offset]=mask;
702 static inline void SetPixelMetacontentExtent(Image *image,const size_t extent)
704 image->metacontent_extent=extent;
707 static inline void SetPixelOpacity(const Image *restrict image,
708 const Quantum alpha,Quantum *restrict pixel)
710 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
711 pixel[image->channel_map[AlphaPixelChannel].offset]=QuantumRange-alpha;
714 static inline void SetPixelRed(const Image *restrict image,const Quantum red,
715 Quantum *restrict pixel)
717 pixel[image->channel_map[RedPixelChannel].offset]=red;
720 static inline void SetPixelRedTraits(Image *image,const PixelTrait traits)
722 image->channel_map[RedPixelChannel].traits=traits;
725 static inline void SetPixelYellow(const Image *restrict image,
726 const Quantum yellow,Quantum *restrict pixel)
728 pixel[image->channel_map[YellowPixelChannel].offset]=yellow;
731 static inline void SetPixelYellowTraits(Image *image,const PixelTrait traits)
733 image->channel_map[YellowPixelChannel].traits=traits;
736 static inline void SetPixelY(const Image *restrict image,const Quantum y,
737 Quantum *restrict pixel)
739 pixel[image->channel_map[YPixelChannel].offset]=y;
742 static inline void SetPixelYTraits(Image *image,const PixelTrait traits)
744 image->channel_map[YPixelChannel].traits=traits;
747 #if defined(__cplusplus) || defined(c_plusplus)