% January 2010 %
% %
% %
-% Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization %
% dedicated to making software imaging solutions freely available. %
% %
% You may not use this file except in compliance with the License. You may %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% 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)
static inline KernelInfo *LastKernelInfo(KernelInfo *kernel)
{
while (kernel->next != (KernelInfo *) NULL)
- kernel = kernel->next;
+ kernel=kernel->next;
return(kernel);
}
*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);
kernel->width,kernel->height*sizeof(*kernel->values)));
if (kernel->values == (MagickRealType *) NULL)
return(DestroyKernelInfo(kernel));
- kernel->minimum = +MagickHuge;
- kernel->maximum = -MagickHuge;
+ kernel->minimum=MagickMaximumValue;
+ kernel->maximum=(-MagickMaximumValue);
kernel->negative_range = kernel->positive_range = 0.0;
for (i=0; (i < (ssize_t) (kernel->width*kernel->height)) && (p < end); i++)
{
#endif
/* check that we recieved at least one real (non-nan) value! */
- if ( kernel->minimum == MagickHuge )
+ if (kernel->minimum == MagickMaximumValue)
return(DestroyKernelInfo(kernel));
if ( (flags & AreaValue) != 0 ) /* '@' symbol in kernel size */
return(kernel);
}
-static KernelInfo *ParseKernelName(const char *kernel_string)
+static KernelInfo *ParseKernelName(const char *kernel_string,
+ 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 != ';'))
break;
}
- kernel = AcquireKernelBuiltIn((KernelInfoType)type, &args);
+ kernel = AcquireKernelBuiltIn((KernelInfoType)type, &args, exception);
if ( kernel == (KernelInfo *) NULL )
return(kernel);
return(kernel);
}
-MagickExport KernelInfo *AcquireKernelInfo(const char *kernel_string)
+MagickExport KernelInfo *AcquireKernelInfo(const char *kernel_string,
+ ExceptionInfo *exception)
{
-
KernelInfo
*kernel,
*new_kernel;
char
- token[MaxTextExtent];
+ *kernel_cache,
+ token[MagickPathExtent];
const char
*p;
- size_t
- kernel_number;
-
if (kernel_string == (const char *) NULL)
return(ParseKernelArray(kernel_string));
- p = kernel_string;
- kernel = NULL;
- kernel_number = 0;
-
- while ( GetMagickToken(p,NULL,token), *token != '\0' ) {
-
- /* ignore extra or multiple ';' kernel separators */
- if ( *token != ';' ) {
-
- /* tokens starting with alpha is a Named kernel */
- if (isalpha((int) ((unsigned char) *token)) != 0)
- new_kernel = ParseKernelName(p);
- else /* otherwise a user defined kernel array */
- new_kernel = ParseKernelArray(p);
-
- /* Error handling -- this is not proper error handling! */
- if ( new_kernel == (KernelInfo *) NULL ) {
- (void) FormatLocaleFile(stderr,"Failed to parse kernel number #%.20g\n",
- (double) kernel_number);
- if ( kernel != (KernelInfo *) NULL )
- kernel=DestroyKernelInfo(kernel);
+ p=kernel_string;
+ kernel_cache=(char *) NULL;
+ if (*kernel_string == '@')
+ {
+ kernel_cache=FileToString(kernel_string+1,~0UL,exception);
+ if (kernel_cache == (char *) NULL)
return((KernelInfo *) NULL);
- }
+ p=(const char *) kernel_cache;
+ }
+ kernel=NULL;
+ while (GetMagickToken(p,NULL,token), *token != '\0')
+ {
+ /* ignore extra or multiple ';' kernel separators */
+ if (*token != ';')
+ {
+ /* tokens starting with alpha is a Named kernel */
+ if (isalpha((int) ((unsigned char) *token)) != 0)
+ new_kernel=ParseKernelName(p,exception);
+ else /* otherwise a user defined kernel array */
+ new_kernel=ParseKernelArray(p);
+
+ /* Error handling -- this is not proper error handling! */
+ if (new_kernel == (KernelInfo *) NULL)
+ {
+ if (kernel != (KernelInfo *) NULL)
+ kernel=DestroyKernelInfo(kernel);
+ return((KernelInfo *) NULL);
+ }
- /* initialise or append the kernel list */
- if ( kernel == (KernelInfo *) NULL )
- kernel = new_kernel;
- else
- LastKernelInfo(kernel)->next = new_kernel;
- }
+ /* initialise or append the kernel list */
+ if (kernel == (KernelInfo *) NULL)
+ kernel=new_kernel;
+ else
+ LastKernelInfo(kernel)->next=new_kernel;
+ }
/* look for the next kernel in list */
- p = strchr(p, ';');
- if ( p == (char *) NULL )
+ p=strchr(p,';');
+ if (p == (char *) NULL)
break;
p++;
-
}
+ if (kernel_cache != (char *) NULL)
+ kernel_cache=DestroyString(kernel_cache);
return(kernel);
}
-
\f
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
MagickExport KernelInfo *AcquireKernelBuiltIn(const KernelInfoType type,
- const GeometryInfo *args)
+ const GeometryInfo *args,ExceptionInfo *exception)
{
KernelInfo
*kernel;
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;
}
ScaleKernelInfo(kernel, (double) (1.0/2.0*MagickSQ2), NoValue);
break;
case 10:
- kernel=AcquireKernelInfo("FreiChen:11;FreiChen:12;FreiChen:13;FreiChen:14;FreiChen:15;FreiChen:16;FreiChen:17;FreiChen:18;FreiChen:19");
+ {
+ kernel=AcquireKernelInfo("FreiChen:11;FreiChen:12;FreiChen:13;FreiChen:14;FreiChen:15;FreiChen:16;FreiChen:17;FreiChen:18;FreiChen:19",exception);
if (kernel == (KernelInfo *) NULL)
return(kernel);
break;
+ }
case 1:
case 11:
kernel=ParseKernelArray("3: 1,0,-1 2,0,-2 1,0,-1");
}
case EdgesKernel:
{
- kernel=AcquireKernelInfo("ThinSE:482");
+ kernel=AcquireKernelInfo("ThinSE:482",exception);
if (kernel == (KernelInfo *) NULL)
return(kernel);
kernel->type = type;
}
case CornersKernel:
{
- kernel=AcquireKernelInfo("ThinSE:87");
+ kernel=AcquireKernelInfo("ThinSE:87",exception);
if (kernel == (KernelInfo *) NULL)
return(kernel);
kernel->type = type;
case 0:
default:
/* set of kernels to find all end of lines */
- return(AcquireKernelInfo("LineEnds:1>;LineEnds:2>"));
+ return(AcquireKernelInfo("LineEnds:1>;LineEnds:2>",exception));
case 1:
/* kernel for 4-connected line ends - no rotation */
kernel=ParseKernelArray("3: 0,0,- 0,1,1 0,0,-");
case 0:
default:
/* set of kernels to find all line junctions */
- return(AcquireKernelInfo("LineJunctions:1@;LineJunctions:2>"));
+ return(AcquireKernelInfo("LineJunctions:1@;LineJunctions:2>",exception));
case 1:
/* Y Junction */
kernel=ParseKernelArray("3: 1,-,1 -,1,- -,1,-");
/* Traditional Skeleton...
** A cyclically rotated single kernel
*/
- kernel=AcquireKernelInfo("ThinSE:482");
+ kernel=AcquireKernelInfo("ThinSE:482",exception);
if (kernel == (KernelInfo *) NULL)
return(kernel);
kernel->type = type;
** Corners of the traditional method made more forgiving,
** but the retain the same cyclic order.
*/
- kernel=AcquireKernelInfo("ThinSE:482; ThinSE:87x90;");
+ kernel=AcquireKernelInfo("ThinSE:482; ThinSE:87x90;",exception);
if (kernel == (KernelInfo *) NULL)
return(kernel);
if (kernel->next == (KernelInfo *) NULL)
** by Dan S. Bloomberg, available on Leptonica, Selected Papers,
** http://www.leptonica.com/papers/conn.pdf
*/
- kernel=AcquireKernelInfo(
- "ThinSE:41; ThinSE:42; ThinSE:43");
+ kernel=AcquireKernelInfo("ThinSE:41; ThinSE:42; ThinSE:43",
+ exception);
if (kernel == (KernelInfo *) NULL)
return(kernel);
kernel->type = type;
MagickExport KernelInfo *DestroyKernelInfo(KernelInfo *kernel)
{
assert(kernel != (KernelInfo *) NULL);
- if ( kernel->next != (KernelInfo *) NULL )
+ if (kernel->next != (KernelInfo *) NULL)
kernel->next=DestroyKernelInfo(kernel->next);
kernel->values=(MagickRealType *) RelinquishAlignedMemory(kernel->values);
kernel=(KernelInfo *) RelinquishMagickMemory(kernel);
/* 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:
changes[i]=0;
if ((method == ConvolveMorphology) && (kernel->width == 1))
{
- const int
- id = GetOpenMPThreadId();
-
register ssize_t
x;
#endif
for (x=0; x < (ssize_t) image->columns; x++)
{
+ const int
+ id = GetOpenMPThreadId();
+
register const Quantum
*restrict p;
if ((traits == UndefinedPixelTrait) ||
(morphology_traits == UndefinedPixelTrait))
continue;
- if (((morphology_traits & CopyPixelTrait) != 0) ||
+ if (((traits & CopyPixelTrait) != 0) ||
(GetPixelReadMask(image,p+center) == 0))
{
SetPixelChannel(morphology_image,channel,p[center+i],q);
k=(&kernel->values[kernel->width*kernel->height-1]);
pixels=p;
pixel=bias;
+ gamma=0.0;
count=0;
if ((morphology_traits & BlendPixelTrait) == 0)
+ for (v=0; v < (ssize_t) kernel->height; v++)
{
- /*
- No alpha blending.
- */
- for (v=0; v < (ssize_t) kernel->height; v++)
+ for (u=0; u < (ssize_t) kernel->width; u++)
{
- for (u=0; u < (ssize_t) kernel->width; u++)
- {
- if (IfNaN(*k) == MagickFalse)
- {
- pixel+=(*k)*pixels[i];
- count++;
- }
- k--;
- pixels+=GetPixelChannels(image);
- }
+ if (!IsNaN(*k))
+ {
+ pixel+=(*k)*pixels[i];
+ gamma+=(*k);
+ count++;
+ }
+ k--;
+ pixels+=GetPixelChannels(image);
}
- if (fabs(pixel-p[center+i]) > MagickEpsilon)
- changes[id]++;
- gamma=(double) kernel->height*kernel->width/count;
- SetPixelChannel(morphology_image,channel,ClampToQuantum(gamma*
- pixel),q);
- continue;
}
- /*
- Alpha blending.
- */
- gamma=0.0;
- for (v=0; v < (ssize_t) kernel->height; v++)
- {
- for (u=0; u < (ssize_t) kernel->width; u++)
+ else
+ for (v=0; v < (ssize_t) kernel->height; v++)
{
- if (IfNaN(*k) == MagickFalse)
- {
- alpha=(double) (QuantumScale*GetPixelAlpha(image,pixels));
- pixel+=(*k)*alpha*pixels[i];
- gamma+=(*k)*alpha;
- count++;
- }
- k--;
- pixels+=GetPixelChannels(image);
+ for (u=0; u < (ssize_t) kernel->width; u++)
+ {
+ if (!IsNaN(*k))
+ {
+ alpha=(double) (QuantumScale*GetPixelAlpha(image,pixels));
+ pixel+=alpha*(*k)*pixels[i];
+ gamma+=alpha*(*k);
+ count++;
+ }
+ k--;
+ pixels+=GetPixelChannels(image);
+ }
}
- }
if (fabs(pixel-p[center+i]) > MagickEpsilon)
changes[id]++;
gamma=PerceptibleReciprocal(gamma);
- gamma*=(double) kernel->height*kernel->width/count;
+ if (count != 0)
+ gamma*=(double) kernel->height*kernel->width/count;
SetPixelChannel(morphology_image,channel,ClampToQuantum(gamma*
pixel),q);
}
double
alpha,
gamma,
+ intensity,
maximum,
minimum,
pixel;
if ((traits == UndefinedPixelTrait) ||
(morphology_traits == UndefinedPixelTrait))
continue;
- if (((morphology_traits & CopyPixelTrait) != 0) ||
+ if (((traits & CopyPixelTrait) != 0) ||
(GetPixelReadMask(image,p+center) == 0))
{
SetPixelChannel(morphology_image,channel,p[center+i],q);
/*
Weighted Average of pixels using reflected kernel
- For correct working of this operation for asymetrical
- kernels, the kernel needs to be applied in its reflected form.
- That is its values needs to be reversed.
+ For correct working of this operation for asymetrical kernels,
+ the kernel needs to be applied in its reflected form. That is
+ its values needs to be reversed.
Correlation is actually the same as this but without reflecting
- the kernel, and thus 'lower-level' that Convolution. However
- as Convolution is the more common method used, and it does not
+ the kernel, and thus 'lower-level' that Convolution. However as
+ Convolution is the more common method used, and it does not
really cost us much in terms of processing to use a reflected
kernel, so it is Convolution that is implemented.
- Correlation will have its kernel reflected before calling
- this function to do a Convolve.
+ Correlation will have its kernel reflected before calling this
+ function to do a Convolve.
For more details of Correlation vs Convolution see
http://www.cs.umd.edu/~djacobs/CMSC426/Convolution.pdf
{
for (u=0; u < (ssize_t) kernel->width; u++)
{
- if (IfNaN(*k) == MagickFalse)
+ if (!IsNaN(*k))
{
pixel+=(*k)*pixels[i];
count++;
/*
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+=(*k)*alpha*pixels[i];
- gamma+=(*k)*alpha;
+ pixel+=alpha*(*k)*pixels[i];
+ gamma+=alpha*(*k);
count++;
}
k--;
{
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];
- count++;
}
k--;
pixels+=GetPixelChannels(image);
{
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);
if (fabs(pixel-p[center+i]) > MagickEpsilon)
changes[id]++;
gamma=PerceptibleReciprocal(gamma);
- gamma*=(double) kernel->height*kernel->width/count;
+ if (count != 0)
+ gamma*=(double) kernel->height*kernel->width/count;
SetPixelChannel(morphology_image,channel,ClampToQuantum(gamma*pixel),q);
}
p+=GetPixelChannels(image);
q+=GetPixelChannels(morphology_image);
}
- if ( SyncCacheViewAuthenticPixels(morphology_view,exception) == MagickFalse)
+ if (SyncCacheViewAuthenticPixels(morphology_view,exception) == MagickFalse)
status=MagickFalse;
if (image->progress_monitor != (MagickProgressMonitor) NULL)
{
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);
pixels+=(image->columns-1)*GetPixelChannels(image);
}
k=(&kernel->values[kernel->width*kernel->y+kernel->x-1]);
- pixels=q-offset.x*GetPixelChannels(image);
+ pixels=q;
for (u=offset.x+1; u < (ssize_t) kernel->width; u++)
{
- if ((IfNaN(*k) == MagickFalse) &&
- ((x+u-offset.x) < (ssize_t) image->columns))
+ pixels+=GetPixelChannels(image);
+ if (!IsNaN(*k) && ((x+u-offset.x) < (ssize_t) image->columns))
{
if ((pixels[i]+(*k)) < pixel)
pixel=(double) pixels[i]+(*k);
}
k--;
- pixels+=GetPixelChannels(image);
}
break;
}
{
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+=(image->columns-1)*GetPixelChannels(image);
}
k=(&kernel->values[kernel->width*(kernel->y+1)-1]);
- pixels=q-offset.x*GetPixelChannels(image);
+ pixels=q;
for (u=offset.x+1; u < (ssize_t) kernel->width; u++)
{
- if ((IfNaN(*k) == MagickFalse) &&
- ((x+u-offset.x) < (ssize_t) image->columns))
+ pixels+=GetPixelChannels(image);
+ if (!IsNaN(*k) && ((x+u-offset.x) < (ssize_t) image->columns))
{
if ((pixels[i]+(*k)) < pixel)
pixel=(double) pixels[i]+(*k);
}
k--;
- pixels+=GetPixelChannels(image);
}
break;
}
changed; /* number pixels changed by last primitive operation */
char
- v_info[80];
+ 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
count++;
changed = MorphologyPrimitive(curr_image, work_image, primitive,
this_kernel, bias, exception);
-
if ( IfMagickTrue(verbose) ) {
if ( kernel_loop > 1 )
(void) FormatLocaleFile(stderr, "\n"); /* add end-of-line from previous */
%
% 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;
}