% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% Morpology is the the application of various kernels, of any size and even
-% shape, to a image in various ways (typically binary, but not always).
+% Morphology is the application of various kernels, of any size or shape, to an
+% image in various ways (typically binary, but not always).
%
% Convolution (weighted sum or average) is just one specific type of
% morphology. Just one that is very common for image bluring and sharpening
/*
Other global definitions used by module.
*/
-static inline double MagickMin(const double x,const double y)
-{
- return( x < y ? x : y);
-}
-static inline double MagickMax(const double x,const double y)
-{
- return( x > y ? x : y);
-}
#define Minimize(assign,value) assign=MagickMin(assign,value)
#define Maximize(assign,value) assign=MagickMax(assign,value)
*kernel;
char
- token[MaxTextExtent];
+ token[MagickPathExtent];
const char
*p,
args;
kernel=(KernelInfo *) AcquireQuantumMemory(1,sizeof(*kernel));
- if (kernel == (KernelInfo *)NULL)
+ if (kernel == (KernelInfo *) NULL)
return(kernel);
(void) ResetMagickMemory(kernel,0,sizeof(*kernel));
kernel->minimum = kernel->maximum = kernel->angle = 0.0;
kernel->negative_range = kernel->positive_range = 0.0;
kernel->type = UserDefinedKernel;
kernel->next = (KernelInfo *) NULL;
- kernel->signature = MagickSignature;
+ kernel->signature=MagickCoreSignature;
if (kernel_string == (const char *) NULL)
return(kernel);
ExceptionInfo *exception)
{
char
- token[MaxTextExtent];
+ token[MagickPathExtent];
const char
*p,
GetMagickToken(kernel_string,&p,token);
type=ParseCommandOption(MagickKernelOptions,MagickFalse,token);
if ( type < 0 || type == UserDefinedKernel )
- return((KernelInfo *)NULL); /* not a valid named kernel */
+ return((KernelInfo *) NULL); /* not a valid named kernel */
while (((isspace((int) ((unsigned char) *p)) != 0) ||
(*p == ',') || (*p == ':' )) && (*p != '\0') && (*p != ';'))
char
*kernel_cache,
- token[MaxTextExtent];
+ token[MagickPathExtent];
const char
*p;
switch(type) {
case UndefinedKernel: /* These should not call this function */
case UserDefinedKernel:
- assert("Should not call this function" != (char *)NULL);
+ assert("Should not call this function" != (char *) NULL);
break;
case LaplacianKernel: /* Named Descrete Convolution Kernels */
case SobelKernel: /* these are defined using other kernels */
kernel->negative_range = kernel->positive_range = 0.0;
kernel->type = type;
kernel->next = (KernelInfo *) NULL;
- kernel->signature = MagickSignature;
+ kernel->signature=MagickCoreSignature;
break;
}
/* check actual kernel values */
for (i=0; i < (kernel1->width*kernel1->height); i++) {
/* Test for Nan equivalence */
- if ( IfNaN(kernel1->values[i]) && !IfNaN(kernel2->values[i]) )
+ if ( IsNaN(kernel1->values[i]) && !IsNaN(kernel2->values[i]) )
return MagickFalse;
- if ( IfNaN(kernel2->values[i]) && !IfNaN(kernel1->values[i]) )
+ if ( IsNaN(kernel2->values[i]) && !IsNaN(kernel1->values[i]) )
return MagickFalse;
/* Test actual values are equivalent */
if ( fabs(kernel1->values[i] - kernel2->values[i]) >= MagickEpsilon )
progress;
assert(image != (Image *) NULL);
- assert(image->signature == MagickSignature);
+ assert(image->signature == MagickCoreSignature);
assert(morphology_image != (Image *) NULL);
- assert(morphology_image->signature == MagickSignature);
+ assert(morphology_image->signature == MagickCoreSignature);
assert(kernel != (KernelInfo *) NULL);
- assert(kernel->signature == MagickSignature);
+ assert(kernel->signature == MagickCoreSignature);
assert(exception != (ExceptionInfo *) NULL);
- assert(exception->signature == MagickSignature);
+ assert(exception->signature == MagickCoreSignature);
status=MagickTrue;
progress=0;
image_view=AcquireVirtualCacheView(image,exception);
morphology_view=AcquireAuthenticCacheView(morphology_image,exception);
width=image->columns+kernel->width-1;
- offset.x=0.0;
- offset.y=0.0;
+ offset.x=0;
+ offset.y=0;
switch (method)
{
case ConvolveMorphology:
{
for (u=0; u < (ssize_t) kernel->width; u++)
{
- if (IfNaN(*k) == MagickFalse)
+ if (!IsNaN(*k))
{
pixel+=(*k)*pixels[i];
gamma+=(*k);
{
for (u=0; u < (ssize_t) kernel->width; u++)
{
- if (IfNaN(*k) == MagickFalse)
+ if (!IsNaN(*k))
{
alpha=(double) (QuantumScale*GetPixelAlpha(image,pixels));
pixel+=alpha*(*k)*pixels[i];
double
alpha,
gamma,
+ intensity,
maximum,
minimum,
pixel;
*/
k=(&kernel->values[kernel->width*kernel->height-1]);
count=0;
- gamma=0.0;
if ((morphology_traits & BlendPixelTrait) == 0)
{
/*
{
for (u=0; u < (ssize_t) kernel->width; u++)
{
- if (IfNaN(*k) == MagickFalse)
+ if (!IsNaN(*k))
{
pixel+=(*k)*pixels[i];
- gamma+=(*k);
count++;
}
k--;
/*
Alpha blending.
*/
+ gamma=0.0;
for (v=0; v < (ssize_t) kernel->height; v++)
{
for (u=0; u < (ssize_t) kernel->width; u++)
{
- if (IfNaN(*k) == MagickFalse)
+ if (!IsNaN(*k))
{
alpha=(double) (QuantumScale*GetPixelAlpha(image,pixels));
pixel+=alpha*(*k)*pixels[i];
{
for (u=0; u < (ssize_t) kernel->width; u++)
{
- if ((IfNaN(*k) == MagickFalse) && (*k >= 0.5))
+ if (!IsNaN(*k) && (*k >= 0.5))
{
if ((double) pixels[i] < pixel)
pixel=(double) pixels[i];
{
for (u=0; u < (ssize_t) kernel->width; u++)
{
- if ((IfNaN(*k) == MagickFalse) && (*k > 0.5))
+ if (!IsNaN(*k) && (*k > 0.5))
{
if ((double) pixels[i] > pixel)
pixel=(double) pixels[i];
{
for (u=0; u < (ssize_t) kernel->width; u++)
{
- if (IfNaN(*k) == MagickFalse)
+ if (!IsNaN(*k))
{
if (*k > 0.7)
{
{
for (u=0; u < (ssize_t) kernel->width; u++)
{
- if ((IfNaN(*k) == MagickFalse) && (*k >= 0.5))
+ if (!IsNaN(*k) && (*k >= 0.5))
{
- if (GetPixelIntensity(image,pixels) < minimum)
+ intensity=(double) GetPixelIntensity(image,pixels);
+ if (intensity < minimum)
{
pixel=(double) pixels[i];
- minimum=GetPixelIntensity(image,pixels);
+ minimum=intensity;
}
count++;
}
{
for (u=0; u < (ssize_t) kernel->width; u++)
{
- if ((IfNaN(*k) == MagickFalse) && (*k >= 0.5))
+ if (!IsNaN(*k) && (*k >= 0.5))
{
- if (GetPixelIntensity(image,pixels) > maximum)
+ intensity=(double) GetPixelIntensity(image,pixels);
+ if (intensity > maximum)
{
pixel=(double) pixels[i];
- maximum=GetPixelIntensity(image,pixels);
+ maximum=intensity;
}
count++;
}
{
for (u=0; u < (ssize_t) kernel->width; u++)
{
- if (IfNaN(*k) == MagickFalse)
+ if (!IsNaN(*k))
{
if ((pixels[i]+(*k)) < pixel)
pixel=(double) pixels[i]+(*k);
y;
assert(image != (Image *) NULL);
- assert(image->signature == MagickSignature);
+ assert(image->signature == MagickCoreSignature);
assert(kernel != (KernelInfo *) NULL);
- assert(kernel->signature == MagickSignature);
+ assert(kernel->signature == MagickCoreSignature);
assert(exception != (ExceptionInfo *) NULL);
- assert(exception->signature == MagickSignature);
+ assert(exception->signature == MagickCoreSignature);
status=MagickTrue;
changed=0;
progress=0;
{
for (u=0; u < (ssize_t) kernel->width; u++)
{
- if (IfNaN(*k) == MagickFalse)
+ if (!IsNaN(*k))
{
if ((pixels[i]+(*k)) < pixel)
pixel=(double) pixels[i]+(*k);
pixels=q-offset.x*GetPixelChannels(image);
for (u=0; u < offset.x; u++)
{
- if ((IfNaN(*k) == MagickFalse) && ((x+u-offset.x) >= 0))
+ if (!IsNaN(*k) && ((x+u-offset.x) >= 0))
{
if ((pixels[i]+(*k)) < pixel)
pixel=(double) pixels[i]+(*k);
{
for (u=0; u < (ssize_t) kernel->width; u++)
{
- if (IfNaN(*k) == MagickFalse)
+ if (!IsNaN(*k))
{
if ((pixels[i]+(*k)) < pixel)
pixel=(double) pixels[i]+(*k);
pixels=q-offset.x*GetPixelChannels(image);
for (u=0; u < offset.x; u++)
{
- if ((IfNaN(*k) == MagickFalse) && ((x+u-offset.x) >= 0))
+ if (!IsNaN(*k) && ((x+u-offset.x) >= 0))
{
if ((pixels[i]+(*k)) < pixel)
pixel=(double) pixels[i]+(*k);
{
for (u=0; u < (ssize_t) kernel->width; u++)
{
- if (IfNaN(*k) == MagickFalse)
+ if (!IsNaN(*k))
{
if ((pixels[i]+(*k)) < pixel)
pixel=(double) pixels[i]+(*k);
for (u=offset.x+1; u < (ssize_t) kernel->width; u++)
{
pixels+=GetPixelChannels(image);
- if ((IfNaN(*k) == MagickFalse) &&
- ((x+u-offset.x) < (ssize_t) image->columns))
+ if (!IsNaN(*k) && ((x+u-offset.x) < (ssize_t) image->columns))
{
if ((pixels[i]+(*k)) < pixel)
pixel=(double) pixels[i]+(*k);
{
for (u=0; u < (ssize_t) kernel->width; u++)
{
- if (IfNaN(*k) == MagickFalse)
+ if (!IsNaN(*k))
{
if ((pixels[i]+(*k)) < pixel)
pixel=(double) pixels[i]+(*k);
for (u=offset.x+1; u < (ssize_t) kernel->width; u++)
{
pixels+=GetPixelChannels(image);
- if ((IfNaN(*k) == MagickFalse) &&
- ((x+u-offset.x) < (ssize_t) image->columns))
+ if (!IsNaN(*k) && ((x+u-offset.x) < (ssize_t) image->columns))
{
if ((pixels[i]+(*k)) < pixel)
pixel=(double) pixels[i]+(*k);
changed; /* number pixels changed by last primitive operation */
char
- v_info[MaxTextExtent];
+ v_info[MagickPathExtent];
assert(image != (Image *) NULL);
- assert(image->signature == MagickSignature);
+ assert(image->signature == MagickCoreSignature);
assert(kernel != (KernelInfo *) NULL);
- assert(kernel->signature == MagickSignature);
+ assert(kernel->signature == MagickCoreSignature);
assert(exception != (ExceptionInfo *) NULL);
- assert(exception->signature == MagickSignature);
+ assert(exception->signature == MagickCoreSignature);
count = 0; /* number of low-level morphology primitives performed */
if ( iterations == 0 )
- return((Image *)NULL); /* null operation - nothing to do! */
+ return((Image *) NULL); /* null operation - nothing to do! */
kernel_limit = (size_t) iterations;
if ( iterations < 0 ) /* negative interations = infinite (well alomst) */
/* Extra information for debugging compound operations */
if ( IfMagickTrue(verbose) ) {
if ( stage_limit > 1 )
- (void) FormatLocaleString(v_info,MaxTextExtent,"%s:%.20g.%.20g -> ",
+ (void) FormatLocaleString(v_info,MagickPathExtent,"%s:%.20g.%.20g -> ",
CommandOptionToMnemonic(MagickMorphologyOptions,method),(double)
method_loop,(double) stage_loop);
else if ( primitive != method )
- (void) FormatLocaleString(v_info, MaxTextExtent, "%s:%.20g -> ",
+ (void) FormatLocaleString(v_info, MagickPathExtent, "%s:%.20g -> ",
CommandOptionToMnemonic(MagickMorphologyOptions, method),(double)
method_loop);
else
%
% User defined settings include...
% * Output Bias for Convolution and correlation ("-define convolve:bias=??")
-% * Kernel Scale/normalize settings ("-define convolve:scale=??")
+% * Kernel Scale/normalize settings ("-define convolve:scale=??")
% This can also includes the addition of a scaled unity kernel.
-% * Show Kernel being applied ("-define showkernel=1")
+% * Show Kernel being applied ("-define morphology:showkernel=1")
%
% Other operators that do not want user supplied options interfering,
-% especially "convolve:bias" and "showkernel" should use MorphologyApply()
-% directly.
+% especially "convolve:bias" and "morphology:showkernel" should use
+% MorphologyApply() directly.
%
% The format of the MorphologyImage method is:
%
const MorphologyMethod method,const ssize_t iterations,
const KernelInfo *kernel,ExceptionInfo *exception)
{
- KernelInfo
- *curr_kernel;
+ const char
+ *artifact;
CompositeOperator
compose;
+ double
+ bias;
+
Image
*morphology_image;
- double
- bias;
+ KernelInfo
+ *curr_kernel;
curr_kernel = (KernelInfo *) kernel;
bias=0.0;
/* Scale kernel according to user wishes */
artifact = GetImageArtifact(image,"convolve:scale");
- if ( artifact != (const char *)NULL ) {
+ if ( artifact != (const char *) NULL ) {
if (IfMagickFalse(IsGeometry(artifact)))
(void) ThrowMagickException(exception,GetMagickModule(),
OptionWarning,"InvalidSetting","'%s' '%s'",
}
/* display the (normalized) kernel via stderr */
- if ( IfStringTrue(GetImageArtifact(image,"showkernel"))
- || IfStringTrue(GetImageArtifact(image,"convolve:showkernel"))
- || IfStringTrue(GetImageArtifact(image,"morphology:showkernel")) )
+ artifact=GetImageArtifact(image,"morphology:showkernel");
+ if (IsStringTrue(artifact) != MagickFalse)
ShowKernelInfo(curr_kernel);
/* Override the default handling of multi-kernel morphology results
* Otherwise merge resulting images using compose method given.
* Default for 'HitAndMiss' is 'Lighten'.
*/
- { const char
- *artifact;
+ {
ssize_t
parse;
neg_scale = scaling_factor/neg_scale;
for (i=0; i < (ssize_t) (kernel->width*kernel->height); i++)
- if ( ! IfNaN(kernel->values[i]) )
+ if (!IsNaN(kernel->values[i]))
kernel->values[i] *= (kernel->values[i] >= 0) ? pos_scale : neg_scale;
/* convolution output range */
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ShowKernelInfo() outputs the details of the given kernel defination to
-% standard error, generally due to a users 'showkernel' option request.
+% standard error, generally due to a users 'morphology:showkernel' option
+% request.
%
% The format of the ShowKernel method is:
%
for (i=v=0; v < k->height; v++) {
(void) FormatLocaleFile(stderr, "%2lu:", (unsigned long) v );
for (u=0; u < k->width; u++, i++)
- if ( IfNaN(k->values[i]) )
+ if (IsNaN(k->values[i]))
(void) FormatLocaleFile(stderr," %*s", GetMagickPrecision()+3, "nan");
else
(void) FormatLocaleFile(stderr," %*.*lg", GetMagickPrecision()+3,
i;
/* do the other kernels in a multi-kernel list first */
- if ( kernel->next != (KernelInfo *) NULL)
+ if (kernel->next != (KernelInfo *) NULL)
ZeroKernelNans(kernel->next);
for (i=0; i < (kernel->width*kernel->height); i++)
- if ( IfNaN(kernel->values[i]) )
- kernel->values[i] = 0.0;
+ if (IsNaN(kernel->values[i]))
+ kernel->values[i]=0.0;
return;
}