@@ -15,9 +15,9 @@
#define true 1
#define true 1
#define false 0
#define false 0
int WIDTH, HEIGHT;
static int WIDTH, HEIGHT;
static inline float get(float *src, int x, int y)
static inline float get(float const *src, int x, int y)
{
{
return src[y * WIDTH + x];
return src[y * WIDTH + x];
}
}
@@ -32,7 +32,7 @@ static float *new(void)
return malloc(WIDTH * HEIGHT * sizeof(float));
return malloc(WIDTH * HEIGHT * sizeof(float));
}
}
static float *copy(float *src)
static float *copy(float const *src)
{
{
float *dest = malloc(WIDTH * HEIGHT * sizeof(float));
float *dest = malloc(WIDTH * HEIGHT * sizeof(float));
memcpy(dest, src, WIDTH * HEIGHT * sizeof(float));
memcpy(dest, src, WIDTH * HEIGHT * sizeof(float));
@@ -63,7 +63,7 @@ static void makegauss(float mat[NN][NN], float sigma, float dx, float dy)
mat[i][j] /= t;
mat[i][j] /= t;
}
}
static float *gauss(float *src, float mat[NN][NN])
static float *gauss(float const *src, float mat[NN][NN])
{
{
float *dest = new();
float *dest = new();
int x, y, i, j;
int x, y, i, j;
@@ -83,7 +83,7 @@ static float *gauss(float *src, float mat[NN][NN])
return dest;
return dest;
}
}
static float *fullgauss(float *src, float mat[NN][NN])
static float *fullgauss(float const *src, float mat[NN][NN])
{
{
float *dest = new();
float *dest = new();
int x, y, i, j;
int x, y, i, j;
@@ -105,7 +105,7 @@ static float *fullgauss(float *src, float mat[NN][NN])
return dest;
return dest;
}
}
static float fulldist(float *p1, float *p2)
static float fulldist(float const *p1, const float *p2)
{
{
float error = 0.;
float error = 0.;
int x, y;
int x, y;
@@ -120,22 +120,32 @@ static float fulldist(float *p1, float *p2)
return error / (WIDTH * HEIGHT);
return error / (WIDTH * HEIGHT);
}
}
static float dist(float *p1, float *p2)
static float dist(float const *p1, float cons t *p2, float max )
{
{
float error = 0.;
float error = 0.;
int x, y;
int x, y;
max *= (WIDTH - N) * (HEIGHT - N);
for(y = N; y < HEIGHT - N; y++)
for(y = N; y < HEIGHT - N; y++)
{
for(x = N; x < WIDTH - N; x++)
for(x = N; x < WIDTH - N; x++)
{
{
float t = get(p1, x, y) - get(p2, x, y);
float t = get(p1, x, y) - get(p2, x, y);
error += t * t;
error += t * t;
}
}
/* Experience shows that this is almost useless, because the
* functions we manipulate are so small that the difference
* only happens in the last 1% of the image... */
if(error > max)
break;
}
return error / ((WIDTH - N) * (HEIGHT - N));
return error / ((WIDTH - N) * (HEIGHT - N));
}
}
static float *load(char *name)
static float *load(char const *name)
{
{
SDL_Surface *tmp, *surface;
SDL_Surface *tmp, *surface;
uint32_t *pixels;
uint32_t *pixels;
@@ -168,7 +178,7 @@ static float *load(char *name)
return floats;
return floats;
}
}
static void save(float *src, char *name)
static void save(float const *src, char const *name)
{
{
SDL_Surface *surface;
SDL_Surface *surface;
uint32_t *pixels;
uint32_t *pixels;
@@ -189,7 +199,7 @@ static void save(float *src, char *name)
SDL_SaveBMP(surface, name);
SDL_SaveBMP(surface, name);
}
}
static float *ostromoukhov(float *src)
static float *ostromoukhov(float const *src)
{
{
static int const table[][3] =
static int const table[][3] =
{
{
@@ -275,7 +285,7 @@ static float *ostromoukhov(float *src)
c d e f g
c d e f g
h i j k l
h i j k l
*/
*/
static float *ed(float *src, int serpentine,
static float *ed(float const *src, int serpentine,
int a, int b, int c, int d, int e, int f,
int a, int b, int c, int d, int e, int f,
int g, int h, int i, int j, int k, int l)
int g, int h, int i, int j, int k, int l)
{
{
@@ -356,7 +366,8 @@ static float *ed(float *src, int serpentine,
}
}
/* XXX */
/* XXX */
static float *dbs(float *src, float *orig, float sigma, float dx, float dy)
static float *dbs(float const *src, float const *orig,
float sigma, float dx, float dy)
{
{
float mat[NN][NN];
float mat[NN][NN];
float *dest, *tmp, *tmp2;
float *dest, *tmp, *tmp2;
@@ -369,7 +380,7 @@ static float *dbs(float *src, float *orig, float sigma, float dx, float dy)
dest = copy(orig);
dest = copy(orig);
tmp2 = fullgauss(dest, mat);
tmp2 = fullgauss(dest, mat);
error = dist(tmp, tmp2);
error = dist(tmp, tmp2, 1. );
for(;;)
for(;;)
{
{
@@ -497,33 +508,30 @@ static float *dbs(float *src, float *orig, float sigma, float dx, float dy)
return dest;
return dest;
}
}
static void study(float *src, float *dest, float sigma, float precision)
static void study(float const *src, float const *dest,
float sigma, float precision)
{
{
# define Z 3
# define Z 3
float mat[NN][NN];
float mat[NN][NN];
float *tmp, *tmp2;
float *tmp, *tmp2;
float e0, best = 0., fx = -1., fy = -1., step = 2 .;
float e, e0, best = 1., fx = -1., fy = -1., step = 2., bfx = 0., bfy = 0 .;
int dx, dy;
int dx, dy;
makegauss(mat, sigma, 0., 0.);
makegauss(mat, sigma, 0., 0.);
tmp = gauss(src, mat);
tmp = gauss(src, mat);
tmp2 = gauss(dest, mat);
tmp2 = gauss(dest, mat);
e0 = dist(tmp, tmp2);
e0 = dist(tmp, tmp2, 1. );
free(tmp2);
free(tmp2);
while(step > precision)
while(step > precision)
{
{
float bfx = 0., bfy = 0., e;
best = 9999.;
for(dy = 0; dy <= Z; dy++)
for(dy = 0; dy <= Z; dy++)
for(dx = 0; dx <= Z; dx++)
for(dx = 0; dx <= Z; dx++)
{
{
makegauss(mat, sigma, fx + step * dx / Z, fy + step * dy / Z);
makegauss(mat, sigma, fx + step * dx / Z, fy + step * dy / Z);
tmp2 = gauss(dest, mat);
tmp2 = gauss(dest, mat);
e = dist(tmp, tmp2);
e = dist(tmp, tmp2, best );
free(tmp2);
free(tmp2);
if(e < best)
if(e < best)
{
{
@@ -545,7 +553,7 @@ static void study(float *src, float *dest, float sigma, float precision)
fflush(stdout);
fflush(stdout);
}
}
static float *merge(float *im1, float *im2, float t)
static float *merge(float const *im1, float cons t *im2, float t)
{
{
float *dest = new();
float *dest = new();
int x, y;
int x, y;
@@ -569,11 +577,8 @@ static void usage(char *argv[])
int main(int argc, char *argv[])
int main(int argc, char *argv[])
{
{
float mat0[NN][NN];
float mat[NN][NN];
float *src;
float *src;
float sigma;
int mode, dx, dy, i;
int mode, i;
if(argc < 2)
if(argc < 2)
{
{
@@ -630,6 +635,7 @@ int main(int argc, char *argv[])
case 3:
case 3:
case 4:
case 4:
{
{
float mat0[NN][NN];
float *dest, *tmp, *tmp2;
float *dest, *tmp, *tmp2;
int a, b, c, d, e;
int a, b, c, d, e;
@@ -670,12 +676,12 @@ int main(int argc, char *argv[])
{
{
tmp = gauss(src, mat0);
tmp = gauss(src, mat0);
tmp2 = gauss(dest, mat0);
tmp2 = gauss(dest, mat0);
printf("E = %.5g\n", 1000. * dist(tmp, tmp2));
printf("E = %.5g\n", 1000. * dist(tmp, tmp2, 1. ));
free(tmp);
free(tmp);
free(tmp2);
free(tmp2);
}
}
else
else
study(src, dest, 1.2, 0.01);
study(src, dest, 1.2, 0.00 1);
fflush(stdout);
fflush(stdout);
free(dest);
free(dest);
}
}
@@ -728,7 +734,7 @@ int main(int argc, char *argv[])
makegauss(mat, 1.2, fx, fy);
makegauss(mat, 1.2, fx, fy);
tmp2 = gauss(dest, mat);
tmp2 = gauss(dest, mat);
printf("%g %g %g\n", fy, fx, 1000. * dist(tmp, tmp2));
printf("%g %g %g\n", fy, fx, 1000. * dist(tmp, tmp2, 1. ));
fflush(stdout);
fflush(stdout);
free(tmp2);
free(tmp2);
}
}
@@ -750,7 +756,7 @@ int main(int argc, char *argv[])
dest = ed(src, a, 0, 0, b, c, d, 0, 0, 0, 0, 0, 0);
dest = ed(src, a, 0, 0, b, c, d, 0, 0, 0, 0, 0, 0);
tmp2 = gauss(dest, 0., 0.);
tmp2 = gauss(dest, 0., 0.);
printf("%.5g: (%02d %02d %02d %02d)\n",
printf("%.5g: (%02d %02d %02d %02d)\n",
1000. * dist(tmp, tmp2), a, b, c, d);
1000. * dist(tmp, tmp2, 1. ), a, b, c, d);
free(dest);
free(dest);
free(tmp2);
free(tmp2);
}
}
@@ -765,41 +771,41 @@ int main(int argc, char *argv[])
dest = ed(src, false, 7, 0, 0, 3, 5, 1, 0, 0, 0, 0, 0, 0);
dest = ed(src, false, 7, 0, 0, 3, 5, 1, 0, 0, 0, 0, 0, 0);
tmp2 = gauss(dest, mat0);
tmp2 = gauss(dest, mat0);
printf("%.5g ", 1000. * dist(tmp, tmp2));
printf("%.5g ", 1000. * dist(tmp, tmp2, 1. ));
free(tmp2);
free(tmp2);
makegauss(mat, 1.2, 0.16, 0.28);
makegauss(mat, 1.2, 0.16, 0.28);
tmp2 = gauss(dest, mat);
tmp2 = gauss(dest, mat);
printf("%.5g ", 1000. * dist(tmp, tmp2));
printf("%.5g ", 1000. * dist(tmp, tmp2, 1. ));
free(tmp2);
free(tmp2);
free(dest);
free(dest);
dest = ed(src, false, 7, 5, 3, 5, 7, 5, 3, 1, 3, 5, 3, 1);
dest = ed(src, false, 7, 5, 3, 5, 7, 5, 3, 1, 3, 5, 3, 1);
tmp2 = gauss(dest, mat0);
tmp2 = gauss(dest, mat0);
printf("%.5g ", 1000. * dist(tmp, tmp2));
printf("%.5g ", 1000. * dist(tmp, tmp2, 1. ));
free(tmp2);
free(tmp2);
makegauss(mat, 1.2, 0.26, 0.76);
makegauss(mat, 1.2, 0.26, 0.76);
tmp2 = gauss(dest, mat);
tmp2 = gauss(dest, mat);
printf("%.5g ", 1000. * dist(tmp, tmp2));
printf("%.5g ", 1000. * dist(tmp, tmp2, 1. ));
free(tmp2);
free(tmp2);
free(dest);
free(dest);
dest = ostromoukhov(src);
dest = ostromoukhov(src);
tmp2 = gauss(dest, mat0);
tmp2 = gauss(dest, mat0);
printf("%.5g ", 1000. * dist(tmp, tmp2));
printf("%.5g ", 1000. * dist(tmp, tmp2, 1. ));
free(tmp2);
free(tmp2);
makegauss(mat, 1.2, 0.0, 0.19);
makegauss(mat, 1.2, 0.0, 0.19);
tmp2 = gauss(dest, mat);
tmp2 = gauss(dest, mat);
printf("%.5g ", 1000. * dist(tmp, tmp2));
printf("%.5g ", 1000. * dist(tmp, tmp2, 1. ));
free(tmp2);
free(tmp2);
free(dest);
free(dest);
dest = ed(src, true, 2911, 0, 0, 1373, 3457, 2258, 0, 0, 0, 0, 0, 0);
dest = ed(src, true, 2911, 0, 0, 1373, 3457, 2258, 0, 0, 0, 0, 0, 0);
tmp2 = gauss(dest, mat0);
tmp2 = gauss(dest, mat0);
printf("%.5g ", 1000. * dist(tmp, tmp2));
printf("%.5g ", 1000. * dist(tmp, tmp2, 1. ));
free(tmp2);
free(tmp2);
makegauss(mat, 1.2, 0.0, 0.34);
makegauss(mat, 1.2, 0.0, 0.34);
tmp2 = gauss(dest, mat);
tmp2 = gauss(dest, mat);
printf("%.5g ", 1000. * dist(tmp, tmp2));
printf("%.5g ", 1000. * dist(tmp, tmp2, 1. ));
free(tmp2);
free(tmp2);
free(dest);
free(dest);