|
MagickCore
6.7.5
|
00001 /* 00002 Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization 00003 dedicated to making software imaging solutions freely available. 00004 00005 You may not use this file except in compliance with the License. 00006 obtain a copy of the License at 00007 00008 http://www.imagemagick.org/script/license.php 00009 00010 Unless required by applicable law or agreed to in writing, software 00011 distributed under the License is distributed on an "AS IS" BASIS, 00012 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 See the License for the specific language governing permissions and 00014 limitations under the License. 00015 00016 MagickCore image composite private methods. 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 ImageMagick Alpha Composite Inline Methods (special export) 00027 */ 00028 00029 #include "MagickCore/color.h" 00030 #include "MagickCore/image.h" 00031 #include "MagickCore/image-private.h" 00032 #include "MagickCore/pixel-accessor.h" 00033 00034 static inline MagickRealType MagickOver_(const MagickRealType p, 00035 const MagickRealType alpha,const MagickRealType q,const MagickRealType beta) 00036 { 00037 MagickRealType 00038 Da, 00039 Sa; 00040 00041 Sa=QuantumScale*alpha; 00042 Da=QuantumScale*beta; 00043 return(Sa*p-Sa*Da*q+Da*q); 00044 } 00045 00046 static inline void CompositePixelOver(const Image *image,const PixelInfo *p, 00047 const MagickRealType alpha,const Quantum *q,const MagickRealType beta, 00048 Quantum *composite) 00049 { 00050 MagickRealType 00051 Da, 00052 gamma, 00053 Sa; 00054 00055 register ssize_t 00056 i; 00057 00058 /* 00059 Compose pixel p over pixel q with the given alpha. 00060 */ 00061 Sa=QuantumScale*alpha; 00062 Da=QuantumScale*beta, 00063 gamma=Sa*(-Da)+Sa+Da; 00064 gamma=1.0/(gamma <= MagickEpsilon ? 1.0 : gamma); 00065 for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 00066 { 00067 PixelChannel 00068 channel; 00069 00070 PixelTrait 00071 traits; 00072 00073 channel=GetPixelChannelMapChannel(image,i); 00074 traits=GetPixelChannelMapTraits(image,channel); 00075 if (traits == UndefinedPixelTrait) 00076 continue; 00077 switch (channel) 00078 { 00079 case RedPixelChannel: 00080 { 00081 composite[i]=ClampToQuantum(gamma*MagickOver_((MagickRealType) p->red, 00082 alpha,(MagickRealType) q[i],beta)); 00083 break; 00084 } 00085 case GreenPixelChannel: 00086 { 00087 composite[i]=ClampToQuantum(gamma*MagickOver_((MagickRealType) p->green, 00088 alpha,(MagickRealType) q[i],beta)); 00089 break; 00090 } 00091 case BluePixelChannel: 00092 { 00093 composite[i]=ClampToQuantum(gamma*MagickOver_((MagickRealType) p->blue, 00094 alpha,(MagickRealType) q[i],beta)); 00095 break; 00096 } 00097 case BlackPixelChannel: 00098 { 00099 composite[i]=ClampToQuantum(gamma*MagickOver_((MagickRealType) p->black, 00100 alpha,(MagickRealType) q[i],beta)); 00101 break; 00102 } 00103 case AlphaPixelChannel: 00104 { 00105 composite[i]=ClampToQuantum(QuantumRange*(Sa*(-Da)+Sa+Da)); 00106 break; 00107 } 00108 default: 00109 break; 00110 } 00111 } 00112 } 00113 00114 static inline void CompositePixelInfoOver(const PixelInfo *p, 00115 const MagickRealType alpha,const PixelInfo *q,const MagickRealType beta, 00116 PixelInfo *composite) 00117 { 00118 MagickRealType 00119 Da, 00120 gamma, 00121 Sa; 00122 00123 /* 00124 Compose pixel p over pixel q with the given opacities. 00125 */ 00126 if (fabs(alpha-OpaqueAlpha) < MagickEpsilon) 00127 { 00128 *composite=(*p); 00129 return; 00130 } 00131 Sa=QuantumScale*alpha; 00132 Da=QuantumScale*beta, 00133 gamma=Sa*(-Da)+Sa+Da; 00134 composite->alpha=(MagickRealType) QuantumRange*gamma; 00135 gamma=1.0/(fabs(gamma) <= MagickEpsilon ? 1.0 : gamma); 00136 composite->red=gamma*MagickOver_(p->red,alpha,q->red,beta); 00137 composite->green=gamma*MagickOver_(p->green,alpha,q->green,beta); 00138 composite->blue=gamma*MagickOver_(p->blue,alpha,q->blue,beta); 00139 if (q->colorspace == CMYKColorspace) 00140 composite->black=gamma*MagickOver_(p->black,alpha,q->black,beta); 00141 } 00142 00143 static inline MagickRealType RoundToUnity(const MagickRealType value) 00144 { 00145 return(value < 0.0 ? 0.0 : (value > 1.0) ? 1.0 : value); 00146 } 00147 00148 static inline void CompositePixelInfoPlus(const PixelInfo *p, 00149 const MagickRealType alpha,const PixelInfo *q,const MagickRealType beta, 00150 PixelInfo *composite) 00151 { 00152 MagickRealType 00153 Da, 00154 gamma, 00155 Sa; 00156 00157 /* 00158 Add two pixels with the given opacities. 00159 */ 00160 Sa=QuantumScale*alpha; 00161 Da=QuantumScale*beta; 00162 gamma=RoundToUnity(Sa+Da); /* 'Plus' blending -- not 'Over' blending */ 00163 composite->alpha=(MagickRealType) QuantumRange*gamma; 00164 gamma=1.0/(fabs(gamma) <= MagickEpsilon ? 1.0 : gamma); 00165 composite->red=gamma*(Sa*p->red+Da*q->red); 00166 composite->green=gamma*(Sa*p->green+Da*q->green); 00167 composite->blue=gamma*(Sa*p->blue+Da*q->blue); 00168 if (q->colorspace == CMYKColorspace) 00169 composite->black=gamma*(Sa*p->black+Da*q->black); 00170 } 00171 00172 static inline void CompositePixelInfoAreaBlend(const PixelInfo *p, 00173 const MagickRealType alpha,const PixelInfo *q,const MagickRealType beta, 00174 const MagickRealType area,PixelInfo *composite) 00175 { 00176 /* 00177 Blend pixel colors p and q by the amount given and area. 00178 */ 00179 CompositePixelInfoPlus(p,(MagickRealType) (1.0-area)*alpha,q,(MagickRealType) 00180 (area*beta),composite); 00181 } 00182 00183 static inline void CompositePixelInfoBlend(const PixelInfo *p, 00184 const MagickRealType alpha,const PixelInfo *q,const MagickRealType beta, 00185 PixelInfo *composite) 00186 { 00187 /* 00188 Blend pixel colors p and q by the amount given. 00189 */ 00190 CompositePixelInfoPlus(p,(MagickRealType) (alpha*p->alpha),q,(MagickRealType) 00191 (beta*q->alpha),composite); 00192 } 00193 00194 #if defined(__cplusplus) || defined(c_plusplus) 00195 } 00196 #endif 00197 00198 #endif