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 GetPixelChannelChannel(
117 const Image *restrict image,const ssize_t offset)
119 return(image->channel_map[offset].channel);
122 static inline ssize_t GetPixelChannelOffset(const Image *restrict image,
123 const PixelChannel channel)
125 return(image->channel_map[channel].offset);
128 static inline PixelTrait GetPixelChannelTraits(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 SetPixelChannelChannel(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 SetPixelChannel(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 SetPixelCr(const Image *restrict image,const Quantum cr,
604 Quantum *restrict pixel)
606 pixel[image->channel_map[CrPixelChannel].offset]=cr;
609 static inline void SetPixelCrTraits(Image *image,const PixelTrait traits)
611 image->channel_map[CrPixelChannel].traits=traits;
614 static inline void SetPixelCyan(const Image *restrict image,const Quantum cyan,
615 Quantum *restrict pixel)
617 pixel[image->channel_map[CyanPixelChannel].offset]=cyan;
620 static inline void SetPixelGray(const Image *restrict image,const Quantum gray,
621 Quantum *restrict pixel)
623 pixel[image->channel_map[GrayPixelChannel].offset]=gray;
626 static inline void SetPixelGrayTraits(Image *image,const PixelTrait traits)
628 image->channel_map[GrayPixelChannel].traits=traits;
631 static inline void SetPixelGreen(const Image *restrict image,
632 const Quantum green,Quantum *restrict pixel)
634 pixel[image->channel_map[GreenPixelChannel].offset]=green;
637 static inline void SetPixelGreenTraits(Image *image,const PixelTrait traits)
639 image->channel_map[GreenPixelChannel].traits=traits;
642 static inline void SetPixelIndex(const Image *restrict image,
643 const Quantum index,Quantum *restrict pixel)
645 if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
646 pixel[image->channel_map[IndexPixelChannel].offset]=index;
649 static inline void SetPixelIndexTraits(Image *image,const PixelTrait traits)
651 image->channel_map[IndexPixelChannel].traits=traits;
654 static inline void SetPixelInfoPixel(const Image *restrict image,
655 const PixelInfo *restrict pixel_info,Quantum *restrict pixel)
657 pixel[image->channel_map[RedPixelChannel].offset]=
658 ClampToQuantum(pixel_info->red);
659 pixel[image->channel_map[GreenPixelChannel].offset]=
660 ClampToQuantum(pixel_info->green);
661 pixel[image->channel_map[BluePixelChannel].offset]=
662 ClampToQuantum(pixel_info->blue);
663 if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
664 pixel[image->channel_map[BlackPixelChannel].offset]=
665 ClampToQuantum(pixel_info->black);
666 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
667 pixel[image->channel_map[AlphaPixelChannel].offset]=pixel_info->matte ==
668 MagickFalse ? OpaqueAlpha : ClampToQuantum(pixel_info->alpha);
671 static inline void SetPixelL(const Image *restrict image,const Quantum L,
672 Quantum *restrict pixel)
674 if (image->channel_map[LPixelChannel].traits != UndefinedPixelTrait)
675 pixel[image->channel_map[LPixelChannel].offset]=L;
678 static inline void SetPixelMagenta(const Image *restrict image,
679 const Quantum magenta,Quantum *restrict pixel)
681 pixel[image->channel_map[MagentaPixelChannel].offset]=magenta;
684 static inline void SetPixelMagentaTraits(Image *image,const PixelTrait traits)
686 image->channel_map[MagentaPixelChannel].traits=traits;
689 static inline void SetPixelMask(const Image *restrict image,
690 const Quantum mask,Quantum *restrict pixel)
692 if (image->channel_map[MaskPixelChannel].traits != UndefinedPixelTrait)
693 pixel[image->channel_map[MaskPixelChannel].offset]=mask;
696 static inline void SetPixelMetacontentExtent(Image *image,const size_t extent)
698 image->metacontent_extent=extent;
701 static inline void SetPixelOpacity(const Image *restrict image,
702 const Quantum alpha,Quantum *restrict pixel)
704 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
705 pixel[image->channel_map[AlphaPixelChannel].offset]=QuantumRange-alpha;
708 static inline void SetPixelRed(const Image *restrict image,const Quantum red,
709 Quantum *restrict pixel)
711 pixel[image->channel_map[RedPixelChannel].offset]=red;
714 static inline void SetPixelRedTraits(Image *image,const PixelTrait traits)
716 image->channel_map[RedPixelChannel].traits=traits;
719 static inline void SetPixelYellow(const Image *restrict image,
720 const Quantum yellow,Quantum *restrict pixel)
722 pixel[image->channel_map[YellowPixelChannel].offset]=yellow;
725 static inline void SetPixelYellowTraits(Image *image,const PixelTrait traits)
727 image->channel_map[YellowPixelChannel].traits=traits;
730 static inline void SetPixelY(const Image *restrict image,const Quantum y,
731 Quantum *restrict pixel)
733 pixel[image->channel_map[YPixelChannel].offset]=y;
736 static inline void SetPixelYTraits(Image *image,const PixelTrait traits)
738 image->channel_map[YPixelChannel].traits=traits;
741 #if defined(__cplusplus) || defined(c_plusplus)