2 Copyright 1999-2011 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-view.h>
27 #include <MagickCore/color.h>
28 #include <MagickCore/image.h>
32 static inline Quantum GetPixelAlpha(const Image *restrict image,
33 const Quantum *restrict pixel)
35 if (image->channel_map[AlphaPixelChannel].traits == UndefinedPixelTrait)
37 return(pixel[image->channel_map[AlphaPixelChannel].offset]);
40 static inline PixelTrait GetPixelAlphaTraits(const Image *restrict image)
42 return(image->channel_map[AlphaPixelChannel].traits);
45 static inline Quantum GetPixelBlack(const Image *restrict image,
46 const Quantum *restrict pixel)
48 if (image->channel_map[BlackPixelChannel].traits == UndefinedPixelTrait)
50 return(pixel[image->channel_map[BlackPixelChannel].offset]);
53 static inline PixelTrait GetPixelBlackTraits(const Image *restrict image)
55 return(image->channel_map[BlackPixelChannel].traits);
58 static inline Quantum GetPixelBlue(const Image *restrict image,
59 const Quantum *restrict pixel)
61 return(pixel[image->channel_map[BluePixelChannel].offset]);
64 static inline PixelTrait GetPixelBlueTraits(const Image *restrict image)
66 return(image->channel_map[BluePixelChannel].traits);
69 static inline Quantum GetPixelCb(const Image *restrict image,
70 const Quantum *restrict pixel)
72 return(pixel[image->channel_map[CbPixelChannel].offset]);
75 static inline PixelTrait GetPixelCbTraits(const Image *restrict image)
77 return(image->channel_map[CbPixelChannel].traits);
80 static inline Quantum GetPixelChannel(const Image *restrict image,
81 const PixelChannel channel,const Quantum *restrict pixel)
83 if (image->channel_map[channel].traits == UndefinedPixelTrait)
85 return(pixel[image->channel_map[channel].offset]);
88 static inline PixelChannel GetPixelChannelMapChannel(
89 const Image *restrict image,const int offset)
91 return(image->channel_map[offset].channel);
94 static inline int GetPixelChannelMapOffset(const Image *restrict image,
95 const PixelChannel channel)
97 return(image->channel_map[channel].offset);
100 static inline PixelTrait GetPixelChannelMapTraits(const Image *restrict image,
101 const PixelChannel channel)
103 return(image->channel_map[channel].traits);
106 static inline size_t GetPixelChannels(const Image *restrict image)
108 return(image->number_channels);
111 static inline Quantum GetPixelCr(const Image *restrict image,
112 const Quantum *restrict pixel)
114 return(pixel[image->channel_map[CrPixelChannel].offset]);
117 static inline PixelTrait GetPixelCrTraits(const Image *restrict image)
119 return(image->channel_map[CrPixelChannel].traits);
122 static inline Quantum GetPixelCyan(const Image *restrict image,
123 const Quantum *restrict pixel)
125 return(pixel[image->channel_map[CyanPixelChannel].offset]);
128 static inline PixelTrait GetPixelCyanTraits(const Image *restrict image)
130 return(image->channel_map[CyanPixelChannel].traits);
133 static inline Quantum GetPixelGray(const Image *restrict image,
134 const Quantum *restrict pixel)
136 return(pixel[image->channel_map[GrayPixelChannel].offset]);
139 static inline PixelTrait GetPixelGrayTraits(const Image *restrict image)
141 return(image->channel_map[GrayPixelChannel].traits);
144 static inline Quantum GetPixelGreen(const Image *restrict image,
145 const Quantum *restrict pixel)
147 return(pixel[image->channel_map[GreenPixelChannel].offset]);
150 static inline PixelTrait GetPixelGreenTraits(const Image *restrict image)
152 return(image->channel_map[GreenPixelChannel].traits);
155 static inline Quantum GetPixelIndex(const Image *restrict image,
156 const Quantum *restrict pixel)
158 if (image->channel_map[IndexPixelChannel].traits == UndefinedPixelTrait)
160 return(pixel[image->channel_map[IndexPixelChannel].offset]);
163 static inline PixelTrait GetPixelIndexTraits(const Image *restrict image)
165 return(image->channel_map[IndexPixelChannel].traits);
168 static inline Quantum GetPixelInfoIntensity(
169 const PixelInfo *restrict pixel_info)
171 #if !defined(MAGICKCORE_HDRI_SUPPORT)
172 return((Quantum) (0.299*pixel_info->red+0.587*pixel_info->green+0.114*
173 pixel_info->blue+0.5));
175 return((Quantum) (0.299*pixel_info->red+0.587*pixel_info->green+0.114*
180 static inline Quantum GetPixelInfoLuminance(
181 const PixelInfo *restrict pixel_info)
186 #if !defined(MAGICKCORE_HDRI_SUPPORT)
187 luminance=(Quantum) (0.21267*pixel_info->red+0.71516*pixel_info->green+
188 0.07217*pixel_info->blue+0.5);
190 luminance=(Quantum) (0.21267*pixel_info->red+0.71516*pixel_info->green+
191 0.07217*pixel_info->blue);
193 return((Quantum) luminance);
196 static inline Quantum GetPixelMagenta(const Image *restrict image,
197 const Quantum *restrict pixel)
199 return(pixel[image->channel_map[MagentaPixelChannel].offset]);
202 static inline PixelTrait GetPixelMagentaTraits(const Image *restrict image)
204 return(image->channel_map[MagentaPixelChannel].traits);
207 static inline size_t GetPixelMetaChannels(const Image *restrict image)
209 return(image->number_meta_channels);
212 static inline size_t GetPixelMetacontentExtent(const Image *restrict image)
214 return(image->metacontent_extent);
217 static inline Quantum GetPixelRed(const Image *restrict image,
218 const Quantum *restrict pixel)
220 return(pixel[image->channel_map[RedPixelChannel].offset]);
223 static inline PixelTrait GetPixelRedTraits(const Image *restrict image)
225 return(image->channel_map[RedPixelChannel].traits);
228 static inline void GetPixelInfoPixel(const Image *restrict image,
229 const Quantum *restrict pixel,PixelInfo *restrict pixel_info)
231 pixel_info->red=(MagickRealType)
232 pixel[image->channel_map[RedPixelChannel].offset];
233 pixel_info->green=(MagickRealType)
234 pixel[image->channel_map[GreenPixelChannel].offset];
235 pixel_info->blue=(MagickRealType)
236 pixel[image->channel_map[BluePixelChannel].offset];
238 if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
239 pixel_info->black=(MagickRealType)
240 pixel[image->channel_map[BlackPixelChannel].offset];
241 pixel_info->alpha=OpaqueAlpha;
242 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
243 pixel_info->alpha=(MagickRealType)
244 pixel[image->channel_map[AlphaPixelChannel].offset];
246 if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
247 pixel_info->index=(MagickRealType)
248 pixel[image->channel_map[IndexPixelChannel].offset];
251 static inline PixelTrait GetPixelTraits(const Image *restrict image,
252 const PixelChannel channel)
254 return(image->channel_map[channel].traits);
257 static inline Quantum GetPixelY(const Image *restrict image,
258 const Quantum *restrict pixel)
260 return(pixel[image->channel_map[YPixelChannel].offset]);
263 static inline PixelTrait GetPixelYTraits(const Image *restrict image)
265 return(image->channel_map[YPixelChannel].traits);
268 static inline Quantum GetPixelYellow(const Image *restrict image,
269 const Quantum *restrict pixel)
271 return(pixel[image->channel_map[YellowPixelChannel].offset]);
274 static inline PixelTrait GetPixelYellowTraits(const Image *restrict image)
276 return(image->channel_map[YellowPixelChannel].traits);
279 static inline MagickBooleanType IsPixelEquivalent(const Image *restrict image,
280 const Quantum *restrict p,const PixelInfo *restrict q)
282 if (((double) p[image->channel_map[RedPixelChannel].offset] == q->red) &&
283 ((double) p[image->channel_map[GreenPixelChannel].offset] == q->green) &&
284 ((double) p[image->channel_map[BluePixelChannel].offset] == q->blue))
289 static inline MagickBooleanType IsPixelGray(const Image *restrict image,
290 const Quantum *restrict pixel)
292 #if !defined(MAGICKCORE_HDRI_SUPPORT)
293 if ((pixel[image->channel_map[RedPixelChannel].offset] ==
294 pixel[image->channel_map[GreenPixelChannel].offset]) &&
295 (pixel[image->channel_map[GreenPixelChannel].offset] ==
296 pixel[image->channel_map[BluePixelChannel].offset]))
304 alpha=pixel[image->channel_map[RedPixelChannel].offset]-(double)
305 pixel[image->channel_map[GreenPixelChannel].offset];
306 beta=pixel[image->channel_map[GreenPixelChannel].offset]-(double)
307 pixel[image->channel_map[BluePixelChannel].offset];
308 if ((fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
315 static inline MagickBooleanType IsPixelInfoEquivalent(
316 const PixelInfo *restrict p,const PixelInfo *restrict q)
318 if ((p->matte != MagickFalse) && (q->matte == MagickFalse) &&
319 (fabs(p->alpha-OpaqueAlpha) > 0.5))
321 if ((q->matte != MagickFalse) && (p->matte == MagickFalse) &&
322 (fabs(q->alpha-OpaqueAlpha)) > 0.5)
324 if ((p->matte != MagickFalse) && (q->matte != MagickFalse))
326 if (fabs(p->alpha-q->alpha) > 0.5)
328 if (fabs(p->alpha-TransparentAlpha) <= 0.5)
331 if (fabs(p->red-q->red) > 0.5)
333 if (fabs(p->green-q->green) > 0.5)
335 if (fabs(p->blue-q->blue) > 0.5)
337 if ((p->colorspace == CMYKColorspace) && (fabs(p->black-q->black) > 0.5))
342 static inline MagickBooleanType IsPixelMonochrome(const Image *restrict image,
343 const Quantum *restrict pixel)
345 #if !defined(MAGICKCORE_HDRI_SUPPORT)
346 if (((pixel[image->channel_map[RedPixelChannel].offset] == 0) ||
347 (pixel[image->channel_map[RedPixelChannel].offset] == (Quantum) QuantumRange)) &&
348 (pixel[image->channel_map[RedPixelChannel].offset] ==
349 pixel[image->channel_map[GreenPixelChannel].offset]) &&
350 (pixel[image->channel_map[GreenPixelChannel].offset] ==
351 pixel[image->channel_map[BluePixelChannel].offset]))
359 alpha=pixel[image->channel_map[RedPixelChannel].offset]-(double)
360 pixel[image->channel_map[GreenPixelChannel].offset];
361 beta=pixel[image->channel_map[GreenPixelChannel].offset]-(double)
362 pixel[image->channel_map[BluePixelChannel].offset];
363 if (((fabs(pixel[image->channel_map[RedPixelChannel].offset]) <= MagickEpsilon) ||
364 (fabs(pixel[image->channel_map[RedPixelChannel].offset]-QuantumRange) <= MagickEpsilon)) &&
365 (fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
372 static inline MagickBooleanType IsPixelInfoGray(
373 const PixelInfo *restrict pixel_info)
375 #if !defined(MAGICKCORE_HDRI_SUPPORT)
376 if ((pixel_info->red == pixel_info->green) &&
377 (pixel_info->green == pixel_info->blue))
385 alpha=pixel_info->red-(double) pixel_info->green;
386 beta=pixel_info->green-(double) pixel_info->blue;
387 if ((fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
394 static inline MagickBooleanType IsPixelInfoMonochrome(
395 const PixelInfo *restrict pixel_info)
397 #if !defined(MAGICKCORE_HDRI_SUPPORT)
398 if (((pixel_info->red == 0) || (pixel_info->red == (Quantum) QuantumRange)) &&
399 (pixel_info->red == pixel_info->green) &&
400 (pixel_info->green == pixel_info->blue))
408 alpha=pixel_info->red-(double) pixel_info->green;
409 beta=pixel_info->green-(double) pixel_info->blue;
410 if (((fabs(pixel_info->red) <= MagickEpsilon) ||
411 (fabs(pixel_info->red-QuantumRange) <= MagickEpsilon)) &&
412 (fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
419 static inline void SetPixelAlpha(const Image *restrict image,
420 const Quantum alpha,Quantum *restrict pixel)
422 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
423 pixel[image->channel_map[AlphaPixelChannel].offset]=alpha;
426 static inline void SetPixelAlphaTraits(Image *image,const PixelTrait traits)
428 image->channel_map[AlphaPixelChannel].traits=traits;
431 static inline void SetPixelBlack(const Image *restrict image,
432 const Quantum black,Quantum *restrict pixel)
434 if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
435 pixel[image->channel_map[BlackPixelChannel].offset]=black;
438 static inline void SetPixelBlackTraits(Image *image,const PixelTrait traits)
440 image->channel_map[BlackPixelChannel].traits=traits;
443 static inline void SetPixelBlue(const Image *restrict image,const Quantum blue,
444 Quantum *restrict pixel)
446 pixel[image->channel_map[BluePixelChannel].offset]=blue;
449 static inline void SetPixelBlueTraits(Image *image,const PixelTrait traits)
451 image->channel_map[BluePixelChannel].traits=traits;
454 static inline void SetPixelCb(const Image *restrict image,const Quantum cb,
455 Quantum *restrict pixel)
457 pixel[image->channel_map[CbPixelChannel].offset]=cb;
460 static inline void SetPixelCbTraits(Image *image,const PixelTrait traits)
462 image->channel_map[CbPixelChannel].traits=traits;
465 static inline void SetPixelChannel(const Image *restrict image,
466 const PixelChannel channel,const Quantum quantum,Quantum *restrict pixel)
468 if (image->channel_map[channel].traits != UndefinedPixelTrait)
469 pixel[image->channel_map[channel].offset]=quantum;
472 static inline void SetPixelChannelMapChannel(const Image *restrict image,
473 const PixelChannel channel,const int offset)
475 image->channel_map[offset].channel=channel;
476 image->channel_map[channel].offset=offset;
479 static inline void SetPixelChannelMap(const Image *restrict image,
480 const PixelChannel channel,const PixelTrait traits,const int offset)
482 image->channel_map[offset].channel=channel;
483 image->channel_map[channel].offset=offset;
484 image->channel_map[channel].traits=traits;
487 static inline void SetPixelChannels(Image *image,const size_t number_channels)
489 image->number_channels=number_channels;
492 static inline void SetPixelChannelTraits(Image *image,
493 const PixelChannel channel,const PixelTrait traits)
495 image->channel_map[channel].traits=traits;
498 static inline void SetPixelChannelMapTraits(Image *image,
499 const PixelChannel channel,const PixelTrait traits)
501 image->channel_map[channel].traits=traits;
504 static inline void SetPixelCr(const Image *restrict image,const Quantum cr,
505 Quantum *restrict pixel)
507 pixel[image->channel_map[CrPixelChannel].offset]=cr;
510 static inline void SetPixelCrTraits(Image *image,const PixelTrait traits)
512 image->channel_map[CrPixelChannel].traits=traits;
515 static inline void SetPixelCyan(const Image *restrict image,const Quantum cyan,
516 Quantum *restrict pixel)
518 pixel[image->channel_map[CyanPixelChannel].offset]=cyan;
521 static inline void SetPixelGray(const Image *restrict image,const Quantum gray,
522 Quantum *restrict pixel)
524 pixel[image->channel_map[GrayPixelChannel].offset]=gray;
527 static inline void SetPixelGrayTraits(Image *image,const PixelTrait traits)
529 image->channel_map[GrayPixelChannel].traits=traits;
532 static inline void SetPixelGreen(const Image *restrict image,
533 const Quantum green,Quantum *restrict pixel)
535 pixel[image->channel_map[GreenPixelChannel].offset]=green;
538 static inline void SetPixelGreenTraits(Image *image,const PixelTrait traits)
540 image->channel_map[GreenPixelChannel].traits=traits;
543 static inline void SetPixelIndex(const Image *restrict image,
544 const Quantum index,Quantum *restrict pixel)
546 if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
547 pixel[image->channel_map[IndexPixelChannel].offset]=index;
550 static inline void SetPixelIndexTraits(Image *image,const PixelTrait traits)
552 image->channel_map[IndexPixelChannel].traits=traits;
555 static inline void SetPixelInfo(const Image *restrict image,
556 const PixelInfo *restrict p,PixelInfo *restrict q)
562 if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
564 q->alpha=OpaqueAlpha;
565 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
568 if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
572 static inline void SetPixelInfoPixel(const Image *restrict image,
573 const PixelInfo *restrict pixel_info,Quantum *restrict pixel)
575 pixel[image->channel_map[RedPixelChannel].offset]=
576 ClampToQuantum(pixel_info->red);
577 pixel[image->channel_map[GreenPixelChannel].offset]=
578 ClampToQuantum(pixel_info->green);
579 pixel[image->channel_map[BluePixelChannel].offset]=
580 ClampToQuantum(pixel_info->blue);
581 if ((image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait) &&
582 (image->colorspace == CMYKColorspace) &&
583 (pixel_info->colorspace == CMYKColorspace))
584 pixel[image->channel_map[BlackPixelChannel].offset]=
585 ClampToQuantum(pixel_info->black);
586 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
587 pixel[image->channel_map[AlphaPixelChannel].offset]=
588 pixel_info->matte == MagickFalse ? OpaqueAlpha :
589 ClampToQuantum(pixel_info->alpha);
592 static inline void SetPixelMagenta(const Image *restrict image,
593 const Quantum magenta,Quantum *restrict pixel)
595 pixel[image->channel_map[MagentaPixelChannel].offset]=magenta;
598 static inline void SetPixelMagentaTraits(Image *image,const PixelTrait traits)
600 image->channel_map[MagentaPixelChannel].traits=traits;
603 static inline void SetPixelMetaChannels(Image *image,
604 const size_t number_meta_channels)
606 image->number_meta_channels=number_meta_channels;
609 static inline void SetPixelMetacontentExtent(Image *image,const size_t extent)
611 image->metacontent_extent=extent;
614 static inline void SetPixelRed(const Image *restrict image,const Quantum red,
615 Quantum *restrict pixel)
617 pixel[image->channel_map[RedPixelChannel].offset]=red;
620 static inline void SetPixelRedTraits(Image *image,const PixelTrait traits)
622 image->channel_map[RedPixelChannel].traits=traits;
625 static inline void SetPixelYellow(const Image *restrict image,
626 const Quantum yellow,Quantum *restrict pixel)
628 pixel[image->channel_map[YellowPixelChannel].offset]=yellow;
631 static inline void SetPixelYellowTraits(Image *image,const PixelTrait traits)
633 image->channel_map[YellowPixelChannel].traits=traits;
636 static inline void SetPixelY(const Image *restrict image,const Quantum y,
637 Quantum *restrict pixel)
639 pixel[image->channel_map[YPixelChannel].offset]=y;
642 static inline void SetPixelYTraits(Image *image,const PixelTrait traits)
644 image->channel_map[YPixelChannel].traits=traits;
647 static inline Quantum GetPixelIntensity(const Image *restrict image,
648 const Quantum *restrict pixel)
650 #if !defined(MAGICKCORE_HDRI_SUPPORT)
651 if ((pixel[image->channel_map[RedPixelChannel].offset] ==
652 pixel[image->channel_map[GreenPixelChannel].offset]) &&
653 (pixel[image->channel_map[GreenPixelChannel].offset] ==
654 pixel[image->channel_map[BluePixelChannel].offset]))
655 return(pixel[image->channel_map[RedPixelChannel].offset]);
656 return((Quantum) (0.299*pixel[image->channel_map[RedPixelChannel].offset]+
657 0.587*pixel[image->channel_map[GreenPixelChannel].offset]+0.114*
658 pixel[image->channel_map[BluePixelChannel].offset]+0.5));
665 alpha=pixel[image->channel_map[RedPixelChannel].offset]-(double)
666 pixel[image->channel_map[GreenPixelChannel].offset];
667 beta=pixel[image->channel_map[GreenPixelChannel].offset]-(double)
668 pixel[image->channel_map[BluePixelChannel].offset];
669 if ((fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
670 return(pixel[image->channel_map[RedPixelChannel].offset]);
671 return((Quantum) (0.299*pixel[image->channel_map[RedPixelChannel].offset]+
672 0.587*pixel[image->channel_map[GreenPixelChannel].offset]+0.114*
673 pixel[image->channel_map[BluePixelChannel].offset]));
678 static inline Quantum GetPixelLuminance(const Image *restrict image,
679 const Quantum *restrict pixel)
681 #if !defined(MAGICKCORE_HDRI_SUPPORT)
682 return((Quantum) (0.21267*pixel[image->channel_map[RedPixelChannel].offset]+
683 0.71516*pixel[image->channel_map[GreenPixelChannel].offset]+0.07217*
684 pixel[image->channel_map[BluePixelChannel].offset]+0.5));
686 return((Quantum) (0.21267*pixel[image->channel_map[RedPixelChannel].offset]+
687 0.71516*pixel[image->channel_map[GreenPixelChannel].offset]+0.07217*
688 pixel[image->channel_map[BluePixelChannel].offset]));
692 #if defined(__cplusplus) || defined(c_plusplus)