% The format of the AdaptiveBlurImage method is:
%
% Image *AdaptiveBlurImage(const Image *image,const double radius,
-% const double sigma,ExceptionInfo *exception)
+% const double sigma,const double bias,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
%
% o sigma: the standard deviation of the Laplacian, in pixels.
%
+% o bias: the bias.
+%
% o exception: return any errors or warnings in this structure.
%
*/
}
MagickExport Image *AdaptiveBlurImage(const Image *image,
- const double radius,const double sigma,ExceptionInfo *exception)
+ const double radius,const double sigma,const double bias,
+ ExceptionInfo *exception)
{
#define AdaptiveBlurImageTag "Convolve/Image"
#define MagickSigma (fabs(sigma) <= MagickEpsilon ? 1.0 : sigma)
MagickOffsetType
progress;
- PixelInfo
- bias;
-
register ssize_t
i;
*/
status=MagickTrue;
progress=0;
- GetPixelInfo(image,&bias);
- SetPixelInfoBias(image,&bias);
image_view=AcquireCacheView(image);
edge_view=AcquireCacheView(edge_image);
blur_view=AcquireCacheView(blur_image);
for (y=0; y < (ssize_t) blur_image->rows; y++)
{
register const Quantum
- *restrict p,
*restrict r;
register Quantum
}
for (x=0; x < (ssize_t) blur_image->columns; x++)
{
- PixelInfo
- pixel;
-
- MagickRealType
- alpha,
- gamma;
-
- register const double
- *restrict k;
+ register const Quantum
+ *restrict p;
register ssize_t
- i,
- u,
- v;
+ i;
- gamma=0.0;
- i=(ssize_t) ceil((double) width*QuantumScale*
+ ssize_t
+ center,
+ j;
+
+ j=(ssize_t) ceil((double) width*QuantumScale*
GetPixelIntensity(edge_image,r)-0.5);
- if (i < 0)
- i=0;
+ if (j < 0)
+ j=0;
else
- if (i > (ssize_t) width)
- i=(ssize_t) width;
- if ((i & 0x01) != 0)
- i--;
- p=GetCacheViewVirtualPixels(image_view,x-((ssize_t) (width-i)/2L),y-
- (ssize_t) ((width-i)/2L),width-i,width-i,exception);
+ if (j > (ssize_t) width)
+ j=(ssize_t) width;
+ if ((j & 0x01) != 0)
+ j--;
+ p=GetCacheViewVirtualPixels(image_view,x-((ssize_t) (width-j)/2L),y-
+ (ssize_t) ((width-j)/2L),width-j,width-j,exception);
if (p == (const Quantum *) NULL)
break;
- pixel=bias;
- k=kernel[i];
- for (v=0; v < (ssize_t) (width-i); v++)
+ center=(ssize_t) GetPixelChannels(image)*(width-j)*
+ ((width-j)/2L)+GetPixelChannels(image)*((width-j)/2);
+ for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
- for (u=0; u < (ssize_t) (width-i); u++)
+ MagickRealType
+ alpha,
+ gamma,
+ pixel;
+
+ PixelChannel
+ channel;
+
+ PixelTrait
+ blur_traits,
+ traits;
+
+ register const double
+ *restrict k;
+
+ register const Quantum
+ *restrict pixels;
+
+ register ssize_t
+ u;
+
+ ssize_t
+ v;
+
+ traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
+ channel=GetPixelChannelMapChannel(image,(PixelChannel) i);
+ blur_traits=GetPixelChannelMapTraits(blur_image,channel);
+ if ((traits == UndefinedPixelTrait) ||
+ (blur_traits == UndefinedPixelTrait))
+ continue;
+ if ((blur_traits & CopyPixelTrait) != 0)
+ {
+ q[channel]=p[center+i];
+ continue;
+ }
+ k=kernel[j];
+ pixels=p;
+ pixel=bias;
+ gamma=0.0;
+ if ((blur_traits & BlendPixelTrait) == 0)
+ {
+ /*
+ No alpha blending.
+ */
+ for (v=0; v < (ssize_t) (width-j); v++)
+ {
+ for (u=0; u < (ssize_t) (width-j); u++)
+ {
+ pixel+=(*k)*pixels[i];
+ gamma+=(*k);
+ k++;
+ pixels+=GetPixelChannels(image);
+ }
+ }
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ q[channel]=ClampToQuantum(gamma*pixel);
+ continue;
+ }
+ /*
+ Alpha blending.
+ */
+ for (v=0; v < (ssize_t) (width-j); v++)
{
- alpha=1.0;
- if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
- (image->matte != MagickFalse))
- alpha=(MagickRealType) (QuantumScale*GetPixelAlpha(image,p));
- if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
- pixel.red+=(*k)*alpha*GetPixelRed(image,p);
- if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
- pixel.green+=(*k)*alpha*GetPixelGreen(image,p);
- if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
- pixel.blue+=(*k)*alpha*GetPixelBlue(image,p);
- if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
- (image->colorspace == CMYKColorspace))
- pixel.black+=(*k)*alpha*GetPixelBlack(image,p);
- if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
- pixel.alpha+=(*k)*GetPixelAlpha(image,p);
- gamma+=(*k)*alpha;
- k++;
- p+=GetPixelChannels(image);
+ for (u=0; u < (ssize_t) (width-j); u++)
+ {
+ alpha=(MagickRealType) (QuantumScale*GetPixelAlpha(image,pixels));
+ pixel+=(*k)*alpha*pixels[i];
+ gamma+=(*k)*alpha;
+ k++;
+ pixels+=GetPixelChannels(image);
+ }
}
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ q[channel]=ClampToQuantum(gamma*pixel);
}
- gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
- if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
- SetPixelRed(blur_image,ClampToQuantum(gamma*pixel.red),q);
- if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
- SetPixelGreen(blur_image,ClampToQuantum(gamma*pixel.green),q);
- if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
- SetPixelBlue(blur_image,ClampToQuantum(gamma*pixel.blue),q);
- if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
- (image->colorspace == CMYKColorspace))
- SetPixelBlack(blur_image,ClampToQuantum(gamma*pixel.black),q);
- if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
- SetPixelAlpha(blur_image,ClampToQuantum(pixel.alpha),q);
q+=GetPixelChannels(blur_image);
r+=GetPixelChannels(edge_image);
}
% The format of the AdaptiveSharpenImage method is:
%
% Image *AdaptiveSharpenImage(const Image *image,const double radius,
-% const double sigma,ExceptionInfo *exception)
+% const double sigma,const double bias,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
%
% o sigma: the standard deviation of the Laplacian, in pixels.
%
+% o bias: the bias.
+%
% o exception: return any errors or warnings in this structure.
%
*/
MagickExport Image *AdaptiveSharpenImage(const Image *image,const double radius,
- const double sigma,ExceptionInfo *exception)
+ const double sigma,const double bias,ExceptionInfo *exception)
{
#define AdaptiveSharpenImageTag "Convolve/Image"
#define MagickSigma (fabs(sigma) <= MagickEpsilon ? 1.0 : sigma)
MagickOffsetType
progress;
- PixelInfo
- bias;
-
register ssize_t
i;
*/
status=MagickTrue;
progress=0;
- GetPixelInfo(image,&bias);
- SetPixelInfoBias(image,&bias);
image_view=AcquireCacheView(image);
edge_view=AcquireCacheView(edge_image);
sharp_view=AcquireCacheView(sharp_image);
for (y=0; y < (ssize_t) sharp_image->rows; y++)
{
register const Quantum
- *restrict p,
*restrict r;
register Quantum
}
for (x=0; x < (ssize_t) sharp_image->columns; x++)
{
- PixelInfo
- pixel;
-
- MagickRealType
- alpha,
- gamma;
-
- register const double
- *restrict k;
+ register const Quantum
+ *restrict p;
register ssize_t
- i,
- u,
- v;
+ i;
- gamma=0.0;
- i=(ssize_t) ceil((double) width*QuantumScale*
+ ssize_t
+ center,
+ j;
+
+ j=(ssize_t) ceil((double) width*QuantumScale*
GetPixelIntensity(edge_image,r)-0.5);
- if (i < 0)
- i=0;
+ if (j < 0)
+ j=0;
else
- if (i > (ssize_t) width)
- i=(ssize_t) width;
- if ((i & 0x01) != 0)
- i--;
- p=GetCacheViewVirtualPixels(image_view,x-((ssize_t) (width-i)/2L),y-
- (ssize_t) ((width-i)/2L),width-i,width-i,exception);
+ if (j > (ssize_t) width)
+ j=(ssize_t) width;
+ if ((j & 0x01) != 0)
+ j--;
+ p=GetCacheViewVirtualPixels(image_view,x-((ssize_t) (width-j)/2L),y-
+ (ssize_t) ((width-j)/2L),width-j,width-j,exception);
if (p == (const Quantum *) NULL)
break;
- k=kernel[i];
- pixel=bias;
- for (v=0; v < (ssize_t) (width-i); v++)
+ center=(ssize_t) GetPixelChannels(image)*(width-j)*
+ ((width-j)/2L)+GetPixelChannels(image)*((width-j)/2);
+ for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
- for (u=0; u < (ssize_t) (width-i); u++)
+ MagickRealType
+ alpha,
+ gamma,
+ pixel;
+
+ PixelChannel
+ channel;
+
+ PixelTrait
+ sharp_traits,
+ traits;
+
+ register const double
+ *restrict k;
+
+ register const Quantum
+ *restrict pixels;
+
+ register ssize_t
+ u;
+
+ ssize_t
+ v;
+
+ traits=GetPixelChannelMapTraits(image,(PixelChannel) i);
+ channel=GetPixelChannelMapChannel(image,(PixelChannel) i);
+ sharp_traits=GetPixelChannelMapTraits(sharp_image,channel);
+ if ((traits == UndefinedPixelTrait) ||
+ (sharp_traits == UndefinedPixelTrait))
+ continue;
+ if ((sharp_traits & CopyPixelTrait) != 0)
+ {
+ q[channel]=p[center+i];
+ continue;
+ }
+ k=kernel[j];
+ pixels=p;
+ pixel=bias;
+ gamma=0.0;
+ if ((sharp_traits & BlendPixelTrait) == 0)
+ {
+ /*
+ No alpha blending.
+ */
+ for (v=0; v < (ssize_t) (width-j); v++)
+ {
+ for (u=0; u < (ssize_t) (width-j); u++)
+ {
+ pixel+=(*k)*pixels[i];
+ gamma+=(*k);
+ k++;
+ pixels+=GetPixelChannels(image);
+ }
+ }
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ q[channel]=ClampToQuantum(gamma*pixel);
+ continue;
+ }
+ /*
+ Alpha blending.
+ */
+ for (v=0; v < (ssize_t) (width-j); v++)
{
- alpha=1.0;
- if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
- (image->matte != MagickFalse))
- alpha=(MagickRealType) (QuantumScale*GetPixelAlpha(image,p));
- if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
- pixel.red+=(*k)*alpha*GetPixelRed(image,p);
- if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
- pixel.green+=(*k)*alpha*GetPixelGreen(image,p);
- if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
- pixel.blue+=(*k)*alpha*GetPixelBlue(image,p);
- if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
- (image->colorspace == CMYKColorspace))
- pixel.black+=(*k)*alpha*GetPixelBlack(image,p);
- if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
- pixel.alpha+=(*k)*GetPixelAlpha(image,p);
- gamma+=(*k)*alpha;
- k++;
- p+=GetPixelChannels(image);
+ for (u=0; u < (ssize_t) (width-j); u++)
+ {
+ alpha=(MagickRealType) (QuantumScale*GetPixelAlpha(image,pixels));
+ pixel+=(*k)*alpha*pixels[i];
+ gamma+=(*k)*alpha;
+ k++;
+ pixels+=GetPixelChannels(image);
+ }
}
+ gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
+ q[channel]=ClampToQuantum(gamma*pixel);
}
- gamma=1.0/(fabs((double) gamma) <= MagickEpsilon ? 1.0 : gamma);
- if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
- SetPixelRed(sharp_image,ClampToQuantum(gamma*pixel.red),q);
- if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
- SetPixelGreen(sharp_image,ClampToQuantum(gamma*pixel.green),q);
- if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
- SetPixelBlue(sharp_image,ClampToQuantum(gamma*pixel.blue),q);
- if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
- (image->colorspace == CMYKColorspace))
- SetPixelBlack(sharp_image,ClampToQuantum(gamma*pixel.black),q);
- if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
- SetPixelAlpha(sharp_image,ClampToQuantum(pixel.alpha),q);
q+=GetPixelChannels(sharp_image);
r+=GetPixelChannels(edge_image);
}
% The format of the MagickAdaptiveBlurImage method is:
%
% MagickBooleanType MagickAdaptiveBlurImage(MagickWand *wand,
-% const double radius,const double sigma)
+% const double radius,const double sigma,const double bias)
%
% A description of each parameter follows:
%
%
% o sigma: the standard deviation of the Gaussian, in pixels.
%
+% o bias: the bias.
+%
*/
WandExport MagickBooleanType MagickAdaptiveBlurImage(MagickWand *wand,
- const double radius,const double sigma)
+ const double radius,const double sigma,const double bias)
{
Image
*sharp_image;
(void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
if (wand->images == (Image *) NULL)
ThrowWandException(WandError,"ContainsNoImages",wand->name);
- sharp_image=AdaptiveBlurImage(wand->images,radius,sigma,wand->exception);
+ sharp_image=AdaptiveBlurImage(wand->images,radius,sigma,bias,wand->exception);
if (sharp_image == (Image *) NULL)
return(MagickFalse);
ReplaceImageInList(&wand->images,sharp_image);
% The format of the MagickAdaptiveSharpenImage method is:
%
% MagickBooleanType MagickAdaptiveSharpenImage(MagickWand *wand,
-% const double radius,const double sigma)
+% const double radius,const double sigma,const double bias)
%
% A description of each parameter follows:
%
%
% o sigma: the standard deviation of the Gaussian, in pixels.
%
+% o bias: the bias.
+%
*/
WandExport MagickBooleanType MagickAdaptiveSharpenImage(MagickWand *wand,
- const double radius,const double sigma)
+ const double radius,const double sigma,const double bias)
{
Image
*sharp_image;
(void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
if (wand->images == (Image *) NULL)
ThrowWandException(WandError,"ContainsNoImages",wand->name);
- sharp_image=AdaptiveSharpenImage(wand->images,radius,sigma,wand->exception);
+ sharp_image=AdaptiveSharpenImage(wand->images,radius,sigma,bias,
+ wand->exception);
if (sharp_image == (Image *) NULL)
return(MagickFalse);
ReplaceImageInList(&wand->images,sharp_image);
{ "Sans1", },
{ "AdaptiveSharpen", { {"geometry", StringReference},
{"radius", RealReference}, {"sigma", RealReference},
- {"channel", MagickChannelOptions} } },
+ {"bias", RealReference}, {"channel", MagickChannelOptions} } },
{ "Transpose", },
{ "Transverse", },
{ "AutoOrient", },
{ "AdaptiveBlur", { {"geometry", StringReference},
{"radius", RealReference}, {"sigma", RealReference},
- {"channel", MagickChannelOptions} } },
+ {"bias", RealReference}, {"channel", MagickChannelOptions} } },
{ "Sketch", { {"geometry", StringReference},
{"radius", RealReference}, {"sigma", RealReference},
{"angle", RealReference} } },
&geometry_info);
if ((flags & SigmaValue) == 0)
geometry_info.sigma=1.0;
+ if ((flags & XiValue) == 0)
+ geometry_info.xi=0.0;
}
if (attribute_flag[1] != 0)
geometry_info.rho=argument_list[1].real_reference;
if (attribute_flag[2] != 0)
geometry_info.sigma=argument_list[2].real_reference;
if (attribute_flag[3] != 0)
- channel=(ChannelType) argument_list[3].integer_reference;
+ geometry_info.xi=argument_list[3].real_reference;
+ if (attribute_flag[4] != 0)
+ channel=(ChannelType) argument_list[4].integer_reference;
channel_mask=SetPixelChannelMask(image,channel);
image=AdaptiveSharpenImage(image,geometry_info.rho,
- geometry_info.sigma,exception);
+ geometry_info.sigma,geometry_info.xi,exception);
if (image != (Image *) NULL)
(void) SetPixelChannelMask(image,channel_mask);
break;
&geometry_info);
if ((flags & SigmaValue) == 0)
geometry_info.sigma=1.0;
+ if ((flags & XiValue) == 0)
+ geometry_info.xi=0.0;
}
if (attribute_flag[1] != 0)
geometry_info.rho=argument_list[1].real_reference;
if (attribute_flag[2] != 0)
geometry_info.sigma=argument_list[2].real_reference;
if (attribute_flag[3] != 0)
- channel=(ChannelType) argument_list[3].integer_reference;
+ geometry_info.xi=argument_list[3].real_reference;
+ if (attribute_flag[4] != 0)
+ channel=(ChannelType) argument_list[4].integer_reference;
channel_mask=SetPixelChannelMask(image,channel);
image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
- exception);
+ geometry_info.xi,exception);
if (image != (Image *) NULL)
(void) SetPixelChannelMask(image,channel_mask);
break;