00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef MAGICKCORE_COMPOSITE_PRIVATE_H
00019 #define MAGICKCORE_COMPOSITE_PRIVATE_H
00020
00021
00022 #include "MagickCore/color.h"
00023 #include "MagickCore/image.h"
00024 #include "MagickCore/image-private.h"
00025 #include "MagickCore/pixel-accessor.h"
00026 #include "MagickCore/pixel-private.h"
00027
00028 #if defined(__cplusplus) || defined(c_plusplus)
00029 extern "C" {
00030 #endif
00031
00032
00033
00034
00035 static inline double MagickOver_(const double p,const double alpha,
00036 const double q,const double beta)
00037 {
00038 double
00039 Da,
00040 Sa;
00041
00042 Sa=QuantumScale*alpha;
00043 Da=QuantumScale*beta;
00044 return(Sa*p+Da*q*(1.0-Sa));
00045 }
00046
00047 static inline double RoundToUnity(const double value)
00048 {
00049 return(value < 0.0 ? 0.0 : (value > 1.0) ? 1.0 : value);
00050 }
00051
00052 static inline void CompositePixelOver(const Image *image,const PixelInfo *p,
00053 const double alpha,const Quantum *q,const double beta,Quantum *composite)
00054 {
00055 double
00056 Da,
00057 gamma,
00058 Sa;
00059
00060 register ssize_t
00061 i;
00062
00063
00064
00065
00066 Sa=QuantumScale*alpha;
00067 Da=QuantumScale*beta;
00068 gamma=Sa+Da-Sa*Da;
00069 gamma=PerceptibleReciprocal(gamma);
00070 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
00071 {
00072 PixelChannel
00073 channel;
00074
00075 PixelTrait
00076 traits;
00077
00078 channel=GetPixelChannelChannel(image,i);
00079 traits=GetPixelChannelTraits(image,channel);
00080 if (traits == UndefinedPixelTrait)
00081 continue;
00082 switch (channel)
00083 {
00084 case RedPixelChannel:
00085 {
00086 composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->red,alpha,
00087 (double) q[i],beta));
00088 break;
00089 }
00090 case GreenPixelChannel:
00091 {
00092 composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->green,alpha,
00093 (double) q[i],beta));
00094 break;
00095 }
00096 case BluePixelChannel:
00097 {
00098 composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->blue,alpha,
00099 (double) q[i],beta));
00100 break;
00101 }
00102 case BlackPixelChannel:
00103 {
00104 composite[i]=ClampToQuantum(gamma*MagickOver_((double) p->black,alpha,
00105 (double) q[i],beta));
00106 break;
00107 }
00108 case AlphaPixelChannel:
00109 {
00110 composite[i]=ClampToQuantum(QuantumRange*RoundToUnity(Sa+Da-Sa*Da));
00111 break;
00112 }
00113 default:
00114 {
00115 composite[i]=q[i];
00116 break;
00117 }
00118 }
00119 }
00120 }
00121
00122 static inline void CompositePixelInfoOver(const PixelInfo *p,const double alpha,
00123 const PixelInfo *q,const double beta,PixelInfo *composite)
00124 {
00125 double
00126 Da,
00127 gamma,
00128 Sa;
00129
00130
00131
00132
00133 Sa=QuantumScale*alpha;
00134 Da=QuantumScale*beta,
00135 gamma=Sa+Da-Sa*Da;
00136 composite->alpha=(double) QuantumRange*RoundToUnity(gamma);
00137 gamma=PerceptibleReciprocal(gamma);
00138 composite->red=gamma*MagickOver_(p->red,alpha,q->red,beta);
00139 composite->green=gamma*MagickOver_(p->green,alpha,q->green,beta);
00140 composite->blue=gamma*MagickOver_(p->blue,alpha,q->blue,beta);
00141 if (q->colorspace == CMYKColorspace)
00142 composite->black=gamma*MagickOver_(p->black,alpha,q->black,beta);
00143 }
00144
00145 static inline void CompositePixelInfoPlus(const PixelInfo *p,
00146 const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite)
00147 {
00148 double
00149 Da,
00150 gamma,
00151 Sa;
00152
00153
00154
00155
00156 Sa=QuantumScale*alpha;
00157 Da=QuantumScale*beta;
00158 gamma=RoundToUnity(Sa+Da);
00159 composite->alpha=(double) QuantumRange*RoundToUnity(gamma);
00160 gamma=PerceptibleReciprocal(gamma);
00161 composite->red=gamma*(Sa*p->red+Da*q->red);
00162 composite->green=gamma*(Sa*p->green+Da*q->green);
00163 composite->blue=gamma*(Sa*p->blue+Da*q->blue);
00164 if (q->colorspace == CMYKColorspace)
00165 composite->black=gamma*(Sa*p->black+Da*q->black);
00166 }
00167
00168 static inline void CompositePixelInfoAreaBlend(const PixelInfo *p,
00169 const double alpha,const PixelInfo *q,const double beta,const double area,
00170 PixelInfo *composite)
00171 {
00172
00173
00174
00175 CompositePixelInfoPlus(p,(double) (1.0-area)*alpha,q,(double) (area*beta),
00176 composite);
00177 }
00178
00179 static inline void CompositePixelInfoBlend(const PixelInfo *p,
00180 const double alpha,const PixelInfo *q,const double beta,PixelInfo *composite)
00181 {
00182
00183
00184
00185 CompositePixelInfoPlus(p,(double) (alpha*p->alpha),q,(double) (beta*q->alpha),
00186 composite);
00187 }
00188
00189 static inline MagickBooleanType GetCompositeClipToSelf(
00190 const CompositeOperator compose)
00191 {
00192 switch (compose)
00193 {
00194 case ClearCompositeOp:
00195 case SrcCompositeOp:
00196 case InCompositeOp:
00197 case SrcInCompositeOp:
00198 case OutCompositeOp:
00199 case SrcOutCompositeOp:
00200 case DstInCompositeOp:
00201 case DstAtopCompositeOp:
00202 case CopyAlphaCompositeOp:
00203 case ChangeMaskCompositeOp:
00204 {
00205 return(MagickFalse);
00206 break;
00207 }
00208 default:
00209 break;
00210 }
00211 return(MagickTrue);
00212 }
00213
00214 #if defined(__cplusplus) || defined(c_plusplus)
00215 }
00216 #endif
00217
00218 #endif