Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

660 wiersze
18 KiB

  1. /*
  2. * libpipi Proper image processing implementation library
  3. * Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * $Id$
  7. *
  8. * This library is free software. It comes without any warranty, to
  9. * the extent permitted by applicable law. You can redistribute it
  10. * and/or modify it under the terms of the Do What The Fuck You Want
  11. * To Public License, Version 2, as published by Sam Hocevar. See
  12. * http://sam.zoy.org/wtfpl/COPYING for more details.
  13. */
  14. /*
  15. * context.c: processing stack handling routines
  16. */
  17. #include "config.h"
  18. #include "common.h"
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <stdarg.h>
  22. #include <string.h>
  23. #include "pipi.h"
  24. #include "pipi_internals.h"
  25. pipi_context_t *pipi_create_context()
  26. {
  27. pipi_context_t *ret;
  28. ret = malloc(sizeof(pipi_context_t));
  29. memset(ret, 0, sizeof(pipi_context_t));
  30. return ret;
  31. }
  32. void pipi_destroy_context(pipi_context_t *ctx)
  33. {
  34. free(ctx);
  35. }
  36. int pipi_command(pipi_context_t *ctx, char const *cmd, ...)
  37. {
  38. if(!strcmp(cmd, "load"))
  39. {
  40. char const *file;
  41. va_list ap;
  42. va_start(ap, cmd);
  43. file = va_arg(ap, char const *);
  44. va_end(ap);
  45. ctx->images[ctx->nimages] = pipi_load(file);
  46. if(ctx->images[ctx->nimages] == NULL)
  47. return -1;
  48. ctx->nimages++;
  49. }
  50. else if(!strcmp(cmd, "save"))
  51. {
  52. char const *file;
  53. va_list ap;
  54. if(ctx->nimages < 1)
  55. return -1;
  56. ctx->nimages--;
  57. va_start(ap, cmd);
  58. file = va_arg(ap, char const *);
  59. va_end(ap);
  60. pipi_save(ctx->images[ctx->nimages], file);
  61. pipi_free(ctx->images[ctx->nimages]);
  62. }
  63. else if(!strcmp(cmd, "dither"))
  64. {
  65. pipi_image_t *src, *dst;
  66. char const *method;
  67. va_list ap;
  68. if(ctx->nimages < 1)
  69. return -1;
  70. va_start(ap, cmd);
  71. method = va_arg(ap, char const *);
  72. va_end(ap);
  73. src = ctx->images[ctx->nimages - 1];
  74. dst = NULL;
  75. if(!strcmp(method, "ost"))
  76. dst = pipi_dither_ostromoukhov(src, 0);
  77. else if(!strcmp(method, "sost"))
  78. dst = pipi_dither_ostromoukhov(src, 1);
  79. else if(!strcmp(method, "ediff"))
  80. {
  81. if(ctx->nimages < 2)
  82. return -1;
  83. dst = pipi_dither_ediff(ctx->images[ctx->nimages - 2], src, 0);
  84. pipi_free(ctx->images[ctx->nimages - 2]);
  85. ctx->nimages--;
  86. }
  87. else if(!strcmp(method, "sediff"))
  88. {
  89. if(ctx->nimages < 2)
  90. return -1;
  91. dst = pipi_dither_ediff(ctx->images[ctx->nimages - 2], src, 1);
  92. pipi_free(ctx->images[ctx->nimages - 2]);
  93. ctx->nimages--;
  94. }
  95. else if(!strcmp(method, "ordered"))
  96. {
  97. if(ctx->nimages < 2)
  98. return -1;
  99. dst = pipi_dither_ordered(ctx->images[ctx->nimages - 2], src);
  100. pipi_free(ctx->images[ctx->nimages - 2]);
  101. ctx->nimages--;
  102. }
  103. else if(!strcmp(method, "random"))
  104. dst = pipi_dither_random(src);
  105. else if(!strcmp(method, "dbs"))
  106. dst = pipi_dither_dbs(src);
  107. if(dst == NULL)
  108. return -1;
  109. pipi_free(src);
  110. ctx->images[ctx->nimages - 1] = dst;
  111. }
  112. else if(!strcmp(cmd, "blur"))
  113. {
  114. pipi_image_t *src, *dst;
  115. char const *arg;
  116. va_list ap;
  117. double w, h, a = 0.0;
  118. if(ctx->nimages < 1)
  119. return -1;
  120. va_start(ap, cmd);
  121. arg = va_arg(ap, char const *);
  122. va_end(ap);
  123. w = h = atof(arg);
  124. arg = strchr(arg, 'x');
  125. if(arg)
  126. {
  127. h = atof(arg + 1);
  128. arg = strchr(arg, 'r');
  129. if(arg)
  130. a = atof(arg + 1);
  131. }
  132. src = ctx->images[ctx->nimages - 1];
  133. dst = pipi_gaussian_blur_ext(src, w, h, a, 0.0, 0.0);
  134. if(dst == NULL)
  135. return -1;
  136. pipi_free(src);
  137. ctx->images[ctx->nimages - 1] = dst;
  138. }
  139. else if(!strcmp(cmd, "boxblur"))
  140. {
  141. pipi_image_t *src, *dst;
  142. char const *arg;
  143. va_list ap;
  144. double w, h;
  145. if(ctx->nimages < 1)
  146. return -1;
  147. va_start(ap, cmd);
  148. arg = va_arg(ap, char const *);
  149. va_end(ap);
  150. w = h = atof(arg);
  151. arg = strchr(arg, 'x');
  152. if(arg)
  153. h = atof(arg + 1);
  154. src = ctx->images[ctx->nimages - 1];
  155. dst = pipi_box_blur_ext(src, w, h);
  156. if(dst == NULL)
  157. return -1;
  158. pipi_free(src);
  159. ctx->images[ctx->nimages - 1] = dst;
  160. }
  161. else if(!strcmp(cmd, "median"))
  162. {
  163. pipi_image_t *src, *dst;
  164. char const *arg;
  165. va_list ap;
  166. double w, h;
  167. if(ctx->nimages < 1)
  168. return -1;
  169. va_start(ap, cmd);
  170. arg = va_arg(ap, char const *);
  171. va_end(ap);
  172. w = h = atof(arg);
  173. arg = strchr(arg, 'x');
  174. if(arg)
  175. h = atof(arg + 1);
  176. src = ctx->images[ctx->nimages - 1];
  177. dst = pipi_median_ext(src, w, h);
  178. if(dst == NULL)
  179. return -1;
  180. pipi_free(src);
  181. ctx->images[ctx->nimages - 1] = dst;
  182. }
  183. else if(!strcmp(cmd, "geometry"))
  184. {
  185. pipi_image_t *src, *dst;
  186. char const *arg;
  187. va_list ap;
  188. int w, h;
  189. if(ctx->nimages < 1)
  190. return -1;
  191. va_start(ap, cmd);
  192. arg = va_arg(ap, char const *);
  193. va_end(ap);
  194. w = atoi(arg);
  195. arg = strchr(arg, 'x');
  196. if(!arg)
  197. return -1;
  198. h = atoi(arg + 1);
  199. if(w <= 0 || h <= 0)
  200. return -1;
  201. src = ctx->images[ctx->nimages - 1];
  202. dst = pipi_resize(src, w, h);
  203. if(dst == NULL)
  204. return -1;
  205. pipi_free(src);
  206. ctx->images[ctx->nimages - 1] = dst;
  207. }
  208. else if(!strcmp(cmd, "tile"))
  209. {
  210. pipi_image_t *src, *dst;
  211. char const *arg;
  212. va_list ap;
  213. int w, h;
  214. if(ctx->nimages < 1)
  215. return -1;
  216. va_start(ap, cmd);
  217. arg = va_arg(ap, char const *);
  218. va_end(ap);
  219. w = atoi(arg);
  220. arg = strchr(arg, 'x');
  221. if(!arg)
  222. return -1;
  223. h = atoi(arg + 1);
  224. if(w <= 0 || h <= 0)
  225. return -1;
  226. src = ctx->images[ctx->nimages - 1];
  227. dst = pipi_tile(src, w, h);
  228. if(dst == NULL)
  229. return -1;
  230. pipi_free(src);
  231. ctx->images[ctx->nimages - 1] = dst;
  232. }
  233. else if(!strcmp(cmd, "scale"))
  234. {
  235. pipi_image_t *src, *dst;
  236. char const *arg;
  237. va_list ap;
  238. double scale;
  239. int w, h;
  240. if(ctx->nimages < 1)
  241. return -1;
  242. src = ctx->images[ctx->nimages - 1];
  243. va_start(ap, cmd);
  244. arg = va_arg(ap, char const *);
  245. va_end(ap);
  246. scale = atof(arg);
  247. w = (int)(scale * src->w + 0.5);
  248. h = (int)(scale * src->h + 0.5);
  249. if(w <= 0 || h <= 0)
  250. return -1;
  251. dst = pipi_resize(src, w, h);
  252. if(dst == NULL)
  253. return -1;
  254. pipi_free(src);
  255. ctx->images[ctx->nimages - 1] = dst;
  256. }
  257. else if(!strcmp(cmd, "brightness"))
  258. {
  259. pipi_image_t *src, *dst;
  260. char const *arg;
  261. va_list ap;
  262. double val;
  263. if(ctx->nimages < 1)
  264. return -1;
  265. va_start(ap, cmd);
  266. arg = va_arg(ap, char const *);
  267. va_end(ap);
  268. val = atof(arg);
  269. src = ctx->images[ctx->nimages - 1];
  270. dst = pipi_brightness(src, val);
  271. if(dst == NULL)
  272. return -1;
  273. pipi_free(src);
  274. ctx->images[ctx->nimages - 1] = dst;
  275. }
  276. else if(!strcmp(cmd, "contrast"))
  277. {
  278. pipi_image_t *src, *dst;
  279. char const *arg;
  280. va_list ap;
  281. double val;
  282. if(ctx->nimages < 1)
  283. return -1;
  284. va_start(ap, cmd);
  285. arg = va_arg(ap, char const *);
  286. va_end(ap);
  287. val = atof(arg);
  288. src = ctx->images[ctx->nimages - 1];
  289. dst = pipi_contrast(src, val);
  290. if(dst == NULL)
  291. return -1;
  292. pipi_free(src);
  293. ctx->images[ctx->nimages - 1] = dst;
  294. }
  295. else if(!strcmp(cmd, "threshold"))
  296. {
  297. pipi_image_t *src, *dst;
  298. char const *arg;
  299. va_list ap;
  300. double val;
  301. if(ctx->nimages < 1)
  302. return -1;
  303. va_start(ap, cmd);
  304. arg = va_arg(ap, char const *);
  305. va_end(ap);
  306. val = atof(arg);
  307. src = ctx->images[ctx->nimages - 1];
  308. dst = pipi_threshold(src, val);
  309. if(dst == NULL)
  310. return -1;
  311. pipi_free(src);
  312. ctx->images[ctx->nimages - 1] = dst;
  313. }
  314. else if(!strcmp(cmd, "hflip"))
  315. {
  316. pipi_image_t *tmp;
  317. if(ctx->nimages < 1)
  318. return -1;
  319. tmp = ctx->images[ctx->nimages - 1];
  320. ctx->images[ctx->nimages - 1] = pipi_hflip(tmp);
  321. pipi_free(tmp);
  322. }
  323. else if(!strcmp(cmd, "vflip"))
  324. {
  325. pipi_image_t *tmp;
  326. if(ctx->nimages < 1)
  327. return -1;
  328. tmp = ctx->images[ctx->nimages - 1];
  329. ctx->images[ctx->nimages - 1] = pipi_vflip(tmp);
  330. pipi_free(tmp);
  331. }
  332. else if(!strcmp(cmd, "rotate90"))
  333. {
  334. pipi_image_t *tmp;
  335. if(ctx->nimages < 1)
  336. return -1;
  337. tmp = ctx->images[ctx->nimages - 1];
  338. ctx->images[ctx->nimages - 1] = pipi_rotate90(tmp);
  339. pipi_free(tmp);
  340. }
  341. else if(!strcmp(cmd, "rotate180"))
  342. {
  343. pipi_image_t *tmp;
  344. if(ctx->nimages < 1)
  345. return -1;
  346. tmp = ctx->images[ctx->nimages - 1];
  347. ctx->images[ctx->nimages - 1] = pipi_rotate180(tmp);
  348. pipi_free(tmp);
  349. }
  350. else if(!strcmp(cmd, "rotate270"))
  351. {
  352. pipi_image_t *tmp;
  353. if(ctx->nimages < 1)
  354. return -1;
  355. tmp = ctx->images[ctx->nimages - 1];
  356. ctx->images[ctx->nimages - 1] = pipi_rotate270(tmp);
  357. pipi_free(tmp);
  358. }
  359. else if(!strcmp(cmd, "split"))
  360. {
  361. pipi_image_t *src;
  362. if(ctx->nimages < 1)
  363. return -1;
  364. src = ctx->images[ctx->nimages - 1];
  365. ctx->nimages += 2;
  366. ctx->images[ctx->nimages - 3] = pipi_red(src);
  367. ctx->images[ctx->nimages - 2] = pipi_green(src);
  368. ctx->images[ctx->nimages - 1] = pipi_blue(src);
  369. pipi_free(src);
  370. }
  371. else if(!strcmp(cmd, "combine"))
  372. {
  373. pipi_image_t *dst;
  374. if(ctx->nimages < 3)
  375. return -1;
  376. dst = pipi_rgb(ctx->images[ctx->nimages - 3],
  377. ctx->images[ctx->nimages - 2],
  378. ctx->images[ctx->nimages - 1]);
  379. if(dst == NULL)
  380. return -1;
  381. pipi_free(ctx->images[ctx->nimages - 3]);
  382. pipi_free(ctx->images[ctx->nimages - 2]);
  383. pipi_free(ctx->images[ctx->nimages - 1]);
  384. ctx->images[ctx->nimages - 3] = dst;
  385. ctx->nimages -= 2;
  386. }
  387. else if(!strcmp(cmd, "mean"))
  388. {
  389. pipi_image_t *dst;
  390. if(ctx->nimages < 2)
  391. return -1;
  392. dst = pipi_mean(ctx->images[ctx->nimages - 2],
  393. ctx->images[ctx->nimages - 1]);
  394. if(dst == NULL)
  395. return -1;
  396. pipi_free(ctx->images[ctx->nimages - 2]);
  397. pipi_free(ctx->images[ctx->nimages - 1]);
  398. ctx->images[ctx->nimages - 2] = dst;
  399. ctx->nimages--;
  400. }
  401. else if(!strcmp(cmd, "min"))
  402. {
  403. pipi_image_t *dst;
  404. if(ctx->nimages < 2)
  405. return -1;
  406. dst = pipi_min(ctx->images[ctx->nimages - 2],
  407. ctx->images[ctx->nimages - 1]);
  408. if(dst == NULL)
  409. return -1;
  410. pipi_free(ctx->images[ctx->nimages - 2]);
  411. pipi_free(ctx->images[ctx->nimages - 1]);
  412. ctx->images[ctx->nimages - 2] = dst;
  413. ctx->nimages--;
  414. }
  415. else if(!strcmp(cmd, "max"))
  416. {
  417. pipi_image_t *dst;
  418. if(ctx->nimages < 2)
  419. return -1;
  420. dst = pipi_max(ctx->images[ctx->nimages - 2],
  421. ctx->images[ctx->nimages - 1]);
  422. if(dst == NULL)
  423. return -1;
  424. pipi_free(ctx->images[ctx->nimages - 2]);
  425. pipi_free(ctx->images[ctx->nimages - 1]);
  426. ctx->images[ctx->nimages - 2] = dst;
  427. ctx->nimages--;
  428. }
  429. else if(!strcmp(cmd, "add"))
  430. {
  431. pipi_image_t *dst;
  432. if(ctx->nimages < 2)
  433. return -1;
  434. dst = pipi_add(ctx->images[ctx->nimages - 2],
  435. ctx->images[ctx->nimages - 1]);
  436. if(dst == NULL)
  437. return -1;
  438. pipi_free(ctx->images[ctx->nimages - 2]);
  439. pipi_free(ctx->images[ctx->nimages - 1]);
  440. ctx->images[ctx->nimages - 2] = dst;
  441. ctx->nimages--;
  442. }
  443. else if(!strcmp(cmd, "sub"))
  444. {
  445. pipi_image_t *dst;
  446. if(ctx->nimages < 2)
  447. return -1;
  448. dst = pipi_sub(ctx->images[ctx->nimages - 2],
  449. ctx->images[ctx->nimages - 1]);
  450. if(dst == NULL)
  451. return -1;
  452. pipi_free(ctx->images[ctx->nimages - 2]);
  453. pipi_free(ctx->images[ctx->nimages - 1]);
  454. ctx->images[ctx->nimages - 2] = dst;
  455. ctx->nimages--;
  456. }
  457. else if(!strcmp(cmd, "difference"))
  458. {
  459. pipi_image_t *dst;
  460. if(ctx->nimages < 2)
  461. return -1;
  462. dst = pipi_difference(ctx->images[ctx->nimages - 2],
  463. ctx->images[ctx->nimages - 1]);
  464. if(dst == NULL)
  465. return -1;
  466. pipi_free(ctx->images[ctx->nimages - 2]);
  467. pipi_free(ctx->images[ctx->nimages - 1]);
  468. ctx->images[ctx->nimages - 2] = dst;
  469. ctx->nimages--;
  470. }
  471. else if(!strcmp(cmd, "multiply"))
  472. {
  473. pipi_image_t *dst;
  474. if(ctx->nimages < 2)
  475. return -1;
  476. dst = pipi_multiply(ctx->images[ctx->nimages - 2],
  477. ctx->images[ctx->nimages - 1]);
  478. if(dst == NULL)
  479. return -1;
  480. pipi_free(ctx->images[ctx->nimages - 2]);
  481. pipi_free(ctx->images[ctx->nimages - 1]);
  482. ctx->images[ctx->nimages - 2] = dst;
  483. ctx->nimages--;
  484. }
  485. else if(!strcmp(cmd, "divide"))
  486. {
  487. pipi_image_t *dst;
  488. if(ctx->nimages < 2)
  489. return -1;
  490. dst = pipi_divide(ctx->images[ctx->nimages - 2],
  491. ctx->images[ctx->nimages - 1]);
  492. if(dst == NULL)
  493. return -1;
  494. pipi_free(ctx->images[ctx->nimages - 2]);
  495. pipi_free(ctx->images[ctx->nimages - 1]);
  496. ctx->images[ctx->nimages - 2] = dst;
  497. ctx->nimages--;
  498. }
  499. else if(!strcmp(cmd, "screen"))
  500. {
  501. pipi_image_t *dst;
  502. if(ctx->nimages < 2)
  503. return -1;
  504. dst = pipi_screen(ctx->images[ctx->nimages - 2],
  505. ctx->images[ctx->nimages - 1]);
  506. if(dst == NULL)
  507. return -1;
  508. pipi_free(ctx->images[ctx->nimages - 2]);
  509. pipi_free(ctx->images[ctx->nimages - 1]);
  510. ctx->images[ctx->nimages - 2] = dst;
  511. ctx->nimages--;
  512. }
  513. else if(!strcmp(cmd, "overlay"))
  514. {
  515. pipi_image_t *dst;
  516. if(ctx->nimages < 2)
  517. return -1;
  518. dst = pipi_overlay(ctx->images[ctx->nimages - 2],
  519. ctx->images[ctx->nimages - 1]);
  520. if(dst == NULL)
  521. return -1;
  522. pipi_free(ctx->images[ctx->nimages - 2]);
  523. pipi_free(ctx->images[ctx->nimages - 1]);
  524. ctx->images[ctx->nimages - 2] = dst;
  525. ctx->nimages--;
  526. }
  527. else if(!strcmp(cmd, "wrap"))
  528. {
  529. if(ctx->nimages < 1)
  530. return -1;
  531. ctx->images[ctx->nimages - 1]->wrap = 1;
  532. }
  533. else if(!strcmp(cmd, "autocontrast"))
  534. {
  535. pipi_image_t *tmp;
  536. if(ctx->nimages < 1)
  537. return -1;
  538. tmp = ctx->images[ctx->nimages - 1];
  539. ctx->images[ctx->nimages - 1] = pipi_autocontrast(tmp);
  540. pipi_free(tmp);
  541. }
  542. else if(!strcmp(cmd, "invert"))
  543. {
  544. pipi_image_t *tmp;
  545. if(ctx->nimages < 1)
  546. return -1;
  547. tmp = ctx->images[ctx->nimages - 1];
  548. ctx->images[ctx->nimages - 1] = pipi_invert(tmp);
  549. pipi_free(tmp);
  550. }
  551. else if(!strcmp(cmd, "dilate"))
  552. {
  553. pipi_image_t *tmp;
  554. if(ctx->nimages < 1)
  555. return -1;
  556. tmp = ctx->images[ctx->nimages - 1];
  557. ctx->images[ctx->nimages - 1] = pipi_dilate(tmp);
  558. pipi_free(tmp);
  559. }
  560. else if(!strcmp(cmd, "erode"))
  561. {
  562. pipi_image_t *tmp;
  563. if(ctx->nimages < 1)
  564. return -1;
  565. tmp = ctx->images[ctx->nimages - 1];
  566. ctx->images[ctx->nimages - 1] = pipi_erode(tmp);
  567. pipi_free(tmp);
  568. }
  569. else if(!strcmp(cmd, "gray"))
  570. {
  571. if(ctx->nimages < 1)
  572. return -1;
  573. pipi_getpixels(ctx->images[ctx->nimages - 1], PIPI_PIXELS_Y_F);
  574. }
  575. else if(!strcmp(cmd, "free"))
  576. {
  577. if(ctx->nimages < 1)
  578. return -1;
  579. ctx->nimages--;
  580. pipi_free(ctx->images[ctx->nimages]);
  581. }
  582. else if(!strcmp(cmd, "dup"))
  583. {
  584. if(ctx->nimages < 1)
  585. return -1;
  586. ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
  587. ctx->nimages++;
  588. }
  589. else if(!strcmp(cmd, "swap"))
  590. {
  591. pipi_image_t *tmp;
  592. if(ctx->nimages < 2)
  593. return -1;
  594. tmp = ctx->images[ctx->nimages - 1];
  595. ctx->images[ctx->nimages - 1] = ctx->images[ctx->nimages - 2];
  596. ctx->images[ctx->nimages - 2] = tmp;
  597. }
  598. else if(!strcmp(cmd, "roll"))
  599. {
  600. pipi_image_t *tmp;
  601. char const *arg;
  602. va_list ap;
  603. int val;
  604. va_start(ap, cmd);
  605. arg = va_arg(ap, char const *);
  606. va_end(ap);
  607. val = atoi(arg);
  608. if(val <= 0 || ctx->nimages < val)
  609. return -1;
  610. if(val == 1)
  611. return 0;
  612. tmp = ctx->images[ctx->nimages - val];
  613. memmove(ctx->images + ctx->nimages - val,
  614. ctx->images + ctx->nimages - val + 1,
  615. (val - 1) * sizeof(*ctx->images));
  616. ctx->images[ctx->nimages - 1] = tmp;
  617. }
  618. else
  619. {
  620. return -1;
  621. }
  622. return 0;
  623. }