18#ifndef MAGICKCORE_COMPOSITE_PRIVATE_H
19#define MAGICKCORE_COMPOSITE_PRIVATE_H
22#include "MagickCore/color.h"
23#include "MagickCore/image.h"
24#include "MagickCore/artifact.h"
25#include "MagickCore/image-private.h"
26#include "MagickCore/pixel-accessor.h"
28#if defined(__cplusplus) || defined(c_plusplus)
35static inline double MagickOver_(
const double p,
const double alpha,
36 const double q,
const double beta)
42 Sa=QuantumScale*alpha;
44 return(Sa*p+Da*q*(1.0-Sa));
47static inline double RoundToUnity(
const double value)
49 return(value < 0.0 ? 0.0 : (value > 1.0) ? 1.0 : value);
52static inline void CompositePixelOver(
const Image *image,
const PixelInfo *p,
53 const double alpha,
const Quantum *q,
const double beta,Quantum *composite)
66 Sa=QuantumScale*alpha;
69 gamma=PerceptibleReciprocal(gamma);
70 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
78 channel=GetPixelChannelChannel(image,i);
79 traits=GetPixelChannelTraits(image,channel);
80 if (traits == UndefinedPixelTrait)
86 composite[i]=ClampToQuantum(gamma*MagickOver_((
double) p->red,alpha,
90 case GreenPixelChannel:
92 composite[i]=ClampToQuantum(gamma*MagickOver_((
double) p->green,alpha,
96 case BluePixelChannel:
98 composite[i]=ClampToQuantum(gamma*MagickOver_((
double) p->blue,alpha,
102 case BlackPixelChannel:
104 composite[i]=ClampToQuantum(gamma*MagickOver_((
double) p->black,alpha,
105 (
double) q[i],beta));
108 case AlphaPixelChannel:
110 composite[i]=ClampToQuantum((
double) QuantumRange*
111 RoundToUnity(Sa+Da-Sa*Da));
123static inline void CompositePixelInfoOver(
const PixelInfo *p,
const double alpha,
134 Sa=QuantumScale*alpha;
135 Da=QuantumScale*beta,
137 composite->alpha=(double) QuantumRange*RoundToUnity(gamma);
138 gamma=PerceptibleReciprocal(gamma);
139 composite->red=gamma*MagickOver_(p->red,alpha,q->red,beta);
140 composite->green=gamma*MagickOver_(p->green,alpha,q->green,beta);
141 composite->blue=gamma*MagickOver_(p->blue,alpha,q->blue,beta);
142 if (q->colorspace == CMYKColorspace)
143 composite->black=gamma*MagickOver_(p->black,alpha,q->black,beta);
146static inline void CompositePixelInfoPlus(
const PixelInfo *p,
157 Sa=QuantumScale*alpha;
158 Da=QuantumScale*beta;
159 gamma=RoundToUnity(Sa+Da);
160 composite->alpha=(double) QuantumRange*RoundToUnity(gamma);
161 gamma=PerceptibleReciprocal(gamma);
162 composite->red=gamma*(Sa*p->red+Da*q->red);
163 composite->green=gamma*(Sa*p->green+Da*q->green);
164 composite->blue=gamma*(Sa*p->blue+Da*q->blue);
165 if (q->colorspace == CMYKColorspace)
166 composite->black=gamma*(Sa*p->black+Da*q->black);
169static inline void CompositePixelInfoAreaBlend(
const PixelInfo *p,
170 const double alpha,
const PixelInfo *q,
const double beta,
const double area,
176 CompositePixelInfoPlus(p,(
double) (1.0-area)*alpha,q,(
double) (area*beta),
180static inline void CompositePixelInfoBlend(
const PixelInfo *p,
186 CompositePixelInfoPlus(p,(
double) (alpha*p->alpha),q,(
double) (beta*q->alpha),
190static inline void DisableCompositeClampUnlessSpecified(
Image *image)
192 if (GetImageArtifact(image,
"compose:clamp") == (
const char *) NULL)
193 (void) SetImageArtifact(image,
"compose:clamp",
"off");
196static inline MagickBooleanType GetCompositeClipToSelf(
197 const CompositeOperator compose)
201 case ClearCompositeOp:
204 case SrcInCompositeOp:
206 case SrcOutCompositeOp:
207 case DstInCompositeOp:
208 case DstAtopCompositeOp:
209 case CopyAlphaCompositeOp:
210 case ChangeMaskCompositeOp:
221#if defined(__cplusplus) || defined(c_plusplus)