10b3cd894449ef55209b831c27b05746e8eece387cristy/* 23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% CCCC OOO M M PPPP OOO SSSSS IIIII TTTTT EEEEE % 73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% C O O MM MM P P O O SS I T E % 83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% C O O M M M PPPP O O SSS I T EEE % 93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% C O O M M P O O SS I T E % 103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% CCCC OOO M M P OOO SSSSS IIIII T EEEEE % 113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickCore Image Composite Methods % 143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Software Design % 16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy% Cristy % 173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% July 1992 % 183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 207ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% dedicated to making software imaging solutions freely available. % 223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% You may not use this file except in compliance with the License. You may % 243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% obtain a copy of the License at % 253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% http://www.imagemagick.org/script/license.php % 273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Unless required by applicable law or agreed to in writing, software % 293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% distributed under the License is distributed on an "AS IS" BASIS, % 303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% See the License for the specific language governing permissions and % 323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% limitations under the License. % 333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Include declarations. 423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 434c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h" 444c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/artifact.h" 454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache.h" 465201002e1ba0118594060d26142b48bdfb1320a2cristy#include "MagickCore/cache-private.h" 474c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache-view.h" 486a2180cee55312a7c0c633670803f9face88a82acristy#include "MagickCore/channel.h" 494c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/client.h" 504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color.h" 514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color-private.h" 524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colorspace.h" 534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colorspace-private.h" 544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/composite.h" 554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/composite-private.h" 564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/constitute.h" 574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/draw.h" 584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/fx.h" 594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/gem.h" 604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/geometry.h" 614c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image.h" 624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h" 634c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/list.h" 644c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/log.h" 654c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor.h" 664c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor-private.h" 674c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h" 684c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/option.h" 694c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h" 704c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/property.h" 714c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum.h" 724c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/resample.h" 734c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/resource_.h" 744c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h" 754c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/thread-private.h" 76191c0b74324ab2ee84cf3c426285ecc07ef57394cristy#include "MagickCore/threshold.h" 7763a81879d3568083e4ee4f78ebcae2bc831cb764cristy#include "MagickCore/token.h" 784c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/utility.h" 79d1dd6e4fefa0810b9893e6ac9418f79c97c1b39acristy#include "MagickCore/utility-private.h" 804c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/version.h" 813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 87f4ad9df69835f9ed5c687a9f93e8a53e23a3258fcristy% C o m p o s i t e I m a g e % 883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 91e29f70ab001fe353d9fa73ff8c0d6d52daab3379anthony%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 92e29f70ab001fe353d9fa73ff8c0d6d52daab3379anthony% 93f4ad9df69835f9ed5c687a9f93e8a53e23a3258fcristy% CompositeImage() returns the second image composited onto the first 943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% at the specified offset, using the specified composite method. 953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 96f4ad9df69835f9ed5c687a9f93e8a53e23a3258fcristy% The format of the CompositeImage method is: 973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType CompositeImage(Image *image, 99e8e8eff5f2414d6096195a41934fc0edee9d9212cristy% const Image *source_image,const CompositeOperator compose, 100feb3e9695150978a5d2372d3fe2f60466a7c8066cristy% const MagickBooleanType clip_to_self,const ssize_t x_offset, 101feb3e9695150978a5d2372d3fe2f60466a7c8066cristy% const ssize_t y_offset,ExceptionInfo *exception) 1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 105e8e8eff5f2414d6096195a41934fc0edee9d9212cristy% o image: the canvas image, modified by he composition 1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 107e8e8eff5f2414d6096195a41934fc0edee9d9212cristy% o source_image: the source image. 108feb3e9695150978a5d2372d3fe2f60466a7c8066cristy% 1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o compose: This operator affects how the composite is applied to 1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% the image. The operators and how they are utilized are listed here 1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% http://www.w3.org/TR/SVG12/#compositing. 1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 113feb3e9695150978a5d2372d3fe2f60466a7c8066cristy% o clip_to_self: set to MagickTrue to limit composition to area composed. 1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o x_offset: the column offset of the composited image. 1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o y_offset: the row offset of the composited image. 1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 11955a83c75eeede1662a9e6c43c3af201502c9442fdirk% Extra Controls from Image meta-data in 'image' (artifacts) 1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o "compose:args" 1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A string containing extra numerical arguments for specific compose 1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% methods, generally expressed as a 'geometry' or a comma separated list 1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% of numbers. 1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Compose methods needing such arguments include "BlendCompositeOp" and 1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% "DisplaceCompositeOp". 1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 129e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy% o exception: return any errors or warnings in this structure. 130e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy% 1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 133ea068a53d23d6dca08f1bce44c8937d54f83b983anthony/* 134ea068a53d23d6dca08f1bce44c8937d54f83b983anthony Composition based on the SVG specification: 135ea068a53d23d6dca08f1bce44c8937d54f83b983anthony 136ea068a53d23d6dca08f1bce44c8937d54f83b983anthony A Composition is defined by... 137ea068a53d23d6dca08f1bce44c8937d54f83b983anthony Color Function : f(Sc,Dc) where Sc and Dc are the normizalized colors 138ea068a53d23d6dca08f1bce44c8937d54f83b983anthony Blending areas : X = 1 for area of overlap, ie: f(Sc,Dc) 139ea068a53d23d6dca08f1bce44c8937d54f83b983anthony Y = 1 for source preserved 140e8e8eff5f2414d6096195a41934fc0edee9d9212cristy Z = 1 for canvas preserved 141ea068a53d23d6dca08f1bce44c8937d54f83b983anthony 142ea068a53d23d6dca08f1bce44c8937d54f83b983anthony Conversion to transparency (then optimized) 143ea068a53d23d6dca08f1bce44c8937d54f83b983anthony Dca' = f(Sc, Dc)*Sa*Da + Y*Sca*(1-Da) + Z*Dca*(1-Sa) 144ea068a53d23d6dca08f1bce44c8937d54f83b983anthony Da' = X*Sa*Da + Y*Sa*(1-Da) + Z*Da*(1-Sa) 145ea068a53d23d6dca08f1bce44c8937d54f83b983anthony 146ea068a53d23d6dca08f1bce44c8937d54f83b983anthony Where... 147ea068a53d23d6dca08f1bce44c8937d54f83b983anthony Sca = Sc*Sa normalized Source color divided by Source alpha 148ea068a53d23d6dca08f1bce44c8937d54f83b983anthony Dca = Dc*Da normalized Dest color divided by Dest alpha 149ea068a53d23d6dca08f1bce44c8937d54f83b983anthony Dc' = Dca'/Da' the desired color value for this channel. 150ea068a53d23d6dca08f1bce44c8937d54f83b983anthony 151ea068a53d23d6dca08f1bce44c8937d54f83b983anthony Da' in in the follow formula as 'gamma' The resulting alpla value. 152ea068a53d23d6dca08f1bce44c8937d54f83b983anthony 153ea068a53d23d6dca08f1bce44c8937d54f83b983anthony Most functions use a blending mode of over (X=1,Y=1,Z=1) this results in 154ea068a53d23d6dca08f1bce44c8937d54f83b983anthony the following optimizations... 155ea068a53d23d6dca08f1bce44c8937d54f83b983anthony gamma = Sa+Da-Sa*Da; 156ea068a53d23d6dca08f1bce44c8937d54f83b983anthony gamma = 1 - QuantiumScale*alpha * QuantiumScale*beta; 157ea068a53d23d6dca08f1bce44c8937d54f83b983anthony opacity = QuantiumScale*alpha*beta; // over blend, optimized 1-Gamma 158ea068a53d23d6dca08f1bce44c8937d54f83b983anthony 159ea068a53d23d6dca08f1bce44c8937d54f83b983anthony The above SVG definitions also definate that Mathematical Composition 160ea068a53d23d6dca08f1bce44c8937d54f83b983anthony methods should use a 'Over' blending mode for Alpha Channel. 161ea068a53d23d6dca08f1bce44c8937d54f83b983anthony It however was not applied for composition modes of 'Plus', 'Minus', 162ea068a53d23d6dca08f1bce44c8937d54f83b983anthony the modulus versions of 'Add' and 'Subtract'. 163ea068a53d23d6dca08f1bce44c8937d54f83b983anthony 164ea068a53d23d6dca08f1bce44c8937d54f83b983anthony Mathematical operator changes to be applied from IM v6.7... 165ea068a53d23d6dca08f1bce44c8937d54f83b983anthony 166ea068a53d23d6dca08f1bce44c8937d54f83b983anthony 1) Modulus modes 'Add' and 'Subtract' are obsoleted and renamed 167ea068a53d23d6dca08f1bce44c8937d54f83b983anthony 'ModulusAdd' and 'ModulusSubtract' for clarity. 168ea068a53d23d6dca08f1bce44c8937d54f83b983anthony 169ea068a53d23d6dca08f1bce44c8937d54f83b983anthony 2) All mathematical compositions work as per the SVG specification 170ea068a53d23d6dca08f1bce44c8937d54f83b983anthony with regard to blending. This now includes 'ModulusAdd' and 171ea068a53d23d6dca08f1bce44c8937d54f83b983anthony 'ModulusSubtract'. 172ea068a53d23d6dca08f1bce44c8937d54f83b983anthony 173ea068a53d23d6dca08f1bce44c8937d54f83b983anthony 3) When the special channel flag 'sync' (syncronize channel updates) 174ea068a53d23d6dca08f1bce44c8937d54f83b983anthony is turned off (enabled by default) then mathematical compositions are 175ea068a53d23d6dca08f1bce44c8937d54f83b983anthony only performed on the channels specified, and are applied 176ea068a53d23d6dca08f1bce44c8937d54f83b983anthony independantally of each other. In other words the mathematics is 177ea068a53d23d6dca08f1bce44c8937d54f83b983anthony performed as 'pure' mathematical operations, rather than as image 178ea068a53d23d6dca08f1bce44c8937d54f83b983anthony operations. 179ea068a53d23d6dca08f1bce44c8937d54f83b983anthony*/ 180d8f16f7357707bfee6a939d39b5b312d1486d5c5cristy 1817159f66759ae05f052aad309915b9784f7aca927cristystatic void HCLComposite(const MagickRealType hue,const MagickRealType chroma, 1827159f66759ae05f052aad309915b9784f7aca927cristy const MagickRealType luma,MagickRealType *red,MagickRealType *green, 1837159f66759ae05f052aad309915b9784f7aca927cristy MagickRealType *blue) 1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 1857159f66759ae05f052aad309915b9784f7aca927cristy MagickRealType 186d8f16f7357707bfee6a939d39b5b312d1486d5c5cristy b, 1877133e649ea494c1286ff16bcb02342d660097219cristy c, 188d8f16f7357707bfee6a939d39b5b312d1486d5c5cristy g, 1897133e649ea494c1286ff16bcb02342d660097219cristy h, 1907133e649ea494c1286ff16bcb02342d660097219cristy m, 191d8f16f7357707bfee6a939d39b5b312d1486d5c5cristy r, 192398fd02612ac738cc5c950c0e5df20a6db3db001cristy x; 1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1944c08aed51c5899665ade97263692328eea4af106cristy /* 1957133e649ea494c1286ff16bcb02342d660097219cristy Convert HCL to RGB colorspace. 1964c08aed51c5899665ade97263692328eea4af106cristy */ 1977159f66759ae05f052aad309915b9784f7aca927cristy assert(red != (MagickRealType *) NULL); 1987159f66759ae05f052aad309915b9784f7aca927cristy assert(green != (MagickRealType *) NULL); 1997159f66759ae05f052aad309915b9784f7aca927cristy assert(blue != (MagickRealType *) NULL); 2007133e649ea494c1286ff16bcb02342d660097219cristy h=6.0*hue; 2017133e649ea494c1286ff16bcb02342d660097219cristy c=chroma; 2027133e649ea494c1286ff16bcb02342d660097219cristy x=c*(1.0-fabs(fmod(h,2.0)-1.0)); 2037133e649ea494c1286ff16bcb02342d660097219cristy r=0.0; 2047133e649ea494c1286ff16bcb02342d660097219cristy g=0.0; 2057133e649ea494c1286ff16bcb02342d660097219cristy b=0.0; 2067133e649ea494c1286ff16bcb02342d660097219cristy if ((0.0 <= h) && (h < 1.0)) 2074c08aed51c5899665ade97263692328eea4af106cristy { 208e171528c27d8cf01c41f7601969cf56379224d47cristy r=c; 209e171528c27d8cf01c41f7601969cf56379224d47cristy g=x; 2104c08aed51c5899665ade97263692328eea4af106cristy } 211d8f16f7357707bfee6a939d39b5b312d1486d5c5cristy else 2127133e649ea494c1286ff16bcb02342d660097219cristy if ((1.0 <= h) && (h < 2.0)) 2137133e649ea494c1286ff16bcb02342d660097219cristy { 214e171528c27d8cf01c41f7601969cf56379224d47cristy r=x; 215e171528c27d8cf01c41f7601969cf56379224d47cristy g=c; 2167133e649ea494c1286ff16bcb02342d660097219cristy } 2177133e649ea494c1286ff16bcb02342d660097219cristy else 2187133e649ea494c1286ff16bcb02342d660097219cristy if ((2.0 <= h) && (h < 3.0)) 2197133e649ea494c1286ff16bcb02342d660097219cristy { 220e171528c27d8cf01c41f7601969cf56379224d47cristy g=c; 221e171528c27d8cf01c41f7601969cf56379224d47cristy b=x; 2227133e649ea494c1286ff16bcb02342d660097219cristy } 2237133e649ea494c1286ff16bcb02342d660097219cristy else 2247133e649ea494c1286ff16bcb02342d660097219cristy if ((3.0 <= h) && (h < 4.0)) 2257133e649ea494c1286ff16bcb02342d660097219cristy { 226e171528c27d8cf01c41f7601969cf56379224d47cristy g=x; 227e171528c27d8cf01c41f7601969cf56379224d47cristy b=c; 2287133e649ea494c1286ff16bcb02342d660097219cristy } 2297133e649ea494c1286ff16bcb02342d660097219cristy else 2307133e649ea494c1286ff16bcb02342d660097219cristy if ((4.0 <= h) && (h < 5.0)) 2317133e649ea494c1286ff16bcb02342d660097219cristy { 232e171528c27d8cf01c41f7601969cf56379224d47cristy r=x; 233e171528c27d8cf01c41f7601969cf56379224d47cristy b=c; 2347133e649ea494c1286ff16bcb02342d660097219cristy } 2357133e649ea494c1286ff16bcb02342d660097219cristy else 2367133e649ea494c1286ff16bcb02342d660097219cristy if ((5.0 <= h) && (h < 6.0)) 2377133e649ea494c1286ff16bcb02342d660097219cristy { 238e171528c27d8cf01c41f7601969cf56379224d47cristy r=c; 239e171528c27d8cf01c41f7601969cf56379224d47cristy b=x; 2407133e649ea494c1286ff16bcb02342d660097219cristy } 2419e2436a78bdabef900e018dc77c0cc497bf6fbafcristy m=luma-(0.298839*r+0.586811*g+0.114350*b); 242398fd02612ac738cc5c950c0e5df20a6db3db001cristy *red=QuantumRange*(r+m); 243398fd02612ac738cc5c950c0e5df20a6db3db001cristy *green=QuantumRange*(g+m); 244398fd02612ac738cc5c950c0e5df20a6db3db001cristy *blue=QuantumRange*(b+m); 245c5d68fe2846b7ed7b866c8a5d9287264d75458caanthony} 246c5d68fe2846b7ed7b866c8a5d9287264d75458caanthony 2477159f66759ae05f052aad309915b9784f7aca927cristystatic void CompositeHCL(const MagickRealType red,const MagickRealType green, 2487159f66759ae05f052aad309915b9784f7aca927cristy const MagickRealType blue,MagickRealType *hue,MagickRealType *chroma, 2497159f66759ae05f052aad309915b9784f7aca927cristy MagickRealType *luma) 2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2517159f66759ae05f052aad309915b9784f7aca927cristy MagickRealType 252d8f16f7357707bfee6a939d39b5b312d1486d5c5cristy b, 2537133e649ea494c1286ff16bcb02342d660097219cristy c, 254d8f16f7357707bfee6a939d39b5b312d1486d5c5cristy g, 2557133e649ea494c1286ff16bcb02342d660097219cristy h, 256d8f16f7357707bfee6a939d39b5b312d1486d5c5cristy max, 257d8f16f7357707bfee6a939d39b5b312d1486d5c5cristy r; 258ddeeea23285164a7029e2f28475642f26882f2d7cristy 259d8f16f7357707bfee6a939d39b5b312d1486d5c5cristy /* 2607133e649ea494c1286ff16bcb02342d660097219cristy Convert RGB to HCL colorspace. 261d8f16f7357707bfee6a939d39b5b312d1486d5c5cristy */ 2627159f66759ae05f052aad309915b9784f7aca927cristy assert(hue != (MagickRealType *) NULL); 2637159f66759ae05f052aad309915b9784f7aca927cristy assert(chroma != (MagickRealType *) NULL); 2647159f66759ae05f052aad309915b9784f7aca927cristy assert(luma != (MagickRealType *) NULL); 2657133e649ea494c1286ff16bcb02342d660097219cristy r=red; 2667133e649ea494c1286ff16bcb02342d660097219cristy g=green; 2677133e649ea494c1286ff16bcb02342d660097219cristy b=blue; 268d8f16f7357707bfee6a939d39b5b312d1486d5c5cristy max=MagickMax(r,MagickMax(g,b)); 2697159f66759ae05f052aad309915b9784f7aca927cristy c=max-(MagickRealType) MagickMin(r,MagickMin(g,b)); 2707133e649ea494c1286ff16bcb02342d660097219cristy h=0.0; 2717133e649ea494c1286ff16bcb02342d660097219cristy if (c == 0) 2727133e649ea494c1286ff16bcb02342d660097219cristy h=0.0; 273d8f16f7357707bfee6a939d39b5b312d1486d5c5cristy else 2747133e649ea494c1286ff16bcb02342d660097219cristy if (red == max) 2759e2436a78bdabef900e018dc77c0cc497bf6fbafcristy h=fmod((g-b)/c+6.0,6.0); 276d8f16f7357707bfee6a939d39b5b312d1486d5c5cristy else 2777133e649ea494c1286ff16bcb02342d660097219cristy if (green == max) 2787133e649ea494c1286ff16bcb02342d660097219cristy h=((b-r)/c)+2.0; 2797133e649ea494c1286ff16bcb02342d660097219cristy else 2807133e649ea494c1286ff16bcb02342d660097219cristy if (blue == max) 2817133e649ea494c1286ff16bcb02342d660097219cristy h=((r-g)/c)+4.0; 2827133e649ea494c1286ff16bcb02342d660097219cristy *hue=(h/6.0); 2837133e649ea494c1286ff16bcb02342d660097219cristy *chroma=QuantumScale*c; 2849e2436a78bdabef900e018dc77c0cc497bf6fbafcristy *luma=QuantumScale*(0.298839*r+0.586811*g+0.114350*b); 2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 287e4a404711bf20d9062d11ab28bc12e5acd307f9ccristystatic MagickBooleanType CompositeOverImage(Image *image, 288e8e8eff5f2414d6096195a41934fc0edee9d9212cristy const Image *source_image,const MagickBooleanType clip_to_self, 289feb3e9695150978a5d2372d3fe2f60466a7c8066cristy const ssize_t x_offset,const ssize_t y_offset,ExceptionInfo *exception) 2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 291e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy#define CompositeImageTag "Composite/Image" 2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 293e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy CacheView 2945e6f3783f4f9fa7d6a7b5cd2399841c3c5eb4af9Cristy *image_view, 2955e6f3783f4f9fa7d6a7b5cd2399841c3c5eb4af9Cristy *source_view; 2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 29747c61c996128275174b8a120ab6a88a5c1bec3d3cristy const char 2985e6f3783f4f9fa7d6a7b5cd2399841c3c5eb4af9Cristy *value; 29947c61c996128275174b8a120ab6a88a5c1bec3d3cristy 300e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy MagickBooleanType 30147c61c996128275174b8a120ab6a88a5c1bec3d3cristy clamp, 302e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy status; 3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 304e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy MagickOffsetType 305e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy progress; 3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 307e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy ssize_t 308e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy y; 309c5d68fe2846b7ed7b866c8a5d9287264d75458caanthony 3104c08aed51c5899665ade97263692328eea4af106cristy /* 311e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Composite image. 3127c9eaf7cdb3640167dc0978406eb4a4a42a0ff3aanthony */ 313e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy status=MagickTrue; 314e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy progress=0; 31547c61c996128275174b8a120ab6a88a5c1bec3d3cristy clamp=MagickTrue; 31647c61c996128275174b8a120ab6a88a5c1bec3d3cristy value=GetImageArtifact(image,"compose:clamp"); 31747c61c996128275174b8a120ab6a88a5c1bec3d3cristy if (value != (const char *) NULL) 31847c61c996128275174b8a120ab6a88a5c1bec3d3cristy clamp=IsStringTrue(value); 319e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_view=AcquireVirtualCacheView(source_image,exception); 32046ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy image_view=AcquireAuthenticCacheView(image,exception); 321e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 322ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy #pragma omp parallel for schedule(static,4) shared(progress,status) \ 323e8e8eff5f2414d6096195a41934fc0edee9d9212cristy magick_threads(source_image,image,image->rows,1) 324e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy#endif 325e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy for (y=0; y < (ssize_t) image->rows; y++) 326e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 327e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy const Quantum 328e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy *pixels; 329c5d68fe2846b7ed7b866c8a5d9287264d75458caanthony 330e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy register const Quantum 33105d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict p; 332c5d68fe2846b7ed7b866c8a5d9287264d75458caanthony 333e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy register Quantum 33405d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict q; 335c5d68fe2846b7ed7b866c8a5d9287264d75458caanthony 336e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy register ssize_t 337e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy x; 3384c08aed51c5899665ade97263692328eea4af106cristy 339564a56979706a30a3d0f920fd5f538a408efd4f1cristy size_t 340564a56979706a30a3d0f920fd5f538a408efd4f1cristy channels; 341564a56979706a30a3d0f920fd5f538a408efd4f1cristy 342e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (status == MagickFalse) 343e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 344feb3e9695150978a5d2372d3fe2f60466a7c8066cristy if (clip_to_self != MagickFalse) 345e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 346e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (y < y_offset) 347e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 348e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if ((y-y_offset) >= (ssize_t) source_image->rows) 349e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 350e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 351e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy /* 352e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy If pixels is NULL, y is outside overlay region. 353e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy */ 354e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixels=(Quantum *) NULL; 355e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy p=(Quantum *) NULL; 356e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if ((y >= y_offset) && ((y-y_offset) < (ssize_t) source_image->rows)) 357e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 358e8e8eff5f2414d6096195a41934fc0edee9d9212cristy p=GetCacheViewVirtualPixels(source_view,0,y-y_offset, 359e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_image->columns,1,exception); 360e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (p == (const Quantum *) NULL) 361e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 362e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy status=MagickFalse; 363e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 364e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 365e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixels=p; 366e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (x_offset < 0) 367e8e8eff5f2414d6096195a41934fc0edee9d9212cristy p-=x_offset*GetPixelChannels(source_image); 368e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 369e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception); 370e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (q == (Quantum *) NULL) 371e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 372e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy status=MagickFalse; 373e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 374e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 375e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy for (x=0; x < (ssize_t) image->columns; x++) 3764c08aed51c5899665ade97263692328eea4af106cristy { 3777159f66759ae05f052aad309915b9784f7aca927cristy MagickRealType 378e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Da, 379e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Dc, 3802bd6f5be4b25c2b325a18a49cc10cfcb358070edcristy Dca, 38195a92efd222d2268b66bf4fbb3bd5167437ba466cristy gamma, 382e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Sa, 3832bd6f5be4b25c2b325a18a49cc10cfcb358070edcristy Sc, 3842bd6f5be4b25c2b325a18a49cc10cfcb358070edcristy Sca; 385c5d68fe2846b7ed7b866c8a5d9287264d75458caanthony 386e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy register ssize_t 387e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy i; 388c5d68fe2846b7ed7b866c8a5d9287264d75458caanthony 389feb3e9695150978a5d2372d3fe2f60466a7c8066cristy if (clip_to_self != MagickFalse) 390e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 391e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (x < x_offset) 392e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 393e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy q+=GetPixelChannels(image); 394e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 395e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 396e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if ((x-x_offset) >= (ssize_t) source_image->columns) 397e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 398e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 399e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if ((pixels == (Quantum *) NULL) || (x < x_offset) || 400e8e8eff5f2414d6096195a41934fc0edee9d9212cristy ((x-x_offset) >= (ssize_t) source_image->columns)) 401e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 402e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Quantum 403e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy source[MaxPixelChannels]; 4044c08aed51c5899665ade97263692328eea4af106cristy 405e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy /* 406e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Virtual composite: 407e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Sc: source color. 408e8e8eff5f2414d6096195a41934fc0edee9d9212cristy Dc: canvas color. 409e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy */ 410883fde11debec15cedb05dc5d7228d8588066bc0cristy if (GetPixelReadMask(image,q) == 0) 41110a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy { 41210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy q+=GetPixelChannels(image); 41310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy continue; 41410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy } 415e8e8eff5f2414d6096195a41934fc0edee9d9212cristy (void) GetOneVirtualPixel(source_image,x-x_offset,y-y_offset, 416c94ba6f2e80cce201ffaf24ce7534019b6353dfecristy source,exception); 417e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 418e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 4195a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(image,i); 4205a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(image,channel); 421e8e8eff5f2414d6096195a41934fc0edee9d9212cristy PixelTrait source_traits=GetPixelChannelTraits(source_image, 4225a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy channel); 423e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if ((traits == UndefinedPixelTrait) || 424e8e8eff5f2414d6096195a41934fc0edee9d9212cristy (source_traits == UndefinedPixelTrait)) 425e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 426e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy q[i]=source[channel]; 427e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 428e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy q+=GetPixelChannels(image); 429e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 430e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 4314c08aed51c5899665ade97263692328eea4af106cristy /* 432e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Authentic composite: 433e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Sa: normalized source alpha. 434e8e8eff5f2414d6096195a41934fc0edee9d9212cristy Da: normalized canvas alpha. 4354c08aed51c5899665ade97263692328eea4af106cristy */ 436e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if (GetPixelReadMask(source_image,p) == 0) 437c94ba6f2e80cce201ffaf24ce7534019b6353dfecristy { 438e8e8eff5f2414d6096195a41934fc0edee9d9212cristy p+=GetPixelChannels(source_image); 439e8e8eff5f2414d6096195a41934fc0edee9d9212cristy channels=GetPixelChannels(source_image); 440e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if (p >= (pixels+channels*source_image->columns)) 441c94ba6f2e80cce201ffaf24ce7534019b6353dfecristy p=pixels; 442c94ba6f2e80cce201ffaf24ce7534019b6353dfecristy q+=GetPixelChannels(image); 443c94ba6f2e80cce201ffaf24ce7534019b6353dfecristy continue; 444c94ba6f2e80cce201ffaf24ce7534019b6353dfecristy } 445e8e8eff5f2414d6096195a41934fc0edee9d9212cristy Sa=QuantumScale*GetPixelAlpha(source_image,p); 446e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Da=QuantumScale*GetPixelAlpha(image,q); 44795a92efd222d2268b66bf4fbb3bd5167437ba466cristy gamma=Sa+Da-Sa*Da; 44895a92efd222d2268b66bf4fbb3bd5167437ba466cristy gamma=PerceptibleReciprocal(gamma); 449e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 450e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 4515a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(image,i); 4525a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(image,channel); 453e8e8eff5f2414d6096195a41934fc0edee9d9212cristy PixelTrait source_traits=GetPixelChannelTraits(source_image, 4545a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy channel); 455e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if ((traits == UndefinedPixelTrait) || 456e8e8eff5f2414d6096195a41934fc0edee9d9212cristy (source_traits == UndefinedPixelTrait)) 457e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 458e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if ((traits & CopyPixelTrait) != 0) 459e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 460e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy /* 461e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy Copy channel. 462e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy */ 463e8e8eff5f2414d6096195a41934fc0edee9d9212cristy q[i]=GetPixelChannel(source_image,channel,p); 464e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy continue; 465e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy } 466e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy if (channel == AlphaPixelChannel) 467e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy { 468e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy /* 469e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Set alpha channel. 470e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy */ 47147c61c996128275174b8a120ab6a88a5c1bec3d3cristy q[i]=clamp != MagickFalse ? 47247c61c996128275174b8a120ab6a88a5c1bec3d3cristy ClampPixel(QuantumRange*(Sa+Da-Sa*Da)) : 47347c61c996128275174b8a120ab6a88a5c1bec3d3cristy ClampToQuantum(QuantumRange*(Sa+Da-Sa*Da)); 474e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 475e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 476e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy /* 477e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Sc: source color. 478e8e8eff5f2414d6096195a41934fc0edee9d9212cristy Dc: canvas color. 479e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy */ 480e8e8eff5f2414d6096195a41934fc0edee9d9212cristy Sc=(MagickRealType) GetPixelChannel(source_image,channel,p); 4817159f66759ae05f052aad309915b9784f7aca927cristy Dc=(MagickRealType) q[i]; 4822bd6f5be4b25c2b325a18a49cc10cfcb358070edcristy Sca=QuantumScale*Sa*Sc; 4832bd6f5be4b25c2b325a18a49cc10cfcb358070edcristy Dca=QuantumScale*Da*Dc; 48447c61c996128275174b8a120ab6a88a5c1bec3d3cristy q[i]=clamp != MagickFalse ? 48595a92efd222d2268b66bf4fbb3bd5167437ba466cristy ClampPixel(gamma*QuantumRange*(Sca+Dca*(1.0-Sa))) : 48695a92efd222d2268b66bf4fbb3bd5167437ba466cristy ClampToQuantum(gamma*QuantumRange*(Sca+Dca*(1.0-Sa))); 487e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 488e8e8eff5f2414d6096195a41934fc0edee9d9212cristy p+=GetPixelChannels(source_image); 489e8e8eff5f2414d6096195a41934fc0edee9d9212cristy channels=GetPixelChannels(source_image); 490e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if (p >= (pixels+channels*source_image->columns)) 491e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy p=pixels; 492e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy q+=GetPixelChannels(image); 4934c08aed51c5899665ade97263692328eea4af106cristy } 494e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) 495e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy status=MagickFalse; 496e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (image->progress_monitor != (MagickProgressMonitor) NULL) 497e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 498e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy MagickBooleanType 499e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy proceed; 5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 501e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 502ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy #pragma omp critical (MagickCore_CompositeImage) 503e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy#endif 504e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy proceed=SetImageProgress(image,CompositeImageTag,progress++, 505e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy image->rows); 506e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (proceed == MagickFalse) 507e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy status=MagickFalse; 508e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 509e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 510e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_view=DestroyCacheView(source_view); 511e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy image_view=DestroyCacheView(image_view); 512e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy return(status); 5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 515e4a404711bf20d9062d11ab28bc12e5acd307f9ccristyMagickExport MagickBooleanType CompositeImage(Image *image, 516a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy const Image *composite,const CompositeOperator compose, 51744c9841ae88065e1a321ec8564293859101e7b49cristy const MagickBooleanType clip_to_self,const ssize_t x_offset, 51844c9841ae88065e1a321ec8564293859101e7b49cristy const ssize_t y_offset,ExceptionInfo *exception) 5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 520e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy#define CompositeImageTag "Composite/Image" 5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 522e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy CacheView 523e8e8eff5f2414d6096195a41934fc0edee9d9212cristy *source_view, 524e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy *image_view; 5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 52647c61c996128275174b8a120ab6a88a5c1bec3d3cristy const char 52747c61c996128275174b8a120ab6a88a5c1bec3d3cristy *value; 52847c61c996128275174b8a120ab6a88a5c1bec3d3cristy 529e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy GeometryInfo 530e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy geometry_info; 5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 532e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Image 533e8e8eff5f2414d6096195a41934fc0edee9d9212cristy *canvas_image, 534e8e8eff5f2414d6096195a41934fc0edee9d9212cristy *source_image; 5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 536e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy MagickBooleanType 53747c61c996128275174b8a120ab6a88a5c1bec3d3cristy clamp, 538e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy status; 539e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 540e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy MagickOffsetType 541e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy progress; 5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5437159f66759ae05f052aad309915b9784f7aca927cristy MagickRealType 544e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy amount, 545e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_dissolve, 546e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy midpoint, 5477133e649ea494c1286ff16bcb02342d660097219cristy percent_luma, 5487133e649ea494c1286ff16bcb02342d660097219cristy percent_chroma, 549e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy source_dissolve, 550e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy threshold; 5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 552e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy MagickStatusType 553e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy flags; 5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 555d197cbbbde474ea2cbdd56d0defa45f100e44cd0cristy ssize_t 556d197cbbbde474ea2cbdd56d0defa45f100e44cd0cristy y; 557d197cbbbde474ea2cbdd56d0defa45f100e44cd0cristy 558e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy assert(image != (Image *) NULL); 559e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 560e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (image->debug != MagickFalse) 561e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 562a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy assert(composite!= (Image *) NULL); 563e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(composite->signature == MagickCoreSignature); 564e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 565e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy return(MagickFalse); 566e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_image=CloneImage(composite,0,0,MagickTrue,exception); 567e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if (source_image == (const Image *) NULL) 568a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy return(MagickFalse); 569de067e9672d8873c45d0f1f5aabf9e5b0bb13293cristy if (IsGrayColorspace(image->colorspace) != MagickFalse) 570de067e9672d8873c45d0f1f5aabf9e5b0bb13293cristy (void) SetImageColorspace(image,sRGBColorspace,exception); 571e8e8eff5f2414d6096195a41934fc0edee9d9212cristy (void) SetImageColorspace(source_image,image->colorspace,exception); 572597358bb71c59d54a67f64b76644b5436365733bdirk if ((image->alpha_trait != UndefinedPixelTrait) && 573e8e8eff5f2414d6096195a41934fc0edee9d9212cristy (source_image->alpha_trait == UndefinedPixelTrait)) 574e8e8eff5f2414d6096195a41934fc0edee9d9212cristy (void) SetImageAlphaChannel(source_image,SetAlphaChannel,exception); 575e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if ((compose == OverCompositeOp) || (compose == SrcOverCompositeOp)) 5764c08aed51c5899665ade97263692328eea4af106cristy { 577e8e8eff5f2414d6096195a41934fc0edee9d9212cristy status=CompositeOverImage(image,source_image,clip_to_self,x_offset, 578feb3e9695150978a5d2372d3fe2f60466a7c8066cristy y_offset,exception); 579e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_image=DestroyImage(source_image); 580e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy return(status); 581c5d68fe2846b7ed7b866c8a5d9287264d75458caanthony } 5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy amount=0.5; 58347c61c996128275174b8a120ab6a88a5c1bec3d3cristy canvas_image=(Image *) NULL; 584e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_dissolve=1.0; 58547c61c996128275174b8a120ab6a88a5c1bec3d3cristy clamp=MagickTrue; 58647c61c996128275174b8a120ab6a88a5c1bec3d3cristy value=GetImageArtifact(image,"compose:clamp"); 58747c61c996128275174b8a120ab6a88a5c1bec3d3cristy if (value != (const char *) NULL) 58847c61c996128275174b8a120ab6a88a5c1bec3d3cristy clamp=IsStringTrue(value); 589e92d6b54a3f0971ac57523d4a1786f4f8fbe3fe8cristy SetGeometryInfo(&geometry_info); 5907133e649ea494c1286ff16bcb02342d660097219cristy percent_luma=100.0; 5917133e649ea494c1286ff16bcb02342d660097219cristy percent_chroma=100.0; 5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy source_dissolve=1.0; 5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy threshold=0.05f; 5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (compose) 5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 596308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy case CopyCompositeOp: 597308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy { 598b41560a2138121a95d9a02465e98355fd6fdd27fcristy if ((x_offset < 0) || (y_offset < 0)) 599308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy break; 600e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if ((x_offset+(ssize_t) source_image->columns) > (ssize_t) image->columns) 601308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy break; 602e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if ((y_offset+(ssize_t) source_image->rows) > (ssize_t) image->rows) 603308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy break; 604308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy status=MagickTrue; 605e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_view=AcquireVirtualCacheView(source_image,exception); 60646ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy image_view=AcquireAuthenticCacheView(image,exception); 607b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 608ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy #pragma omp parallel for schedule(static,4) shared(status) \ 609e8e8eff5f2414d6096195a41934fc0edee9d9212cristy magick_threads(source_image,image,source_image->rows,1) 610308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy#endif 611e8e8eff5f2414d6096195a41934fc0edee9d9212cristy for (y=0; y < (ssize_t) source_image->rows; y++) 612308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy { 613308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy MagickBooleanType 614308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy sync; 615308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy 6164c08aed51c5899665ade97263692328eea4af106cristy register const Quantum 617308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy *p; 618308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy 6194c08aed51c5899665ade97263692328eea4af106cristy register Quantum 620308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy *q; 621308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy 6224c08aed51c5899665ade97263692328eea4af106cristy register ssize_t 6234c08aed51c5899665ade97263692328eea4af106cristy x; 6244c08aed51c5899665ade97263692328eea4af106cristy 625308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy if (status == MagickFalse) 626308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy continue; 6272fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy p=GetCacheViewVirtualPixels(source_view,0,y,source_image->columns,1, 6282fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy exception); 629e1c18e93d64dd07e6deb00400c7f1e4d8b96ecd9cristy q=GetCacheViewAuthenticPixels(image_view,x_offset,y+y_offset, 630e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_image->columns,1,exception); 6314c08aed51c5899665ade97263692328eea4af106cristy if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) 632308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy { 633308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy status=MagickFalse; 634308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy continue; 635308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy } 636e8e8eff5f2414d6096195a41934fc0edee9d9212cristy for (x=0; x < (ssize_t) source_image->columns; x++) 6374c08aed51c5899665ade97263692328eea4af106cristy { 638bdecccc80762c4bd28cd68cfd0c8279f45624c69cristy register ssize_t 639bdecccc80762c4bd28cd68cfd0c8279f45624c69cristy i; 640bdecccc80762c4bd28cd68cfd0c8279f45624c69cristy 641e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if (GetPixelReadMask(source_image,p) == 0) 64210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy { 643e8e8eff5f2414d6096195a41934fc0edee9d9212cristy p+=GetPixelChannels(source_image); 64410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy q+=GetPixelChannels(image); 64510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy continue; 64610a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy } 647e8e8eff5f2414d6096195a41934fc0edee9d9212cristy for (i=0; i < (ssize_t) GetPixelChannels(source_image); i++) 648bdecccc80762c4bd28cd68cfd0c8279f45624c69cristy { 649e8e8eff5f2414d6096195a41934fc0edee9d9212cristy PixelChannel channel=GetPixelChannelChannel(source_image,i); 650e8e8eff5f2414d6096195a41934fc0edee9d9212cristy PixelTrait source_traits=GetPixelChannelTraits(source_image, 6515a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy channel); 6525a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(image,channel); 653bdecccc80762c4bd28cd68cfd0c8279f45624c69cristy if ((traits == UndefinedPixelTrait) || 654e8e8eff5f2414d6096195a41934fc0edee9d9212cristy (source_traits == UndefinedPixelTrait)) 655bdecccc80762c4bd28cd68cfd0c8279f45624c69cristy continue; 656bdecccc80762c4bd28cd68cfd0c8279f45624c69cristy SetPixelChannel(image,channel,p[i],q); 657bdecccc80762c4bd28cd68cfd0c8279f45624c69cristy } 658e8e8eff5f2414d6096195a41934fc0edee9d9212cristy p+=GetPixelChannels(source_image); 659ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy q+=GetPixelChannels(image); 6604c08aed51c5899665ade97263692328eea4af106cristy } 661308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy sync=SyncCacheViewAuthenticPixels(image_view,exception); 662308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy if (sync == MagickFalse) 663308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy status=MagickFalse; 664308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy if (image->progress_monitor != (MagickProgressMonitor) NULL) 665308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy { 666308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy MagickBooleanType 667308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy proceed; 668308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy 669b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 670bd0435bb0fa5e2e20ec8d3c5288a5edc44aba9a0cristy #pragma omp critical (MagickCore_CompositeImage) 671308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy#endif 672cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy proceed=SetImageProgress(image,CompositeImageTag, 673cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy (MagickOffsetType) y,image->rows); 674308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy if (proceed == MagickFalse) 675308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy status=MagickFalse; 676308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy } 677308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy } 678e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_view=DestroyCacheView(source_view); 679308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy image_view=DestroyCacheView(image_view); 680e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_image=DestroyImage(source_image); 681308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy return(status); 682308b4e68536c39f0a3d7fe55c4c04bfd0ba2ce9bcristy } 68317a88593850db8b76af9e1389670ac5f1163514ccristy case IntensityCompositeOp: 68417a88593850db8b76af9e1389670ac5f1163514ccristy { 68517a88593850db8b76af9e1389670ac5f1163514ccristy if ((x_offset < 0) || (y_offset < 0)) 68617a88593850db8b76af9e1389670ac5f1163514ccristy break; 687e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if ((x_offset+(ssize_t) source_image->columns) > (ssize_t) image->columns) 68817a88593850db8b76af9e1389670ac5f1163514ccristy break; 689e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if ((y_offset+(ssize_t) source_image->rows) > (ssize_t) image->rows) 69017a88593850db8b76af9e1389670ac5f1163514ccristy break; 69117a88593850db8b76af9e1389670ac5f1163514ccristy status=MagickTrue; 692e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_view=AcquireVirtualCacheView(source_image,exception); 69317a88593850db8b76af9e1389670ac5f1163514ccristy image_view=AcquireAuthenticCacheView(image,exception); 69417a88593850db8b76af9e1389670ac5f1163514ccristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 69517a88593850db8b76af9e1389670ac5f1163514ccristy #pragma omp parallel for schedule(static,4) shared(status) \ 696e8e8eff5f2414d6096195a41934fc0edee9d9212cristy magick_threads(source_image,image,source_image->rows,1) 69717a88593850db8b76af9e1389670ac5f1163514ccristy#endif 698e8e8eff5f2414d6096195a41934fc0edee9d9212cristy for (y=0; y < (ssize_t) source_image->rows; y++) 69917a88593850db8b76af9e1389670ac5f1163514ccristy { 70017a88593850db8b76af9e1389670ac5f1163514ccristy MagickBooleanType 70117a88593850db8b76af9e1389670ac5f1163514ccristy sync; 70217a88593850db8b76af9e1389670ac5f1163514ccristy 70317a88593850db8b76af9e1389670ac5f1163514ccristy register const Quantum 70417a88593850db8b76af9e1389670ac5f1163514ccristy *p; 70517a88593850db8b76af9e1389670ac5f1163514ccristy 70617a88593850db8b76af9e1389670ac5f1163514ccristy register Quantum 70717a88593850db8b76af9e1389670ac5f1163514ccristy *q; 70817a88593850db8b76af9e1389670ac5f1163514ccristy 70917a88593850db8b76af9e1389670ac5f1163514ccristy register ssize_t 71017a88593850db8b76af9e1389670ac5f1163514ccristy x; 71117a88593850db8b76af9e1389670ac5f1163514ccristy 71217a88593850db8b76af9e1389670ac5f1163514ccristy if (status == MagickFalse) 71317a88593850db8b76af9e1389670ac5f1163514ccristy continue; 7142fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy p=GetCacheViewVirtualPixels(source_view,0,y,source_image->columns,1, 7152fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy exception); 71617a88593850db8b76af9e1389670ac5f1163514ccristy q=GetCacheViewAuthenticPixels(image_view,x_offset,y+y_offset, 717e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_image->columns,1,exception); 71817a88593850db8b76af9e1389670ac5f1163514ccristy if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) 71917a88593850db8b76af9e1389670ac5f1163514ccristy { 72017a88593850db8b76af9e1389670ac5f1163514ccristy status=MagickFalse; 72117a88593850db8b76af9e1389670ac5f1163514ccristy continue; 72217a88593850db8b76af9e1389670ac5f1163514ccristy } 723e8e8eff5f2414d6096195a41934fc0edee9d9212cristy for (x=0; x < (ssize_t) source_image->columns; x++) 72417a88593850db8b76af9e1389670ac5f1163514ccristy { 725e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if (GetPixelReadMask(source_image,p) == 0) 72617a88593850db8b76af9e1389670ac5f1163514ccristy { 727e8e8eff5f2414d6096195a41934fc0edee9d9212cristy p+=GetPixelChannels(source_image); 72817a88593850db8b76af9e1389670ac5f1163514ccristy q+=GetPixelChannels(image); 72917a88593850db8b76af9e1389670ac5f1163514ccristy continue; 73017a88593850db8b76af9e1389670ac5f1163514ccristy } 73147c61c996128275174b8a120ab6a88a5c1bec3d3cristy SetPixelAlpha(image,clamp != MagickFalse ? 73247c61c996128275174b8a120ab6a88a5c1bec3d3cristy ClampPixel(GetPixelIntensity(source_image,p)) : 73347c61c996128275174b8a120ab6a88a5c1bec3d3cristy ClampToQuantum(GetPixelIntensity(source_image,p)),q); 734e8e8eff5f2414d6096195a41934fc0edee9d9212cristy p+=GetPixelChannels(source_image); 73517a88593850db8b76af9e1389670ac5f1163514ccristy q+=GetPixelChannels(image); 73617a88593850db8b76af9e1389670ac5f1163514ccristy } 73717a88593850db8b76af9e1389670ac5f1163514ccristy sync=SyncCacheViewAuthenticPixels(image_view,exception); 73817a88593850db8b76af9e1389670ac5f1163514ccristy if (sync == MagickFalse) 73917a88593850db8b76af9e1389670ac5f1163514ccristy status=MagickFalse; 74017a88593850db8b76af9e1389670ac5f1163514ccristy if (image->progress_monitor != (MagickProgressMonitor) NULL) 74117a88593850db8b76af9e1389670ac5f1163514ccristy { 74217a88593850db8b76af9e1389670ac5f1163514ccristy MagickBooleanType 74317a88593850db8b76af9e1389670ac5f1163514ccristy proceed; 74417a88593850db8b76af9e1389670ac5f1163514ccristy 74517a88593850db8b76af9e1389670ac5f1163514ccristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 74617a88593850db8b76af9e1389670ac5f1163514ccristy #pragma omp critical (MagickCore_CompositeImage) 74717a88593850db8b76af9e1389670ac5f1163514ccristy#endif 74817a88593850db8b76af9e1389670ac5f1163514ccristy proceed=SetImageProgress(image,CompositeImageTag, 74917a88593850db8b76af9e1389670ac5f1163514ccristy (MagickOffsetType) y,image->rows); 75017a88593850db8b76af9e1389670ac5f1163514ccristy if (proceed == MagickFalse) 75117a88593850db8b76af9e1389670ac5f1163514ccristy status=MagickFalse; 75217a88593850db8b76af9e1389670ac5f1163514ccristy } 75317a88593850db8b76af9e1389670ac5f1163514ccristy } 754e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_view=DestroyCacheView(source_view); 75517a88593850db8b76af9e1389670ac5f1163514ccristy image_view=DestroyCacheView(image_view); 756e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_image=DestroyImage(source_image); 75717a88593850db8b76af9e1389670ac5f1163514ccristy return(status); 75817a88593850db8b76af9e1389670ac5f1163514ccristy } 759e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case CopyAlphaCompositeOp: 7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case ChangeMaskCompositeOp: 7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 763e8e8eff5f2414d6096195a41934fc0edee9d9212cristy Modify canvas outside the overlaid region and require an alpha 7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy channel to exist, to add transparency. 7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 76617f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy if (image->alpha_trait == UndefinedPixelTrait) 76742c41dead2898886d6330544548f859da29ce8c0cristy (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception); 7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case BlurCompositeOp: 7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 772559401046eb333547a09fb8b67b11fd7f1b05faccristy CacheView 773fa589d6096099562cbc2bc14e508931968a8c055dirk *canvas_view; 774feb3e9695150978a5d2372d3fe2f60466a7c8066cristy 7757159f66759ae05f052aad309915b9784f7aca927cristy MagickRealType 776559401046eb333547a09fb8b67b11fd7f1b05faccristy angle_range, 777173ad0fb5d2718a7f47d7f576ad61c0bbd9f3bbdanthony angle_start, 778559401046eb333547a09fb8b67b11fd7f1b05faccristy height, 779559401046eb333547a09fb8b67b11fd7f1b05faccristy width; 7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 781bce4f4a707e7a4d956df6e36e14f31c5e162f8aecristy PixelInfo 782bce4f4a707e7a4d956df6e36e14f31c5e162f8aecristy pixel; 783bce4f4a707e7a4d956df6e36e14f31c5e162f8aecristy 7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ResampleFilter 7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *resample_filter; 7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 787559401046eb333547a09fb8b67b11fd7f1b05faccristy SegmentInfo 788559401046eb333547a09fb8b67b11fd7f1b05faccristy blur; 7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 7919cb63ccb02272521283da6d251068d91196cc5bfanthony Blur Image by resampling. 7929cb63ccb02272521283da6d251068d91196cc5bfanthony 793559401046eb333547a09fb8b67b11fd7f1b05faccristy Blur Image dictated by an overlay gradient map: X = red_channel; 794559401046eb333547a09fb8b67b11fd7f1b05faccristy Y = green_channel; compose:args = x_scale[,y_scale[,angle]]. 7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 796e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_image=CloneImage(image,image->columns,image->rows,MagickTrue, 7978a11cb146177680bfc1b7d89a8cd0c8f2befe468cristy exception); 798e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if (canvas_image == (Image *) NULL) 79944886b9874b0dc62e49d0c26f16aa4fbcb2407f0cristy { 800e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_image=DestroyImage(source_image); 80144886b9874b0dc62e49d0c26f16aa4fbcb2407f0cristy return(MagickFalse); 80244886b9874b0dc62e49d0c26f16aa4fbcb2407f0cristy } 8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 8049cb63ccb02272521283da6d251068d91196cc5bfanthony Gather the maximum blur sigma values from user. 8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags=NoValue; 8071a78095355e735d713d5994eb662b36037ce69f2cristy value=GetImageArtifact(image,"compose:args"); 8081a78095355e735d713d5994eb662b36037ce69f2cristy if (value != (const char *) NULL) 8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags=ParseGeometry(value,&geometry_info); 8101a78095355e735d713d5994eb662b36037ce69f2cristy if ((flags & WidthValue) == 0) 8111a78095355e735d713d5994eb662b36037ce69f2cristy { 8121a78095355e735d713d5994eb662b36037ce69f2cristy (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning, 8131a78095355e735d713d5994eb662b36037ce69f2cristy "InvalidSetting","'%s' '%s'","compose:args",value); 814e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_image=DestroyImage(source_image); 815e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_image=DestroyImage(canvas_image); 8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8189cb63ccb02272521283da6d251068d91196cc5bfanthony /* 8199cb63ccb02272521283da6d251068d91196cc5bfanthony Users input sigma now needs to be converted to the EWA ellipse size. 8209cb63ccb02272521283da6d251068d91196cc5bfanthony The filter defaults to a sigma of 0.5 so to make this match the 8219cb63ccb02272521283da6d251068d91196cc5bfanthony users input the ellipse size needs to be doubled. 822d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony */ 823d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony width=height=geometry_info.rho*2.0; 824d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony if ((flags & HeightValue) != 0 ) 825d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony height=geometry_info.sigma*2.0; 8267159f66759ae05f052aad309915b9784f7aca927cristy /* 8277159f66759ae05f052aad309915b9784f7aca927cristy Default the unrotated ellipse width and height axis vectors. 8287159f66759ae05f052aad309915b9784f7aca927cristy */ 829d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony blur.x1=width; 830559401046eb333547a09fb8b67b11fd7f1b05faccristy blur.x2=0.0; 831559401046eb333547a09fb8b67b11fd7f1b05faccristy blur.y1=0.0; 832d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony blur.y2=height; 833d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony /* rotate vectors if a rotation angle is given */ 834173ad0fb5d2718a7f47d7f576ad61c0bbd9f3bbdanthony if ((flags & XValue) != 0 ) 8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8367159f66759ae05f052aad309915b9784f7aca927cristy MagickRealType 837173ad0fb5d2718a7f47d7f576ad61c0bbd9f3bbdanthony angle; 838173ad0fb5d2718a7f47d7f576ad61c0bbd9f3bbdanthony 839559401046eb333547a09fb8b67b11fd7f1b05faccristy angle=DegreesToRadians(geometry_info.xi); 840dff7476eed3fa4bc0095561868c3d4d1710d0641anthony blur.x1=width*cos(angle); 841dff7476eed3fa4bc0095561868c3d4d1710d0641anthony blur.x2=width*sin(angle); 842dff7476eed3fa4bc0095561868c3d4d1710d0641anthony blur.y1=(-height*sin(angle)); 843dff7476eed3fa4bc0095561868c3d4d1710d0641anthony blur.y2=height*cos(angle); 844173ad0fb5d2718a7f47d7f576ad61c0bbd9f3bbdanthony } 845d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony /* Otherwise lets set a angle range and calculate in the loop */ 846d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony angle_start=0.0; 847d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony angle_range=0.0; 848173ad0fb5d2718a7f47d7f576ad61c0bbd9f3bbdanthony if ((flags & YValue) != 0 ) 849173ad0fb5d2718a7f47d7f576ad61c0bbd9f3bbdanthony { 850559401046eb333547a09fb8b67b11fd7f1b05faccristy angle_start=DegreesToRadians(geometry_info.xi); 851559401046eb333547a09fb8b67b11fd7f1b05faccristy angle_range=DegreesToRadians(geometry_info.psi)-angle_start; 8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 8549cb63ccb02272521283da6d251068d91196cc5bfanthony Set up a gaussian cylindrical filter for EWA Bluring. 855d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony 8569cb63ccb02272521283da6d251068d91196cc5bfanthony As the minimum ellipse radius of support*1.0 the EWA algorithm 8579cb63ccb02272521283da6d251068d91196cc5bfanthony can only produce a minimum blur of 0.5 for Gaussian (support=2.0) 8589cb63ccb02272521283da6d251068d91196cc5bfanthony This means that even 'No Blur' will be still a little blurry! 859d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony 8609cb63ccb02272521283da6d251068d91196cc5bfanthony The solution (as well as the problem of preventing any user 8619cb63ccb02272521283da6d251068d91196cc5bfanthony expert filter settings, is to set our own user settings, then 8629cb63ccb02272521283da6d251068d91196cc5bfanthony restore them afterwards. 8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 8648a11cb146177680bfc1b7d89a8cd0c8f2befe468cristy resample_filter=AcquireResampleFilter(image,exception); 865d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony SetResampleFilter(resample_filter,GaussianFilter); 8669cb63ccb02272521283da6d251068d91196cc5bfanthony 8679cb63ccb02272521283da6d251068d91196cc5bfanthony /* do the variable blurring of each pixel in image */ 8689cb63ccb02272521283da6d251068d91196cc5bfanthony GetPixelInfo(image,&pixel); 869e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_view=AcquireVirtualCacheView(source_image,exception); 870e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_view=AcquireAuthenticCacheView(canvas_image,exception); 871e8e8eff5f2414d6096195a41934fc0edee9d9212cristy for (y=0; y < (ssize_t) source_image->rows; y++) 8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy sync; 8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8764c08aed51c5899665ade97263692328eea4af106cristy register const Quantum 87705d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict p; 8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8794c08aed51c5899665ade97263692328eea4af106cristy register Quantum 88005d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict q; 8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 882bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy x; 8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 885bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if (((y+y_offset) < 0) || ((y+y_offset) >= (ssize_t) image->rows)) 8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 8872fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy p=GetCacheViewVirtualPixels(source_view,0,y,source_image->columns,1, 8882fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy exception); 8892fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy q=QueueCacheViewAuthenticPixels(canvas_view,0,y,canvas_image->columns,1, 8902fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy exception); 8914c08aed51c5899665ade97263692328eea4af106cristy if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) 8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 893e8e8eff5f2414d6096195a41934fc0edee9d9212cristy for (x=0; x < (ssize_t) source_image->columns; x++) 8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 895bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if (((x_offset+x) < 0) || ((x_offset+x) >= (ssize_t) image->columns)) 8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 897e8e8eff5f2414d6096195a41934fc0edee9d9212cristy p+=GetPixelChannels(source_image); 8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9003bdd925dbb0804df99e548c50667670319655816cristy if (fabs((double) angle_range) > MagickEpsilon) 901173ad0fb5d2718a7f47d7f576ad61c0bbd9f3bbdanthony { 9027159f66759ae05f052aad309915b9784f7aca927cristy MagickRealType 903173ad0fb5d2718a7f47d7f576ad61c0bbd9f3bbdanthony angle; 904173ad0fb5d2718a7f47d7f576ad61c0bbd9f3bbdanthony 905559401046eb333547a09fb8b67b11fd7f1b05faccristy angle=angle_start+angle_range*QuantumScale* 906e8e8eff5f2414d6096195a41934fc0edee9d9212cristy GetPixelBlue(source_image,p); 907dff7476eed3fa4bc0095561868c3d4d1710d0641anthony blur.x1=width*cos(angle); 908dff7476eed3fa4bc0095561868c3d4d1710d0641anthony blur.x2=width*sin(angle); 909dff7476eed3fa4bc0095561868c3d4d1710d0641anthony blur.y1=(-height*sin(angle)); 910dff7476eed3fa4bc0095561868c3d4d1710d0641anthony blur.y2=height*cos(angle); 911173ad0fb5d2718a7f47d7f576ad61c0bbd9f3bbdanthony } 912d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony#if 0 913d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony if ( x == 10 && y == 60 ) { 9147159f66759ae05f052aad309915b9784f7aca927cristy (void) fprintf(stderr, "blur.x=%lf,%lf, blur.y=%lf,%lf\n",blur.x1, 9157159f66759ae05f052aad309915b9784f7aca927cristy blur.x2,blur.y1, blur.y2); 9167159f66759ae05f052aad309915b9784f7aca927cristy (void) fprintf(stderr, "scaled by=%lf,%lf\n",QuantumScale* 9177159f66759ae05f052aad309915b9784f7aca927cristy GetPixelRed(p),QuantumScale*GetPixelGreen(p)); 918d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony#endif 919d2923915a5f0e17e3f1ea511cddbf7d3cb8b6c99anthony ScaleResampleFilter(resample_filter, 920e8e8eff5f2414d6096195a41934fc0edee9d9212cristy blur.x1*QuantumScale*GetPixelRed(source_image,p), 921e8e8eff5f2414d6096195a41934fc0edee9d9212cristy blur.y1*QuantumScale*GetPixelGreen(source_image,p), 922e8e8eff5f2414d6096195a41934fc0edee9d9212cristy blur.x2*QuantumScale*GetPixelRed(source_image,p), 923e8e8eff5f2414d6096195a41934fc0edee9d9212cristy blur.y2*QuantumScale*GetPixelGreen(source_image,p) ); 9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ResamplePixelColor(resample_filter,(double) x_offset+x, 925db070957cf6bf959df9283a482377e8854c3d4d2cristy (double) y_offset+y,&pixel,exception); 926e8e8eff5f2414d6096195a41934fc0edee9d9212cristy SetPixelViaPixelInfo(canvas_image,&pixel,q); 927e8e8eff5f2414d6096195a41934fc0edee9d9212cristy p+=GetPixelChannels(source_image); 928e8e8eff5f2414d6096195a41934fc0edee9d9212cristy q+=GetPixelChannels(canvas_image); 9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 930e8e8eff5f2414d6096195a41934fc0edee9d9212cristy sync=SyncCacheViewAuthenticPixels(canvas_view,exception); 9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (sync == MagickFalse) 9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resample_filter=DestroyResampleFilter(resample_filter); 935e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_view=DestroyCacheView(source_view); 936e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_view=DestroyCacheView(canvas_view); 937e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_image=DestroyImage(source_image); 938e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_image=canvas_image; 9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case DisplaceCompositeOp: 9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case DistortCompositeOp: 9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 944559401046eb333547a09fb8b67b11fd7f1b05faccristy CacheView 945fa589d6096099562cbc2bc14e508931968a8c055dirk *canvas_view; 946feb3e9695150978a5d2372d3fe2f60466a7c8066cristy 9477159f66759ae05f052aad309915b9784f7aca927cristy MagickRealType 9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy horizontal_scale, 949559401046eb333547a09fb8b67b11fd7f1b05faccristy vertical_scale; 950559401046eb333547a09fb8b67b11fd7f1b05faccristy 9514f60be50be2ee99d6ea941c702b6789fd7ca68cfcristy PixelInfo 9524f60be50be2ee99d6ea941c702b6789fd7ca68cfcristy pixel; 9534f60be50be2ee99d6ea941c702b6789fd7ca68cfcristy 954559401046eb333547a09fb8b67b11fd7f1b05faccristy PointInfo 955559401046eb333547a09fb8b67b11fd7f1b05faccristy center, 956559401046eb333547a09fb8b67b11fd7f1b05faccristy offset; 9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 9593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Displace/Distort based on overlay gradient map: 9603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy X = red_channel; Y = green_channel; 961559401046eb333547a09fb8b67b11fd7f1b05faccristy compose:args = x_scale[,y_scale[,center.x,center.y]] 9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 963e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_image=CloneImage(image,image->columns,image->rows,MagickTrue, 9648a11cb146177680bfc1b7d89a8cd0c8f2befe468cristy exception); 965e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if (canvas_image == (Image *) NULL) 96644886b9874b0dc62e49d0c26f16aa4fbcb2407f0cristy { 967e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_image=DestroyImage(source_image); 96844886b9874b0dc62e49d0c26f16aa4fbcb2407f0cristy return(MagickFalse); 96944886b9874b0dc62e49d0c26f16aa4fbcb2407f0cristy } 9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy SetGeometryInfo(&geometry_info); 9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags=NoValue; 97255a83c75eeede1662a9e6c43c3af201502c9442fdirk value=GetImageArtifact(image,"compose:args"); 9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (value != (char *) NULL) 9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags=ParseGeometry(value,&geometry_info); 97548054f3dcda89dd0764c43571a95b41a7deeee6ecristy if ((flags & (WidthValue | HeightValue)) == 0 ) 976559401046eb333547a09fb8b67b11fd7f1b05faccristy { 977559401046eb333547a09fb8b67b11fd7f1b05faccristy if ((flags & AspectValue) == 0) 978559401046eb333547a09fb8b67b11fd7f1b05faccristy { 979ad1b65039ac9430edfe2a79ed4187729e6f0a4eccristy horizontal_scale=(MagickRealType) (source_image->columns-1)/2.0; 980ad1b65039ac9430edfe2a79ed4187729e6f0a4eccristy vertical_scale=(MagickRealType) (source_image->rows-1)/2.0; 981559401046eb333547a09fb8b67b11fd7f1b05faccristy } 982559401046eb333547a09fb8b67b11fd7f1b05faccristy else 983559401046eb333547a09fb8b67b11fd7f1b05faccristy { 984ad1b65039ac9430edfe2a79ed4187729e6f0a4eccristy horizontal_scale=(MagickRealType) (image->columns-1)/2.0; 985ad1b65039ac9430edfe2a79ed4187729e6f0a4eccristy vertical_scale=(MagickRealType) (image->rows-1)/2.0; 986559401046eb333547a09fb8b67b11fd7f1b05faccristy } 987559401046eb333547a09fb8b67b11fd7f1b05faccristy } 9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy horizontal_scale=geometry_info.rho; 9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy vertical_scale=geometry_info.sigma; 9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((flags & PercentValue) != 0) 9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((flags & AspectValue) == 0) 9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 996ad1b65039ac9430edfe2a79ed4187729e6f0a4eccristy horizontal_scale*=(source_image->columns-1)/200.0; 997ad1b65039ac9430edfe2a79ed4187729e6f0a4eccristy vertical_scale*=(source_image->rows-1)/200.0; 9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1001ad1b65039ac9430edfe2a79ed4187729e6f0a4eccristy horizontal_scale*=(image->columns-1)/200.0; 1002ad1b65039ac9430edfe2a79ed4187729e6f0a4eccristy vertical_scale*=(image->rows-1)/200.0; 10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((flags & HeightValue) == 0) 10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy vertical_scale=horizontal_scale; 10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Determine fixed center point for absolute distortion map 10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Absolute distort == 1011559401046eb333547a09fb8b67b11fd7f1b05faccristy Displace offset relative to a fixed absolute point 10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Select that point according to +X+Y user inputs. 10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default = center of overlay image 1014d37a5cb8553a1e408ffd22a51c2fc0ec17dfce5eanthony arg flag '!' = locations/percentage relative to background image 10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 10167159f66759ae05f052aad309915b9784f7aca927cristy center.x=(MagickRealType) x_offset; 10177159f66759ae05f052aad309915b9784f7aca927cristy center.y=(MagickRealType) y_offset; 10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (compose == DistortCompositeOp) 10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((flags & XValue) == 0) 1021190f47988052d03eb6b79c49cce4404eca4e353bcristy if ((flags & AspectValue) != 0) 1022190f47988052d03eb6b79c49cce4404eca4e353bcristy center.x=(MagickRealType) ((image->columns-1)/2.0); 1023190f47988052d03eb6b79c49cce4404eca4e353bcristy else 1024e8e8eff5f2414d6096195a41934fc0edee9d9212cristy center.x=(MagickRealType) (x_offset+(source_image->columns-1)/ 10257159f66759ae05f052aad309915b9784f7aca927cristy 2.0); 10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 1027190f47988052d03eb6b79c49cce4404eca4e353bcristy if ((flags & AspectValue) != 0) 1028559401046eb333547a09fb8b67b11fd7f1b05faccristy center.x=geometry_info.xi; 10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 1030190f47988052d03eb6b79c49cce4404eca4e353bcristy center.x=(MagickRealType) (x_offset+geometry_info.xi); 1031190f47988052d03eb6b79c49cce4404eca4e353bcristy if ((flags & YValue) == 0) 1032190f47988052d03eb6b79c49cce4404eca4e353bcristy if ((flags & AspectValue) != 0) 1033ad1b65039ac9430edfe2a79ed4187729e6f0a4eccristy center.y=(MagickRealType) ((image->rows-1)/2.0); 10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 1035190f47988052d03eb6b79c49cce4404eca4e353bcristy center.y=(MagickRealType) (y_offset+(source_image->rows-1)/2.0); 1036190f47988052d03eb6b79c49cce4404eca4e353bcristy else 1037190f47988052d03eb6b79c49cce4404eca4e353bcristy if ((flags & AspectValue) != 0) 1038559401046eb333547a09fb8b67b11fd7f1b05faccristy center.y=geometry_info.psi; 1039190f47988052d03eb6b79c49cce4404eca4e353bcristy else 1040190f47988052d03eb6b79c49cce4404eca4e353bcristy center.y=(MagickRealType) (y_offset+geometry_info.psi); 10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 1043559401046eb333547a09fb8b67b11fd7f1b05faccristy Shift the pixel offset point as defined by the provided, 10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy displacement/distortion map. -- Like a lens... 10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 1046e10859aa31abb52913175e089e5d25cbd670499fcristy GetPixelInfo(image,&pixel); 104746ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy image_view=AcquireVirtualCacheView(image,exception); 1048e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_view=AcquireVirtualCacheView(source_image,exception); 1049e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_view=AcquireAuthenticCacheView(canvas_image,exception); 1050e8e8eff5f2414d6096195a41934fc0edee9d9212cristy for (y=0; y < (ssize_t) source_image->rows; y++) 10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 10523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy sync; 10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10554c08aed51c5899665ade97263692328eea4af106cristy register const Quantum 105605d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict p; 10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10584c08aed51c5899665ade97263692328eea4af106cristy register Quantum 105905d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict q; 10604c08aed51c5899665ade97263692328eea4af106cristy 1061bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 10623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy x; 10633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1064bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if (((y+y_offset) < 0) || ((y+y_offset) >= (ssize_t) image->rows)) 10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 1066ad1b65039ac9430edfe2a79ed4187729e6f0a4eccristy p=GetCacheViewVirtualPixels(source_view,0,y,source_image->columns,1, 1067ad1b65039ac9430edfe2a79ed4187729e6f0a4eccristy exception); 1068ad1b65039ac9430edfe2a79ed4187729e6f0a4eccristy q=QueueCacheViewAuthenticPixels(canvas_view,0,y,canvas_image->columns,1, 1069ad1b65039ac9430edfe2a79ed4187729e6f0a4eccristy exception); 10704c08aed51c5899665ade97263692328eea4af106cristy if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) 10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 1072e8e8eff5f2414d6096195a41934fc0edee9d9212cristy for (x=0; x < (ssize_t) source_image->columns; x++) 10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1074bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if (((x_offset+x) < 0) || ((x_offset+x) >= (ssize_t) image->columns)) 10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1076e8e8eff5f2414d6096195a41934fc0edee9d9212cristy p+=GetPixelChannels(source_image); 10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy continue; 10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 1080559401046eb333547a09fb8b67b11fd7f1b05faccristy Displace the offset. 10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 1082e8e8eff5f2414d6096195a41934fc0edee9d9212cristy offset.x=(double) (horizontal_scale*(GetPixelRed(source_image,p)- 10837159f66759ae05f052aad309915b9784f7aca927cristy (((MagickRealType) QuantumRange+1.0)/2.0)))/(((MagickRealType) 10847159f66759ae05f052aad309915b9784f7aca927cristy QuantumRange+1.0)/2.0)+center.x+((compose == DisplaceCompositeOp) ? 10857159f66759ae05f052aad309915b9784f7aca927cristy x : 0); 1086e8e8eff5f2414d6096195a41934fc0edee9d9212cristy offset.y=(double) (vertical_scale*(GetPixelGreen(source_image,p)- 10877159f66759ae05f052aad309915b9784f7aca927cristy (((MagickRealType) QuantumRange+1.0)/2.0)))/(((MagickRealType) 10887159f66759ae05f052aad309915b9784f7aca927cristy QuantumRange+1.0)/2.0)+center.y+((compose == DisplaceCompositeOp) ? 10897159f66759ae05f052aad309915b9784f7aca927cristy y : 0); 1090c692a833300c9d5a58c221c7fb87cf369f54e16ecristy (void) InterpolatePixelInfo(image,image_view, 1091c692a833300c9d5a58c221c7fb87cf369f54e16ecristy UndefinedInterpolatePixel,(double) offset.x,(double) offset.y, 1092c692a833300c9d5a58c221c7fb87cf369f54e16ecristy &pixel,exception); 10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 1094c5d68fe2846b7ed7b866c8a5d9287264d75458caanthony Mask with the 'invalid pixel mask' in alpha channel. 10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 10964f60be50be2ee99d6ea941c702b6789fd7ca68cfcristy pixel.alpha=(MagickRealType) QuantumRange*(QuantumScale*pixel.alpha)* 10974f60be50be2ee99d6ea941c702b6789fd7ca68cfcristy (QuantumScale*GetPixelAlpha(source_image,p)); 1098e8e8eff5f2414d6096195a41934fc0edee9d9212cristy SetPixelViaPixelInfo(canvas_image,&pixel,q); 1099e8e8eff5f2414d6096195a41934fc0edee9d9212cristy p+=GetPixelChannels(source_image); 1100e8e8eff5f2414d6096195a41934fc0edee9d9212cristy q+=GetPixelChannels(canvas_image); 11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1102e8e8eff5f2414d6096195a41934fc0edee9d9212cristy sync=SyncCacheViewAuthenticPixels(canvas_view,exception); 11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (sync == MagickFalse) 11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1106e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_view=DestroyCacheView(canvas_view); 1107e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_view=DestroyCacheView(source_view); 1108d76c51ed30cf4084f4434ba08925d16001d1e340cristy image_view=DestroyCacheView(image_view); 1109e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_image=DestroyImage(source_image); 1110e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_image=canvas_image; 11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case DissolveCompositeOp: 11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Geometry arguments to dissolve factors. 11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 111855a83c75eeede1662a9e6c43c3af201502c9442fdirk value=GetImageArtifact(image,"compose:args"); 11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (value != (char *) NULL) 11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags=ParseGeometry(value,&geometry_info); 11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy source_dissolve=geometry_info.rho/100.0; 1123e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_dissolve=1.0; 11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((source_dissolve-MagickEpsilon) < 0.0) 11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy source_dissolve=0.0; 11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((source_dissolve+MagickEpsilon) > 1.0) 11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1128e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_dissolve=2.0-source_dissolve; 11293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy source_dissolve=1.0; 11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((flags & SigmaValue) != 0) 1132e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_dissolve=geometry_info.sigma/100.0; 1133e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if ((canvas_dissolve-MagickEpsilon) < 0.0) 1134e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_dissolve=0.0; 11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case BlendCompositeOp: 11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 114055a83c75eeede1662a9e6c43c3af201502c9442fdirk value=GetImageArtifact(image,"compose:args"); 11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (value != (char *) NULL) 11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags=ParseGeometry(value,&geometry_info); 11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy source_dissolve=geometry_info.rho/100.0; 1145e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_dissolve=1.0-source_dissolve; 11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((flags & SigmaValue) != 0) 1147e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_dissolve=geometry_info.sigma/100.0; 11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case MathematicsCompositeOp: 11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Just collect the values from "compose:args", setting. 11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Unused values are set to zero automagically. 11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Arguments are normally a comma separated list, so this probably should 11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy be changed to some 'general comma list' parser, (with a minimum 11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number of values) 11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy SetGeometryInfo(&geometry_info); 116255a83c75eeede1662a9e6c43c3af201502c9442fdirk value=GetImageArtifact(image,"compose:args"); 11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (value != (char *) NULL) 11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ParseGeometry(value,&geometry_info); 11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case ModulateCompositeOp: 11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 11707133e649ea494c1286ff16bcb02342d660097219cristy Determine the luma and chroma scale. 11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 117255a83c75eeede1662a9e6c43c3af201502c9442fdirk value=GetImageArtifact(image,"compose:args"); 11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (value != (char *) NULL) 11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags=ParseGeometry(value,&geometry_info); 11767133e649ea494c1286ff16bcb02342d660097219cristy percent_luma=geometry_info.rho; 11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((flags & SigmaValue) != 0) 11787133e649ea494c1286ff16bcb02342d660097219cristy percent_chroma=geometry_info.sigma; 11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case ThresholdCompositeOp: 11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Determine the amount and threshold. 11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 118755a83c75eeede1662a9e6c43c3af201502c9442fdirk value=GetImageArtifact(image,"compose:args"); 11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (value != (char *) NULL) 11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags=ParseGeometry(value,&geometry_info); 11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy amount=geometry_info.rho; 11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy threshold=geometry_info.sigma; 11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((flags & SigmaValue) == 0) 11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy threshold=0.05f; 11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy threshold*=QuantumRange; 11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default: 12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Composite image. 12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=MagickTrue; 12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy progress=0; 12077159f66759ae05f052aad309915b9784f7aca927cristy midpoint=((MagickRealType) QuantumRange+1.0)/2; 1208e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_view=AcquireVirtualCacheView(source_image,exception); 120946ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy image_view=AcquireAuthenticCacheView(image,exception); 1210b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 1211ac245f8a51ea65b085d751c41d8ca4b426bdfe5bcristy #pragma omp parallel for schedule(static,4) shared(progress,status) \ 1212e8e8eff5f2414d6096195a41934fc0edee9d9212cristy magick_threads(source_image,image,image->rows,1) 12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 1214bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=0; y < (ssize_t) image->rows; y++) 12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 12164c08aed51c5899665ade97263692328eea4af106cristy const Quantum 12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *pixels; 12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12197159f66759ae05f052aad309915b9784f7aca927cristy MagickRealType 1220e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy blue, 122112e4d2e452fe147da90070df55b10dfbd88b7067cristy chroma, 1222e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy green, 1223e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy hue, 122412e4d2e452fe147da90070df55b10dfbd88b7067cristy luma, 122512e4d2e452fe147da90070df55b10dfbd88b7067cristy red; 1226e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 1227ddeeea23285164a7029e2f28475642f26882f2d7cristy PixelInfo 1228e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_pixel, 1229ddeeea23285164a7029e2f28475642f26882f2d7cristy source_pixel; 1230ddeeea23285164a7029e2f28475642f26882f2d7cristy 1231e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy register const Quantum 123205d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict p; 1233e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 1234e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy register Quantum 123505d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict q; 1236e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 1237e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy register ssize_t 1238e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy x; 1239e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 1240e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (status == MagickFalse) 1241e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 1242feb3e9695150978a5d2372d3fe2f60466a7c8066cristy if (clip_to_self != MagickFalse) 1243e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1244e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (y < y_offset) 1245e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 1246e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if ((y-y_offset) >= (ssize_t) source_image->rows) 1247e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 1248e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1249e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy /* 1250e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy If pixels is NULL, y is outside overlay region. 1251e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy */ 1252e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixels=(Quantum *) NULL; 1253e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy p=(Quantum *) NULL; 1254e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if ((y >= y_offset) && ((y-y_offset) < (ssize_t) source_image->rows)) 1255e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1256e8e8eff5f2414d6096195a41934fc0edee9d9212cristy p=GetCacheViewVirtualPixels(source_view,0,y-y_offset, 1257e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_image->columns,1,exception); 1258e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (p == (const Quantum *) NULL) 1259e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1260e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy status=MagickFalse; 1261e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 1262e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1263e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixels=p; 1264e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (x_offset < 0) 1265e8e8eff5f2414d6096195a41934fc0edee9d9212cristy p-=x_offset*GetPixelChannels(source_image); 1266e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1267e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception); 1268e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (q == (Quantum *) NULL) 1269e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1270e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy status=MagickFalse; 1271e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 1272e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1273e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy hue=0.0; 12747133e649ea494c1286ff16bcb02342d660097219cristy chroma=0.0; 12757133e649ea494c1286ff16bcb02342d660097219cristy luma=0.0; 1276e8e8eff5f2414d6096195a41934fc0edee9d9212cristy GetPixelInfo(image,&canvas_pixel); 1277e8e8eff5f2414d6096195a41934fc0edee9d9212cristy GetPixelInfo(source_image,&source_pixel); 1278e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy for (x=0; x < (ssize_t) image->columns; x++) 1279e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 128017028dccbf579855c1805d9e62561ad83104bb56cristy double 128117028dccbf579855c1805d9e62561ad83104bb56cristy gamma; 128217028dccbf579855c1805d9e62561ad83104bb56cristy 12837159f66759ae05f052aad309915b9784f7aca927cristy MagickRealType 1284e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy alpha, 1285e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Da, 1286e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Dc, 1287e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Dca, 1288e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Sa, 1289e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Sc, 1290e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Sca; 1291e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 1292e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy register ssize_t 1293e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy i; 1294e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 1295564a56979706a30a3d0f920fd5f538a408efd4f1cristy size_t 1296564a56979706a30a3d0f920fd5f538a408efd4f1cristy channels; 1297564a56979706a30a3d0f920fd5f538a408efd4f1cristy 1298feb3e9695150978a5d2372d3fe2f60466a7c8066cristy if (clip_to_self != MagickFalse) 1299e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1300e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (x < x_offset) 13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1302e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy q+=GetPixelChannels(image); 1303e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1305e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if ((x-x_offset) >= (ssize_t) source_image->columns) 1306e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1307e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1308e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if ((pixels == (Quantum *) NULL) || (x < x_offset) || 1309e8e8eff5f2414d6096195a41934fc0edee9d9212cristy ((x-x_offset) >= (ssize_t) source_image->columns)) 1310e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1311e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Quantum 1312e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy source[MaxPixelChannels]; 1313e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 1314e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy /* 1315e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Virtual composite: 1316e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Sc: source color. 1317e8e8eff5f2414d6096195a41934fc0edee9d9212cristy Dc: canvas color. 1318e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy */ 13192fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy (void) GetOneVirtualPixel(source_image,x-x_offset,y-y_offset,source, 13202fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy exception); 1321883fde11debec15cedb05dc5d7228d8588066bc0cristy if (GetPixelReadMask(image,q) == 0) 132210a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy { 132310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy q+=GetPixelChannels(image); 132410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy continue; 132510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy } 1326e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 1327e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 13287159f66759ae05f052aad309915b9784f7aca927cristy MagickRealType 1329e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel; 1330e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 13315a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(image,i); 13325a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(image,channel); 1333e8e8eff5f2414d6096195a41934fc0edee9d9212cristy PixelTrait source_traits=GetPixelChannelTraits(source_image, 13345a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy channel); 1335e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if ((traits == UndefinedPixelTrait) || 1336e8e8eff5f2414d6096195a41934fc0edee9d9212cristy (source_traits == UndefinedPixelTrait)) 1337e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 1338e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy switch (compose) 133943e26daee2f110555b6fe976a58a89775c03508fcristy { 1340c8d636784204aa4d970c212b156bffc387836b93cristy case AlphaCompositeOp: 1341e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ChangeMaskCompositeOp: 1342e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case CopyAlphaCompositeOp: 1343e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DstAtopCompositeOp: 1344e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DstInCompositeOp: 1345e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case InCompositeOp: 1346e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case OutCompositeOp: 1347e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case SrcInCompositeOp: 1348e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case SrcOutCompositeOp: 1349e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1350e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (channel == AlphaPixelChannel) 13517159f66759ae05f052aad309915b9784f7aca927cristy pixel=(MagickRealType) TransparentAlpha; 13521474c08cbd2d489254a9b41a22fab1e4c698740bdirk else 13531474c08cbd2d489254a9b41a22fab1e4c698740bdirk pixel=(MagickRealType) q[i]; 1354e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1355e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1356e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ClearCompositeOp: 1357e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case CopyCompositeOp: 1358e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ReplaceCompositeOp: 1359e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case SrcCompositeOp: 1360e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1361e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (channel == AlphaPixelChannel) 13621474c08cbd2d489254a9b41a22fab1e4c698740bdirk pixel=(MagickRealType) TransparentAlpha; 13631474c08cbd2d489254a9b41a22fab1e4c698740bdirk else 13641474c08cbd2d489254a9b41a22fab1e4c698740bdirk pixel=0.0; 1365e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1366e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 136799abff36ae5d479bfd76652d166a4894ceada102cristy case BlendCompositeOp: 1368e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DissolveCompositeOp: 1369e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1370e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (channel == AlphaPixelChannel) 137112e4d2e452fe147da90070df55b10dfbd88b7067cristy pixel=canvas_dissolve*GetPixelAlpha(source_image,source); 13721474c08cbd2d489254a9b41a22fab1e4c698740bdirk else 13731474c08cbd2d489254a9b41a22fab1e4c698740bdirk pixel=(MagickRealType) source[channel]; 1374e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1375e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1376e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy default: 1377e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 13787159f66759ae05f052aad309915b9784f7aca927cristy pixel=(MagickRealType) source[channel]; 1379e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1380e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 138143e26daee2f110555b6fe976a58a89775c03508fcristy } 138247c61c996128275174b8a120ab6a88a5c1bec3d3cristy q[i]=clamp != MagickFalse ? ClampPixel(pixel) : 138347c61c996128275174b8a120ab6a88a5c1bec3d3cristy ClampToQuantum(pixel); 13843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1385e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy q+=GetPixelChannels(image); 1386e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy continue; 1387e10859aa31abb52913175e089e5d25cbd670499fcristy } 1388e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy /* 1389e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Authentic composite: 1390e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Sa: normalized source alpha. 1391e8e8eff5f2414d6096195a41934fc0edee9d9212cristy Da: normalized canvas alpha. 1392e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy */ 1393e8e8eff5f2414d6096195a41934fc0edee9d9212cristy Sa=QuantumScale*GetPixelAlpha(source_image,p); 1394e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Da=QuantumScale*GetPixelAlpha(image,q); 1395e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy switch (compose) 1396e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1397e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case BumpmapCompositeOp: 1398e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1399e8e8eff5f2414d6096195a41934fc0edee9d9212cristy alpha=GetPixelIntensity(source_image,p)*Sa; 1400e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1401e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1402e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ColorBurnCompositeOp: 1403e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ColorDodgeCompositeOp: 140430dac202caf1ded0e356ab1c2b67ec8d7929e06dcristy case DarkenCompositeOp: 1405e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DifferenceCompositeOp: 1406e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DivideDstCompositeOp: 1407e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DivideSrcCompositeOp: 1408e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ExclusionCompositeOp: 1409e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case HardLightCompositeOp: 141099fc217dffe2ed10ebefd0ac85900df37b60e3fdcristy case HardMixCompositeOp: 1411e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case LinearBurnCompositeOp: 1412e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case LinearDodgeCompositeOp: 1413e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case LinearLightCompositeOp: 141430dac202caf1ded0e356ab1c2b67ec8d7929e06dcristy case LightenCompositeOp: 1415e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case MathematicsCompositeOp: 1416e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case MinusDstCompositeOp: 1417e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case MinusSrcCompositeOp: 1418e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ModulusAddCompositeOp: 1419e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ModulusSubtractCompositeOp: 1420e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case MultiplyCompositeOp: 1421e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case OverlayCompositeOp: 1422e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case PegtopLightCompositeOp: 1423e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case PinLightCompositeOp: 1424e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ScreenCompositeOp: 1425e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case SoftLightCompositeOp: 1426e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case VividLightCompositeOp: 1427e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1428e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy alpha=RoundToUnity(Sa+Da-Sa*Da); 1429e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1430e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1431e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DstAtopCompositeOp: 1432e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DstInCompositeOp: 1433e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case InCompositeOp: 1434e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case SrcInCompositeOp: 1435e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1436e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy alpha=Sa*Da; 1437e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1438e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1439e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DissolveCompositeOp: 1440e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 14412fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy alpha=source_dissolve*Sa*(-canvas_dissolve*Da)+source_dissolve*Sa+ 14422fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy canvas_dissolve*Da; 1443e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1444e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1445e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DstOverCompositeOp: 14461749597845aafe5e61783d9a1b43d333f7071ccddirk case OverCompositeOp: 14471749597845aafe5e61783d9a1b43d333f7071ccddirk case SrcOverCompositeOp: 1448e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 144930dac202caf1ded0e356ab1c2b67ec8d7929e06dcristy alpha=Sa+Da-Sa*Da; 1450e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1451e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1452e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DstOutCompositeOp: 1453e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1454e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy alpha=Da*(1.0-Sa); 1455e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1456e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1457e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case OutCompositeOp: 1458e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case SrcOutCompositeOp: 1459e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1460e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy alpha=Sa*(1.0-Da); 1461e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1462e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 146399abff36ae5d479bfd76652d166a4894ceada102cristy case BlendCompositeOp: 1464e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case PlusCompositeOp: 1465e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1466b37bf1647d1a963a149a082366d81445217bd754cristy alpha=RoundToUnity(source_dissolve*Sa+canvas_dissolve*Da); 1467e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1468e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1469e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case XorCompositeOp: 1470e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1471e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy alpha=Sa+Da-2.0*Sa*Da; 1472e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1473e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1474e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy default: 1475e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1476e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy alpha=1.0; 1477e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1478e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1479e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1480883fde11debec15cedb05dc5d7228d8588066bc0cristy if (GetPixelReadMask(image,q) == 0) 148110a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy { 1482e8e8eff5f2414d6096195a41934fc0edee9d9212cristy p+=GetPixelChannels(source_image); 148310a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy q+=GetPixelChannels(image); 148410a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy continue; 148510a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy } 14869d3d279297b7248caacd9f37f433974b92df5fedcristy switch (compose) 14879d3d279297b7248caacd9f37f433974b92df5fedcristy { 14889d3d279297b7248caacd9f37f433974b92df5fedcristy case ColorizeCompositeOp: 14899d3d279297b7248caacd9f37f433974b92df5fedcristy case HueCompositeOp: 14909d3d279297b7248caacd9f37f433974b92df5fedcristy case LuminizeCompositeOp: 14919d3d279297b7248caacd9f37f433974b92df5fedcristy case ModulateCompositeOp: 14929d3d279297b7248caacd9f37f433974b92df5fedcristy case SaturateCompositeOp: 14939d3d279297b7248caacd9f37f433974b92df5fedcristy { 1494e8e8eff5f2414d6096195a41934fc0edee9d9212cristy GetPixelInfoPixel(source_image,p,&source_pixel); 1495e8e8eff5f2414d6096195a41934fc0edee9d9212cristy GetPixelInfoPixel(image,q,&canvas_pixel); 14969d3d279297b7248caacd9f37f433974b92df5fedcristy break; 14979d3d279297b7248caacd9f37f433974b92df5fedcristy } 14989d3d279297b7248caacd9f37f433974b92df5fedcristy default: 14999d3d279297b7248caacd9f37f433974b92df5fedcristy break; 15009d3d279297b7248caacd9f37f433974b92df5fedcristy } 1501e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 1502e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 15037159f66759ae05f052aad309915b9784f7aca927cristy MagickRealType 15047159f66759ae05f052aad309915b9784f7aca927cristy pixel, 1505564a56979706a30a3d0f920fd5f538a408efd4f1cristy sans; 1506564a56979706a30a3d0f920fd5f538a408efd4f1cristy 15075a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(image,i); 15085a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(image,channel); 15092fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy PixelTrait source_traits=GetPixelChannelTraits(source_image,channel); 15100cd1f214a416f7827dbd000cecd6687f1df3cef6cristy if (traits == UndefinedPixelTrait) 15110cd1f214a416f7827dbd000cecd6687f1df3cef6cristy continue; 1512e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if ((source_traits == UndefinedPixelTrait) && 1513597358bb71c59d54a67f64b76644b5436365733bdirk (((compose != CopyAlphaCompositeOp) && 1514597358bb71c59d54a67f64b76644b5436365733bdirk (compose != ChangeMaskCompositeOp)) || 151595ef69591ab25c59c552584384ad3cd5cc5b358bdirk (channel != AlphaPixelChannel))) 1516597358bb71c59d54a67f64b76644b5436365733bdirk continue; 1517e10859aa31abb52913175e089e5d25cbd670499fcristy /* 1518e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Sc: source color. 1519e8e8eff5f2414d6096195a41934fc0edee9d9212cristy Dc: canvas color. 1520e10859aa31abb52913175e089e5d25cbd670499fcristy */ 1521e8e8eff5f2414d6096195a41934fc0edee9d9212cristy Sc=(MagickRealType) GetPixelChannel(source_image,channel,p); 15227159f66759ae05f052aad309915b9784f7aca927cristy Dc=(MagickRealType) q[i]; 1523e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if ((traits & CopyPixelTrait) != 0) 1524e10859aa31abb52913175e089e5d25cbd670499fcristy { 1525e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy /* 1526e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy Copy channel. 1527e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy */ 152847c61c996128275174b8a120ab6a88a5c1bec3d3cristy q[i]=Sc; 1529e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy continue; 1530e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy } 1531e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy if (channel == AlphaPixelChannel) 1532e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy { 1533e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy /* 1534e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Set alpha channel. 1535e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy */ 1536e10859aa31abb52913175e089e5d25cbd670499fcristy switch (compose) 15373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1538c8d636784204aa4d970c212b156bffc387836b93cristy case AlphaCompositeOp: 1539c8d636784204aa4d970c212b156bffc387836b93cristy { 1540a7b079186ad7e0943fa65611a8978531bb612eeccristy pixel=QuantumRange*Sa; 1541c8d636784204aa4d970c212b156bffc387836b93cristy break; 1542c8d636784204aa4d970c212b156bffc387836b93cristy } 1543e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case AtopCompositeOp: 154499abff36ae5d479bfd76652d166a4894ceada102cristy case CopyBlackCompositeOp: 154599abff36ae5d479bfd76652d166a4894ceada102cristy case CopyBlueCompositeOp: 154699abff36ae5d479bfd76652d166a4894ceada102cristy case CopyCyanCompositeOp: 154799abff36ae5d479bfd76652d166a4894ceada102cristy case CopyGreenCompositeOp: 154899abff36ae5d479bfd76652d166a4894ceada102cristy case CopyMagentaCompositeOp: 154999abff36ae5d479bfd76652d166a4894ceada102cristy case CopyRedCompositeOp: 155099abff36ae5d479bfd76652d166a4894ceada102cristy case CopyYellowCompositeOp: 1551e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case SrcAtopCompositeOp: 1552e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DstCompositeOp: 1553e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case NoCompositeOp: 1554e10859aa31abb52913175e089e5d25cbd670499fcristy { 1555e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=QuantumRange*Da; 1556e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1557e10859aa31abb52913175e089e5d25cbd670499fcristy } 1558e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ChangeMaskCompositeOp: 1559e10859aa31abb52913175e089e5d25cbd670499fcristy { 1560e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy MagickBooleanType 1561e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy equivalent; 1562e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 1563f32657d0171432253bfcbc52a031734ac9bcd9cbdirk if (Da < 0.5) 156499abff36ae5d479bfd76652d166a4894ceada102cristy { 15657159f66759ae05f052aad309915b9784f7aca927cristy pixel=(MagickRealType) TransparentAlpha; 156699abff36ae5d479bfd76652d166a4894ceada102cristy break; 156799abff36ae5d479bfd76652d166a4894ceada102cristy } 1568e8e8eff5f2414d6096195a41934fc0edee9d9212cristy equivalent=IsFuzzyEquivalencePixel(source_image,p,image,q); 156999abff36ae5d479bfd76652d166a4894ceada102cristy if (equivalent != MagickFalse) 157040e1cb503f5f973a02d9bf139ce68690ac41c915dirk pixel=(MagickRealType) TransparentAlpha; 157140e1cb503f5f973a02d9bf139ce68690ac41c915dirk else 157240e1cb503f5f973a02d9bf139ce68690ac41c915dirk pixel=(MagickRealType) OpaqueAlpha; 1573e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1574e10859aa31abb52913175e089e5d25cbd670499fcristy } 157599abff36ae5d479bfd76652d166a4894ceada102cristy case ClearCompositeOp: 157699abff36ae5d479bfd76652d166a4894ceada102cristy { 15777159f66759ae05f052aad309915b9784f7aca927cristy pixel=(MagickRealType) TransparentAlpha; 157899abff36ae5d479bfd76652d166a4894ceada102cristy break; 157999abff36ae5d479bfd76652d166a4894ceada102cristy } 158099abff36ae5d479bfd76652d166a4894ceada102cristy case ColorizeCompositeOp: 158199abff36ae5d479bfd76652d166a4894ceada102cristy case HueCompositeOp: 158299abff36ae5d479bfd76652d166a4894ceada102cristy case LuminizeCompositeOp: 158399abff36ae5d479bfd76652d166a4894ceada102cristy case SaturateCompositeOp: 158499abff36ae5d479bfd76652d166a4894ceada102cristy { 15853bdd925dbb0804df99e548c50667670319655816cristy if (fabs((double) (QuantumRange*Sa-TransparentAlpha)) < MagickEpsilon) 158699abff36ae5d479bfd76652d166a4894ceada102cristy { 158799abff36ae5d479bfd76652d166a4894ceada102cristy pixel=QuantumRange*Da; 158899abff36ae5d479bfd76652d166a4894ceada102cristy break; 158999abff36ae5d479bfd76652d166a4894ceada102cristy } 15903bdd925dbb0804df99e548c50667670319655816cristy if (fabs((double) (QuantumRange*Da-TransparentAlpha)) < MagickEpsilon) 159199abff36ae5d479bfd76652d166a4894ceada102cristy { 159299abff36ae5d479bfd76652d166a4894ceada102cristy pixel=QuantumRange*Sa; 159399abff36ae5d479bfd76652d166a4894ceada102cristy break; 159499abff36ae5d479bfd76652d166a4894ceada102cristy } 159599abff36ae5d479bfd76652d166a4894ceada102cristy if (Sa < Da) 159699abff36ae5d479bfd76652d166a4894ceada102cristy { 159799abff36ae5d479bfd76652d166a4894ceada102cristy pixel=QuantumRange*Da; 159899abff36ae5d479bfd76652d166a4894ceada102cristy break; 159999abff36ae5d479bfd76652d166a4894ceada102cristy } 160099abff36ae5d479bfd76652d166a4894ceada102cristy pixel=QuantumRange*Sa; 160199abff36ae5d479bfd76652d166a4894ceada102cristy break; 160299abff36ae5d479bfd76652d166a4894ceada102cristy } 160399abff36ae5d479bfd76652d166a4894ceada102cristy case CopyAlphaCompositeOp: 160424d5d722cf4ba0767eb0d790e1b228a518d737cfcristy { 16054659893fa7803753e0300a0bde92ede4905aa496cristy if ((source_traits & BlendPixelTrait) == 0) 1606e8e8eff5f2414d6096195a41934fc0edee9d9212cristy pixel=GetPixelIntensity(source_image,p); 160740e1cb503f5f973a02d9bf139ce68690ac41c915dirk else 160840e1cb503f5f973a02d9bf139ce68690ac41c915dirk pixel=QuantumRange*Sa; 160924d5d722cf4ba0767eb0d790e1b228a518d737cfcristy break; 161024d5d722cf4ba0767eb0d790e1b228a518d737cfcristy } 161124d5d722cf4ba0767eb0d790e1b228a518d737cfcristy case CopyCompositeOp: 161299abff36ae5d479bfd76652d166a4894ceada102cristy case DisplaceCompositeOp: 161399abff36ae5d479bfd76652d166a4894ceada102cristy case DistortCompositeOp: 1614e10859aa31abb52913175e089e5d25cbd670499fcristy case DstAtopCompositeOp: 1615e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ReplaceCompositeOp: 1616e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case SrcCompositeOp: 1617e10859aa31abb52913175e089e5d25cbd670499fcristy { 1618e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=QuantumRange*Sa; 1619e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1620e10859aa31abb52913175e089e5d25cbd670499fcristy } 1621e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DarkenIntensityCompositeOp: 1622e10859aa31abb52913175e089e5d25cbd670499fcristy { 1623e8e8eff5f2414d6096195a41934fc0edee9d9212cristy pixel=Sa*GetPixelIntensity(source_image,p) < 1624076d0c9a787cf3054f29089d5bced8b08b606b94cristy Da*GetPixelIntensity(image,q) ? Sa : Da; 1625e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1626e10859aa31abb52913175e089e5d25cbd670499fcristy } 1627e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case LightenIntensityCompositeOp: 1628e10859aa31abb52913175e089e5d25cbd670499fcristy { 1629e8e8eff5f2414d6096195a41934fc0edee9d9212cristy pixel=Sa*GetPixelIntensity(source_image,p) > 1630e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Da*GetPixelIntensity(image,q) ? Sa : Da; 1631e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1632e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 163399abff36ae5d479bfd76652d166a4894ceada102cristy case ModulateCompositeOp: 163499abff36ae5d479bfd76652d166a4894ceada102cristy { 163599abff36ae5d479bfd76652d166a4894ceada102cristy pixel=QuantumRange*Da; 163699abff36ae5d479bfd76652d166a4894ceada102cristy break; 163799abff36ae5d479bfd76652d166a4894ceada102cristy } 1638e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy default: 1639e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1640e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=QuantumRange*alpha; 1641e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1642e10859aa31abb52913175e089e5d25cbd670499fcristy } 1643e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 164447c61c996128275174b8a120ab6a88a5c1bec3d3cristy q[i]=clamp != MagickFalse ? ClampPixel(pixel) : 164547c61c996128275174b8a120ab6a88a5c1bec3d3cristy ClampToQuantum(pixel); 1646e10859aa31abb52913175e089e5d25cbd670499fcristy continue; 1647e10859aa31abb52913175e089e5d25cbd670499fcristy } 1648e10859aa31abb52913175e089e5d25cbd670499fcristy /* 164999abff36ae5d479bfd76652d166a4894ceada102cristy Porter-Duff compositions: 165099abff36ae5d479bfd76652d166a4894ceada102cristy Sca: source normalized color multiplied by alpha. 1651e8e8eff5f2414d6096195a41934fc0edee9d9212cristy Dca: normalized canvas color multiplied by alpha. 1652e10859aa31abb52913175e089e5d25cbd670499fcristy */ 165399abff36ae5d479bfd76652d166a4894ceada102cristy Sca=QuantumScale*Sa*Sc; 165499abff36ae5d479bfd76652d166a4894ceada102cristy Dca=QuantumScale*Da*Dc; 1655e10859aa31abb52913175e089e5d25cbd670499fcristy switch (compose) 1656e10859aa31abb52913175e089e5d25cbd670499fcristy { 1657e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DarkenCompositeOp: 1658e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case LightenCompositeOp: 165999abff36ae5d479bfd76652d166a4894ceada102cristy case ModulusSubtractCompositeOp: 1660e10859aa31abb52913175e089e5d25cbd670499fcristy { 1661f0202bea5f6551326ceaf416ab0f748fe862f245cristy gamma=PerceptibleReciprocal(1.0-alpha); 16623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 1663e10859aa31abb52913175e089e5d25cbd670499fcristy } 1664e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy default: 16651749597845aafe5e61783d9a1b43d333f7071ccddirk { 1666f0202bea5f6551326ceaf416ab0f748fe862f245cristy gamma=PerceptibleReciprocal(alpha); 1667e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1668f0202bea5f6551326ceaf416ab0f748fe862f245cristy } 1669e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1670d197cbbbde474ea2cbdd56d0defa45f100e44cd0cristy pixel=Dc; 1671e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy switch (compose) 1672e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1673a7b079186ad7e0943fa65611a8978531bb612eeccristy case AlphaCompositeOp: 1674a7b079186ad7e0943fa65611a8978531bb612eeccristy { 1675a7b079186ad7e0943fa65611a8978531bb612eeccristy pixel=QuantumRange*Sa; 1676a7b079186ad7e0943fa65611a8978531bb612eeccristy break; 1677a7b079186ad7e0943fa65611a8978531bb612eeccristy } 1678e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case AtopCompositeOp: 1679e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case SrcAtopCompositeOp: 1680e10859aa31abb52913175e089e5d25cbd670499fcristy { 1681e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy pixel=QuantumRange*(Sca*Da+Dca*(1.0-Sa)); 16823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 1683e10859aa31abb52913175e089e5d25cbd670499fcristy } 1684e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case BlendCompositeOp: 1685e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1686e8e8eff5f2414d6096195a41934fc0edee9d9212cristy pixel=gamma*(source_dissolve*Sa*Sc+canvas_dissolve*Da*Dc); 1687e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1688e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1689e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case BlurCompositeOp: 1690e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case CopyCompositeOp: 1691e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ReplaceCompositeOp: 1692e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case SrcCompositeOp: 1693e10859aa31abb52913175e089e5d25cbd670499fcristy { 169430dac202caf1ded0e356ab1c2b67ec8d7929e06dcristy pixel=QuantumRange*Sca; 1695e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1696e10859aa31abb52913175e089e5d25cbd670499fcristy } 16978e028780f2ba885f17f75ec6927f6d59cc90f37fcristy case DisplaceCompositeOp: 16988e028780f2ba885f17f75ec6927f6d59cc90f37fcristy case DistortCompositeOp: 16998e028780f2ba885f17f75ec6927f6d59cc90f37fcristy { 17008e028780f2ba885f17f75ec6927f6d59cc90f37fcristy pixel=Sc; 17018e028780f2ba885f17f75ec6927f6d59cc90f37fcristy break; 17028e028780f2ba885f17f75ec6927f6d59cc90f37fcristy } 1703e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case BumpmapCompositeOp: 1704e10859aa31abb52913175e089e5d25cbd670499fcristy { 17053bdd925dbb0804df99e548c50667670319655816cristy if (fabs((double) (QuantumRange*Sa-TransparentAlpha)) < MagickEpsilon) 1706e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1707e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=Dc; 1708e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1709e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1710e8e8eff5f2414d6096195a41934fc0edee9d9212cristy pixel=QuantumScale*GetPixelIntensity(source_image,p)*Dc; 1711e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1712e10859aa31abb52913175e089e5d25cbd670499fcristy } 171399abff36ae5d479bfd76652d166a4894ceada102cristy case ChangeMaskCompositeOp: 171499abff36ae5d479bfd76652d166a4894ceada102cristy { 171599abff36ae5d479bfd76652d166a4894ceada102cristy pixel=Dc; 171699abff36ae5d479bfd76652d166a4894ceada102cristy break; 171799abff36ae5d479bfd76652d166a4894ceada102cristy } 171899abff36ae5d479bfd76652d166a4894ceada102cristy case ClearCompositeOp: 171999abff36ae5d479bfd76652d166a4894ceada102cristy { 172099abff36ae5d479bfd76652d166a4894ceada102cristy pixel=0.0; 172199abff36ae5d479bfd76652d166a4894ceada102cristy break; 172299abff36ae5d479bfd76652d166a4894ceada102cristy } 1723e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ColorBurnCompositeOp: 1724e10859aa31abb52913175e089e5d25cbd670499fcristy { 172530dac202caf1ded0e356ab1c2b67ec8d7929e06dcristy if ((Sca == 0.0) && (Dca == Da)) 1726e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 172795a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sa*Da+Dca*(1.0-Sa)); 1728e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1729e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 173030dac202caf1ded0e356ab1c2b67ec8d7929e06dcristy if (Sca == 0.0) 1731e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 173295a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Dca*(1.0-Sa)); 1733e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1734e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 173595a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sa*Da-Sa*Da*MagickMin(1.0,(1.0-Dca/Da)*Sa/ 173695a92efd222d2268b66bf4fbb3bd5167437ba466cristy Sca)+Sca*(1.0-Da)+Dca*(1.0-Sa)); 1737e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1738e10859aa31abb52913175e089e5d25cbd670499fcristy } 1739e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ColorDodgeCompositeOp: 1740e10859aa31abb52913175e089e5d25cbd670499fcristy { 17415379e0c0b6f55b8ac9f7c867b4234b6ec239545bdirk if ((Sca*Da+Dca*Sa) >= Sa*Da) 17425379e0c0b6f55b8ac9f7c867b4234b6ec239545bdirk pixel=QuantumRange*gamma*(Sa*Da+Sca*(1.0-Da)+Dca*(1.0-Sa)); 17435379e0c0b6f55b8ac9f7c867b4234b6ec239545bdirk else 174489bfadafcca84f2839410175c63192cb2dc59111Cristy pixel=QuantumRange*gamma*(Dca*Sa*Sa/(Sa-Sca)+Sca*(1.0-Da)+Dca* 174589bfadafcca84f2839410175c63192cb2dc59111Cristy (1.0-Sa)); 1746e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1747e10859aa31abb52913175e089e5d25cbd670499fcristy } 1748e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ColorizeCompositeOp: 1749e10859aa31abb52913175e089e5d25cbd670499fcristy { 17503bdd925dbb0804df99e548c50667670319655816cristy if (fabs((double) (QuantumRange*Sa-TransparentAlpha)) < MagickEpsilon) 1751e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1752e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=Dc; 1753e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1754e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 17553bdd925dbb0804df99e548c50667670319655816cristy if (fabs((double) (QuantumRange*Da-TransparentAlpha)) < MagickEpsilon) 1756e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1757e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=Sc; 1758e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1759e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 17602fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy CompositeHCL(canvas_pixel.red,canvas_pixel.green,canvas_pixel.blue, 17612fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy &sans,&sans,&luma); 17627133e649ea494c1286ff16bcb02342d660097219cristy CompositeHCL(source_pixel.red,source_pixel.green,source_pixel.blue, 17637133e649ea494c1286ff16bcb02342d660097219cristy &hue,&chroma,&sans); 17647133e649ea494c1286ff16bcb02342d660097219cristy HCLComposite(hue,chroma,luma,&red,&green,&blue); 1765e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy switch (channel) 1766e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1767e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case RedPixelChannel: pixel=red; break; 1768e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case GreenPixelChannel: pixel=green; break; 1769e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case BluePixelChannel: pixel=blue; break; 1770e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy default: pixel=Dc; break; 1771e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1772e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1773e10859aa31abb52913175e089e5d25cbd670499fcristy } 1774e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case CopyAlphaCompositeOp: 1775e10859aa31abb52913175e089e5d25cbd670499fcristy { 177624d5d722cf4ba0767eb0d790e1b228a518d737cfcristy pixel=Dc; 1777e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1778e10859aa31abb52913175e089e5d25cbd670499fcristy } 1779e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case CopyBlackCompositeOp: 1780e10859aa31abb52913175e089e5d25cbd670499fcristy { 1781d197cbbbde474ea2cbdd56d0defa45f100e44cd0cristy if (channel == BlackPixelChannel) 17822fda00b7affa23c29e86e8218b7e1c5fe7785705cristy pixel=(MagickRealType) (QuantumRange- 1783e8e8eff5f2414d6096195a41934fc0edee9d9212cristy GetPixelBlack(source_image,p)); 1784e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1785e10859aa31abb52913175e089e5d25cbd670499fcristy } 1786e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case CopyBlueCompositeOp: 1787e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case CopyYellowCompositeOp: 1788e10859aa31abb52913175e089e5d25cbd670499fcristy { 1789d197cbbbde474ea2cbdd56d0defa45f100e44cd0cristy if (channel == BluePixelChannel) 1790e8e8eff5f2414d6096195a41934fc0edee9d9212cristy pixel=(MagickRealType) GetPixelBlue(source_image,p); 1791e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1792e10859aa31abb52913175e089e5d25cbd670499fcristy } 1793e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case CopyGreenCompositeOp: 1794e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case CopyMagentaCompositeOp: 1795e10859aa31abb52913175e089e5d25cbd670499fcristy { 1796d197cbbbde474ea2cbdd56d0defa45f100e44cd0cristy if (channel == GreenPixelChannel) 1797e8e8eff5f2414d6096195a41934fc0edee9d9212cristy pixel=(MagickRealType) GetPixelGreen(source_image,p); 1798e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1799e10859aa31abb52913175e089e5d25cbd670499fcristy } 1800e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case CopyRedCompositeOp: 1801e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case CopyCyanCompositeOp: 1802e10859aa31abb52913175e089e5d25cbd670499fcristy { 1803d197cbbbde474ea2cbdd56d0defa45f100e44cd0cristy if (channel == RedPixelChannel) 1804e8e8eff5f2414d6096195a41934fc0edee9d9212cristy pixel=(MagickRealType) GetPixelRed(source_image,p); 1805e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1806e10859aa31abb52913175e089e5d25cbd670499fcristy } 180799abff36ae5d479bfd76652d166a4894ceada102cristy case DarkenCompositeOp: 180899abff36ae5d479bfd76652d166a4894ceada102cristy { 180999abff36ae5d479bfd76652d166a4894ceada102cristy /* 181099abff36ae5d479bfd76652d166a4894ceada102cristy Darken is equivalent to a 'Minimum' method 181199abff36ae5d479bfd76652d166a4894ceada102cristy OR a greyscale version of a binary 'Or' 181299abff36ae5d479bfd76652d166a4894ceada102cristy OR the 'Intersection' of pixel sets. 181399abff36ae5d479bfd76652d166a4894ceada102cristy */ 181430dac202caf1ded0e356ab1c2b67ec8d7929e06dcristy if ((Sca*Da) < (Dca*Sa)) 181599abff36ae5d479bfd76652d166a4894ceada102cristy { 1816e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy pixel=QuantumRange*(Sca+Dca*(1.0-Sa)); 181799abff36ae5d479bfd76652d166a4894ceada102cristy break; 181899abff36ae5d479bfd76652d166a4894ceada102cristy } 1819e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy pixel=QuantumRange*(Dca+Sca*(1.0-Da)); 182099abff36ae5d479bfd76652d166a4894ceada102cristy break; 182199abff36ae5d479bfd76652d166a4894ceada102cristy } 1822e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DarkenIntensityCompositeOp: 1823e10859aa31abb52913175e089e5d25cbd670499fcristy { 1824e8e8eff5f2414d6096195a41934fc0edee9d9212cristy pixel=Sa*GetPixelIntensity(source_image,p) < 1825076d0c9a787cf3054f29089d5bced8b08b606b94cristy Da*GetPixelIntensity(image,q) ? Sc : Dc; 1826e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1827e10859aa31abb52913175e089e5d25cbd670499fcristy } 1828e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DifferenceCompositeOp: 1829e10859aa31abb52913175e089e5d25cbd670499fcristy { 183095a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sca+Dca-2.0*MagickMin(Sca*Da,Dca*Sa)); 1831e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1832e10859aa31abb52913175e089e5d25cbd670499fcristy } 1833e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DissolveCompositeOp: 1834e10859aa31abb52913175e089e5d25cbd670499fcristy { 1835e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=gamma*(source_dissolve*Sa*Sc-source_dissolve*Sa* 1836e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_dissolve*Da*Dc+canvas_dissolve*Da*Dc); 1837e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1838e10859aa31abb52913175e089e5d25cbd670499fcristy } 1839e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DivideDstCompositeOp: 1840e10859aa31abb52913175e089e5d25cbd670499fcristy { 18413bdd925dbb0804df99e548c50667670319655816cristy if ((fabs((double) Sca) < MagickEpsilon) && 18423bdd925dbb0804df99e548c50667670319655816cristy (fabs((double) Dca) < MagickEpsilon)) 1843e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 184495a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sca*(1.0-Da)+Dca*(1.0-Sa)); 1845e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1846e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 18473bdd925dbb0804df99e548c50667670319655816cristy if (fabs((double) Dca) < MagickEpsilon) 1848e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 184995a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sa*Da+Sca*(1.0-Da)+Dca*(1.0-Sa)); 1850e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1851e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 185295a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sca*Da*Da/Dca+Sca*(1.0-Da)+Dca*(1.0-Sa)); 1853e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1854e10859aa31abb52913175e089e5d25cbd670499fcristy } 1855e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DivideSrcCompositeOp: 1856e10859aa31abb52913175e089e5d25cbd670499fcristy { 18573bdd925dbb0804df99e548c50667670319655816cristy if ((fabs((double) Dca) < MagickEpsilon) && 18583bdd925dbb0804df99e548c50667670319655816cristy (fabs((double) Sca) < MagickEpsilon)) 1859e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 186095a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Dca*(1.0-Sa)+Sca*(1.0-Da)); 1861e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1862e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 18633bdd925dbb0804df99e548c50667670319655816cristy if (fabs((double) Sca) < MagickEpsilon) 1864e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 186595a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Da*Sa+Dca*(1.0-Sa)+Sca*(1.0-Da)); 1866e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1867e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 186895a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Dca*Sa*Sa/Sca+Dca*(1.0-Sa)+Sca*(1.0-Da)); 1869e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1870e10859aa31abb52913175e089e5d25cbd670499fcristy } 1871e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DstAtopCompositeOp: 1872e10859aa31abb52913175e089e5d25cbd670499fcristy { 1873e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy pixel=QuantumRange*(Dca*Sa+Sca*(1.0-Da)); 1874e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1875e10859aa31abb52913175e089e5d25cbd670499fcristy } 1876e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DstCompositeOp: 1877e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case NoCompositeOp: 1878e10859aa31abb52913175e089e5d25cbd670499fcristy { 187930dac202caf1ded0e356ab1c2b67ec8d7929e06dcristy pixel=QuantumRange*Dca; 1880e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1881e10859aa31abb52913175e089e5d25cbd670499fcristy } 1882e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DstInCompositeOp: 1883e10859aa31abb52913175e089e5d25cbd670499fcristy { 1884e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy pixel=QuantumRange*(Dca*Sa); 1885e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1886e10859aa31abb52913175e089e5d25cbd670499fcristy } 1887e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DstOutCompositeOp: 1888e10859aa31abb52913175e089e5d25cbd670499fcristy { 1889e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy pixel=QuantumRange*(Dca*(1.0-Sa)); 1890e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1891e10859aa31abb52913175e089e5d25cbd670499fcristy } 1892e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case DstOverCompositeOp: 1893e10859aa31abb52913175e089e5d25cbd670499fcristy { 189495a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Dca+Sca*(1.0-Da)); 1895e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1896e10859aa31abb52913175e089e5d25cbd670499fcristy } 1897e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ExclusionCompositeOp: 1898e10859aa31abb52913175e089e5d25cbd670499fcristy { 189995a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sca*Da+Dca*Sa-2.0*Sca*Dca+Sca*(1.0-Da)+ 190095a92efd222d2268b66bf4fbb3bd5167437ba466cristy Dca*(1.0-Sa)); 1901e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1902e10859aa31abb52913175e089e5d25cbd670499fcristy } 1903e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case HardLightCompositeOp: 1904e10859aa31abb52913175e089e5d25cbd670499fcristy { 1905e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if ((2.0*Sca) < Sa) 1906e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 190795a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(2.0*Sca*Dca+Sca*(1.0-Da)+Dca*(1.0- 190895a92efd222d2268b66bf4fbb3bd5167437ba466cristy Sa)); 1909e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1910e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 191195a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sa*Da-2.0*(Da-Dca)*(Sa-Sca)+Sca*(1.0-Da)+ 191295a92efd222d2268b66bf4fbb3bd5167437ba466cristy Dca*(1.0-Sa)); 191399fc217dffe2ed10ebefd0ac85900df37b60e3fdcristy break; 191499fc217dffe2ed10ebefd0ac85900df37b60e3fdcristy } 191599fc217dffe2ed10ebefd0ac85900df37b60e3fdcristy case HardMixCompositeOp: 191699fc217dffe2ed10ebefd0ac85900df37b60e3fdcristy { 19171749597845aafe5e61783d9a1b43d333f7071ccddirk pixel=gamma*(((Sca+Dca) < 1.0) ? 0.0 : QuantumRange); 1918e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1919e10859aa31abb52913175e089e5d25cbd670499fcristy } 1920e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case HueCompositeOp: 1921e10859aa31abb52913175e089e5d25cbd670499fcristy { 19223bdd925dbb0804df99e548c50667670319655816cristy if (fabs((double) (QuantumRange*Sa-TransparentAlpha)) < MagickEpsilon) 1923e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1924e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=Dc; 1925e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1926e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 19273bdd925dbb0804df99e548c50667670319655816cristy if (fabs((double) (QuantumRange*Da-TransparentAlpha)) < MagickEpsilon) 1928e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1929e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=Sc; 1930e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1931e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 19322fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy CompositeHCL(canvas_pixel.red,canvas_pixel.green,canvas_pixel.blue, 19332fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy &hue,&chroma,&luma); 19347133e649ea494c1286ff16bcb02342d660097219cristy CompositeHCL(source_pixel.red,source_pixel.green,source_pixel.blue, 1935e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy &hue,&sans,&sans); 19367133e649ea494c1286ff16bcb02342d660097219cristy HCLComposite(hue,chroma,luma,&red,&green,&blue); 1937e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy switch (channel) 1938e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1939e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case RedPixelChannel: pixel=red; break; 1940e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case GreenPixelChannel: pixel=green; break; 1941e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case BluePixelChannel: pixel=blue; break; 1942e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy default: pixel=Dc; break; 1943e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1944e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1945e10859aa31abb52913175e089e5d25cbd670499fcristy } 1946e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case InCompositeOp: 1947e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case SrcInCompositeOp: 1948e10859aa31abb52913175e089e5d25cbd670499fcristy { 1949e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy pixel=QuantumRange*(Sca*Da); 1950e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1951e10859aa31abb52913175e089e5d25cbd670499fcristy } 1952e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case LinearBurnCompositeOp: 1953e10859aa31abb52913175e089e5d25cbd670499fcristy { 1954e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy /* 1955e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy LinearBurn: as defined by Abode Photoshop, according to 1956e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy http://www.simplefilter.de/en/basics/mixmods.html is: 1957e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 1958e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy f(Sc,Dc) = Sc + Dc - 1 1959e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy */ 196095a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sca+Dca-Sa*Da); 1961e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1962e10859aa31abb52913175e089e5d25cbd670499fcristy } 1963e10859aa31abb52913175e089e5d25cbd670499fcristy case LinearDodgeCompositeOp: 1964e10859aa31abb52913175e089e5d25cbd670499fcristy { 196595a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=gamma*(Sa*Sc+Da*Dc); 1966e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1967e10859aa31abb52913175e089e5d25cbd670499fcristy } 1968e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case LinearLightCompositeOp: 1969e10859aa31abb52913175e089e5d25cbd670499fcristy { 1970e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy /* 1971e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy LinearLight: as defined by Abode Photoshop, according to 1972e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy http://www.simplefilter.de/en/basics/mixmods.html is: 1973e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 1974e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy f(Sc,Dc) = Dc + 2*Sc - 1 1975e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy */ 197695a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*((Sca-Sa)*Da+Sca+Dca); 1977e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1978e10859aa31abb52913175e089e5d25cbd670499fcristy } 1979e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case LightenCompositeOp: 1980e10859aa31abb52913175e089e5d25cbd670499fcristy { 198130dac202caf1ded0e356ab1c2b67ec8d7929e06dcristy if ((Sca*Da) > (Dca*Sa)) 1982e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 1983e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy pixel=QuantumRange*(Sca+Dca*(1.0-Sa)); 1984e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 1985e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 1986e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy pixel=QuantumRange*(Dca+Sca*(1.0-Da)); 198799abff36ae5d479bfd76652d166a4894ceada102cristy break; 198899abff36ae5d479bfd76652d166a4894ceada102cristy } 198999abff36ae5d479bfd76652d166a4894ceada102cristy case LightenIntensityCompositeOp: 199099abff36ae5d479bfd76652d166a4894ceada102cristy { 199199abff36ae5d479bfd76652d166a4894ceada102cristy /* 199299abff36ae5d479bfd76652d166a4894ceada102cristy Lighten is equivalent to a 'Maximum' method 199399abff36ae5d479bfd76652d166a4894ceada102cristy OR a greyscale version of a binary 'And' 199499abff36ae5d479bfd76652d166a4894ceada102cristy OR the 'Union' of pixel sets. 199599abff36ae5d479bfd76652d166a4894ceada102cristy */ 1996e8e8eff5f2414d6096195a41934fc0edee9d9212cristy pixel=Sa*GetPixelIntensity(source_image,p) > 199799abff36ae5d479bfd76652d166a4894ceada102cristy Da*GetPixelIntensity(image,q) ? Sc : Dc; 1998e10859aa31abb52913175e089e5d25cbd670499fcristy break; 1999e10859aa31abb52913175e089e5d25cbd670499fcristy } 2000e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case LuminizeCompositeOp: 2001e10859aa31abb52913175e089e5d25cbd670499fcristy { 20023bdd925dbb0804df99e548c50667670319655816cristy if (fabs((double) (QuantumRange*Sa-TransparentAlpha)) < MagickEpsilon) 2003e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 2004e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=Dc; 2005e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 2006e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 20073bdd925dbb0804df99e548c50667670319655816cristy if (fabs((double) (QuantumRange*Da-TransparentAlpha)) < MagickEpsilon) 2008e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 2009e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=Sc; 2010e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 2011e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 20122fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy CompositeHCL(canvas_pixel.red,canvas_pixel.green,canvas_pixel.blue, 20132fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy &hue,&chroma,&luma); 20147133e649ea494c1286ff16bcb02342d660097219cristy CompositeHCL(source_pixel.red,source_pixel.green,source_pixel.blue, 20157133e649ea494c1286ff16bcb02342d660097219cristy &sans,&sans,&luma); 20167133e649ea494c1286ff16bcb02342d660097219cristy HCLComposite(hue,chroma,luma,&red,&green,&blue); 2017e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy switch (channel) 2018e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 2019e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case RedPixelChannel: pixel=red; break; 2020e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case GreenPixelChannel: pixel=green; break; 2021e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case BluePixelChannel: pixel=blue; break; 2022e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy default: pixel=Dc; break; 2023e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 2024e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2025e10859aa31abb52913175e089e5d25cbd670499fcristy } 2026e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case MathematicsCompositeOp: 2027e10859aa31abb52913175e089e5d25cbd670499fcristy { 2028e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy /* 2029e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 'Mathematics' a free form user control mathematical composition 2030e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy is defined as... 2031e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 2032e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy f(Sc,Dc) = A*Sc*Dc + B*Sc + C*Dc + D 2033e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 2034e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Where the arguments A,B,C,D are (currently) passed to composite 2035e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy as a command separated 'geometry' string in "compose:args" image 2036e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy artifact. 2037e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 2038e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy A = a->rho, B = a->sigma, C = a->xi, D = a->psi 2039e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 2040e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Applying the SVG transparency formula (see above), we get... 2041e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 2042e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Dca' = Sa*Da*f(Sc,Dc) + Sca*(1.0-Da) + Dca*(1.0-Sa) 2043e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 2044e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Dca' = A*Sca*Dca + B*Sca*Da + C*Dca*Sa + D*Sa*Da + Sca*(1.0-Da) + 2045e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Dca*(1.0-Sa) 2046e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy */ 204793af61fba92ced57cbbb2b13ff1a026c9bb1e1cdcristy pixel=QuantumRange*gamma*(geometry_info.rho*Sca*Dca+ 2048744051e2f5398cc1a8f6c1154f4c419dcf996a3dcristy geometry_info.sigma*Sca*Da+geometry_info.xi*Dca*Sa+ 2049744051e2f5398cc1a8f6c1154f4c419dcf996a3dcristy geometry_info.psi*Sa*Da+Sca*(1.0-Da)+Dca*(1.0-Sa)); 2050e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2051e10859aa31abb52913175e089e5d25cbd670499fcristy } 2052e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case MinusDstCompositeOp: 2053e10859aa31abb52913175e089e5d25cbd670499fcristy { 2054ecf950212ff9019e8778789d0f83722b320c6519cristy pixel=gamma*(Sa*Sc+Da*Dc-2.0*Da*Dc*Sa); 2055e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2056e10859aa31abb52913175e089e5d25cbd670499fcristy } 2057e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case MinusSrcCompositeOp: 2058e10859aa31abb52913175e089e5d25cbd670499fcristy { 2059e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy /* 2060e8e8eff5f2414d6096195a41934fc0edee9d9212cristy Minus source from canvas. 2061e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 2062e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy f(Sc,Dc) = Sc - Dc 2063e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy */ 2064ecf950212ff9019e8778789d0f83722b320c6519cristy pixel=gamma*(Da*Dc+Sa*Sc-2.0*Sa*Sc*Da); 2065e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2066e10859aa31abb52913175e089e5d25cbd670499fcristy } 2067e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ModulateCompositeOp: 2068e10859aa31abb52913175e089e5d25cbd670499fcristy { 2069e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy ssize_t 2070e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy offset; 2071e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 20723bdd925dbb0804df99e548c50667670319655816cristy if (fabs((double) (QuantumRange*Sa-TransparentAlpha)) < MagickEpsilon) 2073e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 2074e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=Dc; 2075e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 2076e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 2077e8e8eff5f2414d6096195a41934fc0edee9d9212cristy offset=(ssize_t) (GetPixelIntensity(source_image,p)-midpoint); 2078e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (offset == 0) 2079e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 2080e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=Dc; 2081e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 2082e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 20832fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy CompositeHCL(canvas_pixel.red,canvas_pixel.green,canvas_pixel.blue, 20842fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy &hue,&chroma,&luma); 20857133e649ea494c1286ff16bcb02342d660097219cristy luma+=(0.01*percent_luma*offset)/midpoint; 20867133e649ea494c1286ff16bcb02342d660097219cristy chroma*=0.01*percent_chroma; 20877133e649ea494c1286ff16bcb02342d660097219cristy HCLComposite(hue,chroma,luma,&red,&green,&blue); 2088e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy switch (channel) 2089e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 2090e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case RedPixelChannel: pixel=red; break; 2091e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case GreenPixelChannel: pixel=green; break; 2092e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case BluePixelChannel: pixel=blue; break; 2093e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy default: pixel=Dc; break; 2094e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 2095e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2096e10859aa31abb52913175e089e5d25cbd670499fcristy } 2097e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ModulusAddCompositeOp: 2098e10859aa31abb52913175e089e5d25cbd670499fcristy { 2099e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=Sc+Dc; 2100b0c753681b67213741db6355930bf4a6881170dfCristy while (pixel > QuantumRange) 2101516edc171c30bf475761914bcc3db3a6e298e103cristy pixel-=QuantumRange; 2102b0c753681b67213741db6355930bf4a6881170dfCristy while (pixel < 0.0) 2103b0c753681b67213741db6355930bf4a6881170dfCristy pixel+=QuantumRange; 21047a91a5e606a33d0624d750e50a04b6fa9b995199cristy pixel=(Sa*Da*pixel+Sa*Sc*(1.0-Da)+Da*Dc*(1.0-Sa)); 2105e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2106e10859aa31abb52913175e089e5d25cbd670499fcristy } 2107e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ModulusSubtractCompositeOp: 2108e10859aa31abb52913175e089e5d25cbd670499fcristy { 210999abff36ae5d479bfd76652d166a4894ceada102cristy pixel=Sc-Dc; 2110b0c753681b67213741db6355930bf4a6881170dfCristy while (pixel > QuantumRange) 2111b0c753681b67213741db6355930bf4a6881170dfCristy pixel-=QuantumRange; 2112b0c753681b67213741db6355930bf4a6881170dfCristy while (pixel < 0.0) 2113516edc171c30bf475761914bcc3db3a6e298e103cristy pixel+=QuantumRange; 21147a91a5e606a33d0624d750e50a04b6fa9b995199cristy pixel=(Sa*Da*pixel+Sa*Sc*(1.0-Da)+Da*Dc*(1.0-Sa)); 2115e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2116e10859aa31abb52913175e089e5d25cbd670499fcristy } 2117e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case MultiplyCompositeOp: 2118e10859aa31abb52913175e089e5d25cbd670499fcristy { 211995a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sca*Dca+Sca*(1.0-Da)+Dca*(1.0-Sa)); 21203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 2121e10859aa31abb52913175e089e5d25cbd670499fcristy } 2122e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case OutCompositeOp: 2123e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case SrcOutCompositeOp: 2124e10859aa31abb52913175e089e5d25cbd670499fcristy { 2125e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy pixel=QuantumRange*(Sca*(1.0-Da)); 2126e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2127e10859aa31abb52913175e089e5d25cbd670499fcristy } 2128e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case OverCompositeOp: 2129e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case SrcOverCompositeOp: 2130e10859aa31abb52913175e089e5d25cbd670499fcristy { 213195a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sca+Dca*(1.0-Sa)); 2132e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2133e10859aa31abb52913175e089e5d25cbd670499fcristy } 2134e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case OverlayCompositeOp: 2135e10859aa31abb52913175e089e5d25cbd670499fcristy { 21360bd8cb4808b9ff3811fc4a73cae38e061f8a96ffdirk if ((2.0*Dca) < Da) 213799abff36ae5d479bfd76652d166a4894ceada102cristy { 21380bd8cb4808b9ff3811fc4a73cae38e061f8a96ffdirk pixel=QuantumRange*gamma*(2.0*Dca*Sca+Dca*(1.0-Sa)+Sca*(1.0- 21390bd8cb4808b9ff3811fc4a73cae38e061f8a96ffdirk Da)); 214099abff36ae5d479bfd76652d166a4894ceada102cristy break; 214199abff36ae5d479bfd76652d166a4894ceada102cristy } 21420bd8cb4808b9ff3811fc4a73cae38e061f8a96ffdirk pixel=QuantumRange*gamma*(Da*Sa-2.0*(Sa-Sca)*(Da-Dca)+Dca*(1.0-Sa)+ 21430bd8cb4808b9ff3811fc4a73cae38e061f8a96ffdirk Sca*(1.0-Da)); 2144e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2145e10859aa31abb52913175e089e5d25cbd670499fcristy } 2146e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case PegtopLightCompositeOp: 2147e10859aa31abb52913175e089e5d25cbd670499fcristy { 2148e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy /* 2149e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy PegTop: A Soft-Light alternative: A continuous version of the 2150e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Softlight function, producing very similar results. 2151e10859aa31abb52913175e089e5d25cbd670499fcristy 2152e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy f(Sc,Dc) = Dc^2*(1-2*Sc) + 2*Sc*Dc 2153e10859aa31abb52913175e089e5d25cbd670499fcristy 2154e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy http://www.pegtop.net/delphi/articles/blendmodes/softlight.htm. 2155e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy */ 21563bdd925dbb0804df99e548c50667670319655816cristy if (fabs((double) Da) < MagickEpsilon) 2157e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 215895a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sca); 2159e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 2160e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 216195a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Dca*Dca*(Sa-2.0*Sca)/Da+Sca*(2.0*Dca+1.0- 216295a92efd222d2268b66bf4fbb3bd5167437ba466cristy Da)+Dca*(1.0-Sa)); 21633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 2164e10859aa31abb52913175e089e5d25cbd670499fcristy } 2165e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case PinLightCompositeOp: 2166e10859aa31abb52913175e089e5d25cbd670499fcristy { 2167e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy /* 2168e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy PinLight: A Photoshop 7 composition method 2169e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy http://www.simplefilter.de/en/basics/mixmods.html 2170e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 2171e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy f(Sc,Dc) = Dc<2*Sc-1 ? 2*Sc-1 : Dc>2*Sc ? 2*Sc : Dc 2172e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy */ 2173e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if ((Dca*Sa) < (Da*(2.0*Sca-Sa))) 2174e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 217595a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sca*(Da+1.0)-Sa*Da+Dca*(1.0-Sa)); 2176e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 2177e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 2178e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if ((Dca*Sa) > (2.0*Sca*Da)) 2179e10859aa31abb52913175e089e5d25cbd670499fcristy { 218095a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sca*Da+Sca+Dca*(1.0-Sa)); 2181e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2182e10859aa31abb52913175e089e5d25cbd670499fcristy } 218395a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sca*(1.0-Da)+Dca); 2184e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 2185e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 2186e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case PlusCompositeOp: 2187e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 2188e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy pixel=QuantumRange*(Sca+Dca); 21893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 2190e10859aa31abb52913175e089e5d25cbd670499fcristy } 2191e10859aa31abb52913175e089e5d25cbd670499fcristy case SaturateCompositeOp: 2192e10859aa31abb52913175e089e5d25cbd670499fcristy { 21933bdd925dbb0804df99e548c50667670319655816cristy if (fabs((double) (QuantumRange*Sa-TransparentAlpha)) < MagickEpsilon) 2194e10859aa31abb52913175e089e5d25cbd670499fcristy { 2195e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=Dc; 2196e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2197e10859aa31abb52913175e089e5d25cbd670499fcristy } 21983bdd925dbb0804df99e548c50667670319655816cristy if (fabs((double) (QuantumRange*Da-TransparentAlpha)) < MagickEpsilon) 2199e10859aa31abb52913175e089e5d25cbd670499fcristy { 2200e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=Sc; 2201e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2202e10859aa31abb52913175e089e5d25cbd670499fcristy } 22032fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy CompositeHCL(canvas_pixel.red,canvas_pixel.green,canvas_pixel.blue, 22042fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy &hue,&chroma,&luma); 22057133e649ea494c1286ff16bcb02342d660097219cristy CompositeHCL(source_pixel.red,source_pixel.green,source_pixel.blue, 22067133e649ea494c1286ff16bcb02342d660097219cristy &sans,&chroma,&sans); 22077133e649ea494c1286ff16bcb02342d660097219cristy HCLComposite(hue,chroma,luma,&red,&green,&blue); 2208e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy switch (channel) 2209e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 2210e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case RedPixelChannel: pixel=red; break; 2211e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case GreenPixelChannel: pixel=green; break; 2212e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case BluePixelChannel: pixel=blue; break; 2213e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy default: pixel=Dc; break; 2214e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 2215e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2216e10859aa31abb52913175e089e5d25cbd670499fcristy } 2217e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ScreenCompositeOp: 2218e10859aa31abb52913175e089e5d25cbd670499fcristy { 2219e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy /* 2220e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy Screen: a negated multiply: 2221e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 2222e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy f(Sc,Dc) = 1.0-(1.0-Sc)*(1.0-Dc) 2223e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy */ 222495a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sca+Dca-Sca*Dca); 2225e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2226e10859aa31abb52913175e089e5d25cbd670499fcristy } 2227e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case SoftLightCompositeOp: 2228e10859aa31abb52913175e089e5d25cbd670499fcristy { 2229e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if ((2.0*Sca) < Sa) 2230e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 223195a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Dca*(Sa+(2.0*Sca-Sa)*(1.0-(Dca/Da)))+ 223295a92efd222d2268b66bf4fbb3bd5167437ba466cristy Sca*(1.0-Da)+Dca*(1.0-Sa)); 2233e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 2234e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 2235e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if (((2.0*Sca) > Sa) && ((4.0*Dca) <= Da)) 2236e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 223795a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Dca*Sa+Da*(2.0*Sca-Sa)*(4.0*(Dca/Da)* 223895a92efd222d2268b66bf4fbb3bd5167437ba466cristy (4.0*(Dca/Da)+1.0)*((Dca/Da)-1.0)+7.0*(Dca/Da))+Sca*(1.0-Da)+ 223995a92efd222d2268b66bf4fbb3bd5167437ba466cristy Dca*(1.0-Sa)); 2240e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 2241e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 224295a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Dca*Sa+Da*(2.0*Sca-Sa)*(pow((Dca/Da),0.5)- 224395a92efd222d2268b66bf4fbb3bd5167437ba466cristy (Dca/Da))+Sca*(1.0-Da)+Dca*(1.0-Sa)); 2244e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2245e10859aa31abb52913175e089e5d25cbd670499fcristy } 2246e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case ThresholdCompositeOp: 2247e10859aa31abb52913175e089e5d25cbd670499fcristy { 22487159f66759ae05f052aad309915b9784f7aca927cristy MagickRealType 2249e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy delta; 2250e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 2251e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy delta=Sc-Dc; 22527159f66759ae05f052aad309915b9784f7aca927cristy if ((MagickRealType) fabs((double) (2.0*delta)) < threshold) 2253e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 2254e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=gamma*Dc; 2255e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 2256e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 2257e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=gamma*(Dc+delta*amount); 2258e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2259e10859aa31abb52913175e089e5d25cbd670499fcristy } 2260e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case VividLightCompositeOp: 2261e10859aa31abb52913175e089e5d25cbd670499fcristy { 2262e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy /* 2263e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy VividLight: A Photoshop 7 composition method. See 2264e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy http://www.simplefilter.de/en/basics/mixmods.html. 2265e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy 2266e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy f(Sc,Dc) = (2*Sc < 1) ? 1-(1-Dc)/(2*Sc) : Dc/(2*(1-Sc)) 2267e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy */ 22683bdd925dbb0804df99e548c50667670319655816cristy if ((fabs((double) Sa) < MagickEpsilon) || 22693bdd925dbb0804df99e548c50667670319655816cristy (fabs((double) (Sca-Sa)) < MagickEpsilon)) 2270e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy { 227195a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sa*Da+Sca*(1.0-Da)+Dca*(1.0-Sa)); 2272e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy break; 2273e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy } 2274e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy if ((2.0*Sca) <= Sa) 2275e10859aa31abb52913175e089e5d25cbd670499fcristy { 227695a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Sa*(Da+Sa*(Dca-Da)/(2.0*Sca))+Sca* 227795a92efd222d2268b66bf4fbb3bd5167437ba466cristy (1.0-Da)+Dca*(1.0-Sa)); 2278e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2279e10859aa31abb52913175e089e5d25cbd670499fcristy } 228095a92efd222d2268b66bf4fbb3bd5167437ba466cristy pixel=QuantumRange*gamma*(Dca*Sa*Sa/(2.0*(Sa-Sca))+Sca*(1.0-Da)+Dca* 2281e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy (1.0-Sa)); 2282e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2283e10859aa31abb52913175e089e5d25cbd670499fcristy } 2284e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy case XorCompositeOp: 2285e10859aa31abb52913175e089e5d25cbd670499fcristy { 2286e224ed7f0f18bb06d91c18aea7919de623fbd8b3cristy pixel=QuantumRange*(Sca*(1.0-Da)+Dca*(1.0-Sa)); 2287e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2288e10859aa31abb52913175e089e5d25cbd670499fcristy } 2289e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy default: 2290e10859aa31abb52913175e089e5d25cbd670499fcristy { 2291e4a404711bf20d9062d11ab28bc12e5acd307f9ccristy pixel=Sc; 2292e10859aa31abb52913175e089e5d25cbd670499fcristy break; 2293e10859aa31abb52913175e089e5d25cbd670499fcristy } 2294c5d68fe2846b7ed7b866c8a5d9287264d75458caanthony } 229547c61c996128275174b8a120ab6a88a5c1bec3d3cristy q[i]=clamp != MagickFalse ? ClampPixel(pixel) : ClampToQuantum(pixel); 22963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 2297e8e8eff5f2414d6096195a41934fc0edee9d9212cristy p+=GetPixelChannels(source_image); 2298e8e8eff5f2414d6096195a41934fc0edee9d9212cristy channels=GetPixelChannels(source_image); 2299e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if (p >= (pixels+channels*source_image->columns)) 23003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p=pixels; 2301ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy q+=GetPixelChannels(image); 23023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 23033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) 23043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=MagickFalse; 23053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->progress_monitor != (MagickProgressMonitor) NULL) 23063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 23073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 23083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy proceed; 23093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2310b5d5f725fef80ff5d50db3111c05a1a521b81e7fcristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 2311bd0435bb0fa5e2e20ec8d3c5288a5edc44aba9a0cristy #pragma omp critical (MagickCore_CompositeImage) 23123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 23133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy proceed=SetImageProgress(image,CompositeImageTag,progress++, 23143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->rows); 23153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (proceed == MagickFalse) 23163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=MagickFalse; 23173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 23183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 2319e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_view=DestroyCacheView(source_view); 23203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image_view=DestroyCacheView(image_view); 2321e8e8eff5f2414d6096195a41934fc0edee9d9212cristy if (canvas_image != (Image * ) NULL) 2322e8e8eff5f2414d6096195a41934fc0edee9d9212cristy canvas_image=DestroyImage(canvas_image); 2323f661c4d04693ffdf83b5a8a300a9ac4a38a9c762cristy else 2324e8e8eff5f2414d6096195a41934fc0edee9d9212cristy source_image=DestroyImage(source_image); 23253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 23263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2327316d51773c093e74e15de805e8bf620d6b56bc8bcristy 2328316d51773c093e74e15de805e8bf620d6b56bc8bcristy/* 2329316d51773c093e74e15de805e8bf620d6b56bc8bcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2330316d51773c093e74e15de805e8bf620d6b56bc8bcristy% % 2331316d51773c093e74e15de805e8bf620d6b56bc8bcristy% % 2332316d51773c093e74e15de805e8bf620d6b56bc8bcristy% % 2333316d51773c093e74e15de805e8bf620d6b56bc8bcristy% T e x t u r e I m a g e % 2334316d51773c093e74e15de805e8bf620d6b56bc8bcristy% % 2335316d51773c093e74e15de805e8bf620d6b56bc8bcristy% % 2336316d51773c093e74e15de805e8bf620d6b56bc8bcristy% % 2337316d51773c093e74e15de805e8bf620d6b56bc8bcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2338316d51773c093e74e15de805e8bf620d6b56bc8bcristy% 2339316d51773c093e74e15de805e8bf620d6b56bc8bcristy% TextureImage() repeatedly tiles the texture image across and down the image 2340316d51773c093e74e15de805e8bf620d6b56bc8bcristy% canvas. 2341316d51773c093e74e15de805e8bf620d6b56bc8bcristy% 2342316d51773c093e74e15de805e8bf620d6b56bc8bcristy% The format of the TextureImage method is: 2343316d51773c093e74e15de805e8bf620d6b56bc8bcristy% 234430d8c94aa45a8a386d4ce3b3340ddfed3aa2421ecristy% MagickBooleanType TextureImage(Image *image,const Image *texture, 2345e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy% ExceptionInfo *exception) 2346316d51773c093e74e15de805e8bf620d6b56bc8bcristy% 2347316d51773c093e74e15de805e8bf620d6b56bc8bcristy% A description of each parameter follows: 2348316d51773c093e74e15de805e8bf620d6b56bc8bcristy% 2349316d51773c093e74e15de805e8bf620d6b56bc8bcristy% o image: the image. 2350316d51773c093e74e15de805e8bf620d6b56bc8bcristy% 2351e6178503e4d6d3260666d42080d6f02545413685cristy% o texture_image: This image is the texture to layer on the background. 2352316d51773c093e74e15de805e8bf620d6b56bc8bcristy% 2353316d51773c093e74e15de805e8bf620d6b56bc8bcristy*/ 235430d8c94aa45a8a386d4ce3b3340ddfed3aa2421ecristyMagickExport MagickBooleanType TextureImage(Image *image,const Image *texture, 235530d8c94aa45a8a386d4ce3b3340ddfed3aa2421ecristy ExceptionInfo *exception) 2356316d51773c093e74e15de805e8bf620d6b56bc8bcristy{ 2357316d51773c093e74e15de805e8bf620d6b56bc8bcristy#define TextureImageTag "Texture/Image" 2358316d51773c093e74e15de805e8bf620d6b56bc8bcristy 2359fcb1a668b974425a0378c278db25aca29ec70894cristy CacheView 2360fcb1a668b974425a0378c278db25aca29ec70894cristy *image_view, 2361fcb1a668b974425a0378c278db25aca29ec70894cristy *texture_view; 2362fcb1a668b974425a0378c278db25aca29ec70894cristy 236330d8c94aa45a8a386d4ce3b3340ddfed3aa2421ecristy Image 236430d8c94aa45a8a386d4ce3b3340ddfed3aa2421ecristy *texture_image; 236530d8c94aa45a8a386d4ce3b3340ddfed3aa2421ecristy 2366fcb1a668b974425a0378c278db25aca29ec70894cristy MagickBooleanType 2367316d51773c093e74e15de805e8bf620d6b56bc8bcristy status; 2368316d51773c093e74e15de805e8bf620d6b56bc8bcristy 23699d314ff2c17a77996c05413c2013880387e50f0ecristy ssize_t 23709d314ff2c17a77996c05413c2013880387e50f0ecristy y; 23719d314ff2c17a77996c05413c2013880387e50f0ecristy 2372316d51773c093e74e15de805e8bf620d6b56bc8bcristy assert(image != (Image *) NULL); 2373316d51773c093e74e15de805e8bf620d6b56bc8bcristy if (image->debug != MagickFalse) 2374316d51773c093e74e15de805e8bf620d6b56bc8bcristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 2375e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 237630d8c94aa45a8a386d4ce3b3340ddfed3aa2421ecristy if (texture == (const Image *) NULL) 237730d8c94aa45a8a386d4ce3b3340ddfed3aa2421ecristy return(MagickFalse); 237830d8c94aa45a8a386d4ce3b3340ddfed3aa2421ecristy if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 237930d8c94aa45a8a386d4ce3b3340ddfed3aa2421ecristy return(MagickFalse); 238030d8c94aa45a8a386d4ce3b3340ddfed3aa2421ecristy texture_image=CloneImage(texture,0,0,MagickTrue,exception); 2381e6178503e4d6d3260666d42080d6f02545413685cristy if (texture_image == (const Image *) NULL) 2382316d51773c093e74e15de805e8bf620d6b56bc8bcristy return(MagickFalse); 2383a865ccd68cbccfdf00a5fdd40bc491c5f5390303cristy (void) TransformImageColorspace(texture_image,image->colorspace,exception); 2384387430f111ba7864990ca03fbc89968e20074ecdcristy (void) SetImageVirtualPixelMethod(texture_image,TileVirtualPixelMethod, 2385387430f111ba7864990ca03fbc89968e20074ecdcristy exception); 2386fcb1a668b974425a0378c278db25aca29ec70894cristy status=MagickTrue; 2387fcb1a668b974425a0378c278db25aca29ec70894cristy if ((image->compose != CopyCompositeOp) && 2388974a2a89b5345623d899221fc6bb3b82ca97b10fcristy ((image->compose != OverCompositeOp) || 238917f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy (image->alpha_trait != UndefinedPixelTrait) || 239017f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy (texture_image->alpha_trait != UndefinedPixelTrait))) 2391fcb1a668b974425a0378c278db25aca29ec70894cristy { 2392fcb1a668b974425a0378c278db25aca29ec70894cristy /* 2393fcb1a668b974425a0378c278db25aca29ec70894cristy Tile texture onto the image background. 2394fcb1a668b974425a0378c278db25aca29ec70894cristy */ 2395e6178503e4d6d3260666d42080d6f02545413685cristy for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) texture_image->rows) 2396fcb1a668b974425a0378c278db25aca29ec70894cristy { 2397bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 2398fcb1a668b974425a0378c278db25aca29ec70894cristy x; 239982b1583d4ca9179180de2754e6c25eef115cc181cristy 2400fcb1a668b974425a0378c278db25aca29ec70894cristy if (status == MagickFalse) 2401fcb1a668b974425a0378c278db25aca29ec70894cristy continue; 2402e6178503e4d6d3260666d42080d6f02545413685cristy for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) texture_image->columns) 2403fcb1a668b974425a0378c278db25aca29ec70894cristy { 2404fcb1a668b974425a0378c278db25aca29ec70894cristy MagickBooleanType 2405fcb1a668b974425a0378c278db25aca29ec70894cristy thread_status; 240682b1583d4ca9179180de2754e6c25eef115cc181cristy 2407feb3e9695150978a5d2372d3fe2f60466a7c8066cristy thread_status=CompositeImage(image,texture_image,image->compose, 24083de10e80ee511dd3e9e2eaa6a5d45b1d46ffe13cCristy MagickTrue,x+texture_image->tile_offset.x,y+ 2409feb3e9695150978a5d2372d3fe2f60466a7c8066cristy texture_image->tile_offset.y,exception); 2410fcb1a668b974425a0378c278db25aca29ec70894cristy if (thread_status == MagickFalse) 2411fcb1a668b974425a0378c278db25aca29ec70894cristy { 2412fcb1a668b974425a0378c278db25aca29ec70894cristy status=thread_status; 2413fcb1a668b974425a0378c278db25aca29ec70894cristy break; 2414fcb1a668b974425a0378c278db25aca29ec70894cristy } 2415fcb1a668b974425a0378c278db25aca29ec70894cristy } 2416fcb1a668b974425a0378c278db25aca29ec70894cristy if (image->progress_monitor != (MagickProgressMonitor) NULL) 2417fcb1a668b974425a0378c278db25aca29ec70894cristy { 2418fcb1a668b974425a0378c278db25aca29ec70894cristy MagickBooleanType 2419fcb1a668b974425a0378c278db25aca29ec70894cristy proceed; 242082b1583d4ca9179180de2754e6c25eef115cc181cristy 24212fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy proceed=SetImageProgress(image,TextureImageTag,(MagickOffsetType) y, 24222fb92284dc08cba0f635ccced4635f9b8f71fcf7cristy image->rows); 2423fcb1a668b974425a0378c278db25aca29ec70894cristy if (proceed == MagickFalse) 2424fcb1a668b974425a0378c278db25aca29ec70894cristy status=MagickFalse; 2425fcb1a668b974425a0378c278db25aca29ec70894cristy } 2426fcb1a668b974425a0378c278db25aca29ec70894cristy } 2427fcb1a668b974425a0378c278db25aca29ec70894cristy (void) SetImageProgress(image,TextureImageTag,(MagickOffsetType) 2428fcb1a668b974425a0378c278db25aca29ec70894cristy image->rows,image->rows); 242930d8c94aa45a8a386d4ce3b3340ddfed3aa2421ecristy texture_image=DestroyImage(texture_image); 2430fcb1a668b974425a0378c278db25aca29ec70894cristy return(status); 2431fcb1a668b974425a0378c278db25aca29ec70894cristy } 2432316d51773c093e74e15de805e8bf620d6b56bc8bcristy /* 2433fcb1a668b974425a0378c278db25aca29ec70894cristy Tile texture onto the image background (optimized). 2434316d51773c093e74e15de805e8bf620d6b56bc8bcristy */ 2435316d51773c093e74e15de805e8bf620d6b56bc8bcristy status=MagickTrue; 243646ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy texture_view=AcquireVirtualCacheView(texture_image,exception); 243746ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy image_view=AcquireAuthenticCacheView(image,exception); 2438e89143995d3c70f2b172e615d1915b1373ab835bcristy#if defined(MAGICKCORE_OPENMP_SUPPORT) 2439d643247965337aae790abe62ef297abc3cc63c3dcristy #pragma omp parallel for schedule(static,4) shared(status) \ 2440d643247965337aae790abe62ef297abc3cc63c3dcristy magick_threads(texture_image,image,1,1) 2441e89143995d3c70f2b172e615d1915b1373ab835bcristy#endif 2442bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=0; y < (ssize_t) image->rows; y++) 2443316d51773c093e74e15de805e8bf620d6b56bc8bcristy { 2444fcb1a668b974425a0378c278db25aca29ec70894cristy MagickBooleanType 2445fcb1a668b974425a0378c278db25aca29ec70894cristy sync; 2446fcb1a668b974425a0378c278db25aca29ec70894cristy 24474c08aed51c5899665ade97263692328eea4af106cristy register const Quantum 24484c08aed51c5899665ade97263692328eea4af106cristy *p, 24494c08aed51c5899665ade97263692328eea4af106cristy *pixels; 2450fcb1a668b974425a0378c278db25aca29ec70894cristy 2451bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 2452316d51773c093e74e15de805e8bf620d6b56bc8bcristy x; 2453316d51773c093e74e15de805e8bf620d6b56bc8bcristy 24544c08aed51c5899665ade97263692328eea4af106cristy register Quantum 2455fcb1a668b974425a0378c278db25aca29ec70894cristy *q; 2456fcb1a668b974425a0378c278db25aca29ec70894cristy 2457bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 2458fcb1a668b974425a0378c278db25aca29ec70894cristy width; 2459fcb1a668b974425a0378c278db25aca29ec70894cristy 2460fcb1a668b974425a0378c278db25aca29ec70894cristy if (status == MagickFalse) 2461fcb1a668b974425a0378c278db25aca29ec70894cristy continue; 2462e6178503e4d6d3260666d42080d6f02545413685cristy pixels=GetCacheViewVirtualPixels(texture_view,texture_image->tile_offset.x, 2463e6178503e4d6d3260666d42080d6f02545413685cristy (y+texture_image->tile_offset.y) % texture_image->rows, 2464e6178503e4d6d3260666d42080d6f02545413685cristy texture_image->columns,1,exception); 2465e6178503e4d6d3260666d42080d6f02545413685cristy q=QueueCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception); 24664c08aed51c5899665ade97263692328eea4af106cristy if ((pixels == (const Quantum *) NULL) || (q == (Quantum *) NULL)) 2467fcb1a668b974425a0378c278db25aca29ec70894cristy { 2468fcb1a668b974425a0378c278db25aca29ec70894cristy status=MagickFalse; 2469fcb1a668b974425a0378c278db25aca29ec70894cristy continue; 2470fcb1a668b974425a0378c278db25aca29ec70894cristy } 2471e6178503e4d6d3260666d42080d6f02545413685cristy for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) texture_image->columns) 2472fcb1a668b974425a0378c278db25aca29ec70894cristy { 24734c08aed51c5899665ade97263692328eea4af106cristy register ssize_t 2474e6178503e4d6d3260666d42080d6f02545413685cristy j; 24754c08aed51c5899665ade97263692328eea4af106cristy 24764c08aed51c5899665ade97263692328eea4af106cristy p=pixels; 2477e6178503e4d6d3260666d42080d6f02545413685cristy width=texture_image->columns; 2478bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if ((x+(ssize_t) width) > (ssize_t) image->columns) 2479fcb1a668b974425a0378c278db25aca29ec70894cristy width=image->columns-x; 2480e6178503e4d6d3260666d42080d6f02545413685cristy for (j=0; j < (ssize_t) width; j++) 24814c08aed51c5899665ade97263692328eea4af106cristy { 2482e6178503e4d6d3260666d42080d6f02545413685cristy register ssize_t 2483e6178503e4d6d3260666d42080d6f02545413685cristy i; 2484e6178503e4d6d3260666d42080d6f02545413685cristy 2485883fde11debec15cedb05dc5d7228d8588066bc0cristy if (GetPixelReadMask(image,q) == 0) 248610a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy { 248710a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy p+=GetPixelChannels(texture_image); 248810a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy q+=GetPixelChannels(image); 248910a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy continue; 249010a6c61544fb48d72f29ec8f9573bdcd52abf1b7cristy } 2491e6178503e4d6d3260666d42080d6f02545413685cristy for (i=0; i < (ssize_t) GetPixelChannels(texture_image); i++) 2492e6178503e4d6d3260666d42080d6f02545413685cristy { 24935a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelChannel channel=GetPixelChannelChannel(texture_image,i); 24945a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait traits=GetPixelChannelTraits(image,channel); 24955a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy PixelTrait texture_traits=GetPixelChannelTraits(texture_image, 24965a23c55ddcfdf6ae717dd42d8a1c1a2ff8c6305fcristy channel); 2497e6178503e4d6d3260666d42080d6f02545413685cristy if ((traits == UndefinedPixelTrait) || 2498e6178503e4d6d3260666d42080d6f02545413685cristy (texture_traits == UndefinedPixelTrait)) 2499e6178503e4d6d3260666d42080d6f02545413685cristy continue; 2500e6178503e4d6d3260666d42080d6f02545413685cristy SetPixelChannel(image,channel,p[i],q); 2501e6178503e4d6d3260666d42080d6f02545413685cristy } 2502e6178503e4d6d3260666d42080d6f02545413685cristy p+=GetPixelChannels(texture_image); 2503ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy q+=GetPixelChannels(image); 25044c08aed51c5899665ade97263692328eea4af106cristy } 2505fcb1a668b974425a0378c278db25aca29ec70894cristy } 2506fcb1a668b974425a0378c278db25aca29ec70894cristy sync=SyncCacheViewAuthenticPixels(image_view,exception); 2507fcb1a668b974425a0378c278db25aca29ec70894cristy if (sync == MagickFalse) 2508fcb1a668b974425a0378c278db25aca29ec70894cristy status=MagickFalse; 2509316d51773c093e74e15de805e8bf620d6b56bc8bcristy if (image->progress_monitor != (MagickProgressMonitor) NULL) 2510316d51773c093e74e15de805e8bf620d6b56bc8bcristy { 2511316d51773c093e74e15de805e8bf620d6b56bc8bcristy MagickBooleanType 2512316d51773c093e74e15de805e8bf620d6b56bc8bcristy proceed; 2513316d51773c093e74e15de805e8bf620d6b56bc8bcristy 2514cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy proceed=SetImageProgress(image,TextureImageTag,(MagickOffsetType) y, 2515cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy image->rows); 2516316d51773c093e74e15de805e8bf620d6b56bc8bcristy if (proceed == MagickFalse) 2517316d51773c093e74e15de805e8bf620d6b56bc8bcristy status=MagickFalse; 2518316d51773c093e74e15de805e8bf620d6b56bc8bcristy } 2519316d51773c093e74e15de805e8bf620d6b56bc8bcristy } 2520fcb1a668b974425a0378c278db25aca29ec70894cristy texture_view=DestroyCacheView(texture_view); 2521fcb1a668b974425a0378c278db25aca29ec70894cristy image_view=DestroyCacheView(image_view); 252230d8c94aa45a8a386d4ce3b3340ddfed3aa2421ecristy texture_image=DestroyImage(texture_image); 2523fcb1a668b974425a0378c278db25aca29ec70894cristy return(status); 2524316d51773c093e74e15de805e8bf620d6b56bc8bcristy} 2525