92 #define Minimize(assign,value) assign=MagickMin(assign,value) 93 #define Maximize(assign,value) assign=MagickMax(assign,value) 97 static inline size_t fact(
size_t n)
100 for(f=1, l=2; l <= n; f=f*l, l++);
104 #define fact(n) ((size_t)tgamma((double)n+1)) 106 #define fact(n) ((size_t)lgamma((double)n+1)) 230 nan = sqrt((
double)-1.0);
241 (void) memset(kernel,0,
sizeof(*kernel));
247 if (kernel_string == (
const char *) NULL)
251 end = strchr(kernel_string,
';');
252 if ( end == (
char *) NULL )
253 end = strchr(kernel_string,
'\0');
261 p = strchr(kernel_string,
':');
262 if ( p != (
char *) NULL && p < end)
265 memcpy(token, kernel_string, (
size_t) (p-kernel_string));
266 token[p-kernel_string] =
'\0';
273 if ( args.
rho < 1.0 )
275 if ( args.
sigma < 1.0 )
281 if ( args.
xi < 0.0 || args.
psi < 0.0 )
283 kernel->
x = ((flags &
XValue)!=0) ? (ssize_t)args.
xi 284 : (ssize_t) (kernel->
width-1)/2;
285 kernel->
y = ((flags &
YValue)!=0) ? (ssize_t)args.
psi 286 : (ssize_t) (kernel->
height-1)/2;
287 if ( kernel->
x >= (ssize_t) kernel->
width ||
288 kernel->
y >= (ssize_t) kernel->
height )
296 p=(
const char *) kernel_string;
297 while ((isspace((
int) ((
unsigned char) *p)) != 0) || (*p ==
'\''))
299 for (i=0; p < end; i++)
306 kernel->
width = kernel->
height= (size_t) sqrt((
double) i+1.0);
307 kernel->
x = kernel->
y = (ssize_t) (kernel->
width-1)/2;
308 p=(
const char *) kernel_string;
309 while ((isspace((
int) ((
unsigned char) *p)) != 0) || (*p ==
'\''))
321 for (i=0; (i < (ssize_t) (kernel->
width*kernel->
height)) && (p < end); i++)
342 if ( *token !=
'\0' && *token !=
';' && *token !=
'\'' )
347 if ( i < (ssize_t) (kernel->
width*kernel->
height) ) {
350 for ( ; i < (ssize_t) (kernel->
width*kernel->
height); i++)
355 if ( i < (ssize_t) (kernel->
width*kernel->
height) )
401 while (((isspace((
int) ((
unsigned char) *p)) != 0) ||
402 (*p ==
',') || (*p ==
':' )) && (*p !=
'\0') && (*p !=
';'))
405 end = strchr(p,
';');
406 if ( end == (
char *) NULL )
407 end = strchr(p,
'\0');
410 memcpy(token, p, (
size_t) (end-p));
417 (void)
FormatLocaleFile(stderr,
"Geometry = 0x%04X : %lg x %lg %+lg %+lg\n",
438 if ( (flags &
XValue) == 0 )
444 if ( args.
rho < 1.0 )
446 if ( args.
sigma < 1.0 )
448 if ( (flags &
XValue) == 0 )
449 args.
xi = (
double)(((ssize_t)args.
rho-1)/2);
450 if ( (flags &
YValue) == 0 )
451 args.
psi = (
double)(((ssize_t)args.
sigma-1)/2);
500 if (kernel_string == (
const char *) NULL)
503 kernel_cache=(
char *) NULL;
504 if (*kernel_string ==
'@')
506 kernel_cache=
FileToString(kernel_string+1,~0UL,exception);
507 if (kernel_cache == (
char *) NULL)
509 p=(
const char *) kernel_cache;
518 if (isalpha((
int) ((
unsigned char) *token)) != 0)
540 if (p == (
char *) NULL)
544 if (kernel_cache != (
char *) NULL)
965 nan = sqrt((
double)-1.0);
972 assert(
"Should not call this function" != (
char *) NULL);
1011 case OctangonalKernel:
1020 (void) memset(kernel,0,
sizeof(*kernel));
1023 kernel->
type = type;
1036 kernel->
x = kernel->
y = (ssize_t) 0;
1049 sigma = fabs(args->
sigma),
1050 sigma2 = fabs(args->
xi),
1053 if ( args->
rho >= 1.0 )
1054 kernel->
width = (size_t)args->
rho*2+1;
1055 else if ( (type !=
DoGKernel) || (sigma >= sigma2) )
1060 kernel->
x = kernel->
y = (ssize_t) (kernel->
width-1)/2;
1063 sizeof(*kernel->
values)));
1077 { A = 1.0/(2.0*sigma*sigma);
1078 B = (double) (1.0/(
Magick2PI*sigma*sigma));
1079 for ( i=0, v=-kernel->
y; v <= (ssize_t)kernel->
y; v++)
1080 for ( u=-kernel->
x; u <= (ssize_t)kernel->
x; u++, i++)
1081 kernel->
values[i] = exp(-((
double)(u*u+v*v))*A)*B;
1084 { (void) memset(kernel->
values,0, (
size_t)
1094 A = 1.0/(2.0*sigma*sigma);
1095 B = (double) (1.0/(
Magick2PI*sigma*sigma));
1096 for ( i=0, v=-kernel->
y; v <= (ssize_t)kernel->
y; v++)
1097 for ( u=-kernel->
x; u <= (ssize_t)kernel->
x; u++, i++)
1098 kernel->
values[i] -= exp(-((
double)(u*u+v*v))*A)*B;
1107 { A = 1.0/(2.0*sigma*sigma);
1108 B = (double) (1.0/(
MagickPI*sigma*sigma*sigma*sigma));
1109 for ( i=0, v=-kernel->
y; v <= (ssize_t)kernel->
y; v++)
1110 for ( u=-kernel->
x; u <= (ssize_t)kernel->
x; u++, i++)
1111 { R = ((double)(u*u+v*v))*A;
1112 kernel->
values[i] = (1-R)*exp(-R)*B;
1116 { (void) memset(kernel->
values,0, (
size_t)
1142 sigma = fabs(args->
sigma),
1145 if ( args->
rho >= 1.0 )
1146 kernel->
width = (size_t)args->
rho*2+1;
1150 kernel->
x = (ssize_t) (kernel->
width-1)/2;
1155 sizeof(*kernel->
values)));
1160 #define KernelRank 3 1176 (void) memset(kernel->
values,0, (
size_t)
1181 alpha = 1.0/(2.0*sigma*sigma);
1183 for ( u=-v; u <= v; u++) {
1185 exp(-((
double)(u*u))*alpha)*beta;
1196 { alpha = 1.0/(2.0*sigma*sigma);
1198 for ( i=0, u=-kernel->
x; u <= (ssize_t)kernel->
x; u++, i++)
1199 kernel->
values[i] = exp(-((
double)(u*u))*alpha)*beta;
1202 { (void) memset(kernel->
values,0, (
size_t)
1230 sigma = fabs(args->
sigma),
1233 if ( args->
rho < 1.0 )
1237 kernel->
x = kernel->
y = 0;
1242 sizeof(*kernel->
values)));
1259 #define KernelRank 3 1261 (
void) memset(kernel->
values,0, (
size_t)
1264 A = 1.0/(2.0*sigma*sigma);
1266 for ( u=0; u < v; u++) {
1268 exp(-((
double)(u*u))*A);
1271 for (i=0; i < (ssize_t) kernel->
width; i++)
1274 A = 1.0/(2.0*sigma*sigma);
1276 for ( i=0; i < (ssize_t) kernel->
width; i++)
1278 kernel->
values[i] = exp(-((
double)(i*i))*A);
1283 { (void) memset(kernel->
values,0, (
size_t)
1302 if (args->
rho < 1.0)
1306 kernel->
x = kernel->
y = (ssize_t) (kernel->
width-1)/2;
1312 sizeof(*kernel->
values)));
1317 for ( i=0, v=0; v < (ssize_t)kernel->
height; v++)
1319 alpha = order_f / (
fact((
size_t) v) *
fact(kernel->
height-v-1) );
1320 for ( u=0; u < (ssize_t)kernel->
width; u++, i++)
1322 (alpha * order_f / (
fact((
size_t) u) *
fact(kernel->
height-u-1) ));
1334 {
switch ( (
int) args->
rho ) {
1350 "5: -4,-1,0,-1,-4 -1,2,3,2,-1 0,3,4,3,0 -1,2,3,2,-1 -4,-1,0,-1,-4");
1354 "7:-10,-5,-2,-1,-2,-5,-10 -5,0,3,4,3,0,-5 -2,3,6,7,6,3,-2 -1,4,7,8,7,4,-1 -2,3,6,7,6,3,-2 -5,0,3,4,3,0,-5 -10,-5,-2,-1,-2,-5,-10" );
1358 "5: 0,0,-1,0,0 0,-1,-2,-1,0 -1,-2,16,-2,-1 0,-1,-2,-1,0 0,0,-1,0,0");
1363 "9: 0,-1,-1,-2,-2,-2,-1,-1,0 -1,-2,-4,-5,-5,-5,-4,-2,-1 -1,-4,-5,-3,-0,-3,-5,-4,-1 -2,-5,-3,12,24,12,-3,-5,-2 -2,-5,-0,24,40,24,-0,-5,-2 -2,-5,-3,12,24,12,-3,-5,-2 -1,-4,-5,-3,-0,-3,-5,-4,-1 -1,-2,-4,-5,-5,-5,-4,-2,-1 0,-1,-1,-2,-2,-2,-1,-1,0");
1368 kernel->
type = type;
1376 kernel->
type = type;
1385 kernel->
type = type;
1394 kernel->
type = type;
1403 kernel->
type = type;
1412 kernel->
type = type;
1420 {
switch ( (
int) args->
rho ) {
1426 kernel->
type = type;
1435 kernel->
type = type;
1443 kernel=
AcquireKernelInfo(
"FreiChen:11;FreiChen:12;FreiChen:13;FreiChen:14;FreiChen:15;FreiChen:16;FreiChen:17;FreiChen:18;FreiChen:19",exception);
1453 kernel->
type = type;
1463 kernel->
type = type;
1473 kernel->
type = type;
1483 kernel->
type = type;
1493 kernel->
type = type;
1500 kernel->
type = type;
1507 kernel->
type = type;
1514 kernel->
type = type;
1521 kernel->
type = type;
1528 else if ( args->
rho > 30.0 || args->
rho < -30.0 )
1539 if (args->
rho < 1.0)
1543 kernel->
x = kernel->
y = (ssize_t) (kernel->
width-1)/2;
1547 sizeof(*kernel->
values)));
1552 for ( i=0, v=-kernel->
y; v <= (ssize_t)kernel->
y; v++)
1553 for ( u=-kernel->
x; u <= (ssize_t)kernel->
x; u++, i++)
1554 if ( (labs((
long) u)+labs((
long) v)) <= (long) kernel->
x)
1567 if (args->
rho < 1.0)
1571 kernel->
x = kernel->
y = (ssize_t) (kernel->
width-1)/2;
1572 scale = args->
sigma;
1576 if ( args->
rho < 1.0 || args->
sigma < 1.0 )
1580 if ( args->
xi < 0.0 || args->
xi > (
double)kernel->
width ||
1581 args->
psi < 0.0 || args->
psi > (double)kernel->
height )
1583 kernel->
x = (ssize_t) args->
xi;
1584 kernel->
y = (ssize_t) args->
psi;
1589 sizeof(*kernel->
values)));
1595 for ( i=0; i < u; i++)
1596 kernel->
values[i] = scale;
1603 if (args->
rho < 1.0)
1607 kernel->
x = kernel->
y = (ssize_t) (kernel->
width-1)/2;
1611 sizeof(*kernel->
values)));
1615 for ( i=0, v=-kernel->
y; v <= (ssize_t)kernel->
y; v++)
1616 for ( u=-kernel->
x; u <= (ssize_t)kernel->
x; u++, i++)
1617 if ( (labs((
long) u)+labs((
long) v)) <=
1618 ((long)kernel->
x + (
long)(kernel->
x/2)) )
1628 limit = (ssize_t)(args->
rho*args->
rho);
1630 if (args->
rho < 0.4)
1634 kernel->
x = kernel->
y = (ssize_t) (kernel->
width-1)/2;
1638 sizeof(*kernel->
values)));
1642 for ( i=0, v=-kernel->
y; v <= (ssize_t)kernel->
y; v++)
1643 for ( u=-kernel->
x; u <= (ssize_t)kernel->
x; u++, i++)
1644 if ((u*u+v*v) <= limit)
1653 if (args->
rho < 1.0)
1657 kernel->
x = kernel->
y = (ssize_t) (kernel->
width-1)/2;
1661 sizeof(*kernel->
values)));
1666 for ( i=0, v=-kernel->
y; v <= (ssize_t)kernel->
y; v++)
1667 for ( u=-kernel->
x; u <= (ssize_t)kernel->
x; u++, i++)
1668 kernel->
values[i] = (u == 0 || v == 0) ? args->
sigma : nan;
1675 if (args->
rho < 1.0)
1679 kernel->
x = kernel->
y = (ssize_t) (kernel->
width-1)/2;
1683 sizeof(*kernel->
values)));
1688 for ( i=0, v=-kernel->
y; v <= (ssize_t)kernel->
y; v++)
1689 for ( u=-kernel->
x; u <= (ssize_t)kernel->
x; u++, i++)
1690 kernel->
values[i] = (u == v || u == -v) ? args->
sigma : nan;
1709 limit1 = (ssize_t)(args->
rho*args->
rho);
1714 kernel->
width = ((size_t)args->
rho)*2+1;
1716 limit2 = (ssize_t)(args->
rho*args->
rho);
1719 kernel->
width = 7L, limit1 = 7L, limit2 = 11L;
1722 kernel->
x = kernel->
y = (ssize_t) (kernel->
width-1)/2;
1725 sizeof(*kernel->
values)));
1730 scale = (ssize_t) (( type ==
PeaksKernel) ? 0.0 : args->
xi);
1731 for ( i=0, v= -kernel->
y; v <= (ssize_t)kernel->
y; v++)
1732 for ( u=-kernel->
x; u <= (ssize_t)kernel->
x; u++, i++)
1733 { ssize_t radius=u*u+v*v;
1734 if (limit1 < radius && radius <= limit2)
1753 kernel->
type = type;
1762 kernel->
type = type;
1768 switch ( (
int) args->
rho ) {
1776 kernel->
type = type;
1780 new_kernel->
type = type;
1794 kernel->
type = type;
1800 switch ( (
int) args->
rho ) {
1824 kernel->
type = type;
1830 switch ( (
int) args->
rho ) {
1858 kernel->
type = type;
1866 switch ( (
int) args->
rho ) {
1872 kernel->
type = type;
1879 kernel->
type = type;
1888 new_kernel->
type = type;
1893 new_kernel->
type = type;
1898 new_kernel->
type = type;
1903 new_kernel->
type = type;
1908 new_kernel->
type = type;
1913 new_kernel->
type = type;
1918 new_kernel->
type = type;
1923 new_kernel->
type = type;
1937 kernel->
type = type;
1943 new_kernel->
type = type;
1950 switch ( (
int) args->
rho ) {
1959 kernel->
type = type;
1972 kernel->
type = type;
1986 kernel->
type = type;
2005 switch ( (
int) args->
rho ) {
2079 kernel->
type = type;
2088 if (args->
rho < 1.0)
2092 kernel->
x = kernel->
y = (ssize_t) (kernel->
width-1)/2;
2096 sizeof(*kernel->
values)));
2100 for ( i=0, v=-kernel->
y; v <= (ssize_t)kernel->
y; v++)
2101 for ( u=-kernel->
x; u <= (ssize_t)kernel->
x; u++, i++)
2109 if (args->
rho < 1.0)
2113 kernel->
x = kernel->
y = (ssize_t) (kernel->
width-1)/2;
2117 sizeof(*kernel->
values)));
2121 for ( i=0, v=-kernel->
y; v <= (ssize_t)kernel->
y; v++)
2122 for ( u=-kernel->
x; u <= (ssize_t)kernel->
x; u++, i++)
2124 args->
sigma*(labs((
long) u)+labs((
long) v)) );
2130 if (args->
rho < 2.0)
2134 kernel->
x = kernel->
y = (ssize_t) (kernel->
width-1)/2;
2138 sizeof(*kernel->
values)));
2142 for ( i=0, v=-kernel->
y; v <= (ssize_t)kernel->
y; v++)
2143 for ( u=-kernel->
x; u <= (ssize_t)kernel->
x; u++, i++)
2146 r1 =
MagickMax(fabs((
double)u),fabs((
double)v)),
2147 r2 = floor((
double)(labs((
long)u)+labs((
long)v)+1)/1.5);
2156 if (args->
rho < 1.0)
2160 kernel->
x = kernel->
y = (ssize_t) (kernel->
width-1)/2;
2164 sizeof(*kernel->
values)));
2168 for ( i=0, v=-kernel->
y; v <= (ssize_t)kernel->
y; v++)
2169 for ( u=-kernel->
x; u <= (ssize_t)kernel->
x; u++, i++)
2171 args->
sigma*sqrt((
double)(u*u+v*v)) );
2225 *new_kernel=(*kernel);
2232 for (i=0; i < (ssize_t) (kernel->
width*kernel->
height); i++)
2310 static void FlopKernelInfo(
KernelInfo *kernel)
2319 for ( y=0, k=kernel->
values; y < kernel->height; y++, k+=kernel->
width)
2320 for ( x=0, r=kernel->
width-1; x<kernel->width/2; x++, r--)
2321 t=k[x], k[x]=k[r], k[r]=t;
2323 kernel->
x = kernel->
width - kernel->
x - 1;
2324 angle = fmod(angle+180.0, 360.0);
2401 || kernel1->
x != kernel2->
x 2402 || kernel1->
y != kernel2->
y )
2406 for (i=0; i < (kernel1->
width*kernel1->
height); i++) {
2488 for (i=0; i < (kernel->
width*kernel->
height); i++)
2566 #define MorphologyTag "Morphology/Image" 2590 assert(image != (
Image *) NULL);
2592 assert(morphology_image != (
Image *) NULL);
2615 offset.
x=(ssize_t) kernel->
width-kernel->
x-1;
2616 offset.
y=(ssize_t) kernel->
height-kernel->
y-1;
2631 assert(
"Not a Primitive Morphology Method" != (
char *) NULL);
2638 if (changes == (
size_t *) NULL)
2654 #if defined(MAGICKCORE_OPENMP_SUPPORT) 2655 #pragma omp parallel for schedule(static) shared(progress,status) \ 2656 magick_number_threads(image,morphology_image,image->columns,1) 2658 for (x=0; x < (ssize_t) image->
columns; x++)
2678 kernel->
height-1,exception);
2680 morphology_image->
rows,exception);
2687 for (r=0; r < (ssize_t) image->
rows; r++)
2736 for (v=0; v < (ssize_t) kernel->
height; v++)
2740 pixel+=(*k)*pixels[i];
2749 for (v=0; v < (ssize_t) kernel->
height; v++)
2754 pixel+=alpha*(*k)*pixels[i];
2766 gamma*=(double) kernel->
height/count;
2780 #if defined(MAGICKCORE_OPENMP_SUPPORT) 2789 morphology_image->
type=image->
type;
2793 changed+=changes[j];
2795 return(status ? (ssize_t) changed : 0);
2800 #if defined(MAGICKCORE_OPENMP_SUPPORT) 2801 #pragma omp parallel for schedule(static) shared(progress,status) \ 2802 magick_number_threads(image,morphology_image,image->rows,1) 2804 for (y=0; y < (ssize_t) image->
rows; y++)
2824 kernel->
height,exception);
2834 for (x=0; x < (ssize_t) image->
columns; x++)
2884 quantum_pixels=(
const Quantum *) NULL;
2908 pixel=(double) p[center+i];
2944 for (v=0; v < (ssize_t) kernel->
height; v++)
2946 for (u=0; u < (ssize_t) kernel->
width; u++)
2950 pixel+=(*k)*pixels[i];
2964 for (v=0; v < (ssize_t) kernel->
height; v++)
2966 for (u=0; u < (ssize_t) kernel->
width; u++)
2971 pixel+=alpha*(*k)*pixels[i];
2993 for (v=0; v < (ssize_t) kernel->
height; v++)
2995 for (u=0; u < (ssize_t) kernel->
width; u++)
2997 if (!
IsNaN(*k) && (*k >= 0.5))
2999 if ((
double) pixels[i] < pixel)
3000 pixel=(
double) pixels[i];
3023 for (v=0; v < (ssize_t) kernel->
height; v++)
3025 for (u=0; u < (ssize_t) kernel->
width; u++)
3027 if (!
IsNaN(*k) && (*k > 0.5))
3029 if ((
double) pixels[i] > pixel)
3030 pixel=(
double) pixels[i];
3056 for (v=0; v < (ssize_t) kernel->
height; v++)
3058 for (u=0; u < (ssize_t) kernel->
width; u++)
3064 if ((
double) pixels[i] < pixel)
3065 pixel=(
double) pixels[i];
3070 if ((
double) pixels[i] > maximum)
3071 maximum=(
double) pixels[i];
3084 pixel=(double) p[center+i]-pixel;
3087 pixel+=(double) p[center+i]+pixel;
3098 for (v=0; v < (ssize_t) kernel->
height; v++)
3100 for (u=0; u < (ssize_t) kernel->
width; u++)
3102 if (!
IsNaN(*k) && (*k >= 0.5))
3105 if (intensity < minimum)
3107 quantum_pixels=pixels;
3108 pixel=(double) pixels[i];
3128 for (v=0; v < (ssize_t) kernel->
height; v++)
3130 for (u=0; u < (ssize_t) kernel->
width; u++)
3132 if (!
IsNaN(*k) && (*k >= 0.5))
3135 if (intensity > maximum)
3137 pixel=(double) pixels[i];
3138 quantum_pixels=pixels;
3176 for (v=0; v < (ssize_t) kernel->
height; v++)
3178 for (u=0; u < (ssize_t) kernel->
width; u++)
3182 if ((pixels[i]+(*k)) < pixel)
3183 pixel=(double) pixels[i]+(*k);
3199 if (quantum_pixels != (
const Quantum *) NULL)
3206 gamma*=(double) kernel->
height*kernel->
width/count;
3219 #if defined(MAGICKCORE_OPENMP_SUPPORT) 3231 changed+=changes[j];
3233 return(status ? (ssize_t) changed : -1);
3273 assert(image != (
Image *) NULL);
3290 offset.
x=(ssize_t) kernel->
width-kernel->
x-1;
3291 offset.
y=(ssize_t) kernel->
height-kernel->
y-1;
3307 for (y=0; y < (ssize_t) image->
rows; y++)
3329 offset.
y+1,exception);
3337 for (x=0; x < (ssize_t) image->
columns; x++)
3378 for (v=0; v <= offset.
y; v++)
3380 for (u=0; u < (ssize_t) kernel->
width; u++)
3384 if ((pixels[i]+(*k)) < pixel)
3385 pixel=(double) pixels[i]+(*k);
3394 for (u=0; u < offset.
x; u++)
3396 if (!
IsNaN(*k) && ((x+u-offset.
x) >= 0))
3398 if ((pixels[i]+(*k)) < pixel)
3399 pixel=(double) pixels[i]+(*k);
3409 for (v=0; v < offset.
y; v++)
3411 for (u=0; u < (ssize_t) kernel->
width; u++)
3415 if ((pixels[i]+(*k)) < pixel)
3416 pixel=(double) pixels[i]+(*k);
3425 for (u=0; u < offset.
x; u++)
3427 if (!
IsNaN(*k) && ((x+u-offset.
x) >= 0))
3429 if ((pixels[i]+(*k)) < pixel)
3430 pixel=(double) pixels[i]+(*k);
3454 #if defined(MAGICKCORE_OPENMP_SUPPORT) 3470 for (y=(ssize_t) image->
rows-1; y >= 0; y--)
3491 kernel->
y+1,exception);
3501 for (x=(ssize_t) image->
columns-1; x >= 0; x--)
3542 for (v=offset.
y; v < (ssize_t) kernel->
height; v++)
3544 for (u=0; u < (ssize_t) kernel->
width; u++)
3548 if ((pixels[i]+(*k)) < pixel)
3549 pixel=(double) pixels[i]+(*k);
3558 for (u=offset.
x+1; u < (ssize_t) kernel->
width; u++)
3561 if (!
IsNaN(*k) && ((x+u-offset.
x) < (ssize_t) image->
columns))
3563 if ((pixels[i]+(*k)) < pixel)
3564 pixel=(double) pixels[i]+(*k);
3573 for (v=offset.
y; v < (ssize_t) kernel->
height; v++)
3575 for (u=0; u < (ssize_t) kernel->
width; u++)
3579 if ((pixels[i]+(*k)) < pixel)
3580 pixel=(double) pixels[i]+(*k);
3589 for (u=offset.
x+1; u < (ssize_t) kernel->
width; u++)
3592 if (!
IsNaN(*k) && ((x+u-offset.
x) < (ssize_t) image->
columns))
3594 if ((pixels[i]+(*k)) < pixel)
3595 pixel=(double) pixels[i]+(*k);
3618 #if defined(MAGICKCORE_OPENMP_SUPPORT) 3629 return(status ? (ssize_t) changed : -1);
3689 assert(image != (
Image *) NULL);
3697 if ( iterations == 0 )
3698 return((
Image *) NULL);
3700 kernel_limit = (size_t) iterations;
3701 if ( iterations < 0 )
3707 curr_image = (
Image *) image;
3708 curr_compose = image->
compose;
3709 (void) curr_compose;
3710 work_image = save_image = rslt_image = (
Image *) NULL;
3721 rslt_compose = compose;
3740 method_limit = kernel_limit;
3757 if (rslt_image == (
Image *) NULL)
3766 "%s:%.20g.%.20g #%.20g => Changed %.20g\n",
3768 1.0,0.0,1.0, (
double) changed);
3787 rslt_compose = compose;
3814 while ( method_loop < method_limit && method_changed > 0 ) {
3821 rflt_kernel = reflected_kernel;
3824 while ( norm_kernel != NULL ) {
3828 while ( stage_loop < stage_limit ) {
3832 this_kernel = norm_kernel;
3846 if ( stage_loop == 2 )
3851 if ( stage_loop == 2 )
3856 this_kernel = rflt_kernel;
3858 if ( stage_loop == 2 )
3862 this_kernel = rflt_kernel;
3864 if ( stage_loop == 2 )
3868 switch ( stage_loop ) {
3876 this_kernel = rflt_kernel;
3880 this_kernel = rflt_kernel;
3887 if ( stage_loop == 2 ) {
3888 save_image = curr_image;
3889 curr_image = (
Image *) image;
3903 this_kernel = rflt_kernel;
3909 assert( this_kernel != (
KernelInfo *) NULL );
3913 if ( stage_limit > 1 )
3916 method_loop,(
double) stage_loop);
3917 else if ( primitive != method )
3929 while ( kernel_loop < kernel_limit && changed > 0 ) {
3933 if ( work_image == (
Image *) NULL )
3936 if (work_image == (
Image *) NULL)
3945 this_kernel, bias, exception);
3947 if ( kernel_loop > 1 )
3950 "%s%s%s:%.20g.%.20g #%.20g => Changed %.20g",
3952 primitive),(this_kernel == rflt_kernel ) ?
"*" :
"",
3953 (
double) (method_loop+kernel_loop-1),(
double) kernel_number,
3954 (
double) count,(
double) changed);
3958 kernel_changed += changed;
3959 method_changed += changed;
3962 {
Image *tmp = work_image;
3963 work_image = curr_image;
3966 if ( work_image == image )
3967 work_image = (
Image *) NULL;
3971 if (verbose !=
MagickFalse && kernel_changed != (
size_t)changed)
3973 if (verbose !=
MagickFalse && stage_loop < stage_limit)
3977 (void)
FormatLocaleFile(stderr,
"--E-- image=0x%lx\n", (
unsigned long)image);
3978 (void)
FormatLocaleFile(stderr,
" curr =0x%lx\n", (
unsigned long)curr_image);
3979 (void)
FormatLocaleFile(stderr,
" work =0x%lx\n", (
unsigned long)work_image);
3980 (void)
FormatLocaleFile(stderr,
" save =0x%lx\n", (
unsigned long)save_image);
3981 (void)
FormatLocaleFile(stderr,
" union=0x%lx\n", (
unsigned long)rslt_image);
4020 rslt_image = curr_image;
4028 rslt_image = curr_image;
4030 else if ( rslt_image == (
Image *) NULL)
4033 rslt_image = curr_image;
4034 curr_image = (
Image *) image;
4050 curr_image = (
Image *) image;
4056 norm_kernel = norm_kernel->
next;
4058 rflt_kernel = rflt_kernel->
next;
4068 if ( curr_image == rslt_image )
4069 curr_image = (
Image *) NULL;
4070 if ( rslt_image != (
Image *) NULL )
4073 if ( curr_image == rslt_image || curr_image == image )
4074 curr_image = (
Image *) NULL;
4075 if ( curr_image != (
Image *) NULL )
4077 if ( work_image != (
Image *) NULL )
4079 if ( save_image != (
Image *) NULL )
4081 if ( reflected_kernel != (
KernelInfo *) NULL )
4166 if ( artifact != (
const char *) NULL) {
4170 "convolve:bias",artifact);
4177 if ( artifact != (
const char *) NULL ) {
4181 "convolve:scale",artifact);
4183 if ( curr_kernel == kernel )
4186 return((
Image *) NULL);
4208 if ( artifact != (
const char *) NULL) {
4214 "morphology:compose",artifact);
4221 curr_kernel,compose,bias,exception);
4224 if ( curr_kernel != kernel )
4226 return(morphology_image);
4271 angle = fmod(angle, 360.0);
4275 if ( 337.5 < angle || angle <= 22.5 )
4279 switch (kernel->
type) {
4303 if ( 135.0 < angle && angle <= 225.0 )
4305 if ( 225.0 < angle && angle <= 315.0 )
4313 if ( 22.5 < fmod(angle,90.0) && fmod(angle,90.0) <= 67.5 )
4317 double t = kernel->
values[0];
4327 if ( kernel->
x != 1 || kernel->
y != 1 ) {
4329 x = (ssize_t) kernel->
x-1;
4330 y = (ssize_t) kernel->
y-1;
4331 if ( x == y ) x = 0;
4332 else if ( x == 0 ) x = -y;
4333 else if ( x == -y ) y = 0;
4334 else if ( y == 0 ) y = x;
4335 kernel->
x = (ssize_t) x+1;
4336 kernel->
y = (ssize_t) y+1;
4338 angle = fmod(angle+315.0, 360.0);
4339 kernel->
angle = fmod(kernel->
angle+45.0, 360.0);
4342 perror(
"Unable to rotate non-3x3 kernel by 45 degrees");
4344 if ( 45.0 < fmod(angle, 180.0) && fmod(angle,180.0) <= 135.0 )
4352 t = (ssize_t) kernel->
width;
4354 kernel->
height = (
size_t) t;
4356 kernel->
x = kernel->
y;
4358 if ( kernel->
width == 1 ) {
4359 angle = fmod(angle+270.0, 360.0);
4360 kernel->
angle = fmod(kernel->
angle+90.0, 360.0);
4362 angle = fmod(angle+90.0, 360.0);
4363 kernel->
angle = fmod(kernel->
angle+270.0, 360.0);
4375 for( i=0, x=(ssize_t) kernel->
width-1; i<=x; i++, x--)
4376 for( j=0, y=(ssize_t) kernel->
height-1; j<y; j++, y--)
4377 { t = k[i+j*kernel->
width];
4381 k[y+i*kernel->
width] = t;
4386 x = (ssize_t) (kernel->
x*2-kernel->
width+1);
4387 y = (ssize_t) (kernel->
y*2-kernel->
height+1);
4388 kernel->
x = (ssize_t) ( -y +(ssize_t) kernel->
width-1)/2;
4389 kernel->
y = (ssize_t) ( +x +(ssize_t) kernel->
height-1)/2;
4391 angle = fmod(angle+270.0, 360.0);
4392 kernel->
angle = fmod(kernel->
angle+90.0, 360.0);
4395 perror(
"Unable to rotate a non-square, non-linear kernel 90 degrees");
4397 if ( 135.0 < angle && angle <= 225.0 )
4416 for (i=0; i < j; i++, j--)
4417 t=k[i], k[i]=k[j], k[j]=t;
4419 kernel->
x = (ssize_t) kernel->
width - kernel->
x - 1;
4420 kernel->
y = (ssize_t) kernel->
height - kernel->
y - 1;
4421 angle = fmod(angle-180.0, 360.0);
4422 kernel->
angle = fmod(kernel->
angle+180.0, 360.0);
4467 const char *geometry)
4480 (void)
FormatLocaleFile(stderr,
"Geometry = 0x%04X : %lg x %lg %+lg %+lg\n",
4485 args.
rho *= 0.01, args.
sigma *= 0.01;
4573 const double scaling_factor,
const GeometryFlags normalize_flags)
4604 neg_scale = pos_scale;
4607 pos_scale = scaling_factor/pos_scale;
4608 neg_scale = scaling_factor/neg_scale;
4610 for (i=0; i < (ssize_t) (kernel->
width*kernel->
height); i++)
4612 kernel->
values[i] *= (kernel->
values[i] >= 0) ? pos_scale : neg_scale;
4618 kernel->
maximum *= (kernel->
maximum >= 0.0) ? pos_scale : neg_scale;
4619 kernel->
minimum *= (kernel->
minimum >= 0.0) ? pos_scale : neg_scale;
4676 (void)
FormatLocaleFile(stderr,
"\" of size %lux%lu%+ld%+ld",(
unsigned long)
4677 k->width,(
unsigned long) k->height,(
long) k->x,(long) k->y);
4679 " with values from %.*lg to %.*lg\n",
4682 (void)
FormatLocaleFile(stderr,
"Forming a output range from %.*lg to %.*lg",
4685 if ( fabs(k->positive_range+k->negative_range) <
MagickEpsilon )
4687 else if ( fabs(k->positive_range+k->negative_range-1.0) <
MagickEpsilon )
4692 for (i=v=0; v < k->height; v++) {
4694 for (u=0; u < k->width; u++, i++)
4695 if (
IsNaN(k->values[i]))
4786 for (i=0; i < (kernel->
width*kernel->
height); i++)
struct _KernelInfo * next
MagickPrivate Image * MorphologyApply(const Image *image, const MorphologyMethod method, const ssize_t iterations, const KernelInfo *kernel, const CompositeOperator compose, const double bias, ExceptionInfo *exception)
MagickDoubleType MagickRealType
MagickExport CacheView * DestroyCacheView(CacheView *cache_view)
static void ExpandMirrorKernelInfo(KernelInfo *)
MagickProgressMonitor progress_monitor
static KernelInfo * LastKernelInfo(KernelInfo *kernel)
static Quantum GetPixelAlpha(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
#define DisableMSCWarning(nr)
#define MagickAssumeAligned(address)
MagickExport ssize_t ParseCommandOption(const CommandOption option, const MagickBooleanType list, const char *options)
MagickExport KernelInfo * DestroyKernelInfo(KernelInfo *kernel)
#define ThrowFatalException(severity, tag)
static size_t GetOpenMPMaximumThreads(void)
MagickExport Image * MorphologyImage(const Image *image, const MorphologyMethod method, const ssize_t iterations, const KernelInfo *kernel, ExceptionInfo *exception)
MagickExport void SetGeometryInfo(GeometryInfo *geometry_info)
static ssize_t MorphologyPrimitive(const Image *image, Image *morphology_image, const MorphologyMethod method, const KernelInfo *kernel, const double bias, ExceptionInfo *exception)
MagickExport const char * GetImageArtifact(const Image *image, const char *artifact)
static ssize_t MorphologyPrimitiveDirect(Image *image, const MorphologyMethod method, const KernelInfo *kernel, ExceptionInfo *exception)
#define Minimize(assign, value)
static double StringToDouble(const char *magick_restrict string, char **magick_restrict sentinal)
static PixelTrait GetPixelChannelTraits(const Image *magick_restrict image, const PixelChannel channel)
MagickExport ssize_t FormatLocaleString(char *magick_restrict string, const size_t length, const char *magick_restrict format,...)
MagickPrivate size_t GetOptimalKernelWidth1D(const double, const double)
MagickExport const Quantum * GetCacheViewVirtualPixels(const CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
MagickExport void ScaleGeometryKernelInfo(KernelInfo *kernel, const char *geometry)
MagickExport void ScaleKernelInfo(KernelInfo *kernel, const double scaling_factor, const GeometryFlags normalize_flags)
static KernelInfo * ParseKernelArray(const char *kernel_string)
MagickExport MagickBooleanType CompositeImage(Image *image, const Image *composite, const CompositeOperator compose, const MagickBooleanType clip_to_self, const ssize_t x_offset, const ssize_t y_offset, ExceptionInfo *exception)
#define Maximize(assign, value)
MagickExport char * FileToString(const char *filename, const size_t extent, ExceptionInfo *exception)
static Quantum ClampToQuantum(const MagickRealType quantum)
MagickExport KernelInfo * AcquireKernelInfo(const char *kernel_string, ExceptionInfo *exception)
#define MagickCoreSignature
MagickExport Quantum * GetCacheViewAuthenticPixels(CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
MagickExport KernelInfo * AcquireKernelBuiltIn(const KernelInfoType type, const GeometryInfo *args, ExceptionInfo *exception)
MagickPrivate void ShowKernelInfo(const KernelInfo *kernel)
MagickExport MagickBooleanType IsGeometry(const char *geometry)
static KernelInfo * ParseKernelName(const char *kernel_string, ExceptionInfo *exception)
MagickExport ssize_t FormatLocaleFile(FILE *file, const char *magick_restrict format,...)
MagickExport MagickBooleanType SetImageAlphaChannel(Image *image, const AlphaChannelOption alpha_type, ExceptionInfo *exception)
unsigned int MagickStatusType
static double PerceptibleReciprocal(const double x)
MagickExport const char * CommandOptionToMnemonic(const CommandOption option, const ssize_t type)
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
MagickPrivate size_t GetOptimalKernelWidth2D(const double, const double)
MagickExport magick_hot_spot size_t GetNextToken(const char *magick_restrict start, const char **magick_restrict end, const size_t extent, char *magick_restrict token)
static int GetOpenMPThreadId(void)
#define RestoreMSCWarning
static size_t fact(size_t n)
MagickExport void * RelinquishAlignedMemory(void *memory)
MagickExport MagickBooleanType IsStringTrue(const char *value)
static void CalcKernelMetaData(KernelInfo *)
MagickExport int GetMagickPrecision(void)
#define MagickMaximumValue
MagickExport MagickBooleanType ThrowMagickException(ExceptionInfo *exception, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *tag, const char *format,...)
MagickBooleanType(* MagickProgressMonitor)(const char *, const MagickOffsetType, const MagickSizeType, void *)
MagickExport MagickBooleanType SetImageStorageClass(Image *image, const ClassType storage_class, ExceptionInfo *exception)
MagickExport void * AcquireAlignedMemory(const size_t count, const size_t quantum)
static size_t GetPixelChannels(const Image *magick_restrict image)
MagickExport int LocaleCompare(const char *p, const char *q)
MagickPrivate void ZeroKernelNans(KernelInfo *kernel)
#define GetMagickModule()
static PixelChannel GetPixelChannelChannel(const Image *magick_restrict image, const ssize_t offset)
MagickExport CacheView * AcquireVirtualCacheView(const Image *image, ExceptionInfo *exception)
static void RotateKernelInfo(KernelInfo *, double)
static double StringToDoubleInterval(const char *string, const double interval)
static MagickBooleanType SameKernelInfo(const KernelInfo *kernel1, const KernelInfo *kernel2)
MagickExport KernelInfo * CloneKernelInfo(const KernelInfo *kernel)
MagickExport char * DestroyString(char *string)
MagickExport void * AcquireMagickMemory(const size_t size)
MagickExport MagickStatusType ParseGeometry(const char *geometry, GeometryInfo *geometry_info)
static void SetPixelChannel(const Image *magick_restrict image, const PixelChannel channel, const Quantum quantum, Quantum *magick_restrict pixel)
MagickExport void * RelinquishMagickMemory(void *memory)
CompositeOperator compose
MagickExport void UnityAddKernelInfo(KernelInfo *kernel, const double scale)
MagickExport MagickBooleanType SyncCacheViewAuthenticPixels(CacheView *magick_restrict cache_view, ExceptionInfo *exception)
MagickExport CacheView * AcquireAuthenticCacheView(const Image *image, ExceptionInfo *exception)
MagickExport MagickRealType GetPixelIntensity(const Image *magick_restrict image, const Quantum *magick_restrict pixel)
static void ExpandRotateKernelInfo(KernelInfo *, const double)
MagickExport Image * DestroyImage(Image *image)
MagickExport Image * CloneImage(const Image *image, const size_t columns, const size_t rows, const MagickBooleanType detach, ExceptionInfo *exception)
MagickExport MagickBooleanType SetImageProgress(const Image *image, const char *tag, const MagickOffsetType offset, const MagickSizeType extent)