MagickCore  6.7.5
composite-private.h
Go to the documentation of this file.
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