25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 
 

856 satır
23 KiB

  1. /*
  2. * libpipi Pathetic image processing interface 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 <stdio.h>
  19. #include <stdlib.h>
  20. #include <stdarg.h>
  21. #include <string.h>
  22. #include "pipi.h"
  23. #include "pipi_internals.h"
  24. pipi_context_t *pipi_create_context()
  25. {
  26. pipi_context_t *ret;
  27. ret = malloc(sizeof(pipi_context_t));
  28. memset(ret, 0, sizeof(pipi_context_t));
  29. return ret;
  30. }
  31. void pipi_destroy_context(pipi_context_t *ctx)
  32. {
  33. free(ctx);
  34. }
  35. pipi_command_t const *pipi_get_command_list(void)
  36. {
  37. static pipi_command_t const list[] =
  38. {
  39. { "load", 1 },
  40. { "save", 1 },
  41. { "dup", 0 },
  42. { "swap", 0 },
  43. { "roll", 1 },
  44. { "gamma", 1 },
  45. { "scale", 1 },
  46. { "crop", 1 },
  47. { "geometry", 1 },
  48. { "tile", 1 },
  49. { "dither", 1 },
  50. { "blur", 1 },
  51. { "boxblur", 1 },
  52. { "median", 1 },
  53. { "gray", 0 },
  54. { "brightness", 1 },
  55. { "contrast", 1 },
  56. { "autocontrast", 0 },
  57. { "order", 0 },
  58. { "hflip", 0 },
  59. { "vflip", 0 },
  60. { "rotate90", 0 },
  61. { "rotate180", 0 },
  62. { "rotate270", 0 },
  63. { "invert", 0 },
  64. { "threshold", 1 },
  65. { "dilate", 0 },
  66. { "erode", 0 },
  67. { "wrap", 0 },
  68. { "combine", 0 },
  69. { "split", 0 },
  70. { "mean", 0 },
  71. { "merge", 1 },
  72. { "min", 0 },
  73. { "max", 0 },
  74. { "add", 0 },
  75. { "sub", 0 },
  76. { "difference", 0 },
  77. { "multiply", 0 },
  78. { "divide", 0 },
  79. { "screen", 0 },
  80. { "overlay", 0 },
  81. { "line", 1 },
  82. { "sine", 1 },
  83. /* End marker */
  84. { NULL, 0 }
  85. };
  86. return list;
  87. }
  88. int pipi_command(pipi_context_t *ctx, char const *cmd, ...)
  89. {
  90. if(!strcmp(cmd, "load"))
  91. {
  92. char const *file;
  93. va_list ap;
  94. va_start(ap, cmd);
  95. file = va_arg(ap, char const *);
  96. va_end(ap);
  97. ctx->images[ctx->nimages] = pipi_load(file);
  98. if(ctx->images[ctx->nimages] == NULL)
  99. return -1;
  100. ctx->nimages++;
  101. }
  102. else if(!strcmp(cmd, "save"))
  103. {
  104. char const *file;
  105. va_list ap;
  106. if(ctx->nimages < 1)
  107. return -1;
  108. ctx->nimages--;
  109. va_start(ap, cmd);
  110. file = va_arg(ap, char const *);
  111. va_end(ap);
  112. pipi_save(ctx->images[ctx->nimages], file);
  113. pipi_free(ctx->images[ctx->nimages]);
  114. }
  115. else if(!strcmp(cmd, "gamma"))
  116. {
  117. char const *val;
  118. va_list ap;
  119. va_start(ap, cmd);
  120. val = va_arg(ap, char const *);
  121. va_end(ap);
  122. pipi_set_gamma(atof(val));
  123. }
  124. else if(!strcmp(cmd, "dither"))
  125. {
  126. pipi_image_t *src, *dst;
  127. char const *method;
  128. va_list ap;
  129. if(ctx->nimages < 1)
  130. return -1;
  131. va_start(ap, cmd);
  132. method = va_arg(ap, char const *);
  133. va_end(ap);
  134. src = ctx->images[ctx->nimages - 1];
  135. dst = NULL;
  136. if(!strcmp(method, "ost"))
  137. dst = pipi_dither_ostromoukhov(src, 0);
  138. else if(!strcmp(method, "sost"))
  139. dst = pipi_dither_ostromoukhov(src, 1);
  140. else if(!strcmp(method, "ediff"))
  141. {
  142. if(ctx->nimages < 2)
  143. return -1;
  144. dst = pipi_dither_ediff(ctx->images[ctx->nimages - 2], src, 0);
  145. pipi_free(ctx->images[ctx->nimages - 2]);
  146. ctx->nimages--;
  147. }
  148. else if(!strcmp(method, "sediff"))
  149. {
  150. if(ctx->nimages < 2)
  151. return -1;
  152. dst = pipi_dither_ediff(ctx->images[ctx->nimages - 2], src, 1);
  153. pipi_free(ctx->images[ctx->nimages - 2]);
  154. ctx->nimages--;
  155. }
  156. else if(!strncmp(method, "ordered", 7))
  157. {
  158. double scale = 1., angle = .0;
  159. if(ctx->nimages < 2)
  160. return -1;
  161. method = strchr(method, ':');
  162. if(method)
  163. {
  164. scale = atof(method + 1);
  165. method = strchr(method + 1, ':');
  166. if(method)
  167. angle = atof(method + 1);
  168. }
  169. if(scale <= 0.)
  170. scale = 1.;
  171. dst = pipi_dither_ordered_ext(ctx->images[ctx->nimages - 2], src,
  172. scale, angle);
  173. pipi_free(ctx->images[ctx->nimages - 2]);
  174. ctx->nimages--;
  175. }
  176. else if(!strncmp(method, "halftone", 8))
  177. {
  178. double r, angle = .0;
  179. method = strchr(method, ':');
  180. if(!method)
  181. return -1;
  182. r = atof(method + 1);
  183. method = strchr(method + 1, ':');
  184. if(method)
  185. angle = atof(method + 1);
  186. if(r < 1.)
  187. r = 1.;
  188. dst = pipi_dither_halftone(src, r, angle);
  189. }
  190. else if(!strcmp(method, "random"))
  191. dst = pipi_dither_random(src);
  192. else if(!strcmp(method, "dbs"))
  193. dst = pipi_dither_dbs(src);
  194. if(dst == NULL)
  195. return -1;
  196. pipi_free(src);
  197. ctx->images[ctx->nimages - 1] = dst;
  198. }
  199. else if(!strcmp(cmd, "blur"))
  200. {
  201. pipi_image_t *src, *dst;
  202. char const *arg;
  203. va_list ap;
  204. double w, h, a = 0.0;
  205. if(ctx->nimages < 1)
  206. return -1;
  207. va_start(ap, cmd);
  208. arg = va_arg(ap, char const *);
  209. va_end(ap);
  210. w = h = atof(arg);
  211. arg = strchr(arg, 'x');
  212. if(arg)
  213. {
  214. h = atof(arg + 1);
  215. arg = strchr(arg, 'r');
  216. if(arg)
  217. a = atof(arg + 1);
  218. }
  219. src = ctx->images[ctx->nimages - 1];
  220. dst = pipi_gaussian_blur_ext(src, w, h, a, 0.0, 0.0);
  221. if(dst == NULL)
  222. return -1;
  223. pipi_free(src);
  224. ctx->images[ctx->nimages - 1] = dst;
  225. }
  226. else if(!strcmp(cmd, "boxblur"))
  227. {
  228. pipi_image_t *src, *dst;
  229. char const *arg;
  230. va_list ap;
  231. double w, h;
  232. if(ctx->nimages < 1)
  233. return -1;
  234. va_start(ap, cmd);
  235. arg = va_arg(ap, char const *);
  236. va_end(ap);
  237. w = h = atof(arg);
  238. arg = strchr(arg, 'x');
  239. if(arg)
  240. h = atof(arg + 1);
  241. src = ctx->images[ctx->nimages - 1];
  242. dst = pipi_box_blur_ext(src, w, h);
  243. if(dst == NULL)
  244. return -1;
  245. pipi_free(src);
  246. ctx->images[ctx->nimages - 1] = dst;
  247. }
  248. else if(!strcmp(cmd, "median"))
  249. {
  250. pipi_image_t *src, *dst;
  251. char const *arg;
  252. va_list ap;
  253. double w, h;
  254. if(ctx->nimages < 1)
  255. return -1;
  256. va_start(ap, cmd);
  257. arg = va_arg(ap, char const *);
  258. va_end(ap);
  259. w = h = atof(arg);
  260. arg = strchr(arg, 'x');
  261. if(arg)
  262. h = atof(arg + 1);
  263. src = ctx->images[ctx->nimages - 1];
  264. dst = pipi_median_ext(src, w, h);
  265. if(dst == NULL)
  266. return -1;
  267. pipi_free(src);
  268. ctx->images[ctx->nimages - 1] = dst;
  269. }
  270. else if(!strcmp(cmd, "geometry"))
  271. {
  272. pipi_image_t *src, *dst;
  273. char const *arg;
  274. va_list ap;
  275. int w, h;
  276. if(ctx->nimages < 1)
  277. return -1;
  278. va_start(ap, cmd);
  279. arg = va_arg(ap, char const *);
  280. va_end(ap);
  281. w = atoi(arg);
  282. arg = strchr(arg, 'x');
  283. if(!arg)
  284. return -1;
  285. h = atoi(arg + 1);
  286. if(w <= 0 || h <= 0)
  287. return -1;
  288. src = ctx->images[ctx->nimages - 1];
  289. dst = pipi_resize(src, w, h);
  290. if(dst == NULL)
  291. return -1;
  292. pipi_free(src);
  293. ctx->images[ctx->nimages - 1] = dst;
  294. }
  295. else if(!strcmp(cmd, "tile"))
  296. {
  297. pipi_image_t *src, *dst;
  298. char const *arg;
  299. va_list ap;
  300. int w, h;
  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. w = atoi(arg);
  307. arg = strchr(arg, 'x');
  308. if(!arg)
  309. return -1;
  310. h = atoi(arg + 1);
  311. if(w <= 0 || h <= 0)
  312. return -1;
  313. src = ctx->images[ctx->nimages - 1];
  314. dst = pipi_tile(src, w, h);
  315. if(dst == NULL)
  316. return -1;
  317. pipi_free(src);
  318. ctx->images[ctx->nimages - 1] = dst;
  319. }
  320. else if(!strcmp(cmd, "scale"))
  321. {
  322. pipi_image_t *src, *dst;
  323. char const *arg;
  324. va_list ap;
  325. double scale;
  326. int w, h;
  327. if(ctx->nimages < 1)
  328. return -1;
  329. src = ctx->images[ctx->nimages - 1];
  330. va_start(ap, cmd);
  331. arg = va_arg(ap, char const *);
  332. va_end(ap);
  333. scale = atof(arg);
  334. w = (int)(scale * src->w + 0.5);
  335. h = (int)(scale * src->h + 0.5);
  336. if(w <= 0 || h <= 0)
  337. return -1;
  338. dst = pipi_resize(src, w, h);
  339. if(dst == NULL)
  340. return -1;
  341. pipi_free(src);
  342. ctx->images[ctx->nimages - 1] = dst;
  343. }
  344. else if(!strcmp(cmd, "crop"))
  345. {
  346. pipi_image_t *tmp;
  347. char const *arg;
  348. va_list ap;
  349. int w, h, x = 0, y = 0;
  350. int ret;
  351. if(ctx->nimages < 1)
  352. return -1;
  353. va_start(ap, cmd);
  354. arg = va_arg(ap, char const *);
  355. va_end(ap);
  356. ret = sscanf(arg, "%dx%d+%d+%d", &w, &h, &x, &y);
  357. if(ret < 2)
  358. return -1;
  359. tmp = ctx->images[ctx->nimages - 1];
  360. ctx->images[ctx->nimages - 1] = pipi_crop(tmp, w, h, x, y);
  361. pipi_free(tmp);
  362. }
  363. else if(!strcmp(cmd, "brightness"))
  364. {
  365. pipi_image_t *src, *dst;
  366. char const *arg;
  367. va_list ap;
  368. double val;
  369. if(ctx->nimages < 1)
  370. return -1;
  371. va_start(ap, cmd);
  372. arg = va_arg(ap, char const *);
  373. va_end(ap);
  374. val = atof(arg);
  375. src = ctx->images[ctx->nimages - 1];
  376. dst = pipi_brightness(src, val);
  377. if(dst == NULL)
  378. return -1;
  379. pipi_free(src);
  380. ctx->images[ctx->nimages - 1] = dst;
  381. }
  382. else if(!strcmp(cmd, "contrast"))
  383. {
  384. pipi_image_t *src, *dst;
  385. char const *arg;
  386. va_list ap;
  387. double val;
  388. if(ctx->nimages < 1)
  389. return -1;
  390. va_start(ap, cmd);
  391. arg = va_arg(ap, char const *);
  392. va_end(ap);
  393. val = atof(arg);
  394. src = ctx->images[ctx->nimages - 1];
  395. dst = pipi_contrast(src, val);
  396. if(dst == NULL)
  397. return -1;
  398. pipi_free(src);
  399. ctx->images[ctx->nimages - 1] = dst;
  400. }
  401. else if(!strcmp(cmd, "threshold"))
  402. {
  403. pipi_image_t *src, *dst;
  404. char const *arg;
  405. va_list ap;
  406. double val;
  407. if(ctx->nimages < 1)
  408. return -1;
  409. va_start(ap, cmd);
  410. arg = va_arg(ap, char const *);
  411. va_end(ap);
  412. val = atof(arg);
  413. src = ctx->images[ctx->nimages - 1];
  414. dst = pipi_threshold(src, val);
  415. if(dst == NULL)
  416. return -1;
  417. pipi_free(src);
  418. ctx->images[ctx->nimages - 1] = dst;
  419. }
  420. else if(!strcmp(cmd, "hflip"))
  421. {
  422. pipi_image_t *tmp;
  423. if(ctx->nimages < 1)
  424. return -1;
  425. tmp = ctx->images[ctx->nimages - 1];
  426. ctx->images[ctx->nimages - 1] = pipi_hflip(tmp);
  427. pipi_free(tmp);
  428. }
  429. else if(!strcmp(cmd, "vflip"))
  430. {
  431. pipi_image_t *tmp;
  432. if(ctx->nimages < 1)
  433. return -1;
  434. tmp = ctx->images[ctx->nimages - 1];
  435. ctx->images[ctx->nimages - 1] = pipi_vflip(tmp);
  436. pipi_free(tmp);
  437. }
  438. else if(!strcmp(cmd, "rotate90"))
  439. {
  440. pipi_image_t *tmp;
  441. if(ctx->nimages < 1)
  442. return -1;
  443. tmp = ctx->images[ctx->nimages - 1];
  444. ctx->images[ctx->nimages - 1] = pipi_rotate90(tmp);
  445. pipi_free(tmp);
  446. }
  447. else if(!strcmp(cmd, "rotate180"))
  448. {
  449. pipi_image_t *tmp;
  450. if(ctx->nimages < 1)
  451. return -1;
  452. tmp = ctx->images[ctx->nimages - 1];
  453. ctx->images[ctx->nimages - 1] = pipi_rotate180(tmp);
  454. pipi_free(tmp);
  455. }
  456. else if(!strcmp(cmd, "rotate270"))
  457. {
  458. pipi_image_t *tmp;
  459. if(ctx->nimages < 1)
  460. return -1;
  461. tmp = ctx->images[ctx->nimages - 1];
  462. ctx->images[ctx->nimages - 1] = pipi_rotate270(tmp);
  463. pipi_free(tmp);
  464. }
  465. else if(!strcmp(cmd, "order"))
  466. {
  467. pipi_image_t *tmp;
  468. if(ctx->nimages < 1)
  469. return -1;
  470. tmp = ctx->images[ctx->nimages - 1];
  471. ctx->images[ctx->nimages - 1] = pipi_order(tmp);
  472. pipi_free(tmp);
  473. }
  474. else if(!strcmp(cmd, "split"))
  475. {
  476. pipi_image_t *src;
  477. if(ctx->nimages < 1)
  478. return -1;
  479. src = ctx->images[ctx->nimages - 1];
  480. ctx->nimages += 2;
  481. ctx->images[ctx->nimages - 3] = pipi_red(src);
  482. ctx->images[ctx->nimages - 2] = pipi_green(src);
  483. ctx->images[ctx->nimages - 1] = pipi_blue(src);
  484. pipi_free(src);
  485. }
  486. else if(!strcmp(cmd, "combine"))
  487. {
  488. pipi_image_t *dst;
  489. if(ctx->nimages < 3)
  490. return -1;
  491. dst = pipi_rgb(ctx->images[ctx->nimages - 3],
  492. ctx->images[ctx->nimages - 2],
  493. ctx->images[ctx->nimages - 1]);
  494. if(dst == NULL)
  495. return -1;
  496. pipi_free(ctx->images[ctx->nimages - 3]);
  497. pipi_free(ctx->images[ctx->nimages - 2]);
  498. pipi_free(ctx->images[ctx->nimages - 1]);
  499. ctx->images[ctx->nimages - 3] = dst;
  500. ctx->nimages -= 2;
  501. }
  502. else if(!strcmp(cmd, "mean"))
  503. {
  504. pipi_image_t *dst;
  505. if(ctx->nimages < 2)
  506. return -1;
  507. dst = pipi_mean(ctx->images[ctx->nimages - 2],
  508. ctx->images[ctx->nimages - 1]);
  509. if(dst == NULL)
  510. return -1;
  511. pipi_free(ctx->images[ctx->nimages - 2]);
  512. pipi_free(ctx->images[ctx->nimages - 1]);
  513. ctx->images[ctx->nimages - 2] = dst;
  514. ctx->nimages--;
  515. }
  516. else if(!strcmp(cmd, "merge"))
  517. {
  518. pipi_image_t *dst;
  519. char const *arg;
  520. va_list ap;
  521. double val;
  522. if(ctx->nimages < 2)
  523. return -1;
  524. va_start(ap, cmd);
  525. arg = va_arg(ap, char const *);
  526. va_end(ap);
  527. val = atof(arg);
  528. dst = pipi_merge(ctx->images[ctx->nimages - 2],
  529. ctx->images[ctx->nimages - 1], val);
  530. if(dst == NULL)
  531. return -1;
  532. pipi_free(ctx->images[ctx->nimages - 2]);
  533. pipi_free(ctx->images[ctx->nimages - 1]);
  534. ctx->images[ctx->nimages - 2] = dst;
  535. ctx->nimages--;
  536. }
  537. else if(!strcmp(cmd, "min"))
  538. {
  539. pipi_image_t *dst;
  540. if(ctx->nimages < 2)
  541. return -1;
  542. dst = pipi_min(ctx->images[ctx->nimages - 2],
  543. ctx->images[ctx->nimages - 1]);
  544. if(dst == NULL)
  545. return -1;
  546. pipi_free(ctx->images[ctx->nimages - 2]);
  547. pipi_free(ctx->images[ctx->nimages - 1]);
  548. ctx->images[ctx->nimages - 2] = dst;
  549. ctx->nimages--;
  550. }
  551. else if(!strcmp(cmd, "max"))
  552. {
  553. pipi_image_t *dst;
  554. if(ctx->nimages < 2)
  555. return -1;
  556. dst = pipi_max(ctx->images[ctx->nimages - 2],
  557. ctx->images[ctx->nimages - 1]);
  558. if(dst == NULL)
  559. return -1;
  560. pipi_free(ctx->images[ctx->nimages - 2]);
  561. pipi_free(ctx->images[ctx->nimages - 1]);
  562. ctx->images[ctx->nimages - 2] = dst;
  563. ctx->nimages--;
  564. }
  565. else if(!strcmp(cmd, "add"))
  566. {
  567. pipi_image_t *dst;
  568. if(ctx->nimages < 2)
  569. return -1;
  570. dst = pipi_add(ctx->images[ctx->nimages - 2],
  571. ctx->images[ctx->nimages - 1]);
  572. if(dst == NULL)
  573. return -1;
  574. pipi_free(ctx->images[ctx->nimages - 2]);
  575. pipi_free(ctx->images[ctx->nimages - 1]);
  576. ctx->images[ctx->nimages - 2] = dst;
  577. ctx->nimages--;
  578. }
  579. else if(!strcmp(cmd, "sub"))
  580. {
  581. pipi_image_t *dst;
  582. if(ctx->nimages < 2)
  583. return -1;
  584. dst = pipi_sub(ctx->images[ctx->nimages - 2],
  585. ctx->images[ctx->nimages - 1]);
  586. if(dst == NULL)
  587. return -1;
  588. pipi_free(ctx->images[ctx->nimages - 2]);
  589. pipi_free(ctx->images[ctx->nimages - 1]);
  590. ctx->images[ctx->nimages - 2] = dst;
  591. ctx->nimages--;
  592. }
  593. else if(!strcmp(cmd, "difference"))
  594. {
  595. pipi_image_t *dst;
  596. if(ctx->nimages < 2)
  597. return -1;
  598. dst = pipi_difference(ctx->images[ctx->nimages - 2],
  599. ctx->images[ctx->nimages - 1]);
  600. if(dst == NULL)
  601. return -1;
  602. pipi_free(ctx->images[ctx->nimages - 2]);
  603. pipi_free(ctx->images[ctx->nimages - 1]);
  604. ctx->images[ctx->nimages - 2] = dst;
  605. ctx->nimages--;
  606. }
  607. else if(!strcmp(cmd, "multiply"))
  608. {
  609. pipi_image_t *dst;
  610. if(ctx->nimages < 2)
  611. return -1;
  612. dst = pipi_multiply(ctx->images[ctx->nimages - 2],
  613. ctx->images[ctx->nimages - 1]);
  614. if(dst == NULL)
  615. return -1;
  616. pipi_free(ctx->images[ctx->nimages - 2]);
  617. pipi_free(ctx->images[ctx->nimages - 1]);
  618. ctx->images[ctx->nimages - 2] = dst;
  619. ctx->nimages--;
  620. }
  621. else if(!strcmp(cmd, "divide"))
  622. {
  623. pipi_image_t *dst;
  624. if(ctx->nimages < 2)
  625. return -1;
  626. dst = pipi_divide(ctx->images[ctx->nimages - 2],
  627. ctx->images[ctx->nimages - 1]);
  628. if(dst == NULL)
  629. return -1;
  630. pipi_free(ctx->images[ctx->nimages - 2]);
  631. pipi_free(ctx->images[ctx->nimages - 1]);
  632. ctx->images[ctx->nimages - 2] = dst;
  633. ctx->nimages--;
  634. }
  635. else if(!strcmp(cmd, "screen"))
  636. {
  637. pipi_image_t *dst;
  638. if(ctx->nimages < 2)
  639. return -1;
  640. dst = pipi_screen(ctx->images[ctx->nimages - 2],
  641. ctx->images[ctx->nimages - 1]);
  642. if(dst == NULL)
  643. return -1;
  644. pipi_free(ctx->images[ctx->nimages - 2]);
  645. pipi_free(ctx->images[ctx->nimages - 1]);
  646. ctx->images[ctx->nimages - 2] = dst;
  647. ctx->nimages--;
  648. }
  649. else if(!strcmp(cmd, "overlay"))
  650. {
  651. pipi_image_t *dst;
  652. if(ctx->nimages < 2)
  653. return -1;
  654. dst = pipi_overlay(ctx->images[ctx->nimages - 2],
  655. ctx->images[ctx->nimages - 1]);
  656. if(dst == NULL)
  657. return -1;
  658. pipi_free(ctx->images[ctx->nimages - 2]);
  659. pipi_free(ctx->images[ctx->nimages - 1]);
  660. ctx->images[ctx->nimages - 2] = dst;
  661. ctx->nimages--;
  662. }
  663. else if(!strcmp(cmd, "wrap"))
  664. {
  665. if(ctx->nimages < 1)
  666. return -1;
  667. ctx->images[ctx->nimages - 1]->wrap = 1;
  668. }
  669. else if(!strcmp(cmd, "autocontrast"))
  670. {
  671. pipi_image_t *tmp;
  672. if(ctx->nimages < 1)
  673. return -1;
  674. tmp = ctx->images[ctx->nimages - 1];
  675. ctx->images[ctx->nimages - 1] = pipi_autocontrast(tmp);
  676. pipi_free(tmp);
  677. }
  678. else if(!strcmp(cmd, "invert"))
  679. {
  680. pipi_image_t *tmp;
  681. if(ctx->nimages < 1)
  682. return -1;
  683. tmp = ctx->images[ctx->nimages - 1];
  684. ctx->images[ctx->nimages - 1] = pipi_invert(tmp);
  685. pipi_free(tmp);
  686. }
  687. else if(!strcmp(cmd, "dilate"))
  688. {
  689. pipi_image_t *tmp;
  690. if(ctx->nimages < 1)
  691. return -1;
  692. tmp = ctx->images[ctx->nimages - 1];
  693. ctx->images[ctx->nimages - 1] = pipi_dilate(tmp);
  694. pipi_free(tmp);
  695. }
  696. else if(!strcmp(cmd, "erode"))
  697. {
  698. pipi_image_t *tmp;
  699. if(ctx->nimages < 1)
  700. return -1;
  701. tmp = ctx->images[ctx->nimages - 1];
  702. ctx->images[ctx->nimages - 1] = pipi_erode(tmp);
  703. pipi_free(tmp);
  704. }
  705. else if(!strcmp(cmd, "gray"))
  706. {
  707. if(ctx->nimages < 1)
  708. return -1;
  709. pipi_get_pixels(ctx->images[ctx->nimages - 1], PIPI_PIXELS_Y_F32);
  710. }
  711. else if(!strcmp(cmd, "free"))
  712. {
  713. if(ctx->nimages < 1)
  714. return -1;
  715. ctx->nimages--;
  716. pipi_free(ctx->images[ctx->nimages]);
  717. }
  718. else if(!strcmp(cmd, "dup"))
  719. {
  720. if(ctx->nimages < 1)
  721. return -1;
  722. ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
  723. ctx->nimages++;
  724. }
  725. else if(!strcmp(cmd, "swap"))
  726. {
  727. pipi_image_t *tmp;
  728. if(ctx->nimages < 2)
  729. return -1;
  730. tmp = ctx->images[ctx->nimages - 1];
  731. ctx->images[ctx->nimages - 1] = ctx->images[ctx->nimages - 2];
  732. ctx->images[ctx->nimages - 2] = tmp;
  733. }
  734. else if(!strcmp(cmd, "roll"))
  735. {
  736. pipi_image_t *tmp;
  737. char const *arg;
  738. va_list ap;
  739. int val;
  740. va_start(ap, cmd);
  741. arg = va_arg(ap, char const *);
  742. va_end(ap);
  743. val = atoi(arg);
  744. if(val <= 0 || ctx->nimages < val)
  745. return -1;
  746. if(val == 1)
  747. return 0;
  748. tmp = ctx->images[ctx->nimages - val];
  749. memmove(ctx->images + ctx->nimages - val,
  750. ctx->images + ctx->nimages - val + 1,
  751. (val - 1) * sizeof(*ctx->images));
  752. ctx->images[ctx->nimages - 1] = tmp;
  753. }
  754. else if(!strcmp(cmd, "line"))
  755. {
  756. char const *arg;
  757. va_list ap;
  758. int x1, y1, x2, y2, aa = 0, ret;
  759. uint32_t color = 0;
  760. if(ctx->nimages < 1)
  761. return -1;
  762. va_start(ap, cmd);
  763. arg = va_arg(ap, char const *);
  764. va_end(ap);
  765. ret = sscanf(arg, "%d,%d,%d,%d,%08x,%d",
  766. &x1, &y1, &x2, &y2, &color, &aa);
  767. if(ret < 5) return -1;
  768. ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
  769. pipi_draw_line(ctx->images[ctx->nimages],
  770. x1, y1, x2, y2, color, aa);
  771. ctx->nimages++;
  772. }
  773. else if(!strcmp(cmd, "sine"))
  774. {
  775. pipi_image_t *tmp;
  776. char const *arg;
  777. va_list ap;
  778. float dw, dh, d = 0.0, a = 0.0;
  779. int ret;
  780. if(ctx->nimages < 1)
  781. return -1;
  782. va_start(ap, cmd);
  783. arg = va_arg(ap, char const *);
  784. va_end(ap);
  785. ret = sscanf(arg, "%gx%g+%gr%g", &dw, &dh, &d, &a);
  786. if(ret < 2)
  787. return -1;
  788. tmp = ctx->images[ctx->nimages - 1];
  789. ctx->images[ctx->nimages - 1] = pipi_sine(tmp, dw, dh, d, a);
  790. pipi_free(tmp);
  791. }
  792. else
  793. {
  794. return -1;
  795. }
  796. return 0;
  797. }