% 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)
*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);
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;
if (kernel_string == (const char *) NULL)
return(ParseKernelArray(kernel_string));
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 */
{
/* tokens starting with alpha is a Named kernel */
if (isalpha((int) ((unsigned char) *token)) != 0)
- new_kernel=ParseKernelName(p);
+ new_kernel=ParseKernelName(p,exception);
else /* otherwise a user defined kernel array */
new_kernel=ParseKernelArray(p);
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;
/* 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 )
*image_view,
*morphology_view;
- MagickBooleanType
- status;
-
- MagickOffsetType
- progress;
-
OffsetInfo
offset;
- PixelChannel
- channel[MaxPixelChannels];
-
- PixelTrait
- morphology_traits[MaxPixelChannels],
- traits[MaxPixelChannels];
-
register ssize_t
i;
+ ssize_t
+ y;
+
size_t
*changes,
changed,
width;
- ssize_t
- y;
+ MagickBooleanType
+ status;
+
+ MagickOffsetType
+ 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;
offset.y=0;
switch (method)
}
default:
{
- assert("not a primitive morphology method" != (char *) NULL);
+ assert("Not a Primitive Morphology Method" != (char *) NULL);
break;
}
}
ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
for (i=0; i < (ssize_t) GetOpenMPMaximumThreads(); i++)
changes[i]=0;
- for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
- {
- channel[i]=GetPixelChannelChannel(image,i);
- traits[i]=GetPixelChannelTraits(image,channel[i]);
- morphology_traits[i]=GetPixelChannelTraits(morphology_image,channel[i]);
- }
- image_view=AcquireVirtualCacheView(image,exception);
- morphology_view=AcquireAuthenticCacheView(morphology_image,exception);
if ((method == ConvolveMorphology) && (kernel->width == 1))
{
- const int
- id = GetOpenMPThreadId();
-
- ssize_t
+ register ssize_t
x;
/*
- Optimized 1-D vertical (column-based) convolution kernel.
- */
+ Special handling (for speed) of vertical (blur) kernels. This performs
+ its handling in columns rather than in rows. This is only done
+ for convolve as it is the only method that generates very large 1-D
+ vertical kernels (such as a 'BlurKernel')
+ */
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(progress,status) \
- magick_threads(image,morphology_image,image->columns,1)
+ #pragma omp parallel for schedule(static,4) shared(progress,status) \
+ magick_threads(image,morphology_image,image->columns,1)
#endif
for (x=0; x < (ssize_t) image->columns; x++)
{
+ const int
+ id = GetOpenMPThreadId();
+
register const Quantum
*restrict p;
center=(ssize_t) GetPixelChannels(image)*offset.y;
for (y=0; y < (ssize_t) image->rows; y++)
{
- double
- gamma[MaxPixelChannels],
- pixel[MaxPixelChannels];
+ register ssize_t
+ i;
- register const MagickRealType
- *restrict k;
+ for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+ {
+ double
+ alpha,
+ gamma,
+ pixel;
- register const Quantum
- *restrict pixels;
+ PixelChannel
+ channel;
- register ssize_t
- i;
+ PixelTrait
+ morphology_traits,
+ traits;
- size_t
- count[MaxPixelChannels];
+ register const MagickRealType
+ *restrict k;
- ssize_t
- v;
+ register const Quantum
+ *restrict pixels;
- for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
- {
- pixel[i]=bias;
- gamma[i]=0.0;
- count[i]=0;
- }
- pixels=p;
- k=(&kernel->values[kernel->width*kernel->height-1]);
- for (v=0; v < (ssize_t) kernel->height; v++)
- {
register ssize_t
u;
- for (u=0; u < (ssize_t) kernel->width; u++)
- {
- if (IfNaN(*k) == MagickFalse)
- for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
- {
- double
- alpha;
-
- alpha=(double) (QuantumScale*GetPixelAlpha(image,pixels));
- if ((traits[i] & BlendPixelTrait) == 0)
- alpha=1.0;
- pixel[i]+=alpha*(*k)*pixels[i];
- gamma[i]+=alpha*(*k);
- count[i]++;
- }
- k--;
- pixels+=GetPixelChannels(image);
- }
- }
- for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
- {
- if ((traits[i] == UndefinedPixelTrait) ||
- (morphology_traits[i] == UndefinedPixelTrait))
+ size_t
+ count;
+
+ ssize_t
+ v;
+
+ channel=GetPixelChannelChannel(image,i);
+ traits=GetPixelChannelTraits(image,channel);
+ morphology_traits=GetPixelChannelTraits(morphology_image,channel);
+ if ((traits == UndefinedPixelTrait) ||
+ (morphology_traits == UndefinedPixelTrait))
continue;
- if (GetPixelReadMask(image,p+center) == 0)
+ if (((traits & CopyPixelTrait) != 0) ||
+ (GetPixelReadMask(image,p+center) == 0))
{
- SetPixelChannel(morphology_image,channel[i],p[center+i],q);
+ SetPixelChannel(morphology_image,channel,p[center+i],q);
continue;
}
- if (fabs(pixel[i]-p[center+i]) > MagickEpsilon)
+ 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++)
+ {
+ for (u=0; u < (ssize_t) kernel->width; u++)
+ {
+ if (!IsNaN(*k))
+ {
+ pixel+=(*k)*pixels[i];
+ gamma+=(*k);
+ count++;
+ }
+ k--;
+ pixels+=GetPixelChannels(image);
+ }
+ }
+ else
+ for (v=0; v < (ssize_t) kernel->height; v++)
+ {
+ 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[i]=PerceptibleReciprocal(gamma[i]);
- if (count[i] != 0)
- gamma[i]*=(double) kernel->height*kernel->width/count[i];
- SetPixelChannel(morphology_image,channel[i],ClampToQuantum(gamma[i]*
- pixel[i]),q);
+ gamma=PerceptibleReciprocal(gamma);
+ 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);
/*
Normal handling of horizontal or rectangular kernels (row by row).
*/
- width=image->columns+kernel->width-1;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
magick_threads(image,morphology_image,image->rows,1)
double
alpha,
gamma,
+ intensity,
maximum,
minimum,
pixel;
if ((traits == UndefinedPixelTrait) ||
(morphology_traits == UndefinedPixelTrait))
continue;
- if (GetPixelReadMask(image,p+center) == 0)
+ if (((traits & CopyPixelTrait) != 0) ||
+ (GetPixelReadMask(image,p+center) == 0))
{
SetPixelChannel(morphology_image,channel,p[center+i],q);
continue;
/*
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
*/
k=(&kernel->values[kernel->width*kernel->height-1]);
+ count=0;
if ((morphology_traits & BlendPixelTrait) == 0)
{
/*
{
for (u=0; u < (ssize_t) kernel->width; u++)
{
- if (IfNaN(*k) == MagickFalse)
- pixel+=(*k)*pixels[i];
+ if (!IsNaN(*k))
+ {
+ pixel+=(*k)*pixels[i];
+ count++;
+ }
k--;
pixels+=GetPixelChannels(image);
}
/*
Alpha blending.
*/
- count=0;
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];
- 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);
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[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;
* This is done BEFORE the ShowKernelInfo() function is called so that
* users can see the results of the 'option:convolve:scale' option.
*/
- if ((method == ConvolveMorphology) || (method == CorrelateMorphology)) {
+ if ( method == ConvolveMorphology || method == CorrelateMorphology ) {
const char
*artifact;
/* 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;
}