Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

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