No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 

1174 líneas
32 KiB

  1. /* test shit */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdarg.h>
  6. #include <math.h>
  7. #ifdef BYTECODE
  8. # include <seccomp-loader.h>
  9. #else
  10. # include <SDL_image.h>
  11. #endif
  12. #define MAXWIDTH 512
  13. #define MAXHEIGHT 512
  14. #define true 1
  15. #define false 0
  16. static int WIDTH, HEIGHT;
  17. int main(int, char *[]);
  18. #ifdef BYTECODE
  19. # define MAXIMAGES 128
  20. static int slots[MAXIMAGES];
  21. static double slotbuf[MAXIMAGES * MAXWIDTH * MAXHEIGHT];
  22. volatile int stop;
  23. void sighandler(int signal)
  24. {
  25. if(sys_write(1, "done", 4) != 4)
  26. sys_exit(3);
  27. stop = 1;
  28. }
  29. void bytecode(unsigned char * mem, int heap_size, int stack_size)
  30. {
  31. char mode[] = "-0";
  32. char *argv[] = { "program", mode, "arg" };
  33. char c;
  34. if(sys_read(0, mode + 1, 1) != 1)
  35. sys_exit(-5);
  36. main(sizeof(argv)/sizeof(*argv), argv);
  37. c = 0;
  38. if(sys_write(1, &c, 1) != 1)
  39. sys_exit(-6);
  40. }
  41. static int myatoi(const char *str)
  42. {
  43. int i = 0;
  44. while(*str)
  45. {
  46. i *= 10;
  47. i += (unsigned char)*str++ - (unsigned char)'0';
  48. }
  49. return i;
  50. }
  51. #define atoi myatoi
  52. #endif
  53. #define WRITE_INT(i, base) \
  54. do \
  55. { \
  56. char buf[128], *b = buf + 127; \
  57. if(i <= 0) \
  58. sys_write(1, (i = -i) ? "-" : "0", 1); /* XXX: hack here */ \
  59. while(i) \
  60. { \
  61. *b-- = hex2char[i % base]; \
  62. i /= base; \
  63. } \
  64. sys_write(1, b + 1, (int)(buf + 127 - b)); \
  65. } while(0)
  66. static void msg(const char *f, ...)
  67. {
  68. va_list args;
  69. va_start(args, f);
  70. #ifdef BYTECODE
  71. static char const *hex2char = "0123456789abcdef";
  72. for( ; *f; f++)
  73. {
  74. if(*f != '%')
  75. {
  76. sys_write(1, f, 1);
  77. continue;
  78. }
  79. f++;
  80. if(!*f)
  81. break;
  82. if(*f == 'c')
  83. {
  84. char i = (char)(unsigned char)va_arg(args, int);
  85. if(i >= 0x20 && i < 0x7f)
  86. sys_write(1, &i, 1);
  87. else if(i == '\n')
  88. sys_write(1, "\\n", 2);
  89. else if(i == '\t')
  90. sys_write(1, "\\t", 2);
  91. else if(i == '\r')
  92. sys_write(1, "\\r", 2);
  93. else
  94. {
  95. sys_write(1, "\\x", 2);
  96. sys_write(1, hex2char + ((i & 0xf0) >> 4), 1);
  97. sys_write(1, hex2char + (i & 0x0f), 1);
  98. }
  99. }
  100. else if(*f == 'i' || *f == 'd')
  101. {
  102. int i = va_arg(args, int);
  103. WRITE_INT(i, 10);
  104. }
  105. else if(*f == 'x')
  106. {
  107. int i = va_arg(args, int);
  108. WRITE_INT(i, 16);
  109. }
  110. else if(f[0] == 'l' && (f[1] == 'i' || f[1] == 'd'))
  111. {
  112. long int i = va_arg(args, long int);
  113. WRITE_INT(i, 10);
  114. f++;
  115. }
  116. else if(f[0] == 'l' && f[1] == 'l' && (f[2] == 'i' || f[1] == 'd'))
  117. {
  118. long long int i = va_arg(args, long long int);
  119. WRITE_INT(i, 10);
  120. f += 2;
  121. }
  122. else if(f[0] == 'g')
  123. {
  124. double g = va_arg(args, double), h = 9.9f;
  125. int i;
  126. if(g < 0.f)
  127. {
  128. sys_write(1, "-", 1);
  129. g = -g;
  130. }
  131. for(i = 0; i < 7; i++)
  132. {
  133. sys_write(1, hex2char + (int)g, 1);
  134. if(i == 0)
  135. sys_write(1, ".", 1);
  136. g = (g - (int)g) * 10;
  137. h = h / 10.f;
  138. if(g < h)
  139. break;
  140. }
  141. }
  142. else if(f[0] == 'p')
  143. {
  144. uintptr_t i = va_arg(args, uintptr_t);
  145. if(!i)
  146. sys_write(1, "NULL", 5);
  147. else
  148. {
  149. sys_write(1, "0x", 2);
  150. WRITE_INT(i, 16);
  151. }
  152. }
  153. else if(f[0] == 's')
  154. {
  155. char *s = va_arg(args, char *);
  156. if(!s)
  157. sys_write(1, "(nil)", 5);
  158. else
  159. {
  160. int l = 0;
  161. while(s[l])
  162. l++;
  163. sys_write(1, s, l);
  164. }
  165. }
  166. else if(f[0] == '0' && f[1] == '2' && f[2] == 'x')
  167. {
  168. int i = va_arg(args, int);
  169. sys_write(1, hex2char + ((i & 0xf0) >> 4), 1);
  170. sys_write(1, hex2char + (i & 0x0f), 1);
  171. f += 2;
  172. }
  173. else
  174. {
  175. sys_write(1, f - 1, 2);
  176. }
  177. }
  178. #else
  179. vprintf(f, args);
  180. fflush(stdout);
  181. #endif
  182. va_end(args);
  183. }
  184. static inline double get(double const *src, int x, int y)
  185. {
  186. return src[y * WIDTH + x];
  187. }
  188. static inline void put(double *src, int x, int y, double p)
  189. {
  190. src[y * WIDTH + x] = p;
  191. }
  192. static double *new(void)
  193. {
  194. #ifdef BYTECODE
  195. int i;
  196. for(i = 0; i < MAXIMAGES; i++)
  197. if(slots[i] == 0)
  198. break;
  199. if(i == MAXIMAGES)
  200. return NULL;
  201. slots[i] = 1;
  202. return slotbuf + i * MAXWIDTH * MAXHEIGHT;
  203. #else
  204. return malloc(WIDTH * HEIGHT * sizeof(double));
  205. #endif
  206. }
  207. static void del(double *img)
  208. {
  209. #ifdef BYTECODE
  210. int i;
  211. for(i = 0; i < MAXIMAGES; i++)
  212. if(slotbuf + i * MAXWIDTH * MAXHEIGHT == img)
  213. break;
  214. if(i == MAXIMAGES)
  215. return;
  216. slots[i] = 0;
  217. #else
  218. free(img);
  219. #endif
  220. }
  221. static double *copy(double const *src)
  222. {
  223. double *dest = new();
  224. memcpy(dest, src, WIDTH * HEIGHT * sizeof(double));
  225. return dest;
  226. }
  227. #define N 5
  228. #define NN ((N * 2 + 1))
  229. static void makegauss(double mat[NN][NN], double sigma, double dx, double dy)
  230. {
  231. double t = 0;
  232. int i, j;
  233. sigma = 2. * sigma * sigma;
  234. for(j = 0; j < NN; j++)
  235. for(i = 0; i < NN; i++)
  236. {
  237. double a = (double)(i - N) + dx;
  238. double b = (double)(j - N) + dy;
  239. mat[i][j] = pow(M_E, - (a * a + b * b) / sigma);
  240. t += mat[i][j];
  241. }
  242. for(j = 0; j < NN; j++)
  243. for(i = 0; i < NN; i++)
  244. mat[i][j] /= t;
  245. }
  246. static double *gauss(double const *src, double mat[NN][NN])
  247. {
  248. double *dest = new();
  249. int x, y, i, j;
  250. for(y = N; y < HEIGHT - N; y++)
  251. for(x = N; x < WIDTH - N; x++)
  252. {
  253. double p = 0;
  254. for(j = 0; j < NN; j++)
  255. for(i = 0; i < NN; i++)
  256. p += get(src, x + i - N, y + j - N) * mat[i][j];
  257. put(dest, x, y, p);
  258. }
  259. return dest;
  260. }
  261. static double *fullgauss(double const *src, double mat[NN][NN])
  262. {
  263. double *dest = new();
  264. int x, y, i, j;
  265. for(y = 0; y < HEIGHT; y++)
  266. for(x = 0; x < WIDTH; x++)
  267. {
  268. double p = 0;
  269. for(j = 0; j < NN; j++)
  270. for(i = 0; i < NN; i++)
  271. if(x + i >= N && x + i < WIDTH + N
  272. && y + j >= N && y + j < HEIGHT + N)
  273. p += get(src, x + i - N, y + j - N) * mat[i][j];
  274. put(dest, x, y, p);
  275. }
  276. return dest;
  277. }
  278. #if 0
  279. static double fulldist(double const *p1, const double *p2)
  280. {
  281. double error = 0.;
  282. int x, y;
  283. for(y = 0; y < HEIGHT; y++)
  284. for(x = 0; x < WIDTH; x++)
  285. {
  286. double t = get(p1, x, y) - get(p2, x, y);
  287. error += t * t;
  288. }
  289. return error / (WIDTH * HEIGHT);
  290. }
  291. #endif
  292. static double dist(double const *p1, double const *p2, double max)
  293. {
  294. double error = 0.;
  295. int x, y;
  296. max *= (WIDTH - N) * (HEIGHT - N);
  297. for(y = N; y < HEIGHT - N; y++)
  298. {
  299. for(x = N; x < WIDTH - N; x++)
  300. {
  301. double t = get(p1, x, y) - get(p2, x, y);
  302. error += t * t;
  303. }
  304. /* Experience shows that this is almost useless, because the
  305. * functions we manipulate are so small that the difference
  306. * only happens in the last 1% of the image... */
  307. if(error > max)
  308. break;
  309. }
  310. return error / ((WIDTH - N) * (HEIGHT - N));
  311. }
  312. static double *load(char const *name)
  313. {
  314. double *floats;
  315. int x, y;
  316. #ifdef BYTECODE
  317. char c;
  318. if(sys_read(0, &c, 1) != 1)
  319. sys_exit(-5);
  320. WIDTH = ((int)(unsigned char)c) << 8;
  321. if(sys_read(0, &c, 1) != 1)
  322. sys_exit(-5);
  323. WIDTH |= (int)(unsigned char)c;
  324. if(sys_read(0, &c, 1) != 1)
  325. sys_exit(-5);
  326. HEIGHT = ((int)(unsigned char)c) << 8;
  327. if(sys_read(0, &c, 1) != 1)
  328. sys_exit(-5);
  329. HEIGHT |= (int)(unsigned char)c;
  330. floats = new();
  331. if(!floats)
  332. return NULL;
  333. for(y = 0; y < HEIGHT; y++)
  334. for(x = 0; x < WIDTH; x++)
  335. {
  336. if(sys_read(0, &c, 1) != 1)
  337. sys_exit(-5);
  338. put(floats, x, y, (double)(unsigned char)c / 0xff);
  339. }
  340. #else
  341. SDL_Surface *tmp, *surface;
  342. uint32_t *pixels;
  343. tmp = IMG_Load(name);
  344. if(!tmp)
  345. return NULL;
  346. WIDTH = tmp->w > MAXWIDTH ? MAXWIDTH : tmp->w;
  347. HEIGHT = tmp->h > MAXHEIGHT ? MAXHEIGHT : tmp->h;
  348. floats = new();
  349. if(!floats)
  350. return NULL;
  351. surface = SDL_CreateRGBSurface(SDL_SWSURFACE, WIDTH, HEIGHT, 32,
  352. 0xff0000, 0xff00, 0xff, 0x0);
  353. pixels = (uint32_t *)surface->pixels;
  354. SDL_BlitSurface(tmp, NULL, surface, NULL);
  355. SDL_FreeSurface(tmp);
  356. for(y = 0; y < HEIGHT; y++)
  357. for(x = 0; x < WIDTH; x++)
  358. {
  359. int green = (pixels[y * surface->pitch / 4 + x] >> 8) & 0xff;
  360. put(floats, x, y, (double)green / 0xff);
  361. }
  362. #endif
  363. return floats;
  364. }
  365. static void save(double const *src, char const *name)
  366. {
  367. int x, y;
  368. #ifdef BYTECODE
  369. for(y = 0; y < HEIGHT; y++)
  370. for(x = 0; x < WIDTH; x++)
  371. {
  372. double p = 255 * get(src, x, y);
  373. uint32_t i = p < 0 ? 0 : p > 255 ? 255 : p;
  374. char c = (char)(unsigned char)i;
  375. if(sys_write(1, &c, 1) != 1)
  376. sys_exit(-6);
  377. }
  378. #else
  379. SDL_Surface *surface;
  380. uint32_t *pixels;
  381. surface = SDL_CreateRGBSurface(SDL_SWSURFACE, WIDTH, HEIGHT, 32,
  382. 0xff0000, 0xff00, 0xff, 0x0);
  383. pixels = (uint32_t *)surface->pixels;
  384. for(y = 0; y < HEIGHT; y++)
  385. for(x = 0; x < WIDTH; x++)
  386. {
  387. double p = 255 * get(src, x, y);
  388. uint32_t i = p < 0 ? 0 : p > 255 ? 255 : p;
  389. pixels[surface->pitch / 4 * y + x] = (i << 16) | (i << 8) | i;
  390. }
  391. SDL_SaveBMP(surface, name);
  392. #endif
  393. }
  394. static double *ostromoukhov(double const *src)
  395. {
  396. static int const table[][3] =
  397. {
  398. {13, 0, 5}, {13, 0, 5}, {21, 0, 10}, {7, 0, 4},
  399. {8, 0, 5}, {47, 3, 28}, {23, 3, 13}, {15, 3, 8},
  400. {22, 6, 11}, {43, 15, 20}, {7, 3, 3}, {501, 224, 211},
  401. {249, 116, 103}, {165, 80, 67}, {123, 62, 49}, {489, 256, 191},
  402. {81, 44, 31}, {483, 272, 181}, {60, 35, 22}, {53, 32, 19},
  403. {237, 148, 83}, {471, 304, 161}, {3, 2, 1}, {481, 314, 185},
  404. {354, 226, 155}, {1389, 866, 685}, {227, 138, 125}, {267, 158, 163},
  405. {327, 188, 220}, {61, 34, 45}, {627, 338, 505}, {1227, 638, 1075},
  406. {20, 10, 19}, {1937, 1000, 1767}, {977, 520, 855}, {657, 360, 551},
  407. {71, 40, 57}, {2005, 1160, 1539}, {337, 200, 247}, {2039, 1240, 1425},
  408. {257, 160, 171}, {691, 440, 437}, {1045, 680, 627}, {301, 200, 171},
  409. {177, 120, 95}, {2141, 1480, 1083}, {1079, 760, 513}, {725, 520, 323},
  410. {137, 100, 57}, {2209, 1640, 855}, {53, 40, 19}, {2243, 1720, 741},
  411. {565, 440, 171}, {759, 600, 209}, {1147, 920, 285}, {2311, 1880, 513},
  412. {97, 80, 19}, {335, 280, 57}, {1181, 1000, 171}, {793, 680, 95},
  413. {599, 520, 57}, {2413, 2120, 171}, {405, 360, 19}, {2447, 2200, 57},
  414. {11, 10, 0}, {158, 151, 3}, {178, 179, 7}, {1030, 1091, 63},
  415. {248, 277, 21}, {318, 375, 35}, {458, 571, 63}, {878, 1159, 147},
  416. {5, 7, 1}, {172, 181, 37}, {97, 76, 22}, {72, 41, 17},
  417. {119, 47, 29}, {4, 1, 1}, {4, 1, 1}, {4, 1, 1},
  418. {4, 1, 1}, {4, 1, 1}, {4, 1, 1}, {4, 1, 1},
  419. {4, 1, 1}, {4, 1, 1}, {65, 18, 17}, {95, 29, 26},
  420. {185, 62, 53}, {30, 11, 9}, {35, 14, 11}, {85, 37, 28},
  421. {55, 26, 19}, {80, 41, 29}, {155, 86, 59}, {5, 3, 2},
  422. {5, 3, 2}, {5, 3, 2}, {5, 3, 2}, {5, 3, 2},
  423. {5, 3, 2}, {5, 3, 2}, {5, 3, 2}, {5, 3, 2},
  424. {5, 3, 2}, {5, 3, 2}, {5, 3, 2}, {5, 3, 2},
  425. {305, 176, 119}, {155, 86, 59}, {105, 56, 39}, {80, 41, 29},
  426. {65, 32, 23}, {55, 26, 19}, {335, 152, 113}, {85, 37, 28},
  427. {115, 48, 37}, {35, 14, 11}, {355, 136, 109}, {30, 11, 9},
  428. {365, 128, 107}, {185, 62, 53}, {25, 8, 7}, {95, 29, 26},
  429. {385, 112, 103}, {65, 18, 17}, {395, 104, 101}, {4, 1, 1}
  430. };
  431. double *dest = new();
  432. double *tmp = copy(src);
  433. int x, y;
  434. for(y = 0; y < HEIGHT; y++)
  435. {
  436. for(x = 0; x < WIDTH; x++)
  437. {
  438. int x1 = (y & 1) ? WIDTH - 1 - x + 1 : x - 1;
  439. int x2 = (y & 1) ? WIDTH - 1 - x : x;
  440. int x3 = (y & 1) ? WIDTH - 1 - x - 1 : x + 1;
  441. double p = get(tmp, x2, y);
  442. double q = p > 0.5 ? 1. : 0.;
  443. double error = (p - q);
  444. int i = p * 255.9999;
  445. put(dest, x2, y, q);
  446. if(i > 127)
  447. i = 255 - i;
  448. if(i < 0)
  449. i = 0;
  450. error /= table[i][0] + table[i][1] + table[i][2];
  451. if(x < WIDTH - 1)
  452. put(tmp, x3, y, get(tmp, x3, y) + error * table[i][0]);
  453. if(y < HEIGHT - 1)
  454. {
  455. if(x > 0)
  456. put(tmp, x1, y + 1,
  457. get(tmp, x1, y + 1) + error * table[i][1]);
  458. put(tmp, x2, y + 1, get(tmp, x2, y + 1) + error * table[i][2]);
  459. }
  460. }
  461. }
  462. del(tmp);
  463. return dest;
  464. }
  465. /* Dither using error diffusion and Floyd-Steinberg-like coefficients:
  466. X a b
  467. c d e f g
  468. h i j k l
  469. */
  470. static double *ed(double const *src, int serpentine,
  471. int a, int b, int c, int d, int e, int f,
  472. int g, int h, int i, int j, int k, int l)
  473. {
  474. double *dest = new();
  475. double *tmp = copy(src);
  476. int x, y, n;
  477. n = a + b + c + d + e + f + g + h + i + j + k + l;
  478. for(y = 0; y < HEIGHT; y++)
  479. {
  480. int swap = serpentine && (y & 1);
  481. for(x = 0; x < WIDTH; x++)
  482. {
  483. int x0 = swap ? WIDTH - 1 - x + 2 : x - 2;
  484. int x1 = swap ? WIDTH - 1 - x + 1 : x - 1;
  485. int x2 = swap ? WIDTH - 1 - x : x;
  486. int x3 = swap ? WIDTH - 1 - x - 1 : x + 1;
  487. int x4 = swap ? WIDTH - 1 - x - 2 : x + 2;
  488. double p = get(tmp, x2, y);
  489. double q = p > 0.5 ? 1. : 0.;
  490. double error = (p - q) / n;
  491. put(dest, x2, y, q);
  492. if(x < WIDTH - 1)
  493. put(tmp, x3, y, get(tmp, x3, y) + error * a);
  494. if(x < WIDTH - 2)
  495. put(tmp, x4, y, get(tmp, x4, y) + error * b);
  496. if(y < HEIGHT - 1)
  497. {
  498. if(x > 0)
  499. {
  500. put(tmp, x1, y + 1,
  501. get(tmp, x1, y + 1) + error * d);
  502. if(x > 1)
  503. put(tmp, x0, y + 1,
  504. get(tmp, x0, y + 1) + error * c);
  505. }
  506. put(tmp, x2, y + 1, get(tmp, x2, y + 1) + error * e);
  507. if(x < WIDTH - 1)
  508. {
  509. put(tmp, x3, y + 1,
  510. get(tmp, x3, y + 1) + error * f);
  511. if(x < WIDTH - 2)
  512. put(tmp, x4, y + 1,
  513. get(tmp, x4, y + 1) + error * g);
  514. }
  515. }
  516. if(y < HEIGHT - 2)
  517. {
  518. if(x > 0)
  519. {
  520. put(tmp, x1, y + 2,
  521. get(tmp, x1, y + 2) + error * h);
  522. if(x > 1)
  523. put(tmp, x0, y + 2,
  524. get(tmp, x0, y + 2) + error * i);
  525. }
  526. put(tmp, x2, y + 2, get(tmp, x2, y + 2) + error * j);
  527. if(x < WIDTH - 1)
  528. {
  529. put(tmp, x3, y + 2,
  530. get(tmp, x3, y + 2) + error * k);
  531. if(x < WIDTH - 2)
  532. put(tmp, x4, y + 2,
  533. get(tmp, x4, y + 2) + error * l);
  534. }
  535. }
  536. }
  537. }
  538. del(tmp);
  539. return dest;
  540. }
  541. /* XXX */
  542. static double *dbs(double const *src, double const *orig,
  543. double sigma, double dx, double dy)
  544. {
  545. double mat[NN][NN];
  546. double *dest, *tmp, *tmp2;
  547. double error;
  548. makegauss(mat, sigma, 0., 0.);
  549. tmp = fullgauss(src, mat);
  550. makegauss(mat, sigma, dx, dy);
  551. dest = copy(orig);
  552. tmp2 = fullgauss(dest, mat);
  553. error = dist(tmp, tmp2, 1.);
  554. for(;;)
  555. {
  556. int changes = 0;
  557. int x, y, i, j, n;
  558. for(y = 0; y < HEIGHT; y++)
  559. for(x = 0; x < WIDTH; x++)
  560. {
  561. double d, d2, e, best = 0.;
  562. int opx = -1, opy = -1;
  563. d = get(dest, x, y);
  564. /* Compute the effect of a toggle */
  565. e = 0.;
  566. for(j = -N; j < N + 1; j++)
  567. {
  568. if(y + j < 0 || y + j >= HEIGHT)
  569. continue;
  570. for(i = -N; i < N + 1; i++)
  571. {
  572. double m, p, q1, q2;
  573. if(x + i < 0 || x + i >= WIDTH)
  574. continue;
  575. m = mat[i + N][j + N];
  576. p = get(tmp, x + i, y + j);
  577. q1 = get(tmp2, x + i, y + j);
  578. q2 = q1 - m * d + m * (1. - d);
  579. e += (q1 - p) * (q1 - p) - (q2 - p) * (q2 - p);
  580. }
  581. }
  582. if(e > best)
  583. {
  584. best = e;
  585. opx = opy = 0;
  586. }
  587. /* Compute the effect of swaps */
  588. for(n = 0; n < 8; n++)
  589. {
  590. static int const step[] =
  591. { 0, 1, 0, -1, -1, 0, 1, 0, -1, -1, -1, 1, 1, -1, 1, 1 };
  592. int idx = step[n * 2], idy = step[n * 2 + 1];
  593. if(y + idy < 0 || y + idy >= HEIGHT
  594. || x + idx < 0 || x + idx >= WIDTH)
  595. continue;
  596. d2 = get(dest, x + idx, y + idy);
  597. if(d2 == d)
  598. continue;
  599. e = 0.;
  600. for(j = -N; j < N + 1; j++)
  601. {
  602. if(y + j < 0 || y + j >= HEIGHT)
  603. continue;
  604. if(j - idy + N < 0 || j - idy + N >= NN)
  605. continue;
  606. for(i = -N; i < N + 1; i++)
  607. {
  608. double ma, mb, p, q1, q2;
  609. if(x + i < 0 || x + i >= WIDTH)
  610. continue;
  611. if(i - idx + N < 0 || i - idx + N >= NN)
  612. continue;
  613. ma = mat[i + N][j + N];
  614. mb = mat[i - idx + N][j - idy + N];
  615. p = get(tmp, x + i, y + j);
  616. q1 = get(tmp2, x + i, y + j);
  617. q2 = q1 - ma * d + ma * d2 - mb * d2 + mb * d;
  618. e += (q1 - p) * (q1 - p) - (q2 - p) * (q2 - p);
  619. }
  620. }
  621. if(e > best)
  622. {
  623. best = e;
  624. opx = idx;
  625. opy = idy;
  626. }
  627. }
  628. /* Apply the change if interesting */
  629. if(best <= 0.)
  630. continue;
  631. if(opx || opy)
  632. {
  633. d2 = get(dest, x + opx, y + opy);
  634. put(dest, x + opx, y + opy, d);
  635. }
  636. else
  637. d2 = 1. - d;
  638. put(dest, x, y, d2);
  639. for(j = -N; j < N + 1; j++)
  640. for(i = -N; i < N + 1; i++)
  641. {
  642. double m = mat[i + N][j + N];
  643. if(y + j >= 0 && y + j < HEIGHT
  644. && x + i >= 0 && x + i < WIDTH)
  645. {
  646. double t = get(tmp2, x + i, y + j);
  647. put(tmp2, x + i, y + j, t + m * (d2 - d));
  648. }
  649. if((opx || opy) && y + opy + j >= 0 && y + opy + j < HEIGHT
  650. && x + opx + i >= 0 && x + opx + i < WIDTH)
  651. {
  652. double t = get(tmp2, x + opx + i, y + opy + j);
  653. put(tmp2, x + opx + i, y + opy + j, t + m * (d - d2));
  654. }
  655. }
  656. changes++;
  657. }
  658. fprintf(stderr, "did %i changes\n", changes);
  659. if(changes == 0)
  660. break;
  661. }
  662. del(tmp);
  663. del(tmp2);
  664. return dest;
  665. }
  666. static void study(double const *src, double const *dest,
  667. double sigma, double precision, double fdx, double fdy)
  668. {
  669. # define Z 3
  670. double mat[NN][NN], mat2[NN][NN];
  671. double *tmp, *tmp2;
  672. double e, e0, e1;
  673. double best = 1., fx = -1., fy = -1., step = 2., bfx = 0., bfy = 0.;
  674. int dx, dy;
  675. makegauss(mat, sigma, 0., 0.);
  676. tmp = gauss(src, mat);
  677. tmp2 = gauss(dest, mat);
  678. e0 = dist(tmp, tmp2, 1.);
  679. del(tmp2);
  680. makegauss(mat2, sigma, fdx, fdy);
  681. tmp2 = gauss(dest, mat2);
  682. e1 = dist(tmp, tmp2, 1.);
  683. del(tmp2);
  684. while(step > precision)
  685. {
  686. for(dy = 0; dy <= Z; dy++)
  687. for(dx = 0; dx <= Z; dx++)
  688. {
  689. makegauss(mat, sigma, fx + step * dx / Z, fy + step * dy / Z);
  690. tmp2 = gauss(dest, mat);
  691. e = dist(tmp, tmp2, best);
  692. del(tmp2);
  693. if(e < best)
  694. {
  695. best = e;
  696. bfx = fx + step * dx / Z;
  697. bfy = fy + step * dy / Z;
  698. }
  699. }
  700. fx = bfx - step / Z;
  701. fy = bfy - step / Z;
  702. step = step * 2 / Z;
  703. }
  704. del(tmp);
  705. msg("E: %g E_fast: %g E_min: %g dx: %g dy: %g\n",
  706. 1000. * e0, 1000. * e1, 1000. * best, fx, fy);
  707. }
  708. static double *merge(double const *im1, double const *im2, double t)
  709. {
  710. double *dest = new();
  711. int x, y;
  712. for(y = 0; y < HEIGHT; y++)
  713. for(x = 0; x < WIDTH; x++)
  714. put(dest, x, y, t * get(im1, x, y) + (1. - t) * get(im2, x, y));
  715. return dest;
  716. }
  717. static void usage(char *argv[])
  718. {
  719. fprintf(stderr, "Usage: %s <mode> [ARGS...]\n", argv[0]);
  720. fprintf(stderr, "Allowed modes:\n");
  721. fprintf(stderr, " -1 <src> raster FS displacement study on src\n");
  722. fprintf(stderr, " -2 <src1> <src2> raster FS displacement study on blends of src1 and src2\n");
  723. fprintf(stderr, " -3 <src> quick (a,b,c,d) ED kernel analysis on src\n");
  724. fprintf(stderr, " -4 <src> exhaustive (a,b,c,d) ED kernel analysis on src\n");
  725. fprintf(stderr, " -5 <src> exhaustive displacement study on src\n");
  726. }
  727. int main(int argc, char *argv[])
  728. {
  729. double *src;
  730. int mode, i;
  731. if(argc < 2)
  732. {
  733. fprintf(stderr, "%s: too few arguments\n", argv[0]);
  734. usage(argv);
  735. return EXIT_FAILURE;
  736. }
  737. if(argv[1][0] != '-' || !(mode = atoi(argv[1] + 1)))
  738. {
  739. fprintf(stderr, "%s: invalid mode `%s'\n", argv[0], argv[1]);
  740. usage(argv);
  741. return EXIT_FAILURE;
  742. }
  743. src = load(argv[2]);
  744. if(!src)
  745. return 2;
  746. msg("### mode %i on `%s' ###\n", mode, argv[2]);
  747. switch(mode)
  748. {
  749. case 1:
  750. {
  751. double *dest = ed(src, false, 7, 0,
  752. 0, 3, 5, 1, 0,
  753. 0, 0, 0, 0, 0);
  754. study(src, dest, 1.2, 0.001, .16, .28);
  755. del(dest);
  756. del(src);
  757. }
  758. break;
  759. case 2:
  760. {
  761. double *src2, *dest, *tmp;
  762. if(argc < 3)
  763. return 3;
  764. src2 = load(argv[2]);
  765. if(!src2)
  766. return 4;
  767. for(i = 0; i <= 100; i++)
  768. {
  769. tmp = merge(src, src2, (double)i / 100.);
  770. dest = ed(tmp, false, 7, 0,
  771. 0, 3, 5, 1, 0,
  772. 0, 0, 0, 0, 0);
  773. study(tmp, dest, 1.2, 0.001, .16, .28);
  774. del(dest);
  775. del(tmp);
  776. }
  777. del(src2);
  778. del(src);
  779. }
  780. break;
  781. case 3:
  782. case 4:
  783. {
  784. double mat[NN][NN];
  785. double *dest, *tmp, *tmp2;
  786. int a, b, c, d, e;
  787. #define TOTAL 16
  788. makegauss(mat, 1.2, 0, 0);
  789. for(a = 0; a <= TOTAL; a++)
  790. for(b = 0; b <= TOTAL; b++)
  791. for(c = 0; c <= TOTAL; c++)
  792. for(d = 0; d <= TOTAL; d++)
  793. for(e = 0; e <= TOTAL; e++)
  794. {
  795. int a2 = a, b2 = b, c2 = c, d2 = d, e2 = e, i;
  796. if(a + b + c + d + e != TOTAL)
  797. continue;
  798. /* Slightly shuffle our coefficients to avoid waiting until
  799. * 75% progress before having an idea of what's going on. */
  800. #define SHUFFLE(p,q,n) \
  801. if(p+q) { int tmp = p+q; p = (p+n) % (tmp+1); q = tmp-p; }
  802. SHUFFLE(c2, d2, 777); SHUFFLE(b2, d2, 555);
  803. SHUFFLE(a2, d2, 333); SHUFFLE(b2, c2, 222);
  804. SHUFFLE(a2, e2, 333); SHUFFLE(b2, e2, 222);
  805. SHUFFLE(a2, c2, 444); SHUFFLE(a2, b2, 666);
  806. SHUFFLE(c2, e2, 999); SHUFFLE(d2, e2, 777);
  807. SHUFFLE(a2, d2, 999); SHUFFLE(a2, b2, 777);
  808. #if 0
  809. if(b2 > c2) continue;
  810. if(d2 > c2) continue;
  811. if(d2 > a2) continue;
  812. #endif
  813. /* We only want 4-cell kernels for now */
  814. if(b2) continue;
  815. for(i = 1; i <= 2; i++)
  816. {
  817. //msg("[%i] K: %d,%d,%d,%d,%d ", i, a2, b2, c2, d2, e2);
  818. msg("[%i] K: %d,%d,%d,%d ", i, a2, c2, d2, e2);
  819. dest = ed(src, i == 2, a2, 0,
  820. b2, c2, d2, e2, 0,
  821. 0, 0, 0, 0, 0);
  822. if(mode == 4)
  823. {
  824. /* XXX: E_fast is meaningless, ignore it */
  825. study(src, dest, 1.2, 0.001, 0., 0.);
  826. }
  827. else
  828. {
  829. tmp = gauss(src, mat);
  830. tmp2 = gauss(dest, mat);
  831. msg("E: %.5g\n", 1000. * dist(tmp, tmp2, 1.));
  832. del(tmp);
  833. del(tmp2);
  834. }
  835. fflush(stdout);
  836. del(dest);
  837. }
  838. }
  839. del(src);
  840. }
  841. break;
  842. case 5:
  843. {
  844. double *dest;
  845. dest = ed(src, false, 7, 0,
  846. 0, 3, 5, 1, 0,
  847. 0, 0, 0, 0, 0);
  848. msg("[1] ");
  849. study(src, dest, 1.2, 0.001, .16, .28);
  850. del(dest);
  851. dest = ed(src, false, 7, 5,
  852. 3, 5, 7, 5, 3,
  853. 1, 3, 5, 3, 1);
  854. msg("[2] ");
  855. study(src, dest, 1.2, 0.001, .26, .76);
  856. del(dest);
  857. dest = ostromoukhov(src);
  858. msg("[3] ");
  859. study(src, dest, 1.2, 0.001, .0, .19);
  860. del(dest);
  861. dest = ed(src, true, 2911, 0,
  862. 0, 1373, 3457, 2258, 0,
  863. 0, 0, 0, 0, 0);
  864. msg("[4] ");
  865. study(src, dest, 1.2, 0.001, .0, .34);
  866. }
  867. break;
  868. case 6:
  869. case 7:
  870. {
  871. double mat[NN][NN];
  872. double *dest;
  873. int a, ax, b, bx, c, cx, d, dx;
  874. if(mode == 6)
  875. a = 7, b = 3, c = 5, d = 1;
  876. else
  877. a = 7, b = 5, c = 4, d = 0;
  878. #undef TOTAL
  879. #define TOTAL (a+b+c+d)
  880. makegauss(mat, 1.2, 0, 0);
  881. for(ax = -2; ax <= 2; ax++)
  882. for(bx = -2; bx <= 2; bx++)
  883. for(cx = -2; cx <= 2; cx++)
  884. for(dx = -2; dx <= 3; dx++)
  885. {
  886. int a2 = a + ax, b2 = b + bx, c2 = c + cx, d2 = d + dx;
  887. if(a2 < 0 || a2 > TOTAL || b2 < 0 || b2 > TOTAL ||
  888. c2 < 0 || c2 > TOTAL || d2 < 0 || d2 > TOTAL)
  889. continue;
  890. if(a2 + b2 + c2 + d2 != TOTAL)
  891. continue;
  892. msg("K: %d,%d,%d,%d ", a2, b2, c2, d2);
  893. dest = ed(src, mode == 7, a2, 0,
  894. 0, b2, c2, d2, 0,
  895. 0, 0, 0, 0, 0);
  896. /* XXX: E_fast is meaningless, ignore it */
  897. study(src, dest, 1.2, 0.001, 0., 0.);
  898. fflush(stdout);
  899. del(dest);
  900. }
  901. del(src);
  902. }
  903. break;
  904. #if 0
  905. tmp = ed(src, 7, 0, 0, 3, 5, 1, 0, 0, 0, 0, 0, 0);
  906. //dest = dbs(src, tmp, 0., 0.);
  907. dest = dbs(src, tmp, 0.20, 0.30);
  908. //dest = dbs(src, tmp, 0.158718, 0.283089);
  909. //dest = copy(tmp);
  910. del(tmp);
  911. study(src, dest, 1.2, 0.00001);
  912. save(dest, "output.bmp");
  913. del(dest);
  914. #endif
  915. #if 0
  916. //dest = ed(src, 5, 0, 0, 3, 5, 3, 0, 0, 0, 0, 0, 0);
  917. //dest = ed(src, false, 7, 0, 0, 3, 5, 1, 0, 0, 0, 0, 0, 0);
  918. //dest = ed(src, true, 7, 0, 0, 3, 5, 1, 0, 0, 0, 0, 0, 0);
  919. //dest = ed(src, true, 7, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0);
  920. //dest = ed(src, 7, 5, 3, 5, 7, 5, 3, 1, 3, 5, 3, 1);
  921. //dest = ed(src, 7, 0, 1, 3, 5, 0, 0, 0, 0, 0, 0, 0);
  922. //dest = ed(src, 7, 0, 1, 4, 4, 0, 0, 0, 0, 0, 0, 0);
  923. //dest = ed(src, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0);
  924. //dest = ed(src, 2911, 0, 1373, 3457, 2258, 0, 0, 0, 0, 0, 0, 0);
  925. dest = ostromoukhov(src);
  926. //dest = ed(src, 7, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 0);
  927. //msg("%s: ", argv[1]);
  928. //study(src, dest, 1.2, 0.001);
  929. save(dest, "output.bmp");
  930. del(dest);
  931. #endif
  932. #if 0
  933. # define STEP 32
  934. dest = ed(src, 7, 0, 0, 3, 5, 1, 0, 0, 0, 0, 0, 0);
  935. makegauss(mat, 1.2, 0., 0.);
  936. tmp = gauss(src, mat);
  937. for(dy = 0; dy < STEP; dy++)
  938. {
  939. for(dx = 0; dx < STEP; dx++)
  940. {
  941. double fy = 2. / STEP * (dy - STEP / 2.);
  942. double fx = 2. / STEP * (dx - STEP / 2.);
  943. makegauss(mat, 1.2, fx, fy);
  944. tmp2 = gauss(dest, mat);
  945. msg("%g %g %g\n", fy, fx, 1000. * dist(tmp, tmp2, 1.));
  946. fflush(stdout);
  947. del(tmp2);
  948. }
  949. msg("\n");
  950. }
  951. save(dest, "output.bmp");
  952. #endif
  953. #if 0
  954. tmp = gauss(src, 0., 0.);
  955. for(a = 0; a < 16; a++)
  956. for(b = 0; b < 16; b++)
  957. for(c = 0; c < 16; c++)
  958. for(d = 0; d < 16; d++)
  959. {
  960. if(a + b + c + d != 16)
  961. continue;
  962. dest = ed(src, a, 0, 0, b, c, d, 0, 0, 0, 0, 0, 0);
  963. tmp2 = gauss(dest, 0., 0.);
  964. msg("%.5g: (%02d %02d %02d %02d)\n",
  965. 1000. * dist(tmp, tmp2, 1.), a, b, c, d);
  966. del(dest);
  967. del(tmp2);
  968. }
  969. save(dest, "output.bmp");
  970. #endif
  971. #if 0
  972. msg("%s\n", argv[1]);
  973. dest = ed(src, false, 7, 0, 0, 3, 5, 1, 0, 0, 0, 0, 0, 0);
  974. study(src, dest, 1.2, 0.01);
  975. del(dest);
  976. dest = ed(src, false, 7, 5, 3, 5, 7, 5, 3, 1, 3, 5, 3, 1);
  977. study(src, dest, 1.2, 0.01);
  978. del(dest);
  979. dest = ostromoukhov(src);
  980. study(src, dest, 1.2, 0.01);
  981. del(dest);
  982. dest = ed(src, true, 2911, 0, 0, 1373, 3457, 2258, 0, 0, 0, 0, 0, 0);
  983. study(src, dest, 1.2, 0.01);
  984. del(dest);
  985. msg("\n");
  986. #endif
  987. #if 0
  988. //dest = ostromoukhov(src);
  989. //dest = ed(src, true, 7, 0, 0, 3, 5, 1, 0, 0, 0, 0, 0, 0);
  990. tmp = new();//ed(src, 7, 0, 0, 3, 5, 1, 0, 0, 0, 0, 0, 0);
  991. dest = dbs(src, tmp, 0., 0.);
  992. for(sigma = 0.8; sigma < 2; sigma *= 1.03)
  993. //for(sigma = 0.8; sigma < 2.; sigma *= 1.01)
  994. {
  995. msg("%g ", sigma);
  996. study(src, dest, sigma, 0.01);
  997. }
  998. #endif
  999. }
  1000. #if 0
  1001. tmp = new();
  1002. a = 0;
  1003. for(sigma = 0.8; sigma < 2; sigma *= 1.03)
  1004. {
  1005. char buf[1024];
  1006. msg("%i: %g\n", a, sigma);
  1007. dest = dbs(src, tmp, sigma, 0., 0.);
  1008. sprintf(buf, "output-dbs-%i.bmp", a++);
  1009. save(dest, buf);
  1010. }
  1011. #endif
  1012. return 0;
  1013. }