*luma=QuantumScale*(0.298839*r+0.586811*g+0.114350*b);
}
-static MagickBooleanType CompositeOverImage(Image *image,
- const Image *source_image,const MagickBooleanType clip_to_self,
- const ssize_t x_offset,const ssize_t y_offset,ExceptionInfo *exception)
-{
-#define CompositeImageTag "Composite/Image"
-
- CacheView
- *image_view,
- *source_view;
-
- const char
- *value;
-
- MagickBooleanType
- clamp,
- status;
-
- MagickOffsetType
- progress;
-
- ssize_t
- y;
-
- /*
- Composite image.
- */
- status=MagickTrue;
- progress=0;
- clamp=MagickTrue;
- value=GetImageArtifact(image,"compose:clamp");
- if (value != (const char *) NULL)
- clamp=IsStringTrue(value);
- source_view=AcquireVirtualCacheView(source_image,exception);
- image_view=AcquireAuthenticCacheView(image,exception);
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(progress,status) \
- magick_threads(source_image,image,image->rows,1)
-#endif
- for (y=0; y < (ssize_t) image->rows; y++)
- {
- const Quantum
- *pixels;
-
- register const Quantum
- *magick_restrict p;
-
- register Quantum
- *magick_restrict q;
-
- register ssize_t
- x;
-
- size_t
- channels;
-
- if (status == MagickFalse)
- continue;
- if (clip_to_self != MagickFalse)
- {
- if (y < y_offset)
- continue;
- if ((y-y_offset) >= (ssize_t) source_image->rows)
- continue;
- }
- /*
- If pixels is NULL, y is outside overlay region.
- */
- pixels=(Quantum *) NULL;
- p=(Quantum *) NULL;
- if ((y >= y_offset) && ((y-y_offset) < (ssize_t) source_image->rows))
- {
- p=GetCacheViewVirtualPixels(source_view,0,y-y_offset,
- source_image->columns,1,exception);
- if (p == (const Quantum *) NULL)
- {
- status=MagickFalse;
- continue;
- }
- pixels=p;
- if (x_offset < 0)
- p-=x_offset*GetPixelChannels(source_image);
- }
- q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
- if (q == (Quantum *) NULL)
- {
- status=MagickFalse;
- continue;
- }
- for (x=0; x < (ssize_t) image->columns; x++)
- {
- MagickRealType
- Da,
- Dc,
- Dca,
- gamma,
- Sa,
- Sc,
- Sca;
-
- register ssize_t
- i;
-
- if (clip_to_self != MagickFalse)
- {
- if (x < x_offset)
- {
- q+=GetPixelChannels(image);
- continue;
- }
- if ((x-x_offset) >= (ssize_t) source_image->columns)
- break;
- }
- if ((pixels == (Quantum *) NULL) || (x < x_offset) ||
- ((x-x_offset) >= (ssize_t) source_image->columns))
- {
- Quantum
- source[MaxPixelChannels];
-
- /*
- Virtual composite:
- Sc: source color.
- Dc: canvas color.
- */
- if (GetPixelReadMask(image,q) == 0)
- {
- q+=GetPixelChannels(image);
- continue;
- }
- (void) GetOneVirtualPixel(source_image,x-x_offset,y-y_offset,
- source,exception);
- for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
- {
- PixelChannel channel=GetPixelChannelChannel(image,i);
- PixelTrait traits=GetPixelChannelTraits(image,channel);
- PixelTrait source_traits=GetPixelChannelTraits(source_image,
- channel);
- if ((traits == UndefinedPixelTrait) ||
- (source_traits == UndefinedPixelTrait))
- continue;
- q[i]=source[channel];
- }
- q+=GetPixelChannels(image);
- continue;
- }
- /*
- Authentic composite:
- Sa: normalized source alpha.
- Da: normalized canvas alpha.
- */
- if (GetPixelReadMask(source_image,p) == 0)
- {
- p+=GetPixelChannels(source_image);
- channels=GetPixelChannels(source_image);
- if (p >= (pixels+channels*source_image->columns))
- p=pixels;
- q+=GetPixelChannels(image);
- continue;
- }
- Sa=QuantumScale*GetPixelAlpha(source_image,p);
- Da=QuantumScale*GetPixelAlpha(image,q);
- gamma=Sa+Da-Sa*Da;
- gamma=PerceptibleReciprocal(gamma);
- for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
- {
- PixelChannel channel=GetPixelChannelChannel(image,i);
- PixelTrait traits=GetPixelChannelTraits(image,channel);
- PixelTrait source_traits=GetPixelChannelTraits(source_image,
- channel);
- if ((traits == UndefinedPixelTrait) ||
- (source_traits == UndefinedPixelTrait))
- continue;
- if ((traits & CopyPixelTrait) != 0)
- {
- /*
- Copy channel.
- */
- q[i]=GetPixelChannel(source_image,channel,p);
- continue;
- }
- if (channel == AlphaPixelChannel)
- {
- /*
- Set alpha channel.
- */
- q[i]=clamp != MagickFalse ?
- ClampPixel(QuantumRange*(Sa+Da-Sa*Da)) :
- ClampToQuantum(QuantumRange*(Sa+Da-Sa*Da));
- continue;
- }
- /*
- Sc: source color.
- Dc: canvas color.
- */
- Sc=(MagickRealType) GetPixelChannel(source_image,channel,p);
- Dc=(MagickRealType) q[i];
- Sca=QuantumScale*Sa*Sc;
- Dca=QuantumScale*Da*Dc;
- q[i]=clamp != MagickFalse ?
- ClampPixel(gamma*QuantumRange*(Sca+Dca*(1.0-Sa))) :
- ClampToQuantum(gamma*QuantumRange*(Sca+Dca*(1.0-Sa)));
- }
- p+=GetPixelChannels(source_image);
- channels=GetPixelChannels(source_image);
- if (p >= (pixels+channels*source_image->columns))
- p=pixels;
- q+=GetPixelChannels(image);
- }
- if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
- status=MagickFalse;
- if (image->progress_monitor != (MagickProgressMonitor) NULL)
- {
- MagickBooleanType
- proceed;
-
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_CompositeImage)
-#endif
- proceed=SetImageProgress(image,CompositeImageTag,progress++,
- image->rows);
- if (proceed == MagickFalse)
- status=MagickFalse;
- }
- }
- source_view=DestroyCacheView(source_view);
- image_view=DestroyCacheView(image_view);
- return(status);
-}
-
MagickExport MagickBooleanType CompositeImage(Image *image,
const Image *composite,const CompositeOperator compose,
const MagickBooleanType clip_to_self,const ssize_t x_offset,
if (IsGrayColorspace(image->colorspace) != MagickFalse)
(void) SetImageColorspace(image,sRGBColorspace,exception);
(void) SetImageColorspace(source_image,image->colorspace,exception);
- if ((compose == OverCompositeOp) || (compose == SrcOverCompositeOp))
- {
- status=CompositeOverImage(image,source_image,clip_to_self,x_offset,
- y_offset,exception);
- source_image=DestroyImage(source_image);
- return(status);
- }
amount=0.5;
canvas_image=(Image *) NULL;
canvas_dissolve=1.0;