43#include "MagickCore/studio.h"
44#include "MagickCore/artifact.h"
45#include "MagickCore/cache.h"
46#include "MagickCore/cache-private.h"
47#include "MagickCore/cache-view.h"
48#include "MagickCore/channel.h"
49#include "MagickCore/client.h"
50#include "MagickCore/color.h"
51#include "MagickCore/color-private.h"
52#include "MagickCore/colorspace.h"
53#include "MagickCore/colorspace-private.h"
54#include "MagickCore/composite.h"
55#include "MagickCore/composite-private.h"
56#include "MagickCore/constitute.h"
57#include "MagickCore/draw.h"
58#include "MagickCore/exception-private.h"
59#include "MagickCore/fx.h"
60#include "MagickCore/gem.h"
61#include "MagickCore/geometry.h"
62#include "MagickCore/image.h"
63#include "MagickCore/image-private.h"
64#include "MagickCore/list.h"
65#include "MagickCore/log.h"
66#include "MagickCore/memory_.h"
67#include "MagickCore/monitor.h"
68#include "MagickCore/monitor-private.h"
69#include "MagickCore/morphology.h"
70#include "MagickCore/option.h"
71#include "MagickCore/pixel-accessor.h"
72#include "MagickCore/property.h"
73#include "MagickCore/quantum.h"
74#include "MagickCore/resample.h"
75#include "MagickCore/resource_.h"
76#include "MagickCore/string_.h"
77#include "MagickCore/string-private.h"
78#include "MagickCore/thread-private.h"
79#include "MagickCore/threshold.h"
80#include "MagickCore/token.h"
81#include "MagickCore/transform.h"
82#include "MagickCore/utility.h"
83#include "MagickCore/utility-private.h"
84#include "MagickCore/version.h"
185static Image *BlendConvolveImage(
const Image *image,
const char *kernel,
186 ExceptionInfo *exception)
198 kernel_info=AcquireKernelInfo(kernel,exception);
199 if (kernel_info == (KernelInfo *) NULL)
200 return((Image *) NULL);
201 clone_image=CloneImage(image,0,0,MagickTrue,exception);
202 if (clone_image == (Image *) NULL)
204 kernel_info=DestroyKernelInfo(kernel_info);
205 return((Image *) NULL);
207 (void) SetImageAlphaChannel(clone_image,OffAlphaChannel,exception);
208 convolve_image=ConvolveImage(clone_image,kernel_info,exception);
209 kernel_info=DestroyKernelInfo(kernel_info);
210 clone_image=DestroyImage(clone_image);
211 return(convolve_image);
214static Image *BlendMagnitudeImage(
const Image *dx_image,
const Image *dy_image,
215 ExceptionInfo *exception)
234 magnitude_image=CloneImage(dx_image,0,0,MagickTrue,exception);
235 if (magnitude_image == (Image *) NULL)
236 return(magnitude_image);
237 dx_view=AcquireVirtualCacheView(dx_image,exception);
238 dy_view=AcquireVirtualCacheView(dy_image,exception);
239 magnitude_view=AcquireAuthenticCacheView(magnitude_image,exception);
240#if defined(MAGICKCORE_OPENMP_SUPPORT)
241 #pragma omp parallel for schedule(static) shared(status) \
242 magick_number_threads(dx_image,magnitude_image,dx_image->rows,1)
244 for (y=0; y < (ssize_t) dx_image->rows; y++)
256 if (status == MagickFalse)
258 p=GetCacheViewVirtualPixels(dx_view,0,y,dx_image->columns,1,exception);
259 q=GetCacheViewVirtualPixels(dy_view,0,y,dx_image->columns,1,exception);
260 r=GetCacheViewAuthenticPixels(magnitude_view,0,y,dx_image->columns,1,
262 if ((p == (
const Quantum *) NULL) || (q == (
const Quantum *) NULL) ||
263 (r == (Quantum *) NULL))
268 for (x=0; x < (ssize_t) dx_image->columns; x++)
273 for (i=0; i < (ssize_t) GetPixelChannels(dx_image); i++)
275 PixelChannel channel = GetPixelChannelChannel(dx_image,i);
276 PixelTrait traits = GetPixelChannelTraits(dx_image,channel);
277 PixelTrait dy_traits = GetPixelChannelTraits(dy_image,channel);
278 if ((traits == UndefinedPixelTrait) ||
279 (dy_traits == UndefinedPixelTrait) ||
280 ((dy_traits & UpdatePixelTrait) == 0))
282 r[i]=ClampToQuantum(hypot((
double) p[i],(
double)
283 GetPixelChannel(dy_image,channel,q)));
285 p+=(ptrdiff_t) GetPixelChannels(dx_image);
286 q+=(ptrdiff_t) GetPixelChannels(dy_image);
287 r+=(ptrdiff_t) GetPixelChannels(magnitude_image);
289 if (SyncCacheViewAuthenticPixels(magnitude_view,exception) == MagickFalse)
292 magnitude_view=DestroyCacheView(magnitude_view);
293 dy_view=DestroyCacheView(dy_view);
294 dx_view=DestroyCacheView(dx_view);
295 if (status == MagickFalse)
296 magnitude_image=DestroyImage(magnitude_image);
297 return(magnitude_image);
300static Image *BlendMaxMagnitudeImage(
const Image *alpha_image,
301 const Image *beta_image,
const Image *dx_image,
const Image *dy_image,
302 ExceptionInfo *exception)
323 magnitude_image=CloneImage(alpha_image,0,0,MagickTrue,exception);
324 if (magnitude_image == (Image *) NULL)
325 return(magnitude_image);
326 alpha_view=AcquireVirtualCacheView(alpha_image,exception);
327 beta_view=AcquireVirtualCacheView(beta_image,exception);
328 dx_view=AcquireVirtualCacheView(dx_image,exception);
329 dy_view=AcquireVirtualCacheView(dy_image,exception);
330 magnitude_view=AcquireAuthenticCacheView(magnitude_image,exception);
331#if defined(MAGICKCORE_OPENMP_SUPPORT)
332 #pragma omp parallel for schedule(static) shared(status) \
333 magick_number_threads(alpha_image,magnitude_image,alpha_image->rows,1)
335 for (y=0; y < (ssize_t) alpha_image->rows; y++)
349 if (status == MagickFalse)
351 p=GetCacheViewVirtualPixels(alpha_view,0,y,alpha_image->columns,1,
353 q=GetCacheViewVirtualPixels(beta_view,0,y,alpha_image->columns,1,exception);
354 r=GetCacheViewVirtualPixels(dx_view,0,y,alpha_image->columns,1,exception);
355 s=GetCacheViewVirtualPixels(dy_view,0,y,alpha_image->columns,1,exception);
356 t=GetCacheViewAuthenticPixels(magnitude_view,0,y,alpha_image->columns,1,
358 if ((p == (
const Quantum *) NULL) || (q == (
const Quantum *) NULL) ||
359 (r == (
const Quantum *) NULL) || (s == (
const Quantum *) NULL) ||
360 (t == (Quantum *) NULL))
365 for (x=0; x < (ssize_t) alpha_image->columns; x++)
370 for (i=0; i < (ssize_t) GetPixelChannels(alpha_image); i++)
372 PixelChannel channel = GetPixelChannelChannel(alpha_image,i);
373 PixelTrait traits = GetPixelChannelTraits(alpha_image,channel);
374 PixelTrait beta_traits = GetPixelChannelTraits(beta_image,channel);
375 if ((traits == UndefinedPixelTrait) ||
376 (beta_traits == UndefinedPixelTrait) ||
377 ((beta_traits & UpdatePixelTrait) == 0))
379 if (p[i] > GetPixelChannel(beta_image,channel,q))
380 t[i]=GetPixelChannel(dx_image,channel,r);
382 t[i]=GetPixelChannel(dy_image,channel,s);
384 p+=(ptrdiff_t) GetPixelChannels(alpha_image);
385 q+=(ptrdiff_t) GetPixelChannels(beta_image);
386 r+=(ptrdiff_t) GetPixelChannels(dx_image);
387 s+=(ptrdiff_t) GetPixelChannels(dy_image);
388 t+=(ptrdiff_t) GetPixelChannels(magnitude_image);
390 if (SyncCacheViewAuthenticPixels(magnitude_view,exception) == MagickFalse)
393 magnitude_view=DestroyCacheView(magnitude_view);
394 dy_view=DestroyCacheView(dy_view);
395 dx_view=DestroyCacheView(dx_view);
396 beta_view=DestroyCacheView(beta_view);
397 alpha_view=DestroyCacheView(alpha_view);
398 if (status == MagickFalse)
399 magnitude_image=DestroyImage(magnitude_image);
400 return(magnitude_image);
403static Image *BlendSumImage(
const Image *alpha_image,
const Image *beta_image,
404 const double attenuate,
const double sign,ExceptionInfo *exception)
423 sum_image=CloneImage(alpha_image,0,0,MagickTrue,exception);
424 if (sum_image == (Image *) NULL)
426 alpha_view=AcquireVirtualCacheView(alpha_image,exception);
427 beta_view=AcquireVirtualCacheView(beta_image,exception);
428 sum_view=AcquireAuthenticCacheView(sum_image,exception);
429#if defined(MAGICKCORE_OPENMP_SUPPORT)
430 #pragma omp parallel for schedule(static) shared(status) \
431 magick_number_threads(alpha_image,sum_image,alpha_image->rows,1)
433 for (y=0; y < (ssize_t) alpha_image->rows; y++)
445 if (status == MagickFalse)
447 p=GetCacheViewVirtualPixels(alpha_view,0,y,alpha_image->columns,1,
449 q=GetCacheViewVirtualPixels(beta_view,0,y,alpha_image->columns,1,exception);
450 r=GetCacheViewAuthenticPixels(sum_view,0,y,alpha_image->columns,1,
452 if ((p == (
const Quantum *) NULL) || (q == (
const Quantum *) NULL) ||
453 (r == (Quantum *) NULL))
458 for (x=0; x < (ssize_t) alpha_image->columns; x++)
463 for (i=0; i < (ssize_t) GetPixelChannels(alpha_image); i++)
465 PixelChannel channel = GetPixelChannelChannel(alpha_image,i);
466 PixelTrait traits = GetPixelChannelTraits(alpha_image,channel);
467 PixelTrait beta_traits = GetPixelChannelTraits(beta_image,channel);
468 if ((traits == UndefinedPixelTrait) ||
469 (beta_traits == UndefinedPixelTrait) ||
470 ((beta_traits & UpdatePixelTrait) == 0))
472 r[i]=ClampToQuantum(attenuate*((
double) p[i]+sign*
473 (
double) GetPixelChannel(beta_image,channel,q)));
475 p+=(ptrdiff_t) GetPixelChannels(alpha_image);
476 q+=(ptrdiff_t) GetPixelChannels(beta_image);
477 r+=(ptrdiff_t) GetPixelChannels(sum_image);
479 if (SyncCacheViewAuthenticPixels(sum_view,exception) == MagickFalse)
482 sum_view=DestroyCacheView(sum_view);
483 beta_view=DestroyCacheView(beta_view);
484 alpha_view=DestroyCacheView(alpha_view);
485 if (status == MagickFalse)
486 sum_image=DestroyImage(sum_image);
490static Image *BlendDivergentImage(
const Image *alpha_image,
491 const Image *beta_image,ExceptionInfo *exception)
493#define FreeDivergentResources() \
495 if (dy_image != (Image *) NULL) \
496 dy_image=DestroyImage(dy_image); \
497 if (dx_image != (Image *) NULL) \
498 dx_image=DestroyImage(dx_image); \
499 if (magnitude_beta != (Image *) NULL) \
500 magnitude_beta=DestroyImage(magnitude_beta); \
501 if (dy_beta != (Image *) NULL) \
502 dy_beta=DestroyImage(dy_beta); \
503 if (dx_beta != (Image *) NULL) \
504 dx_beta=DestroyImage(dx_beta); \
505 if (magnitude_alpha != (Image *) NULL) \
506 magnitude_alpha=DestroyImage(magnitude_alpha); \
507 if (dy_alpha != (Image *) NULL) \
508 dy_alpha=DestroyImage(dy_alpha); \
509 if (dx_alpha != (Image *) NULL) \
510 dx_alpha=DestroyImage(dx_alpha); \
514 *divergent_image = (Image *) NULL,
515 *dx_alpha = (Image *) NULL,
516 *dx_beta = (Image *) NULL,
517 *dx_divergent = (Image *) NULL,
518 *dx_image = (Image *) NULL,
519 *dy_alpha = (Image *) NULL,
520 *dy_beta = (Image *) NULL,
521 *dy_divergent = (Image *) NULL,
522 *dy_image = (Image *) NULL,
523 *magnitude_alpha = (Image *) NULL,
524 *magnitude_beta = (Image *) NULL;
529 dx_alpha=BlendConvolveImage(alpha_image,
"3x1:-0.5,0.0,0.5",exception);
530 if (dx_alpha == (Image *) NULL)
532 FreeDivergentResources();
533 return((Image *) NULL);
535 dy_alpha=BlendConvolveImage(alpha_image,
"1x3:-0.5,0.0,0.5",exception);
536 if (dy_alpha == (Image *) NULL)
538 FreeDivergentResources();
539 return((Image *) NULL);
541 magnitude_alpha=BlendMagnitudeImage(dx_alpha,dy_alpha,exception);
542 if (magnitude_alpha == (Image *) NULL)
544 FreeDivergentResources();
545 return((Image *) NULL);
550 dx_beta=BlendConvolveImage(beta_image,
"3x1:-0.5,0.0,0.5",exception);
551 if (dx_beta == (Image *) NULL)
553 FreeDivergentResources();
554 return((Image *) NULL);
556 dy_beta=BlendConvolveImage(beta_image,
"1x3:-0.5,0.0,0.5",exception);
557 if (dy_beta == (Image *) NULL)
559 FreeDivergentResources();
560 return((Image *) NULL);
562 magnitude_beta=BlendMagnitudeImage(dx_beta,dy_beta,exception);
563 if (magnitude_beta == (Image *) NULL)
565 FreeDivergentResources();
566 return((Image *) NULL);
571 dx_image=BlendMaxMagnitudeImage(magnitude_alpha,magnitude_beta,dx_alpha,
573 if (dx_image == (Image *) NULL)
575 FreeDivergentResources();
576 return((Image *) NULL);
578 dy_image=BlendMaxMagnitudeImage(magnitude_alpha,magnitude_beta,dy_alpha,
580 if (dy_image == (Image *) NULL)
582 FreeDivergentResources();
583 return((Image *) NULL);
585 dx_beta=DestroyImage(dx_beta);
586 dx_alpha=DestroyImage(dx_alpha);
587 magnitude_beta=DestroyImage(magnitude_beta);
588 magnitude_alpha=DestroyImage(magnitude_alpha);
592 dx_divergent=BlendConvolveImage(dx_image,
"3x1:-0.5,0.0,0.5",exception);
593 if (dx_divergent == (Image *) NULL)
595 FreeDivergentResources();
596 return((Image *) NULL);
598 dy_divergent=BlendConvolveImage(dy_image,
"1x3:-0.5,0.0,0.5",exception);
599 if (dy_divergent == (Image *) NULL)
601 FreeDivergentResources();
602 return((Image *) NULL);
604 divergent_image=BlendSumImage(dx_divergent,dy_divergent,0.25,1.0,exception);
605 dy_divergent=DestroyImage(dy_divergent);
606 dx_divergent=DestroyImage(dx_divergent);
607 if (divergent_image == (Image *) NULL)
609 FreeDivergentResources();
610 return((Image *) NULL);
612 FreeDivergentResources();
613 return(divergent_image);
616static MagickBooleanType BlendMaskAlphaChannel(Image *image,
617 const Image *mask_image,ExceptionInfo *exception)
632 if (SetImageAlpha(image,OpaqueAlpha,exception) == MagickFalse)
634 image_view=AcquireAuthenticCacheView(image,exception);
635 mask_view=AcquireVirtualCacheView(mask_image,exception);
636#if defined(MAGICKCORE_OPENMP_SUPPORT)
637 #pragma omp parallel for schedule(static) shared(status) \
638 magick_number_threads(image,image,image->rows,2)
640 for (y=0; y < (ssize_t) image->rows; y++)
651 if (status == MagickFalse)
653 p=GetCacheViewVirtualPixels(mask_view,0,y,image->columns,1,exception);
654 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
655 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
660 for (x=0; x < (ssize_t) image->columns; x++)
663 alpha = GetPixelAlpha(mask_image,p);
666 i = GetPixelChannelOffset(image,AlphaPixelChannel);
668 if (fabs((
double) alpha) >= MagickEpsilon)
670 p+=(ptrdiff_t) GetPixelChannels(mask_image);
671 q+=(ptrdiff_t) GetPixelChannels(image);
673 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
676 mask_view=DestroyCacheView(mask_view);
677 image_view=DestroyCacheView(image_view);
681static Image *BlendMeanImage(Image *image,
const Image *mask_image,
682 ExceptionInfo *exception)
690 mean[MaxPixelChannels];
705 (void) memset(mean,0,MaxPixelChannels*
sizeof(*mean));
706 alpha_view=AcquireVirtualCacheView(image,exception);
707 for (y=0; y < (ssize_t) image->rows; y++)
715 p=GetCacheViewVirtualPixels(alpha_view,0,y,image->columns,1,
717 if (p == (
const Quantum *) NULL)
719 for (x=0; x < (ssize_t) image->columns; x++)
724 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
726 PixelChannel channel = GetPixelChannelChannel(image,i);
727 PixelTrait traits = GetPixelChannelTraits(image,channel);
728 if (traits == UndefinedPixelTrait)
730 mean[i]+=QuantumScale*(double) p[i];
732 p+=(ptrdiff_t) GetPixelChannels(image);
735 alpha_view=DestroyCacheView(alpha_view);
736 if (y < (ssize_t) image->rows)
737 return((Image *) NULL);
738 for (j=0; j < (ssize_t) GetPixelChannels(image); j++)
739 mean[j]=(
double) QuantumRange*mean[j]/image->columns/
744 mean_image=CloneImage(image,0,0,MagickTrue,exception);
745 if (mean_image == (Image *) NULL)
747 mask_view=AcquireVirtualCacheView(mask_image,exception);
748 mean_view=AcquireAuthenticCacheView(mean_image,exception);
749#if defined(MAGICKCORE_OPENMP_SUPPORT)
750 #pragma omp parallel for schedule(static) shared(status) \
751 magick_number_threads(mask_image,mean_image,mean_image->rows,4)
753 for (y=0; y < (ssize_t) mean_image->rows; y++)
764 if (status == MagickFalse)
766 p=GetCacheViewVirtualPixels(mask_view,0,y,mean_image->columns,1,exception);
767 q=GetCacheViewAuthenticPixels(mean_view,0,y,mean_image->columns,1,
769 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
774 for (x=0; x < (ssize_t) mean_image->columns; x++)
777 alpha = GetPixelAlpha(mask_image,p),
778 mask = GetPixelReadMask(mask_image,p);
783 for (i=0; i < (ssize_t) GetPixelChannels(mean_image); i++)
785 PixelChannel channel = GetPixelChannelChannel(mean_image,i);
786 PixelTrait traits = GetPixelChannelTraits(mean_image,channel);
787 if (traits == UndefinedPixelTrait)
789 if (mask <= (QuantumRange/2))
792 if (fabs((
double) alpha) >= MagickEpsilon)
793 q[i]=ClampToQuantum(mean[i]);
795 p+=(ptrdiff_t) GetPixelChannels(mask_image);
796 q+=(ptrdiff_t) GetPixelChannels(mean_image);
798 if (SyncCacheViewAuthenticPixels(mean_view,exception) == MagickFalse)
801 mask_view=DestroyCacheView(mask_view);
802 mean_view=DestroyCacheView(mean_view);
803 if (status == MagickFalse)
804 mean_image=DestroyImage(mean_image);
808static MagickBooleanType BlendRMSEResidual(
const Image *alpha_image,
809 const Image *beta_image,
double *residual,ExceptionInfo *exception)
817 channel_residual = 0.0;
823 columns = MagickMax(alpha_image->columns,beta_image->columns),
824 rows = MagickMax(alpha_image->rows,beta_image->rows);
829 alpha_view=AcquireVirtualCacheView(alpha_image,exception);
830 beta_view=AcquireVirtualCacheView(beta_image,exception);
831#if defined(MAGICKCORE_OPENMP_SUPPORT)
832 #pragma omp parallel for schedule(static) shared(status) \
833 reduction(+:area) reduction(+:channel_residual) \
834 magick_number_threads(alpha_image,alpha_image,rows,1)
836 for (y=0; y < (ssize_t) rows; y++)
845 if (status == MagickFalse)
847 p=GetCacheViewVirtualPixels(alpha_view,0,y,columns,1,exception);
848 q=GetCacheViewVirtualPixels(beta_view,0,y,columns,1,exception);
849 if ((p == (
const Quantum *) NULL) || (q == (
const Quantum *) NULL))
854 channel_residual=0.0;
855 for (x=0; x < (ssize_t) columns; x++)
864 if ((GetPixelReadMask(alpha_image,p) <= (QuantumRange/2)) ||
865 (GetPixelReadMask(beta_image,q) <= (QuantumRange/2)))
867 p+=(ptrdiff_t) GetPixelChannels(alpha_image);
868 q+=(ptrdiff_t) GetPixelChannels(beta_image);
871 Sa=QuantumScale*(double) GetPixelAlpha(alpha_image,p);
872 Da=QuantumScale*(double) GetPixelAlpha(beta_image,q);
873 for (i=0; i < (ssize_t) GetPixelChannels(alpha_image); i++)
878 PixelChannel channel = GetPixelChannelChannel(alpha_image,i);
879 PixelTrait traits = GetPixelChannelTraits(alpha_image,channel);
880 PixelTrait beta_traits = GetPixelChannelTraits(beta_image,channel);
881 if ((traits == UndefinedPixelTrait) ||
882 (beta_traits == UndefinedPixelTrait) ||
883 ((beta_traits & UpdatePixelTrait) == 0))
885 if (channel == AlphaPixelChannel)
886 distance=QuantumScale*((double) p[i]-(double) GetPixelChannel(
887 beta_image,channel,q));
889 distance=QuantumScale*(Sa*(double) p[i]-Da*(double) GetPixelChannel(
890 beta_image,channel,q));
891 channel_residual+=distance*distance;
894 p+=(ptrdiff_t) GetPixelChannels(alpha_image);
895 q+=(ptrdiff_t) GetPixelChannels(beta_image);
898 beta_view=DestroyCacheView(beta_view);
899 alpha_view=DestroyCacheView(alpha_view);
900 area=MagickSafeReciprocal(area);
901 *residual=sqrt(area*channel_residual/(
double) GetImageChannels(alpha_image));
905static MagickBooleanType CompositeOverImage(Image *image,
906 const Image *source_image,
const MagickBooleanType clip_to_self,
907 const ssize_t x_offset,
const ssize_t y_offset,ExceptionInfo *exception)
909#define CompositeImageTag "Composite/Image"
934 value=GetImageArtifact(image,
"compose:clamp");
935 if (value != (
const char *) NULL)
936 clamp=IsStringTrue(value);
939 source_view=AcquireVirtualCacheView(source_image,exception);
940 image_view=AcquireAuthenticCacheView(image,exception);
941#if defined(MAGICKCORE_OPENMP_SUPPORT)
942 #pragma omp parallel for schedule(static) shared(progress,status) \
943 magick_number_threads(source_image,image,image->rows,1)
945 for (y=0; y < (ssize_t) image->rows; y++)
963 if (status == MagickFalse)
965 if (clip_to_self != MagickFalse)
969 if ((y-y_offset) >= (ssize_t) source_image->rows)
975 pixels=(Quantum *) NULL;
977 if ((y >= y_offset) &&
978 ((y-y_offset) < (ssize_t) source_image->rows))
980 p=GetCacheViewVirtualPixels(source_view,0,CastDoubleToSsizeT((
double) y-
981 y_offset),source_image->columns,1,exception);
982 if (p == (
const Quantum *) NULL)
989 p-=(ptrdiff_t) CastDoubleToSsizeT((
double) x_offset*
990 GetPixelChannels(source_image));
992 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
993 if (q == (Quantum *) NULL)
998 GetPixelInfo(image,&canvas_pixel);
999 GetPixelInfo(source_image,&source_pixel);
1000 for (x=0; x < (ssize_t) image->columns; x++)
1020 if (clip_to_self != MagickFalse)
1024 q+=(ptrdiff_t) GetPixelChannels(image);
1027 if ((x-x_offset) >= (ssize_t) source_image->columns)
1030 if ((pixels == (Quantum *) NULL) || (x < x_offset) ||
1031 ((x-x_offset) >= (ssize_t) source_image->columns))
1034 source[MaxPixelChannels];
1041 (void) GetOneVirtualPixel(source_image,
1042 CastDoubleToSsizeT((
double) x-x_offset),
1043 CastDoubleToSsizeT((
double) y-y_offset),source,exception);
1044 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1049 PixelChannel channel = GetPixelChannelChannel(image,i);
1050 PixelTrait traits = GetPixelChannelTraits(image,channel);
1051 PixelTrait source_traits=GetPixelChannelTraits(source_image,
1053 if ((traits == UndefinedPixelTrait) ||
1054 (source_traits == UndefinedPixelTrait))
1056 if (channel == AlphaPixelChannel)
1057 pixel=(MagickRealType) TransparentAlpha;
1059 pixel=(MagickRealType) q[i];
1060 q[i]=clamp != MagickFalse ? ClampPixel(pixel) :
1061 ClampToQuantum(pixel);
1063 q+=(ptrdiff_t) GetPixelChannels(image);
1071 Sa=QuantumScale*(double) GetPixelAlpha(source_image,p);
1072 Da=QuantumScale*(double) GetPixelAlpha(image,q);
1074 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1079 PixelChannel channel = GetPixelChannelChannel(image,i);
1080 PixelTrait traits = GetPixelChannelTraits(image,channel);
1081 PixelTrait source_traits=GetPixelChannelTraits(source_image,channel);
1082 if (traits == UndefinedPixelTrait)
1084 if ((source_traits == UndefinedPixelTrait) &&
1085 (channel != AlphaPixelChannel))
1087 if (channel == AlphaPixelChannel)
1092 if ((traits & UpdatePixelTrait) == 0)
1094 pixel=(double) QuantumRange*alpha;
1095 q[i]=clamp != MagickFalse ? ClampPixel(pixel) :
1096 ClampToQuantum(pixel);
1103 Sc=(MagickRealType) GetPixelChannel(source_image,channel,p);
1104 Dc=(MagickRealType) q[i];
1105 if ((traits & CopyPixelTrait) != 0)
1110 q[i]=ClampToQuantum(Dc);
1118 Sca=QuantumScale*Sa*Sc;
1119 Dca=QuantumScale*Da*Dc;
1120 gamma=MagickSafeReciprocal(alpha);
1121 pixel=(double) QuantumRange*gamma*(Sca+Dca*(1.0-Sa));
1122 q[i]=clamp != MagickFalse ? ClampPixel(pixel) : ClampToQuantum(pixel);
1124 p+=(ptrdiff_t) GetPixelChannels(source_image);
1125 channels=GetPixelChannels(source_image);
1126 if (p >= (pixels+channels*source_image->columns))
1128 q+=(ptrdiff_t) GetPixelChannels(image);
1130 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1132 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1137#if defined(MAGICKCORE_OPENMP_SUPPORT)
1141 proceed=SetImageProgress(image,CompositeImageTag,progress,image->rows);
1142 if (proceed == MagickFalse)
1146 source_view=DestroyCacheView(source_view);
1147 image_view=DestroyCacheView(image_view);
1151static MagickBooleanType SaliencyBlendImage(Image *image,
1152 const Image *source_image,
const ssize_t x_offset,
const ssize_t y_offset,
1153 const double iterations,
const double residual_threshold,
const size_t tick,
1154 ExceptionInfo *exception)
1160 *residual_image = (Image *) NULL;
1166 status = MagickTrue,
1167 verbose = MagickFalse;
1171 source_image->columns,
1183 crop_image=CropImage(image,&crop_info,exception);
1184 if (crop_image == (Image *) NULL)
1185 return(MagickFalse);
1186 DisableCompositeClampUnlessSpecified(crop_image);
1187 divergent_image=BlendDivergentImage(crop_image,source_image,exception);
1188 if (divergent_image == (Image *) NULL)
1190 crop_image=DestroyImage(crop_image);
1191 return(MagickFalse);
1193 (void) ResetImagePage(crop_image,
"0x0+0+0");
1194 relax_image=BlendMeanImage(crop_image,source_image,exception);
1195 if (relax_image == (Image *) NULL)
1197 crop_image=DestroyImage(crop_image);
1198 divergent_image=DestroyImage(divergent_image);
1199 return(MagickFalse);
1201 status=BlendMaskAlphaChannel(crop_image,source_image,exception);
1202 if (status == MagickFalse)
1204 crop_image=DestroyImage(crop_image);
1205 divergent_image=DestroyImage(divergent_image);
1206 return(MagickFalse);
1208 residual_image=CloneImage(relax_image,0,0,MagickTrue,exception);
1209 if (residual_image == (Image *) NULL)
1211 crop_image=DestroyImage(crop_image);
1212 relax_image=DestroyImage(relax_image);
1213 return(MagickFalse);
1218 kernel_info=AcquireKernelInfo(
"3x3:0,0.25,0,0.25,0,0.25,0,0.25,0",exception);
1219 if (kernel_info == (KernelInfo *) NULL)
1221 crop_image=DestroyImage(crop_image);
1222 residual_image=DestroyImage(residual_image);
1223 relax_image=DestroyImage(relax_image);
1224 return(MagickFalse);
1226 verbose=IsStringTrue(GetImageArtifact(image,
"verbose"));
1227 if (verbose != MagickFalse)
1228 (void) FormatLocaleFile(stderr,
"saliency blending:\n");
1229 for (i=0; i < (ssize_t) iterations; i++)
1238 convolve_image=ConvolveImage(relax_image,kernel_info,exception);
1239 if (convolve_image == (Image *) NULL)
1241 relax_image=DestroyImage(relax_image);
1242 relax_image=convolve_image;
1243 sum_image=BlendSumImage(relax_image,divergent_image,1.0,-1.0,exception);
1244 if (sum_image == (Image *) NULL)
1246 relax_image=DestroyImage(relax_image);
1247 relax_image=sum_image;
1248 status=CompositeOverImage(relax_image,crop_image,MagickTrue,0,0,exception);
1249 if (status == MagickFalse)
1251 status=BlendRMSEResidual(relax_image,residual_image,&residual,exception);
1252 if (status == MagickFalse)
1254 if ((verbose != MagickFalse) && ((i % MagickMax(tick,1)) == 0))
1255 (void) FormatLocaleFile(stderr,
" %g: %g\n",(
double) i,(
double) residual);
1256 if (residual < residual_threshold)
1258 if (verbose != MagickFalse)
1259 (void) FormatLocaleFile(stderr,
" %g: %g\n",(
double) i,(
double)
1263 residual_image=DestroyImage(residual_image);
1264 residual_image=CloneImage(relax_image,0,0,MagickTrue,exception);
1265 if (residual_image == (Image *) NULL)
1268 kernel_info=DestroyKernelInfo(kernel_info);
1269 crop_image=DestroyImage(crop_image);
1270 divergent_image=DestroyImage(divergent_image);
1271 residual_image=DestroyImage(residual_image);
1275 status=CompositeOverImage(image,relax_image,MagickTrue,x_offset,y_offset,
1277 relax_image=DestroyImage(relax_image);
1281static MagickBooleanType SeamlessBlendImage(Image *image,
1282 const Image *source_image,
const ssize_t x_offset,
const ssize_t y_offset,
1283 const double iterations,
const double residual_threshold,
const size_t tick,
1284 ExceptionInfo *exception)
1298 status = MagickTrue,
1299 verbose = MagickFalse;
1303 source_image->columns,
1315 crop_image=CropImage(image,&crop_info,exception);
1316 if (crop_image == (Image *) NULL)
1317 return(MagickFalse);
1318 DisableCompositeClampUnlessSpecified(crop_image);
1319 (void) ResetImagePage(crop_image,
"0x0+0+0");
1320 sum_image=BlendSumImage(crop_image,source_image,1.0,-1.0,exception);
1321 crop_image=DestroyImage(crop_image);
1322 if (sum_image == (Image *) NULL)
1323 return(MagickFalse);
1324 mean_image=BlendMeanImage(sum_image,source_image,exception);
1325 sum_image=DestroyImage(sum_image);
1326 if (mean_image == (Image *) NULL)
1327 return(MagickFalse);
1328 relax_image=CloneImage(mean_image,0,0,MagickTrue,exception);
1329 if (relax_image == (Image *) NULL)
1331 mean_image=DestroyImage(mean_image);
1332 return(MagickFalse);
1334 status=BlendMaskAlphaChannel(mean_image,source_image,exception);
1335 if (status == MagickFalse)
1337 relax_image=DestroyImage(relax_image);
1338 mean_image=DestroyImage(mean_image);
1339 return(MagickFalse);
1341 residual_image=CloneImage(relax_image,0,0,MagickTrue,exception);
1342 if (residual_image == (Image *) NULL)
1344 relax_image=DestroyImage(relax_image);
1345 mean_image=DestroyImage(mean_image);
1346 return(MagickFalse);
1351 kernel_info=AcquireKernelInfo(
"3x3:0,0.25,0,0.25,0,0.25,0,0.25,0",exception);
1352 if (kernel_info == (KernelInfo *) NULL)
1354 residual_image=DestroyImage(residual_image);
1355 relax_image=DestroyImage(relax_image);
1356 mean_image=DestroyImage(mean_image);
1357 return(MagickFalse);
1359 verbose=IsStringTrue(GetImageArtifact(image,
"verbose"));
1360 if (verbose != MagickFalse)
1361 (void) FormatLocaleFile(stderr,
"seamless blending:\n");
1362 for (i=0; i < (ssize_t) iterations; i++)
1370 convolve_image=ConvolveImage(relax_image,kernel_info,exception);
1371 if (convolve_image == (Image *) NULL)
1373 relax_image=DestroyImage(relax_image);
1374 relax_image=convolve_image;
1375 status=CompositeOverImage(relax_image,mean_image,MagickTrue,0,0,exception);
1376 if (status == MagickFalse)
1378 status=BlendRMSEResidual(relax_image,residual_image,&residual,exception);
1379 if (status == MagickFalse)
1381 if ((verbose != MagickFalse) && ((i % MagickMax(tick,1)) == 0))
1382 (void) FormatLocaleFile(stderr,
" %g: %g\n",(
double) i,(
double) residual);
1383 if (residual < residual_threshold)
1385 if (verbose != MagickFalse)
1386 (void) FormatLocaleFile(stderr,
" %g: %g\n",(
double) i,(
double)
1390 if (residual_image != (Image *) NULL)
1391 residual_image=DestroyImage(residual_image);
1392 residual_image=CloneImage(relax_image,0,0,MagickTrue,exception);
1393 if (residual_image == (Image *) NULL)
1396 kernel_info=DestroyKernelInfo(kernel_info);
1397 mean_image=DestroyImage(mean_image);
1398 residual_image=DestroyImage(residual_image);
1402 foreground_image=BlendSumImage(source_image,relax_image,1.0,1.0,exception);
1403 relax_image=DestroyImage(relax_image);
1404 if (foreground_image == (Image *) NULL)
1405 return(MagickFalse);
1406 (void) SetImageMask(foreground_image,ReadPixelMask,(
const Image *) NULL,
1408 status=CompositeOverImage(image,foreground_image,MagickTrue,x_offset,y_offset,
1410 foreground_image=DestroyImage(foreground_image);
1414MagickExport MagickBooleanType CompositeImage(Image *image,
1415 const Image *composite,
const CompositeOperator compose,
1416 const MagickBooleanType clip_to_self,
const ssize_t x_offset,
1417 const ssize_t y_offset,ExceptionInfo *exception)
1419#define CompositeImageTag "Composite/Image"
1426 colorspace = HCLColorspace;
1432 white_luminance = 10000.0;
1438 illuminant = D65Illuminant;
1467 assert(image != (Image *) NULL);
1468 assert(image->signature == MagickCoreSignature);
1469 assert(composite != (Image *) NULL);
1470 assert(composite->signature == MagickCoreSignature);
1471 if (IsEventLogging() != MagickFalse)
1472 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1473 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1474 return(MagickFalse);
1475 source_image=CloneImage(composite,0,0,MagickTrue,exception);
1476 if (source_image == (
const Image *) NULL)
1477 return(MagickFalse);
1478 (void) SetImageColorspace(source_image,image->colorspace,exception);
1479 if ((compose == OverCompositeOp) || (compose == SrcOverCompositeOp))
1481 status=CompositeOverImage(image,source_image,clip_to_self,x_offset,
1482 y_offset,exception);
1483 source_image=DestroyImage(source_image);
1487 canvas_image=(Image *) NULL;
1488 canvas_dissolve=1.0;
1489 white_luminance=10000.0;
1490 artifact=GetImageArtifact(image,
"compose:white-luminance");
1491 if (artifact != (
const char *) NULL)
1492 white_luminance=StringToDouble(artifact,(
char **) NULL);
1493 artifact=GetImageArtifact(image,
"compose:illuminant");
1494 if (artifact != (
const char *) NULL)
1499 illuminant_type=ParseCommandOption(MagickIlluminantOptions,MagickFalse,
1501 if (illuminant_type < 0)
1502 illuminant=UndefinedIlluminant;
1504 illuminant=(IlluminantType) illuminant_type;
1506 artifact=GetImageArtifact(image,
"compose:colorspace");
1507 if (artifact != (
const char *) NULL)
1512 colorspace_type=ParseCommandOption(MagickColorspaceOptions,MagickFalse,
1514 if (colorspace_type < 0)
1515 colorspace=UndefinedColorspace;
1517 colorspace=(ColorspaceType) colorspace_type;
1520 artifact=GetImageArtifact(image,
"compose:clamp");
1521 if (artifact != (
const char *) NULL)
1522 clamp=IsStringTrue(artifact);
1523 compose_sync=MagickTrue;
1524 artifact=GetImageArtifact(image,
"compose:sync");
1525 if (artifact != (
const char *) NULL)
1526 compose_sync=IsStringTrue(artifact);
1527 SetGeometryInfo(&geometry_info);
1529 percent_chroma=100.0;
1530 source_dissolve=1.0;
1534 case CopyCompositeOp:
1536 if ((x_offset < 0) || (y_offset < 0))
1538 if ((x_offset+(ssize_t) source_image->columns) > (ssize_t) image->columns)
1540 if ((y_offset+(ssize_t) source_image->rows) > (ssize_t) image->rows)
1542 if ((source_image->alpha_trait == UndefinedPixelTrait) &&
1543 (image->alpha_trait != UndefinedPixelTrait))
1544 (void) SetImageAlphaChannel(source_image,OpaqueAlphaChannel,exception);
1546 source_view=AcquireVirtualCacheView(source_image,exception);
1547 image_view=AcquireAuthenticCacheView(image,exception);
1548#if defined(MAGICKCORE_OPENMP_SUPPORT)
1549 #pragma omp parallel for schedule(static) shared(status) \
1550 magick_number_threads(source_image,image,source_image->rows,4)
1552 for (y=0; y < (ssize_t) source_image->rows; y++)
1566 if (status == MagickFalse)
1568 p=GetCacheViewVirtualPixels(source_view,0,y,source_image->columns,1,
1570 q=GetCacheViewAuthenticPixels(image_view,x_offset,y+y_offset,
1571 source_image->columns,1,exception);
1572 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1577 for (x=0; x < (ssize_t) source_image->columns; x++)
1582 if (GetPixelReadMask(source_image,p) <= (QuantumRange/2))
1584 p+=(ptrdiff_t) GetPixelChannels(source_image);
1585 q+=(ptrdiff_t) GetPixelChannels(image);
1588 for (i=0; i < (ssize_t) GetPixelChannels(source_image); i++)
1590 PixelChannel channel = GetPixelChannelChannel(source_image,i);
1591 PixelTrait source_traits = GetPixelChannelTraits(source_image,
1593 PixelTrait traits = GetPixelChannelTraits(image,channel);
1594 if ((source_traits == UndefinedPixelTrait) ||
1595 (traits == UndefinedPixelTrait) ||
1596 ((traits & UpdatePixelTrait) == 0))
1598 SetPixelChannel(image,channel,p[i],q);
1600 p+=(ptrdiff_t) GetPixelChannels(source_image);
1601 q+=(ptrdiff_t) GetPixelChannels(image);
1603 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1604 if (sync == MagickFalse)
1606 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1611 proceed=SetImageProgress(image,CompositeImageTag,(MagickOffsetType)
1613 if (proceed == MagickFalse)
1617 source_view=DestroyCacheView(source_view);
1618 image_view=DestroyCacheView(image_view);
1619 source_image=DestroyImage(source_image);
1622 case IntensityCompositeOp:
1624 if ((x_offset < 0) || (y_offset < 0))
1626 if ((x_offset+(ssize_t) source_image->columns) > (ssize_t) image->columns)
1628 if ((y_offset+(ssize_t) source_image->rows) > (ssize_t) image->rows)
1631 source_view=AcquireVirtualCacheView(source_image,exception);
1632 image_view=AcquireAuthenticCacheView(image,exception);
1633#if defined(MAGICKCORE_OPENMP_SUPPORT)
1634 #pragma omp parallel for schedule(static) shared(status) \
1635 magick_number_threads(source_image,image,source_image->rows,4)
1637 for (y=0; y < (ssize_t) source_image->rows; y++)
1651 if (status == MagickFalse)
1653 p=GetCacheViewVirtualPixels(source_view,0,y,source_image->columns,1,
1655 q=GetCacheViewAuthenticPixels(image_view,x_offset,y+y_offset,
1656 source_image->columns,1,exception);
1657 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1662 for (x=0; x < (ssize_t) source_image->columns; x++)
1664 if (GetPixelReadMask(source_image,p) <= (QuantumRange/2))
1666 p+=(ptrdiff_t) GetPixelChannels(source_image);
1667 q+=(ptrdiff_t) GetPixelChannels(image);
1670 SetPixelAlpha(image,clamp != MagickFalse ?
1671 ClampPixel(GetPixelIntensity(source_image,p)) :
1672 ClampToQuantum(GetPixelIntensity(source_image,p)),q);
1673 p+=(ptrdiff_t) GetPixelChannels(source_image);
1674 q+=(ptrdiff_t) GetPixelChannels(image);
1676 sync=SyncCacheViewAuthenticPixels(image_view,exception);
1677 if (sync == MagickFalse)
1679 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1684 proceed=SetImageProgress(image,CompositeImageTag,(MagickOffsetType)
1686 if (proceed == MagickFalse)
1690 source_view=DestroyCacheView(source_view);
1691 image_view=DestroyCacheView(image_view);
1692 source_image=DestroyImage(source_image);
1695 case CopyAlphaCompositeOp:
1696 case ChangeMaskCompositeOp:
1702 if ((image->alpha_trait & BlendPixelTrait) == 0)
1703 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1706 case BlurCompositeOp:
1731 canvas_image=CloneImage(image,0,0,MagickTrue,exception);
1732 if (canvas_image == (Image *) NULL)
1734 source_image=DestroyImage(source_image);
1735 return(MagickFalse);
1741 artifact=GetImageArtifact(image,
"compose:args");
1742 if (artifact != (
const char *) NULL)
1743 flags=ParseGeometry(artifact,&geometry_info);
1744 if ((flags & WidthValue) == 0)
1746 (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
1747 "InvalidSetting",
"'%s' '%s'",
"compose:args",artifact);
1748 source_image=DestroyImage(source_image);
1749 canvas_image=DestroyImage(canvas_image);
1750 return(MagickFalse);
1757 width=2.0*geometry_info.rho;
1759 if ((flags & HeightValue) != 0)
1760 height=2.0*geometry_info.sigma;
1768 if ((flags & XValue) != 0 )
1776 angle=DegreesToRadians(geometry_info.xi);
1777 blur.x1=width*cos(angle);
1778 blur.x2=width*sin(angle);
1779 blur.y1=(-height*sin(angle));
1780 blur.y2=height*cos(angle);
1784 if ((flags & YValue) != 0 )
1789 angle_start=DegreesToRadians(geometry_info.xi);
1790 angle_range=DegreesToRadians(geometry_info.psi)-angle_start;
1801 resample_filter=AcquireResampleFilter(image,exception);
1802 SetResampleFilter(resample_filter,GaussianFilter);
1806 GetPixelInfo(image,&pixel);
1807 source_view=AcquireVirtualCacheView(source_image,exception);
1808 canvas_view=AcquireAuthenticCacheView(canvas_image,exception);
1809 for (y=0; y < (ssize_t) source_image->rows; y++)
1823 if (((y+y_offset) < 0) || ((y+y_offset) >= (ssize_t) image->rows))
1825 p=GetCacheViewVirtualPixels(source_view,0,y,source_image->columns,1,
1827 q=QueueCacheViewAuthenticPixels(canvas_view,0,y,canvas_image->columns,1,
1829 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1831 for (x=0; x < (ssize_t) source_image->columns; x++)
1833 if (((x_offset+x) < 0) || ((x_offset+x) >= (ssize_t) image->columns))
1835 p+=(ptrdiff_t) GetPixelChannels(source_image);
1838 if (fabs(angle_range) > MagickEpsilon)
1843 angle=angle_start+angle_range*QuantumScale*(double)
1844 GetPixelBlue(source_image,p);
1845 blur.x1=width*cos(angle);
1846 blur.x2=width*sin(angle);
1847 blur.y1=(-height*sin(angle));
1848 blur.y2=height*cos(angle);
1850 ScaleResampleFilter(resample_filter,
1851 blur.x1*QuantumScale*(
double) GetPixelRed(source_image,p),
1852 blur.y1*QuantumScale*(
double) GetPixelGreen(source_image,p),
1853 blur.x2*QuantumScale*(
double) GetPixelRed(source_image,p),
1854 blur.y2*QuantumScale*(
double) GetPixelGreen(source_image,p) );
1855 (void) ResamplePixelColor(resample_filter,(
double) x_offset+x,
1856 (
double) y_offset+y,&pixel,exception);
1857 SetPixelViaPixelInfo(canvas_image,&pixel,q);
1858 p+=(ptrdiff_t) GetPixelChannels(source_image);
1859 q+=(ptrdiff_t) GetPixelChannels(canvas_image);
1861 sync=SyncCacheViewAuthenticPixels(canvas_view,exception);
1862 if (sync == MagickFalse)
1865 resample_filter=DestroyResampleFilter(resample_filter);
1866 source_view=DestroyCacheView(source_view);
1867 canvas_view=DestroyCacheView(canvas_view);
1868 source_image=DestroyImage(source_image);
1869 source_image=canvas_image;
1872 case DisplaceCompositeOp:
1873 case DistortCompositeOp:
1894 canvas_image=CloneImage(image,0,0,MagickTrue,exception);
1895 if (canvas_image == (Image *) NULL)
1897 source_image=DestroyImage(source_image);
1898 return(MagickFalse);
1900 SetGeometryInfo(&geometry_info);
1902 artifact=GetImageArtifact(image,
"compose:args");
1903 if (artifact != (
char *) NULL)
1904 flags=ParseGeometry(artifact,&geometry_info);
1905 if ((flags & (WidthValue | HeightValue)) == 0 )
1907 if ((flags & AspectValue) == 0)
1909 horizontal_scale=(MagickRealType) (source_image->columns-1)/2.0;
1910 vertical_scale=(MagickRealType) (source_image->rows-1)/2.0;
1914 horizontal_scale=(MagickRealType) (image->columns-1)/2.0;
1915 vertical_scale=(MagickRealType) (image->rows-1)/2.0;
1920 horizontal_scale=geometry_info.rho;
1921 vertical_scale=geometry_info.sigma;
1922 if ((flags & PercentValue) != 0)
1924 if ((flags & AspectValue) == 0)
1926 horizontal_scale*=(source_image->columns-1)/200.0;
1927 vertical_scale*=(source_image->rows-1)/200.0;
1931 horizontal_scale*=(image->columns-1)/200.0;
1932 vertical_scale*=(image->rows-1)/200.0;
1935 if ((flags & HeightValue) == 0)
1936 vertical_scale=horizontal_scale;
1946 center.x=(MagickRealType) x_offset;
1947 center.y=(MagickRealType) y_offset;
1948 if (compose == DistortCompositeOp)
1950 if ((flags & XValue) == 0)
1951 if ((flags & AspectValue) != 0)
1952 center.x=(MagickRealType) ((image->columns-1)/2.0);
1954 center.x=(MagickRealType) (x_offset+(source_image->columns-1)/
1957 if ((flags & AspectValue) != 0)
1958 center.x=geometry_info.xi;
1960 center.x=(MagickRealType) (x_offset+geometry_info.xi);
1961 if ((flags & YValue) == 0)
1962 if ((flags & AspectValue) != 0)
1963 center.y=(MagickRealType) ((image->rows-1)/2.0);
1965 center.y=(MagickRealType) (y_offset+(source_image->rows-1)/2.0);
1967 if ((flags & AspectValue) != 0)
1968 center.y=geometry_info.psi;
1970 center.y=(MagickRealType) (y_offset+geometry_info.psi);
1976 GetPixelInfo(image,&pixel);
1977 image_view=AcquireVirtualCacheView(image,exception);
1978 source_view=AcquireVirtualCacheView(source_image,exception);
1979 canvas_view=AcquireAuthenticCacheView(canvas_image,exception);
1980 for (y=0; y < (ssize_t) source_image->rows; y++)
1994 if (((y+y_offset) < 0) || ((y+y_offset) >= (ssize_t) image->rows))
1996 p=GetCacheViewVirtualPixels(source_view,0,y,source_image->columns,1,
1998 q=QueueCacheViewAuthenticPixels(canvas_view,0,y,canvas_image->columns,1,
2000 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
2002 for (x=0; x < (ssize_t) source_image->columns; x++)
2004 if (((x_offset+x) < 0) || ((x_offset+x) >= (ssize_t) image->columns))
2006 p+=(ptrdiff_t) GetPixelChannels(source_image);
2012 offset.x=(double) (horizontal_scale*((
double) GetPixelRed(
2013 source_image,p)-(((MagickRealType) QuantumRange+1.0)/2.0)))/
2014 (((MagickRealType) QuantumRange+1.0)/2.0)+center.x+
2015 ((compose == DisplaceCompositeOp) ? x : 0);
2016 offset.y=(double) (vertical_scale*((
double) GetPixelGreen(
2017 source_image,p)-(((MagickRealType) QuantumRange+1.0)/2.0)))/
2018 (((MagickRealType) QuantumRange+1.0)/2.0)+center.y+
2019 ((compose == DisplaceCompositeOp) ? y : 0);
2020 status=InterpolatePixelInfo(image,image_view,
2021 UndefinedInterpolatePixel,(
double) offset.x,(
double) offset.y,
2023 if (status == MagickFalse)
2028 pixel.alpha=(MagickRealType) QuantumRange*(QuantumScale*pixel.alpha)*
2029 (QuantumScale*(double) GetPixelAlpha(source_image,p));
2030 SetPixelViaPixelInfo(canvas_image,&pixel,q);
2031 p+=(ptrdiff_t) GetPixelChannels(source_image);
2032 q+=(ptrdiff_t) GetPixelChannels(canvas_image);
2034 if (x < (ssize_t) source_image->columns)
2036 sync=SyncCacheViewAuthenticPixels(canvas_view,exception);
2037 if (sync == MagickFalse)
2040 canvas_view=DestroyCacheView(canvas_view);
2041 source_view=DestroyCacheView(source_view);
2042 image_view=DestroyCacheView(image_view);
2043 source_image=DestroyImage(source_image);
2044 source_image=canvas_image;
2047 case DissolveCompositeOp:
2052 artifact=GetImageArtifact(image,
"compose:args");
2053 if (artifact != (
char *) NULL)
2055 flags=ParseGeometry(artifact,&geometry_info);
2056 source_dissolve=geometry_info.rho/100.0;
2057 canvas_dissolve=1.0;
2058 if ((source_dissolve-MagickEpsilon) < 0.0)
2059 source_dissolve=0.0;
2060 if ((source_dissolve+MagickEpsilon) > 1.0)
2062 canvas_dissolve=2.0-source_dissolve;
2063 source_dissolve=1.0;
2065 if ((flags & SigmaValue) != 0)
2066 canvas_dissolve=geometry_info.sigma/100.0;
2067 if ((canvas_dissolve-MagickEpsilon) < 0.0)
2068 canvas_dissolve=0.0;
2069 if ((canvas_dissolve+MagickEpsilon) > 1.0)
2070 canvas_dissolve=1.0;
2074 case BlendCompositeOp:
2076 artifact=GetImageArtifact(image,
"compose:args");
2077 if (artifact != (
char *) NULL)
2079 flags=ParseGeometry(artifact,&geometry_info);
2080 source_dissolve=geometry_info.rho/100.0;
2081 canvas_dissolve=1.0-source_dissolve;
2082 if ((flags & SigmaValue) != 0)
2083 canvas_dissolve=geometry_info.sigma/100.0;
2087 case SaliencyBlendCompositeOp:
2090 residual_threshold = 0.0002,
2096 artifact=GetImageArtifact(image,
"compose:args");
2097 if (artifact != (
char *) NULL)
2099 flags=ParseGeometry(artifact,&geometry_info);
2100 iterations=geometry_info.rho;
2101 if ((flags & SigmaValue) != 0)
2102 residual_threshold=geometry_info.sigma;
2103 if ((flags & XiValue) != 0)
2104 tick=(size_t) geometry_info.xi;
2106 status=SaliencyBlendImage(image,composite,x_offset,y_offset,iterations,
2107 residual_threshold,tick,exception);
2108 source_image=DestroyImage(source_image);
2111 case SeamlessBlendCompositeOp:
2114 residual_threshold = 0.0002,
2120 artifact=GetImageArtifact(image,
"compose:args");
2121 if (artifact != (
char *) NULL)
2123 flags=ParseGeometry(artifact,&geometry_info);
2124 iterations=geometry_info.rho;
2125 if ((flags & SigmaValue) != 0)
2126 residual_threshold=geometry_info.sigma;
2127 if ((flags & XiValue) != 0)
2128 tick=(size_t) geometry_info.xi;
2130 status=SeamlessBlendImage(image,composite,x_offset,y_offset,iterations,
2131 residual_threshold,tick,exception);
2132 source_image=DestroyImage(source_image);
2135 case MathematicsCompositeOp:
2145 SetGeometryInfo(&geometry_info);
2146 artifact=GetImageArtifact(image,
"compose:args");
2147 if (artifact != (
char *) NULL)
2149 flags=ParseGeometry(artifact,&geometry_info);
2150 if (flags == NoValue)
2151 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
2152 "InvalidGeometry",
"`%s'",artifact);
2156 case ModulateCompositeOp:
2161 artifact=GetImageArtifact(image,
"compose:args");
2162 if (artifact != (
char *) NULL)
2164 flags=ParseGeometry(artifact,&geometry_info);
2165 percent_luma=geometry_info.rho;
2166 if ((flags & SigmaValue) != 0)
2167 percent_chroma=geometry_info.sigma;
2171 case ThresholdCompositeOp:
2176 artifact=GetImageArtifact(image,
"compose:args");
2177 if (artifact != (
char *) NULL)
2179 flags=ParseGeometry(artifact,&geometry_info);
2180 amount=geometry_info.rho;
2181 threshold=geometry_info.sigma;
2182 if ((flags & SigmaValue) == 0)
2185 threshold*=(double) QuantumRange;
2196 midpoint=((MagickRealType) QuantumRange+1.0)/2;
2197 source_view=AcquireVirtualCacheView(source_image,exception);
2198 image_view=AcquireAuthenticCacheView(image,exception);
2199#if defined(MAGICKCORE_OPENMP_SUPPORT)
2200 #pragma omp parallel for schedule(static) shared(progress,status) \
2201 magick_number_threads(source_image,image,image->rows,1)
2203 for (y=0; y < (ssize_t) image->rows; y++)
2227 if (status == MagickFalse)
2229 if (clip_to_self != MagickFalse)
2233 if ((y-y_offset) >= (ssize_t) source_image->rows)
2239 pixels=(Quantum *) NULL;
2241 if ((y >= y_offset) &&
2242 ((y-y_offset) < (ssize_t) source_image->rows))
2244 p=GetCacheViewVirtualPixels(source_view,0,
2245 CastDoubleToSsizeT((
double) y-y_offset),source_image->columns,1,
2247 if (p == (
const Quantum *) NULL)
2254 p-=(ptrdiff_t) CastDoubleToSsizeT((
double) x_offset*
2255 GetPixelChannels(source_image));
2257 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
2258 if (q == (Quantum *) NULL)
2263 GetPixelInfo(image,&canvas_pixel);
2264 GetPixelInfo(source_image,&source_pixel);
2265 for (x=0; x < (ssize_t) image->columns; x++)
2290 if (clip_to_self != MagickFalse)
2294 q+=(ptrdiff_t) GetPixelChannels(image);
2297 if ((x-x_offset) >= (ssize_t) source_image->columns)
2300 if ((pixels == (Quantum *) NULL) || (x < x_offset) ||
2301 ((x-x_offset) >= (ssize_t) source_image->columns))
2304 source[MaxPixelChannels];
2311 (void) GetOneVirtualPixel(source_image,
2312 CastDoubleToSsizeT((
double) x-x_offset),
2313 CastDoubleToSsizeT((
double) y-y_offset),source,exception);
2314 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2319 PixelChannel channel = GetPixelChannelChannel(image,i);
2320 PixelTrait traits = GetPixelChannelTraits(image,channel);
2321 PixelTrait source_traits = GetPixelChannelTraits(source_image,
2323 if ((traits == UndefinedPixelTrait) ||
2324 (source_traits == UndefinedPixelTrait))
2328 case AlphaCompositeOp:
2329 case ChangeMaskCompositeOp:
2330 case CopyAlphaCompositeOp:
2331 case DstAtopCompositeOp:
2332 case DstInCompositeOp:
2334 case OutCompositeOp:
2335 case SrcInCompositeOp:
2336 case SrcOutCompositeOp:
2338 if (channel == AlphaPixelChannel)
2339 pixel=(MagickRealType) TransparentAlpha;
2341 pixel=(MagickRealType) q[i];
2344 case ClearCompositeOp:
2345 case CopyCompositeOp:
2346 case ReplaceCompositeOp:
2348 if (channel == AlphaPixelChannel)
2349 pixel=(MagickRealType) TransparentAlpha;
2354 case BlendCompositeOp:
2355 case DissolveCompositeOp:
2357 if (channel == AlphaPixelChannel)
2358 pixel=canvas_dissolve*(double) GetPixelAlpha(source_image,
2361 pixel=(MagickRealType) source[channel];
2366 pixel=(MagickRealType) source[channel];
2370 q[i]=clamp != MagickFalse ? ClampPixel(pixel) :
2371 ClampToQuantum(pixel);
2373 q+=(ptrdiff_t) GetPixelChannels(image);
2381 Sa=QuantumScale*(double) GetPixelAlpha(source_image,p);
2382 Da=QuantumScale*(double) GetPixelAlpha(image,q);
2385 case BumpmapCompositeOp:
2386 case ColorBurnCompositeOp:
2387 case ColorDodgeCompositeOp:
2388 case DarkenCompositeOp:
2389 case DifferenceCompositeOp:
2390 case DivideCompositeOp:
2391 case DivideDstCompositeOp:
2392 case DivideSrcCompositeOp:
2393 case ExclusionCompositeOp:
2394 case FreezeCompositeOp:
2395 case HardLightCompositeOp:
2396 case HardMixCompositeOp:
2397 case InterpolateCompositeOp:
2398 case LightenCompositeOp:
2399 case LinearBurnCompositeOp:
2400 case LinearDodgeCompositeOp:
2401 case LinearLightCompositeOp:
2402 case MathematicsCompositeOp:
2403 case MinusDstCompositeOp:
2404 case MinusSrcCompositeOp:
2405 case MultiplyCompositeOp:
2406 case NegateCompositeOp:
2407 case OverlayCompositeOp:
2408 case PegtopLightCompositeOp:
2409 case PinLightCompositeOp:
2410 case ReflectCompositeOp:
2411 case ScreenCompositeOp:
2412 case SoftBurnCompositeOp:
2413 case SoftDodgeCompositeOp:
2414 case SoftLightCompositeOp:
2415 case StampCompositeOp:
2416 case VividLightCompositeOp:
2418 alpha=RoundToUnity(Sa+Da-Sa*Da);
2421 case DstAtopCompositeOp:
2422 case DstInCompositeOp:
2424 case SrcInCompositeOp:
2429 case DissolveCompositeOp:
2431 alpha=source_dissolve*Sa*(-canvas_dissolve*Da)+source_dissolve*Sa+
2435 case DstOverCompositeOp:
2436 case OverCompositeOp:
2437 case SrcOverCompositeOp:
2442 case DstOutCompositeOp:
2447 case OutCompositeOp:
2448 case SrcOutCompositeOp:
2453 case BlendCompositeOp:
2454 case PlusCompositeOp:
2456 alpha=RoundToUnity(source_dissolve*Sa+canvas_dissolve*Da);
2459 case XorCompositeOp:
2461 alpha=Sa+Da-2.0*Sa*Da;
2464 case ModulusAddCompositeOp:
2471 alpha=((Sa+Da)-1.0);
2474 case ModulusSubtractCompositeOp:
2481 alpha=((Sa-Da)+1.0);
2492 case ColorizeCompositeOp:
2493 case HueCompositeOp:
2494 case LuminizeCompositeOp:
2495 case ModulateCompositeOp:
2496 case RMSECompositeOp:
2497 case SaturateCompositeOp:
2499 Si=GetPixelIntensity(source_image,p);
2500 GetPixelInfoPixel(source_image,p,&source_pixel);
2501 GetPixelInfoPixel(image,q,&canvas_pixel);
2504 case BumpmapCompositeOp:
2505 case CopyAlphaCompositeOp:
2506 case DarkenIntensityCompositeOp:
2507 case LightenIntensityCompositeOp:
2509 Si=GetPixelIntensity(source_image,p);
2510 Di=GetPixelIntensity(image,q);
2516 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2522 PixelChannel channel = GetPixelChannelChannel(image,i);
2523 PixelTrait traits = GetPixelChannelTraits(image,channel);
2524 PixelTrait source_traits = GetPixelChannelTraits(source_image,channel);
2525 if (traits == UndefinedPixelTrait)
2527 if ((channel == AlphaPixelChannel) &&
2528 ((traits & UpdatePixelTrait) != 0))
2535 case AlphaCompositeOp:
2537 pixel=(double) QuantumRange*Sa;
2540 case AtopCompositeOp:
2541 case CopyBlackCompositeOp:
2542 case CopyBlueCompositeOp:
2543 case CopyCyanCompositeOp:
2544 case CopyGreenCompositeOp:
2545 case CopyMagentaCompositeOp:
2546 case CopyRedCompositeOp:
2547 case CopyYellowCompositeOp:
2548 case SrcAtopCompositeOp:
2549 case DstCompositeOp:
2552 pixel=(double) QuantumRange*Da;
2555 case BumpmapCompositeOp:
2560 case ChangeMaskCompositeOp:
2562 if (IsFuzzyEquivalencePixel(source_image,p,image,q) != MagickFalse)
2563 pixel=(MagickRealType) TransparentAlpha;
2565 pixel=(double) QuantumRange*Da;
2568 case ClearCompositeOp:
2570 pixel=(MagickRealType) TransparentAlpha;
2573 case ColorizeCompositeOp:
2574 case HueCompositeOp:
2575 case LuminizeCompositeOp:
2576 case RMSECompositeOp:
2577 case SaturateCompositeOp:
2579 if (fabs((
double) QuantumRange*Sa-(
double) TransparentAlpha) < MagickEpsilon)
2581 pixel=(double) QuantumRange*Da;
2584 if (fabs((
double) QuantumRange*Da-(
double) TransparentAlpha) < MagickEpsilon)
2586 pixel=(double) QuantumRange*Sa;
2591 pixel=(double) QuantumRange*Da;
2594 pixel=(double) QuantumRange*Sa;
2597 case CopyAlphaCompositeOp:
2599 if (source_image->alpha_trait == UndefinedPixelTrait)
2602 pixel=(double) QuantumRange*Sa;
2605 case BlurCompositeOp:
2606 case CopyCompositeOp:
2607 case DisplaceCompositeOp:
2608 case DistortCompositeOp:
2609 case DstAtopCompositeOp:
2610 case ReplaceCompositeOp:
2611 case SrcCompositeOp:
2613 pixel=(double) QuantumRange*Sa;
2616 case DarkenIntensityCompositeOp:
2618 if (compose_sync == MagickFalse)
2620 pixel=Si < Di ? Sa : Da;
2623 pixel=Sa*Si < Da*Di ? Sa : Da;
2626 case DifferenceCompositeOp:
2628 pixel=(double) QuantumRange*fabs((
double) (Sa-Da));
2631 case FreezeCompositeOp:
2633 pixel=(double) QuantumRange*(1.0-(1.0-Sa)*(1.0-Sa)*
2634 MagickSafeReciprocal(Da));
2639 case InterpolateCompositeOp:
2641 pixel=(double) QuantumRange*(0.5-0.25*cos(MagickPI*Sa)-0.25*
2645 case LightenIntensityCompositeOp:
2647 if (compose_sync == MagickFalse)
2649 pixel=Si > Di ? Sa : Da;
2652 pixel=Sa*Si > Da*Di ? Sa : Da;
2655 case ModulateCompositeOp:
2657 pixel=(double) QuantumRange*Da;
2660 case MultiplyCompositeOp:
2662 if (compose_sync == MagickFalse)
2664 pixel=(double) QuantumRange*Sa*Da;
2667 pixel=(double) QuantumRange*alpha;
2670 case NegateCompositeOp:
2672 pixel=(double) QuantumRange*((1.0-Sa-Da));
2675 case ReflectCompositeOp:
2677 pixel=(double) QuantumRange*(Sa*Sa*
2678 MagickSafeReciprocal(1.0-Da));
2679 if (pixel > (
double) QuantumRange)
2680 pixel=(double) QuantumRange;
2683 case StampCompositeOp:
2685 pixel=(double) QuantumRange*(Sa+Da*Da-1.0);
2688 case StereoCompositeOp:
2690 pixel=(double) QuantumRange*(Sa+Da)/2;
2695 pixel=(double) QuantumRange*alpha;
2699 q[i]=clamp != MagickFalse ? ClampPixel(pixel) :
2700 ClampToQuantum(pixel);
2703 if (source_traits == UndefinedPixelTrait)
2709 Sc=(MagickRealType) GetPixelChannel(source_image,channel,p);
2710 Dc=(MagickRealType) q[i];
2711 if ((traits & CopyPixelTrait) != 0)
2716 q[i]=ClampToQuantum(Dc);
2724 Sca=QuantumScale*Sa*Sc;
2725 Dca=QuantumScale*Da*Dc;
2728 case DarkenCompositeOp:
2729 case LightenCompositeOp:
2730 case ModulusSubtractCompositeOp:
2732 gamma=MagickSafeReciprocal(1.0-alpha);
2737 gamma=MagickSafeReciprocal(alpha);
2744 case AlphaCompositeOp:
2746 pixel=(double) QuantumRange*Sa;
2749 case AtopCompositeOp:
2750 case SrcAtopCompositeOp:
2752 pixel=(double) QuantumRange*(Sca*Da+Dca*(1.0-Sa));
2755 case BlendCompositeOp:
2757 pixel=gamma*(source_dissolve*Sa*Sc+canvas_dissolve*Da*Dc);
2760 case CopyCompositeOp:
2761 case ReplaceCompositeOp:
2763 pixel=(double) QuantumRange*Sca;
2766 case BlurCompositeOp:
2767 case DisplaceCompositeOp:
2768 case DistortCompositeOp:
2769 case SrcCompositeOp:
2774 case BumpmapCompositeOp:
2776 if (fabs((
double) QuantumRange*Sa-(
double) TransparentAlpha) < MagickEpsilon)
2781 pixel=(QuantumScale*Si)*Dc;
2784 case ChangeMaskCompositeOp:
2789 case ClearCompositeOp:
2794 case ColorBurnCompositeOp:
2796 D=(Da > 0.0) ? RoundToUnity(Dca/Da) : 0.0;
2797 S=(Sa > 0.0) ? RoundToUnity(Sca/Sa) : 0.0;
2798 if (fabs(S) < MagickEpsilon)
2801 blend=MagickMin(1.0,MagickMax(0.0,1.0-(1.0-D)/S));
2802 pixel=(double) QuantumRange*gamma*RoundToUnity(Sa*Da*blend+Sa*
2803 (1.0-Da)*S+Da*(1.0-Sa)*D);
2806 case ColorDodgeCompositeOp:
2809 S=RoundToUnity(Sca/Sa);
2813 D=RoundToUnity(Dca/Da);
2826 blend=MagickMin(1.0,D/(1.0-S));
2828 pixel=(double) QuantumRange*gamma*(Sa*Da*blend+Sca*(1.0-Da)+Dca*
2832 case ColorizeCompositeOp:
2834 if (fabs((
double) QuantumRange*Sa-(
double) TransparentAlpha) < MagickEpsilon)
2839 if (fabs((
double) QuantumRange*Da-(
double) TransparentAlpha) < MagickEpsilon)
2844 ConvertRGBToGeneric(colorspace,(
double) canvas_pixel.red,
2845 (
double) canvas_pixel.green,(
double) canvas_pixel.blue,
2846 white_luminance,illuminant,&sans,&sans,&luma);
2847 ConvertRGBToGeneric(colorspace,(
double) source_pixel.red,
2848 (
double) source_pixel.green,(
double) source_pixel.blue,
2849 white_luminance,illuminant,&hue,&chroma,&sans);
2850 ConvertGenericToRGB(colorspace,hue,chroma,luma,
2851 white_luminance,illuminant,&red,&green,&blue);
2854 case RedPixelChannel: pixel=red;
break;
2855 case GreenPixelChannel: pixel=green;
break;
2856 case BluePixelChannel: pixel=blue;
break;
2857 default: pixel=Dc;
break;
2861 case CopyAlphaCompositeOp:
2862 case DstCompositeOp:
2867 case CopyBlackCompositeOp:
2869 if (channel == BlackPixelChannel)
2870 pixel=(MagickRealType) GetPixelBlack(source_image,p);
2873 case CopyBlueCompositeOp:
2874 case CopyYellowCompositeOp:
2876 if (channel == BluePixelChannel)
2877 pixel=(MagickRealType) GetPixelBlue(source_image,p);
2880 case CopyGreenCompositeOp:
2881 case CopyMagentaCompositeOp:
2883 if (channel == GreenPixelChannel)
2884 pixel=(MagickRealType) GetPixelGreen(source_image,p);
2887 case CopyRedCompositeOp:
2888 case CopyCyanCompositeOp:
2890 if (channel == RedPixelChannel)
2891 pixel=(MagickRealType) GetPixelRed(source_image,p);
2894 case DarkenCompositeOp:
2896 if (compose_sync == MagickFalse)
2898 pixel=RoundToUnity(MagickMin(Sca,Dca)+Sca*(1.0-Da)+Dca*
2902 pixel=(double) QuantumRange*RoundToUnity(MagickMin(Sca,Dca)+Sca*
2903 (1.0-Da)+Dca*(1.0-Sa));
2906 case DarkenIntensityCompositeOp:
2908 if (compose_sync == MagickFalse)
2910 pixel=RoundToUnity(MagickMin(Sca,Dca)+Sca*(1.0-Di)+Dca*
2914 pixel=(double) QuantumRange*RoundToUnity(MagickMin(Sca,Dca)+Sca*
2915 (1.0-Di)+Dca*(1.0-Si));
2918 case DifferenceCompositeOp:
2920 if (compose_sync == MagickFalse)
2922 pixel=(double) QuantumRange*RoundToUnity(fabs((
double) Sc-
2926 S=(Sa > 0.0) ? (Sca/Sa) : 0.0;
2927 D=(Da > 0.0) ? (Dca/Da) : 0.0;
2928 pixel=(double) QuantumRange*RoundToUnity(fabs(S-D));
2931 case DissolveCompositeOp:
2933 pixel=gamma*(source_dissolve*Sa*Sc-source_dissolve*Sa*
2934 canvas_dissolve*Da*Dc+canvas_dissolve*Da*Dc);
2937 case DivideCompositeOp:
2939 D=(Da > 0.0) ? (Dca/Da) : 0.0;
2940 S=(Sa > 0.0) ? (Sca/Sa) : 0.0;
2941 if (fabs(S) < MagickEpsilon)
2944 blend=RoundToUnity(D/S);
2945 pixel=(double) QuantumRange*gamma*RoundToUnity(Sca*(1.0-Da)+Dca*(1.0-Sa)+
2949 case DivideDstCompositeOp:
2951 if (compose_sync == MagickFalse)
2953 if (fabs(Dc) < MagickEpsilon)
2954 pixel=(double) QuantumRange;
2956 pixel=(double) QuantumRange*(Sc/Dc);
2959 if (fabs(Dca) < MagickEpsilon)
2960 pixel=(double) QuantumRange*gamma*(Sca+(1.0-Sa));
2962 pixel=(double) QuantumRange*gamma*(Sca/Dca+Sca*(1.0-Da)+Dca*(1.0-Sa));
2965 case DivideSrcCompositeOp:
2967 if (compose_sync == MagickFalse)
2969 if (fabs(Sc) < MagickEpsilon)
2970 pixel=(double) QuantumRange;
2972 pixel=(double) QuantumRange*(Dc/Sc);
2975 if (fabs(Dca) < MagickEpsilon)
2976 pixel=(double) QuantumRange*gamma*(Dca+(1.0-Da));
2978 pixel=(double) QuantumRange*gamma*(Dca/Sca+Dca*(1.0-Sa)+Sca*(1.0-Da));
2981 case DstAtopCompositeOp:
2983 pixel=(double) QuantumRange*(Dca*Sa+Sca*(1.0-Da));
2986 case DstInCompositeOp:
2988 pixel=(double) QuantumRange*gamma*(Dca*Sa);
2991 case DstOutCompositeOp:
2993 pixel=(double) QuantumRange*gamma*(Dca*(1.0-Sa));
2996 case DstOverCompositeOp:
2998 pixel=(double) QuantumRange*gamma*(Dca+Sca*(1.0-Da));
3001 case ExclusionCompositeOp:
3003 S=(Sa > 0.0) ? RoundToUnity(Sca/Sa) : 0.0;
3004 D=(Da > 0.0) ? RoundToUnity(Dca/Da) : 0.0;
3005 blend=RoundToUnity(S+D-2.0*S*D);
3006 pixel=(double) QuantumRange*RoundToUnity((blend*Sa+D*(1.0-Sa))*
3010 case FreezeCompositeOp:
3013 blend=1.0-(1.0-Sca)*(1.0-Sca)/Dca;
3016 pixel=(double) QuantumRange*gamma*RoundToUnity(blend);
3019 case HardLightCompositeOp:
3021 D=(Da > 0.0) ? RoundToUnity(Dca/Da) : 0.0;
3022 S=(Sa > 0.0) ? RoundToUnity(Sca/Sa) : 0.0;
3026 blend=1.0-2.0*(1.0-S)*(1.0-D);
3027 pixel=(double) QuantumRange*gamma*RoundToUnity((1.0-Da)*Sca+
3028 (1.0-Sa)*Dca+blend*Sa*Da);
3031 case HardMixCompositeOp:
3037 S=(Sa > 0.0) ? RoundToUnity(Sca/Sa) : 0.0;
3038 D=(Da > 0.0) ? RoundToUnity(Dca/Da) : 0.0;
3041 if (S <= MagickEpsilon)
3044 vivid=1.0-(1.0-D)/(2.0*S);
3048 if ((1.0-(2.0*S-1.0)) <= MagickEpsilon)
3051 vivid=D/(1.0-(2.0*S-1.0));
3053 hardmix=(vivid < 0.5) ? 0.0 : 1.0;
3054 pixel=(double) QuantumRange*gamma*RoundToUnity(Sa*Da*hardmix+Sca*
3055 (1.0-Da)+Dca*(1.0-Sa));
3058 case HueCompositeOp:
3060 if (fabs((
double) QuantumRange*Sa-(
double) TransparentAlpha) < MagickEpsilon)
3065 if (fabs((
double) QuantumRange*Da-(
double) TransparentAlpha) < MagickEpsilon)
3070 ConvertRGBToGeneric(colorspace,(
double) canvas_pixel.red,
3071 (
double) canvas_pixel.green,(
double) canvas_pixel.blue,
3072 white_luminance,illuminant,&hue,&chroma,&luma);
3073 ConvertRGBToGeneric(colorspace,(
double) source_pixel.red,
3074 (
double) source_pixel.green,(
double) source_pixel.blue,
3075 white_luminance,illuminant,&hue,&sans,&sans);
3076 ConvertGenericToRGB(colorspace,hue,chroma,luma,
3077 white_luminance,illuminant,&red,&green,&blue);
3080 case RedPixelChannel: pixel=red;
break;
3081 case GreenPixelChannel: pixel=green;
break;
3082 case BluePixelChannel: pixel=blue;
break;
3083 default: pixel=Dc;
break;
3088 case SrcInCompositeOp:
3090 pixel=(double) QuantumRange*(Sca*Da);
3093 case InterpolateCompositeOp:
3095 pixel=(double) QuantumRange*(0.5-0.25*cos(MagickPI*Sca)-0.25*
3099 case LinearBurnCompositeOp:
3107 S=(Sa > 0.0) ? RoundToUnity(Sca/Sa) : 0.0;
3108 D=(Da > 0.0) ? RoundToUnity(Dca/Da) : 0.0;
3109 blend=RoundToUnity(S+D-1.0);
3110 pixel=(double) QuantumRange*RoundToUnity(Sa*Da*blend+Sca*(1.0-Da)+
3114 case LinearDodgeCompositeOp:
3116 S=(Sa > 0.0) ? RoundToUnity(Sca/Sa) : 0.0;
3117 D=(Da > 0.0) ? RoundToUnity(Dca/Da) : 0.0;
3118 blend=RoundToUnity(S+D);
3119 pixel=(double) QuantumRange*gamma*RoundToUnity(Sa*Da*blend+
3120 Sca*(1.0-Da)+Dca*(1.0-Sa));
3123 case LinearLightCompositeOp:
3130 S=(Sa > 0.0) ? RoundToUnity(Sca/Sa) : 0.0;
3131 D=(Da > 0.0) ? RoundToUnity(Dca/Da) : 0.0;
3132 blend=RoundToUnity(D+2.0*S-1.0);
3133 pixel=(double) QuantumRange*gamma*RoundToUnity(Sa*Da*blend+Sca*
3134 (1.0-Da)+Dca*(1.0-Sa));
3137 case LightenCompositeOp:
3139 if (compose_sync == MagickFalse)
3141 pixel=MagickMax(Sc,Dc);
3144 S=(Sa > 0.0) ? RoundToUnity(Sca/Sa) : 0.0;
3145 D=(Da > 0.0) ? RoundToUnity(Dca/Da) : 0.0;
3146 pixel=(double) QuantumRange*RoundToUnity(Sca*(1.0-Da)+Dca*(1.0-Sa)+
3147 MagickMax(S,D)*Sa*Da);
3150 case LightenIntensityCompositeOp:
3152 pixel=Si > Di ? Sc : Dc;
3155 case LuminizeCompositeOp:
3157 if (fabs((
double) QuantumRange*Sa-(
double) TransparentAlpha) < MagickEpsilon)
3162 if (fabs((
double) QuantumRange*Da-(
double) TransparentAlpha) < MagickEpsilon)
3167 ConvertRGBToGeneric(colorspace,(
double) canvas_pixel.red,
3168 (
double) canvas_pixel.green,(
double) canvas_pixel.blue,
3169 white_luminance,illuminant,&hue,&chroma,&luma);
3170 ConvertRGBToGeneric(colorspace,(
double) source_pixel.red,
3171 (
double) source_pixel.green,(
double) source_pixel.blue,
3172 white_luminance,illuminant,&sans,&sans,&luma);
3173 ConvertGenericToRGB(colorspace,hue,chroma,luma,
3174 white_luminance,illuminant,&red,&green,&blue);
3177 case RedPixelChannel: pixel=red;
break;
3178 case GreenPixelChannel: pixel=green;
break;
3179 case BluePixelChannel: pixel=blue;
break;
3180 default: pixel=Dc;
break;
3184 case MathematicsCompositeOp:
3205 if (compose_sync == MagickFalse)
3207 pixel=geometry_info.rho*Sc*Dc+geometry_info.sigma*Sc+
3208 geometry_info.xi*Dc+geometry_info.psi;
3211 pixel=(double) QuantumRange*gamma*(geometry_info.rho*Sca*Dca+
3212 geometry_info.sigma*Sca*Da+geometry_info.xi*Dca*Sa+
3213 geometry_info.psi*Sa*Da+Sca*(1.0-Da)+Dca*(1.0-Sa));
3216 case MinusDstCompositeOp:
3218 if (compose_sync == MagickFalse)
3223 pixel=gamma*(Sa*Sc+Da*Dc-2.0*Da*Dc*Sa);
3226 case MinusSrcCompositeOp:
3228 if (compose_sync == MagickFalse)
3233 pixel=gamma*(Da*Dc+Sa*Sc-2.0*Sa*Sc*Da);
3236 case ModulateCompositeOp:
3241 if (fabs((
double) QuantumRange*Sa-(
double) TransparentAlpha) < MagickEpsilon)
3246 offset=(ssize_t) (Si-midpoint);
3252 ConvertRGBToGeneric(colorspace,(
double) canvas_pixel.red,
3253 (
double) canvas_pixel.green,(
double) canvas_pixel.blue,
3254 white_luminance,illuminant,&hue,&chroma,&luma);
3255 luma+=(0.01*percent_luma*offset)/midpoint;
3256 chroma*=0.01*percent_chroma;
3257 ConvertGenericToRGB(colorspace,hue,chroma,luma,
3258 white_luminance,illuminant,&red,&green,&blue);
3261 case RedPixelChannel: pixel=red;
break;
3262 case GreenPixelChannel: pixel=green;
break;
3263 case BluePixelChannel: pixel=blue;
break;
3264 default: pixel=Dc;
break;
3268 case ModulusAddCompositeOp:
3270 if (compose_sync == MagickFalse)
3272 pixel=(Quantum) QuantumRange*((Sc+Dc)-floor(Sc+Dc));
3275 pixel=(Quantum) QuantumRange*((Sca+Dca)-floor(Sca+Dca));
3278 case ModulusSubtractCompositeOp:
3280 if (compose_sync == MagickFalse)
3282 pixel=(Quantum) QuantumRange*((Sc-Dc)-floor(Sc-Dc));
3285 pixel=(Quantum) QuantumRange*((Sca-Dca)-floor(Sca-Dca));
3288 case MultiplyCompositeOp:
3290 if (compose_sync == MagickFalse)
3292 pixel=(double) QuantumRange*Sc*Dc;
3295 pixel=(double) QuantumRange*gamma*(Sca*Dca+Sca*(1.0-Da)+Dca*(1.0-Sa));
3298 case NegateCompositeOp:
3300 D=(Da > 0.0) ? Dca/Da : 0.0;
3301 S=(Sa > 0.0) ? Sca/Sa : 0.0;
3302 pixel=(double) QuantumRange*((1.0-fabs(1.0-S-D))*Da);
3307 pixel=(double) QuantumRange*Dca;
3310 case OutCompositeOp:
3311 case SrcOutCompositeOp:
3313 pixel=(double) QuantumRange*(Sca*(1.0-Da));
3316 case OverCompositeOp:
3317 case SrcOverCompositeOp:
3319 if ((Sa+Da*(1.0-Sa)) <= MagickEpsilon)
3322 pixel=(double) QuantumRange*gamma*((Sca+Dca*(1.0-Sa))/
3326 case OverlayCompositeOp:
3330 pixel=(double) QuantumRange*gamma*(2.0*Dca*Sca+Dca*(1.0-Sa)+
3334 pixel=(double) QuantumRange*gamma*(Da*Sa-2.0*(Sa-Sca)*(Da-Dca)+Dca*
3335 (1.0-Sa)+Sca*(1.0-Da));
3338 case PegtopLightCompositeOp:
3340 if (fabs((
double) Da) < MagickEpsilon)
3342 pixel=(double) QuantumRange*gamma*Sca;
3345 if (RoundToUnity(Sca) <= 0.5)
3346 blend=RoundToUnity(Dca/Da)-(1.0-2.0*RoundToUnity(Sca))*
3347 RoundToUnity(Dca/Da)*(1.0-RoundToUnity(Dca/Da));
3350 if (RoundToUnity(Dca/Da) <= 0.25)
3351 blend=((16.0*RoundToUnity(Dca/Da)-12.0)*RoundToUnity(Dca/Da)+
3352 4.0)*RoundToUnity(Dca/Da);
3354 blend=sqrt(RoundToUnity(Dca/Da));
3355 blend=RoundToUnity(Dca/Da)+(2.0*RoundToUnity(Sca)-1.0)*
3356 (blend-RoundToUnity(Dca/Da));
3358 pixel=(double) QuantumRange*gamma*(RoundToUnity(blend)*Da*Sa+Dca*
3362 case PinLightCompositeOp:
3372 D=(Da > 0.0) ? RoundToUnity(Dca/Da) : 0.0;
3373 S=(Sa > 0.0) ? RoundToUnity(Sca/Sa) : 0.0;
3375 blend=MagickMin(D,2.0*S);
3377 blend=MagickMax(D,2.0*S-1.0);
3378 pixel=(double) QuantumRange*gamma*RoundToUnity(Sa*Da*blend+Sca*
3379 (1.0-Da)+Dca*(1.0-Sa));
3382 case PlusCompositeOp:
3384 if (compose_sync == MagickFalse)
3386 pixel=(double) QuantumRange*(Sc+Dc);
3389 pixel=(double) QuantumRange*(Sca+Dca);
3392 case ReflectCompositeOp:
3394 if (compose_sync == MagickFalse)
3397 blend=(Sc*Sc)/(1.0-Dc);
3400 pixel=(double) QuantumRange*RoundToUnity(blend);
3412 blend=(S*S)/(1.0-D);
3415 pixel=(double) QuantumRange*RoundToUnity((Sa+Da-Sa*Da)*blend);
3418 case RMSECompositeOp:
3423 if (fabs((
double) QuantumRange*Sa-(
double) TransparentAlpha) < MagickEpsilon)
3428 if (fabs((
double) QuantumRange*Da-(
double) TransparentAlpha) < MagickEpsilon)
3434 (canvas_pixel.red-source_pixel.red)*
3435 (canvas_pixel.red-source_pixel.red)+
3436 (canvas_pixel.green-source_pixel.green)*
3437 (canvas_pixel.green-source_pixel.green)+
3438 (canvas_pixel.blue-source_pixel.blue)*
3439 (canvas_pixel.blue-source_pixel.blue)/3.0);
3442 case RedPixelChannel: pixel=gray;
break;
3443 case GreenPixelChannel: pixel=gray;
break;
3444 case BluePixelChannel: pixel=gray;
break;
3445 default: pixel=Dc;
break;
3449 case SaturateCompositeOp:
3451 if (fabs((
double) QuantumRange*Sa-(
double) TransparentAlpha) < MagickEpsilon)
3456 if (fabs((
double) QuantumRange*Da-(
double) TransparentAlpha) < MagickEpsilon)
3461 ConvertRGBToGeneric(colorspace,(
double) canvas_pixel.red,
3462 (
double) canvas_pixel.green,(
double) canvas_pixel.blue,
3463 white_luminance,illuminant,&hue,&chroma,&luma);
3464 ConvertRGBToGeneric(colorspace,(
double) source_pixel.red,
3465 (
double) source_pixel.green,(
double) source_pixel.blue,
3466 white_luminance,illuminant,&sans,&chroma,&sans);
3467 ConvertGenericToRGB(colorspace,hue,chroma,luma,
3468 white_luminance,illuminant,&red,&green,&blue);
3471 case RedPixelChannel: pixel=red;
break;
3472 case GreenPixelChannel: pixel=green;
break;
3473 case BluePixelChannel: pixel=blue;
break;
3474 default: pixel=Dc;
break;
3478 case ScreenCompositeOp:
3480 if (compose_sync == MagickFalse)
3482 pixel=(double) QuantumRange*RoundToUnity(Sc+Dc-Sc*Dc);
3485 S=(Sa > 0.0) ? RoundToUnity(Sca/Sa) : 0.0;
3486 D=(Da > 0.0) ? RoundToUnity(Dca/Da) : 0.0;
3487 blend=RoundToUnity(S+D-S*D);
3488 pixel=(double) QuantumRange*RoundToUnity(Sa*Da*blend+Sca*(1.0-Da)+
3492 case SoftBurnCompositeOp:
3494 if (RoundToUnity(Dca) <= 0.0)
3497 if (RoundToUnity(Sca) >= 1.0)
3500 blend=1.0-MagickMin(1.0,(1.0-RoundToUnity(Dca))/
3502 pixel=(double) QuantumRange*gamma*RoundToUnity(blend);
3505 case SoftDodgeCompositeOp:
3507 if (RoundToUnity(Sca) <= 0.0)
3508 blend=RoundToUnity(Dca);
3510 if (RoundToUnity(Dca) >= 1.0)
3513 blend=MagickMin(1.0,RoundToUnity(Dca)/(1.0-RoundToUnity(Sca)));
3514 pixel=(double) QuantumRange*gamma*RoundToUnity(blend);
3517 case SoftLightCompositeOp:
3519 if (RoundToUnity(Sca) <= 0.5)
3521 pixel=(double) QuantumRange*gamma*(RoundToUnity(Dca)*Sa+Da*
3522 (RoundToUnity(Dca)-(1.0-2.0*RoundToUnity(Sca))*
3523 RoundToUnity(Dca)*(1.0-RoundToUnity(Dca)))+RoundToUnity(Sca)*
3524 (1.0-Da)+RoundToUnity(Dca)*(1.0-Sa));
3527 if (RoundToUnity(Dca) > 0.25)
3528 blend=sqrt(RoundToUnity(Dca));
3530 blend=((16.0*RoundToUnity(Dca)-12.0)*RoundToUnity(Dca)+4.0)*
3532 pixel=(double) QuantumRange*gamma*(RoundToUnity(Dca)*Sa+Da*
3533 (RoundToUnity(Dca)+(2.0*RoundToUnity(Sca)-1.0)*
3534 (RoundToUnity(blend)-RoundToUnity(Dca)))+RoundToUnity(Sca)*
3535 (1.0-Da)+RoundToUnity(Dca)*(1.0-Sa));
3538 case StampCompositeOp:
3540 pixel=(double) QuantumRange*RoundToUnity(Sca+Dca-1.0);
3543 case StereoCompositeOp:
3545 if (channel == RedPixelChannel)
3546 pixel=(MagickRealType) GetPixelRed(source_image,p);
3549 case ThresholdCompositeOp:
3551 S=(Sa > 0.0) ? (Sca/Sa) : 0.0;
3552 D=(Da > 0.0) ? (Dca/Da) : 0.0;
3553 if (fabs(2.0*(S-D)) < threshold)
3556 blend=D+(S-D)*amount;
3557 pixel=(double) QuantumRange*(Sa*Da*RoundToUnity(blend)+Sca*
3558 (1.0-Da)+Dca*(1.0-Sa));
3561 case VividLightCompositeOp:
3563 if ((fabs((
double) Sa) < MagickEpsilon) ||
3564 (fabs((
double) Da) < MagickEpsilon))
3566 pixel=(double) QuantumRange*gamma*(Sa*Da+Sca*(1.0-Da)+Dca*
3570 if (RoundToUnity(Sca/Sa) <= 0.0)
3573 if (RoundToUnity(Sca/Sa) < 0.5)
3574 blend=1.0-(1.0-RoundToUnity(Dca/Da))/(2.0*RoundToUnity(Sca/Sa));
3576 if (RoundToUnity(Sca/Sa) < 1.0)
3577 blend=RoundToUnity(Dca/Da)/(2.0*(1.0-RoundToUnity(Sca/Sa)));
3580 pixel=(double) QuantumRange*gamma*(Sa*Da*RoundToUnity(blend)+Sca*
3581 (1.0-Da)+Dca*(1.0-Sa));
3584 case XorCompositeOp:
3586 pixel=(double) QuantumRange*(Sca*(1.0-Da)+Dca*(1.0-Sa));
3595 q[i]=clamp != MagickFalse ? ClampPixel(pixel) : ClampToQuantum(pixel);
3597 p+=(ptrdiff_t) GetPixelChannels(source_image);
3598 channels=GetPixelChannels(source_image);
3599 if (p >= (pixels+channels*source_image->columns))
3601 q+=(ptrdiff_t) GetPixelChannels(image);
3603 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
3605 if (image->progress_monitor != (MagickProgressMonitor) NULL)
3610#if defined(MAGICKCORE_OPENMP_SUPPORT)
3614 proceed=SetImageProgress(image,CompositeImageTag,progress,image->rows);
3615 if (proceed == MagickFalse)
3619 source_view=DestroyCacheView(source_view);
3620 image_view=DestroyCacheView(image_view);
3621 if (canvas_image != (Image * ) NULL)
3622 canvas_image=DestroyImage(canvas_image);
3624 source_image=DestroyImage(source_image);
3654MagickExport MagickBooleanType TextureImage(Image *image,
const Image *texture,
3655 ExceptionInfo *exception)
3657#define TextureImageTag "Texture/Image"
3672 assert(image != (Image *) NULL);
3673 assert(image->signature == MagickCoreSignature);
3674 if (IsEventLogging() != MagickFalse)
3675 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
3676 if (texture == (
const Image *) NULL)
3677 return(MagickFalse);
3678 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
3679 return(MagickFalse);
3680 texture_image=CloneImage(texture,0,0,MagickTrue,exception);
3681 if (texture_image == (
const Image *) NULL)
3682 return(MagickFalse);
3683 (void) TransformImageColorspace(texture_image,image->colorspace,exception);
3684 (void) SetImageVirtualPixelMethod(texture_image,TileVirtualPixelMethod,
3687 if ((image->compose != CopyCompositeOp) &&
3688 ((image->compose != OverCompositeOp) ||
3689 (image->alpha_trait != UndefinedPixelTrait) ||
3690 (texture_image->alpha_trait != UndefinedPixelTrait)))
3695 for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) texture_image->rows)
3700 if (status == MagickFalse)
3702 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) texture_image->columns)
3707 thread_status=CompositeImage(image,texture_image,image->compose,
3708 MagickTrue,x+texture_image->tile_offset.x,y+
3709 texture_image->tile_offset.y,exception);
3710 if (thread_status == MagickFalse)
3712 status=thread_status;
3716 if (image->progress_monitor != (MagickProgressMonitor) NULL)
3721 proceed=SetImageProgress(image,TextureImageTag,(MagickOffsetType) y,
3723 if (proceed == MagickFalse)
3727 (void) SetImageProgress(image,TextureImageTag,(MagickOffsetType)
3728 image->rows,image->rows);
3729 texture_image=DestroyImage(texture_image);
3736 texture_view=AcquireVirtualCacheView(texture_image,exception);
3737 image_view=AcquireAuthenticCacheView(image,exception);
3738#if defined(MAGICKCORE_OPENMP_SUPPORT)
3739 #pragma omp parallel for schedule(static) shared(status) \
3740 magick_number_threads(texture_image,image,image->rows,2)
3742 for (y=0; y < (ssize_t) image->rows; y++)
3760 if (status == MagickFalse)
3762 pixels=GetCacheViewVirtualPixels(texture_view,texture_image->tile_offset.x,
3763 (y+texture_image->tile_offset.y) % (ssize_t) texture_image->rows,
3764 texture_image->columns,1,exception);
3765 q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
3766 if ((pixels == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
3771 for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) texture_image->columns)
3777 width=texture_image->columns;
3778 if ((x+(ssize_t) width) > (ssize_t) image->columns)
3779 width=image->columns-(size_t) x;
3780 for (j=0; j < (ssize_t) width; j++)
3785 for (i=0; i < (ssize_t) GetPixelChannels(texture_image); i++)
3787 PixelChannel channel = GetPixelChannelChannel(texture_image,i);
3788 PixelTrait traits = GetPixelChannelTraits(image,channel);
3789 PixelTrait texture_traits=GetPixelChannelTraits(texture_image,
3791 if ((traits == UndefinedPixelTrait) ||
3792 (texture_traits == UndefinedPixelTrait))
3794 SetPixelChannel(image,channel,p[i],q);
3796 p+=(ptrdiff_t) GetPixelChannels(texture_image);
3797 q+=(ptrdiff_t) GetPixelChannels(image);
3800 sync=SyncCacheViewAuthenticPixels(image_view,exception);
3801 if (sync == MagickFalse)
3803 if (image->progress_monitor != (MagickProgressMonitor) NULL)
3808 proceed=SetImageProgress(image,TextureImageTag,(MagickOffsetType) y,
3810 if (proceed == MagickFalse)
3814 texture_view=DestroyCacheView(texture_view);
3815 image_view=DestroyCacheView(image_view);
3816 texture_image=DestroyImage(texture_image);