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-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 ssize_t offset)
91 return(image->channel_map[offset].channel);
94 static inline ssize_t 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 GetPixelIntensity(const Image *restrict image,
197 const Quantum *restrict pixel)
199 #if !defined(MAGICKCORE_HDRI_SUPPORT)
200 if ((pixel[image->channel_map[RedPixelChannel].offset] ==
201 pixel[image->channel_map[GreenPixelChannel].offset]) &&
202 (pixel[image->channel_map[GreenPixelChannel].offset] ==
203 pixel[image->channel_map[BluePixelChannel].offset]))
204 return(pixel[image->channel_map[RedPixelChannel].offset]);
205 return((Quantum) (0.299*pixel[image->channel_map[RedPixelChannel].offset]+
206 0.587*pixel[image->channel_map[GreenPixelChannel].offset]+0.114*
207 pixel[image->channel_map[BluePixelChannel].offset]+0.5));
214 alpha=pixel[image->channel_map[RedPixelChannel].offset]-(double)
215 pixel[image->channel_map[GreenPixelChannel].offset];
216 beta=pixel[image->channel_map[GreenPixelChannel].offset]-(double)
217 pixel[image->channel_map[BluePixelChannel].offset];
218 if ((fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
219 return(pixel[image->channel_map[RedPixelChannel].offset]);
220 return((Quantum) (0.299*pixel[image->channel_map[RedPixelChannel].offset]+
221 0.587*pixel[image->channel_map[GreenPixelChannel].offset]+0.114*
222 pixel[image->channel_map[BluePixelChannel].offset]));
227 static inline Quantum GetPixelLuminance(const Image *restrict image,
228 const Quantum *restrict pixel)
230 #if !defined(MAGICKCORE_HDRI_SUPPORT)
231 return((Quantum) (0.21267*pixel[image->channel_map[RedPixelChannel].offset]+
232 0.71516*pixel[image->channel_map[GreenPixelChannel].offset]+0.07217*
233 pixel[image->channel_map[BluePixelChannel].offset]+0.5));
235 return((Quantum) (0.21267*pixel[image->channel_map[RedPixelChannel].offset]+
236 0.71516*pixel[image->channel_map[GreenPixelChannel].offset]+0.07217*
237 pixel[image->channel_map[BluePixelChannel].offset]));
241 static inline Quantum GetPixelMagenta(const Image *restrict image,
242 const Quantum *restrict pixel)
244 return(pixel[image->channel_map[MagentaPixelChannel].offset]);
247 static inline PixelTrait GetPixelMagentaTraits(const Image *restrict image)
249 return(image->channel_map[MagentaPixelChannel].traits);
252 static inline size_t GetPixelMetaChannels(const Image *restrict image)
254 return(image->number_meta_channels);
257 static inline size_t GetPixelMetacontentExtent(const Image *restrict image)
259 return(image->metacontent_extent);
262 static inline Quantum GetPixelRed(const Image *restrict image,
263 const Quantum *restrict pixel)
265 return(pixel[image->channel_map[RedPixelChannel].offset]);
268 static inline PixelTrait GetPixelRedTraits(const Image *restrict image)
270 return(image->channel_map[RedPixelChannel].traits);
273 static inline void GetPixelInfoPixel(const Image *restrict image,
274 const Quantum *restrict pixel,PixelInfo *restrict pixel_info)
276 pixel_info->red=(MagickRealType)
277 pixel[image->channel_map[RedPixelChannel].offset];
278 pixel_info->green=(MagickRealType)
279 pixel[image->channel_map[GreenPixelChannel].offset];
280 pixel_info->blue=(MagickRealType)
281 pixel[image->channel_map[BluePixelChannel].offset];
283 if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
284 pixel_info->black=(MagickRealType)
285 pixel[image->channel_map[BlackPixelChannel].offset];
286 pixel_info->alpha=OpaqueAlpha;
287 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
288 pixel_info->alpha=(MagickRealType)
289 pixel[image->channel_map[AlphaPixelChannel].offset];
291 if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
292 pixel_info->index=(MagickRealType)
293 pixel[image->channel_map[IndexPixelChannel].offset];
296 static inline PixelTrait GetPixelTraits(const Image *restrict image,
297 const PixelChannel channel)
299 return(image->channel_map[channel].traits);
302 static inline Quantum GetPixelY(const Image *restrict image,
303 const Quantum *restrict pixel)
305 return(pixel[image->channel_map[YPixelChannel].offset]);
308 static inline PixelTrait GetPixelYTraits(const Image *restrict image)
310 return(image->channel_map[YPixelChannel].traits);
313 static inline Quantum GetPixelYellow(const Image *restrict image,
314 const Quantum *restrict pixel)
316 return(pixel[image->channel_map[YellowPixelChannel].offset]);
319 static inline PixelTrait GetPixelYellowTraits(const Image *restrict image)
321 return(image->channel_map[YellowPixelChannel].traits);
324 static inline MagickBooleanType IsPixelEquivalent(const Image *restrict image,
325 const Quantum *restrict p,const PixelInfo *restrict q)
327 if (((double) p[image->channel_map[RedPixelChannel].offset] == q->red) &&
328 ((double) p[image->channel_map[GreenPixelChannel].offset] == q->green) &&
329 ((double) p[image->channel_map[BluePixelChannel].offset] == q->blue))
334 static inline MagickBooleanType IsPixelGray(const Image *restrict image,
335 const Quantum *restrict pixel)
337 #if !defined(MAGICKCORE_HDRI_SUPPORT)
338 if ((pixel[image->channel_map[RedPixelChannel].offset] ==
339 pixel[image->channel_map[GreenPixelChannel].offset]) &&
340 (pixel[image->channel_map[GreenPixelChannel].offset] ==
341 pixel[image->channel_map[BluePixelChannel].offset]))
349 alpha=pixel[image->channel_map[RedPixelChannel].offset]-(double)
350 pixel[image->channel_map[GreenPixelChannel].offset];
351 beta=pixel[image->channel_map[GreenPixelChannel].offset]-(double)
352 pixel[image->channel_map[BluePixelChannel].offset];
353 if ((fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
360 static inline MagickBooleanType IsPixelInfoEquivalent(
361 const PixelInfo *restrict p,const PixelInfo *restrict q)
363 if ((p->matte != MagickFalse) && (q->matte == MagickFalse) &&
364 (fabs(p->alpha-OpaqueAlpha) > 0.5))
366 if ((q->matte != MagickFalse) && (p->matte == MagickFalse) &&
367 (fabs(q->alpha-OpaqueAlpha)) > 0.5)
369 if ((p->matte != MagickFalse) && (q->matte != MagickFalse))
371 if (fabs(p->alpha-q->alpha) > 0.5)
373 if (fabs(p->alpha-TransparentAlpha) <= 0.5)
376 if (fabs(p->red-q->red) > 0.5)
378 if (fabs(p->green-q->green) > 0.5)
380 if (fabs(p->blue-q->blue) > 0.5)
382 if ((p->colorspace == CMYKColorspace) && (fabs(p->black-q->black) > 0.5))
387 static inline MagickBooleanType IsPixelMonochrome(const Image *restrict image,
388 const Quantum *restrict pixel)
390 #if !defined(MAGICKCORE_HDRI_SUPPORT)
391 if (((pixel[image->channel_map[RedPixelChannel].offset] == 0) ||
392 (pixel[image->channel_map[RedPixelChannel].offset] == (Quantum) QuantumRange)) &&
393 (pixel[image->channel_map[RedPixelChannel].offset] ==
394 pixel[image->channel_map[GreenPixelChannel].offset]) &&
395 (pixel[image->channel_map[GreenPixelChannel].offset] ==
396 pixel[image->channel_map[BluePixelChannel].offset]))
404 alpha=pixel[image->channel_map[RedPixelChannel].offset]-(double)
405 pixel[image->channel_map[GreenPixelChannel].offset];
406 beta=pixel[image->channel_map[GreenPixelChannel].offset]-(double)
407 pixel[image->channel_map[BluePixelChannel].offset];
408 if (((fabs(pixel[image->channel_map[RedPixelChannel].offset]) <= MagickEpsilon) ||
409 (fabs(pixel[image->channel_map[RedPixelChannel].offset]-QuantumRange) <= MagickEpsilon)) &&
410 (fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
417 static inline MagickBooleanType IsPixelInfoGray(
418 const PixelInfo *restrict pixel_info)
420 #if !defined(MAGICKCORE_HDRI_SUPPORT)
421 if ((pixel_info->red == pixel_info->green) &&
422 (pixel_info->green == pixel_info->blue))
430 alpha=pixel_info->red-(double) pixel_info->green;
431 beta=pixel_info->green-(double) pixel_info->blue;
432 if ((fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
439 static inline MagickBooleanType IsPixelInfoMonochrome(
440 const PixelInfo *restrict pixel_info)
442 #if !defined(MAGICKCORE_HDRI_SUPPORT)
443 if (((pixel_info->red == 0) || (pixel_info->red == (Quantum) QuantumRange)) &&
444 (pixel_info->red == pixel_info->green) &&
445 (pixel_info->green == pixel_info->blue))
453 alpha=pixel_info->red-(double) pixel_info->green;
454 beta=pixel_info->green-(double) pixel_info->blue;
455 if (((fabs(pixel_info->red) <= MagickEpsilon) ||
456 (fabs(pixel_info->red-QuantumRange) <= MagickEpsilon)) &&
457 (fabs(alpha) <= MagickEpsilon) && (fabs(beta) <= MagickEpsilon))
464 static inline void SetPixelAlpha(const Image *restrict image,
465 const Quantum alpha,Quantum *restrict pixel)
467 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
468 pixel[image->channel_map[AlphaPixelChannel].offset]=alpha;
471 static inline void SetPixelAlphaTraits(Image *image,const PixelTrait traits)
473 image->channel_map[AlphaPixelChannel].traits=traits;
476 static inline void SetPixelBlack(const Image *restrict image,
477 const Quantum black,Quantum *restrict pixel)
479 if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
480 pixel[image->channel_map[BlackPixelChannel].offset]=black;
483 static inline void SetPixelBlackTraits(Image *image,const PixelTrait traits)
485 image->channel_map[BlackPixelChannel].traits=traits;
488 static inline void SetPixelBlue(const Image *restrict image,const Quantum blue,
489 Quantum *restrict pixel)
491 pixel[image->channel_map[BluePixelChannel].offset]=blue;
494 static inline void SetPixelBlueTraits(Image *image,const PixelTrait traits)
496 image->channel_map[BluePixelChannel].traits=traits;
499 static inline void SetPixelCb(const Image *restrict image,const Quantum cb,
500 Quantum *restrict pixel)
502 pixel[image->channel_map[CbPixelChannel].offset]=cb;
505 static inline void SetPixelCbTraits(Image *image,const PixelTrait traits)
507 image->channel_map[CbPixelChannel].traits=traits;
510 static inline void SetPixelChannel(const Image *restrict image,
511 const PixelChannel channel,const Quantum quantum,Quantum *restrict pixel)
513 if (image->channel_map[channel].traits != UndefinedPixelTrait)
514 pixel[image->channel_map[channel].offset]=quantum;
517 static inline void SetPixelChannelMapChannel(const Image *restrict image,
518 const PixelChannel channel,const ssize_t offset)
520 image->channel_map[offset].channel=channel;
521 image->channel_map[channel].offset=offset;
524 static inline void SetPixelChannelMap(const Image *restrict image,
525 const PixelChannel channel,const PixelTrait traits,const ssize_t offset)
527 image->channel_map[offset].channel=channel;
528 image->channel_map[channel].offset=offset;
529 image->channel_map[channel].traits=traits;
532 static inline void SetPixelChannels(Image *image,const size_t number_channels)
534 image->number_channels=number_channels;
537 static inline void SetPixelChannelTraits(Image *image,
538 const PixelChannel channel,const PixelTrait traits)
540 image->channel_map[channel].traits=traits;
543 static inline void SetPixelChannelMapTraits(Image *image,
544 const PixelChannel channel,const PixelTrait traits)
546 image->channel_map[channel].traits=traits;
549 static inline void SetPixelCr(const Image *restrict image,const Quantum cr,
550 Quantum *restrict pixel)
552 pixel[image->channel_map[CrPixelChannel].offset]=cr;
555 static inline void SetPixelCrTraits(Image *image,const PixelTrait traits)
557 image->channel_map[CrPixelChannel].traits=traits;
560 static inline void SetPixelCyan(const Image *restrict image,const Quantum cyan,
561 Quantum *restrict pixel)
563 pixel[image->channel_map[CyanPixelChannel].offset]=cyan;
566 static inline void SetPixelGray(const Image *restrict image,const Quantum gray,
567 Quantum *restrict pixel)
569 pixel[image->channel_map[GrayPixelChannel].offset]=gray;
572 static inline void SetPixelGrayTraits(Image *image,const PixelTrait traits)
574 image->channel_map[GrayPixelChannel].traits=traits;
577 static inline void SetPixelGreen(const Image *restrict image,
578 const Quantum green,Quantum *restrict pixel)
580 pixel[image->channel_map[GreenPixelChannel].offset]=green;
583 static inline void SetPixelGreenTraits(Image *image,const PixelTrait traits)
585 image->channel_map[GreenPixelChannel].traits=traits;
588 static inline void SetPixelIndex(const Image *restrict image,
589 const Quantum index,Quantum *restrict pixel)
591 if (image->channel_map[IndexPixelChannel].traits != UndefinedPixelTrait)
592 pixel[image->channel_map[IndexPixelChannel].offset]=index;
595 static inline void SetPixelIndexTraits(Image *image,const PixelTrait traits)
597 image->channel_map[IndexPixelChannel].traits=traits;
600 static inline void SetPixelInfoPixel(const Image *restrict image,
601 const PixelInfo *restrict pixel_info,Quantum *restrict pixel)
603 pixel[image->channel_map[RedPixelChannel].offset]=
604 ClampToQuantum(pixel_info->red);
605 pixel[image->channel_map[GreenPixelChannel].offset]=
606 ClampToQuantum(pixel_info->green);
607 pixel[image->channel_map[BluePixelChannel].offset]=
608 ClampToQuantum(pixel_info->blue);
609 if (image->channel_map[BlackPixelChannel].traits != UndefinedPixelTrait)
610 pixel[image->channel_map[BlackPixelChannel].offset]=
611 ClampToQuantum(pixel_info->black);
612 if (image->channel_map[AlphaPixelChannel].traits != UndefinedPixelTrait)
613 pixel[image->channel_map[AlphaPixelChannel].offset]=pixel_info->matte ==
614 MagickFalse ? OpaqueAlpha : ClampToQuantum(pixel_info->alpha);
617 static inline void SetPixelMagenta(const Image *restrict image,
618 const Quantum magenta,Quantum *restrict pixel)
620 pixel[image->channel_map[MagentaPixelChannel].offset]=magenta;
623 static inline void SetPixelMagentaTraits(Image *image,const PixelTrait traits)
625 image->channel_map[MagentaPixelChannel].traits=traits;
628 static inline void SetPixelMetaChannels(Image *image,
629 const size_t number_meta_channels)
631 image->number_meta_channels=number_meta_channels;
634 static inline void SetPixelMetacontentExtent(Image *image,const size_t extent)
636 image->metacontent_extent=extent;
639 static inline void SetPixelRed(const Image *restrict image,const Quantum red,
640 Quantum *restrict pixel)
642 pixel[image->channel_map[RedPixelChannel].offset]=red;
645 static inline void SetPixelRedTraits(Image *image,const PixelTrait traits)
647 image->channel_map[RedPixelChannel].traits=traits;
650 static inline void SetPixelYellow(const Image *restrict image,
651 const Quantum yellow,Quantum *restrict pixel)
653 pixel[image->channel_map[YellowPixelChannel].offset]=yellow;
656 static inline void SetPixelYellowTraits(Image *image,const PixelTrait traits)
658 image->channel_map[YellowPixelChannel].traits=traits;
661 static inline void SetPixelY(const Image *restrict image,const Quantum y,
662 Quantum *restrict pixel)
664 pixel[image->channel_map[YPixelChannel].offset]=y;
667 static inline void SetPixelYTraits(Image *image,const PixelTrait traits)
669 image->channel_map[YPixelChannel].traits=traits;
672 #if defined(__cplusplus) || defined(c_plusplus)