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 #if defined(__cplusplus) || defined(c_plusplus)
00022 extern "C" {
00023 #endif
00024 
00025 
00026 
00027 
00028 
00029 #include "magick/color.h"
00030 #include "magick/image.h"
00031 #include "magick/image-private.h"
00032 
00033 static inline MagickRealType RoundToUnity(const MagickRealType value)
00034 {
00035   return(value < 0.0 ? 0.0 : (value > 1.0) ? 1.0 : value);
00036 }
00037 
00038 static inline MagickRealType MagickOver_(const MagickRealType p,
00039   const MagickRealType alpha,const MagickRealType q,const MagickRealType beta)
00040 {
00041   MagickRealType
00042     pixel;
00043 
00044   pixel=(1.0-QuantumScale*alpha)*p+(1.0-QuantumScale*beta)*q*QuantumScale*alpha;
00045   return(pixel);
00046 }
00047 
00048 
00049 
00050 
00051 static inline void MagickCompositeOver(const PixelPacket *p,
00052   const MagickRealType alpha,const PixelPacket *q,const MagickRealType beta,
00053   PixelPacket *composite)
00054 {
00055   MagickRealType
00056     gamma;
00057 
00058   if (alpha == TransparentOpacity)
00059     {
00060       *composite=(*q);
00061       return;
00062     }
00063   gamma=1.0-QuantumScale*QuantumScale*alpha*beta;
00064 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00065   composite->opacity=(Quantum) (QuantumRange*(1.0-gamma)+0.5);
00066   gamma=1.0/(gamma <= MagickEpsilon ? 1.0 : gamma);
00067   composite->red=(Quantum) (gamma*MagickOver_((MagickRealType) p->red,alpha,
00068     (MagickRealType) q->red,beta)+0.5);
00069   composite->green=(Quantum) (gamma*MagickOver_((MagickRealType) p->green,alpha,
00070     (MagickRealType) q->green,beta)+0.5);
00071   composite->blue=(Quantum) (gamma*MagickOver_((MagickRealType) p->blue,alpha,
00072     (MagickRealType) q->blue,beta)+0.5);
00073 #else
00074   composite->opacity=(Quantum) (QuantumRange*(1.0-gamma));
00075   gamma=1.0/(gamma <= MagickEpsilon ? 1.0 : gamma);
00076   composite->red=(Quantum) (gamma*MagickOver_((MagickRealType) p->red,alpha,
00077     (MagickRealType) q->red,beta));
00078   composite->green=(Quantum) (gamma*MagickOver_((MagickRealType) p->green,alpha,
00079     (MagickRealType) q->green,beta));
00080   composite->blue=(Quantum) (gamma*MagickOver_((MagickRealType) p->blue,alpha,
00081     (MagickRealType) q->blue,beta));
00082 #endif
00083 }
00084 
00085 
00086 
00087 
00088 static inline void MagickPixelCompositeOver(const MagickPixelPacket *p,
00089   const MagickRealType alpha,const MagickPixelPacket *q,
00090   const MagickRealType beta,MagickPixelPacket *composite)
00091 {
00092   MagickRealType
00093     gamma;
00094 
00095   if (alpha == TransparentOpacity)
00096     {
00097       *composite=(*q);
00098       return;
00099     }
00100   gamma=1.0-QuantumScale*QuantumScale*alpha*beta;
00101   composite->opacity=(MagickRealType) QuantumRange*(1.0-gamma);
00102   gamma=1.0/(gamma <= MagickEpsilon ? 1.0 : gamma);
00103   composite->red=gamma*MagickOver_(p->red,alpha,q->red,beta);
00104   composite->green=gamma*MagickOver_(p->green,alpha,q->green,beta);
00105   composite->blue=gamma*MagickOver_(p->blue,alpha,q->blue,beta);
00106   if ((p->colorspace == CMYKColorspace) && (q->colorspace == CMYKColorspace))
00107     composite->index=gamma*MagickOver_(p->index,alpha,q->index,beta);
00108 }
00109 
00110 
00111 static inline MagickRealType MagickPlus_(const MagickRealType p,
00112   const MagickRealType alpha,const MagickRealType q,const MagickRealType beta)
00113 {
00114   return((1.0-QuantumScale*alpha)*p+(1.0-QuantumScale*beta)*q);
00115 }
00116 
00117 
00118 
00119 
00120 static inline void MagickPixelCompositePlus(const MagickPixelPacket *p,
00121   const MagickRealType alpha,const MagickPixelPacket *q,
00122   const MagickRealType beta,MagickPixelPacket *composite)
00123 {
00124   MagickRealType
00125     gamma;
00126 
00127   gamma=RoundToUnity((1.0-QuantumScale*alpha)+(1.0-QuantumScale*beta));
00128   composite->opacity=(MagickRealType) QuantumRange*(1.0-gamma);
00129   gamma=1.0/(fabs(gamma) <= MagickEpsilon ? 1.0 : gamma);
00130   composite->red=gamma*MagickPlus_(p->red,alpha,q->red,beta);
00131   composite->green=gamma*MagickPlus_(p->green,alpha,q->green,beta);
00132   composite->blue=gamma*MagickPlus_(p->blue,alpha,q->blue,beta);
00133   if (q->colorspace == CMYKColorspace)
00134     composite->index=gamma*MagickPlus_(p->index,alpha,q->index,beta);
00135 }
00136 
00137 
00138 
00139 
00140 static inline void MagickPixelCompositeBlend(const MagickPixelPacket *p,
00141   const MagickRealType alpha,const MagickPixelPacket *q,
00142   const MagickRealType beta,MagickPixelPacket *composite)
00143 {
00144   MagickPixelCompositePlus(p,(MagickRealType) (QuantumRange-alpha*
00145     (QuantumRange-p->opacity)),q,(MagickRealType) (QuantumRange-beta*
00146     (QuantumRange-q->opacity)),composite);
00147 }
00148 
00149 #if defined(__cplusplus) || defined(c_plusplus)
00150 }
00151 #endif
00152 
00153 #endif