You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

711 lines
19 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(!strncmp(method, "ordered", 7))
  96. {
  97. double angle = .0;
  98. method = strchr(method, ':');
  99. if(method)
  100. angle = atof(method + 1);
  101. if(ctx->nimages < 2)
  102. return -1;
  103. dst = pipi_dither_ordered_ext(ctx->images[ctx->nimages - 2], src,
  104. angle);
  105. pipi_free(ctx->images[ctx->nimages - 2]);
  106. ctx->nimages--;
  107. }
  108. else if(!strncmp(method, "halftone", 8))
  109. {
  110. double r, angle = .0;
  111. method = strchr(method, ':');
  112. if(!method)
  113. return -1;
  114. r = atof(method + 1);
  115. method = strchr(method + 1, ':');
  116. if(method)
  117. angle = atof(method + 1);
  118. if(r < 1.)
  119. r = 1.;
  120. dst = pipi_dither_halftone(src, r, angle);
  121. }
  122. else if(!strcmp(method, "random"))
  123. dst = pipi_dither_random(src);
  124. else if(!strcmp(method, "dbs"))
  125. dst = pipi_dither_dbs(src);
  126. if(dst == NULL)
  127. return -1;
  128. pipi_free(src);
  129. ctx->images[ctx->nimages - 1] = dst;
  130. }
  131. else if(!strcmp(cmd, "blur"))
  132. {
  133. pipi_image_t *src, *dst;
  134. char const *arg;
  135. va_list ap;
  136. double w, h, a = 0.0;
  137. if(ctx->nimages < 1)
  138. return -1;
  139. va_start(ap, cmd);
  140. arg = va_arg(ap, char const *);
  141. va_end(ap);
  142. w = h = atof(arg);
  143. arg = strchr(arg, 'x');
  144. if(arg)
  145. {
  146. h = atof(arg + 1);
  147. arg = strchr(arg, 'r');
  148. if(arg)
  149. a = atof(arg + 1);
  150. }
  151. src = ctx->images[ctx->nimages - 1];
  152. dst = pipi_gaussian_blur_ext(src, w, h, a, 0.0, 0.0);
  153. if(dst == NULL)
  154. return -1;
  155. pipi_free(src);
  156. ctx->images[ctx->nimages - 1] = dst;
  157. }
  158. else if(!strcmp(cmd, "boxblur"))
  159. {
  160. pipi_image_t *src, *dst;
  161. char const *arg;
  162. va_list ap;
  163. double w, h;
  164. if(ctx->nimages < 1)
  165. return -1;
  166. va_start(ap, cmd);
  167. arg = va_arg(ap, char const *);
  168. va_end(ap);
  169. w = h = atof(arg);
  170. arg = strchr(arg, 'x');
  171. if(arg)
  172. h = atof(arg + 1);
  173. src = ctx->images[ctx->nimages - 1];
  174. dst = pipi_box_blur_ext(src, w, h);
  175. if(dst == NULL)
  176. return -1;
  177. pipi_free(src);
  178. ctx->images[ctx->nimages - 1] = dst;
  179. }
  180. else if(!strcmp(cmd, "median"))
  181. {
  182. pipi_image_t *src, *dst;
  183. char const *arg;
  184. va_list ap;
  185. double w, h;
  186. if(ctx->nimages < 1)
  187. return -1;
  188. va_start(ap, cmd);
  189. arg = va_arg(ap, char const *);
  190. va_end(ap);
  191. w = h = atof(arg);
  192. arg = strchr(arg, 'x');
  193. if(arg)
  194. h = atof(arg + 1);
  195. src = ctx->images[ctx->nimages - 1];
  196. dst = pipi_median_ext(src, w, h);
  197. if(dst == NULL)
  198. return -1;
  199. pipi_free(src);
  200. ctx->images[ctx->nimages - 1] = dst;
  201. }
  202. else if(!strcmp(cmd, "geometry"))
  203. {
  204. pipi_image_t *src, *dst;
  205. char const *arg;
  206. va_list ap;
  207. int w, h;
  208. if(ctx->nimages < 1)
  209. return -1;
  210. va_start(ap, cmd);
  211. arg = va_arg(ap, char const *);
  212. va_end(ap);
  213. w = atoi(arg);
  214. arg = strchr(arg, 'x');
  215. if(!arg)
  216. return -1;
  217. h = atoi(arg + 1);
  218. if(w <= 0 || h <= 0)
  219. return -1;
  220. src = ctx->images[ctx->nimages - 1];
  221. dst = pipi_resize(src, w, h);
  222. if(dst == NULL)
  223. return -1;
  224. pipi_free(src);
  225. ctx->images[ctx->nimages - 1] = dst;
  226. }
  227. else if(!strcmp(cmd, "tile"))
  228. {
  229. pipi_image_t *src, *dst;
  230. char const *arg;
  231. va_list ap;
  232. int w, h;
  233. if(ctx->nimages < 1)
  234. return -1;
  235. va_start(ap, cmd);
  236. arg = va_arg(ap, char const *);
  237. va_end(ap);
  238. w = atoi(arg);
  239. arg = strchr(arg, 'x');
  240. if(!arg)
  241. return -1;
  242. h = atoi(arg + 1);
  243. if(w <= 0 || h <= 0)
  244. return -1;
  245. src = ctx->images[ctx->nimages - 1];
  246. dst = pipi_tile(src, w, h);
  247. if(dst == NULL)
  248. return -1;
  249. pipi_free(src);
  250. ctx->images[ctx->nimages - 1] = dst;
  251. }
  252. else if(!strcmp(cmd, "scale"))
  253. {
  254. pipi_image_t *src, *dst;
  255. char const *arg;
  256. va_list ap;
  257. double scale;
  258. int w, h;
  259. if(ctx->nimages < 1)
  260. return -1;
  261. src = ctx->images[ctx->nimages - 1];
  262. va_start(ap, cmd);
  263. arg = va_arg(ap, char const *);
  264. va_end(ap);
  265. scale = atof(arg);
  266. w = (int)(scale * src->w + 0.5);
  267. h = (int)(scale * src->h + 0.5);
  268. if(w <= 0 || h <= 0)
  269. return -1;
  270. dst = pipi_resize(src, w, h);
  271. if(dst == NULL)
  272. return -1;
  273. pipi_free(src);
  274. ctx->images[ctx->nimages - 1] = dst;
  275. }
  276. else if(!strcmp(cmd, "brightness"))
  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_brightness(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, "contrast"))
  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_contrast(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, "threshold"))
  315. {
  316. pipi_image_t *src, *dst;
  317. char const *arg;
  318. va_list ap;
  319. double val;
  320. if(ctx->nimages < 1)
  321. return -1;
  322. va_start(ap, cmd);
  323. arg = va_arg(ap, char const *);
  324. va_end(ap);
  325. val = atof(arg);
  326. src = ctx->images[ctx->nimages - 1];
  327. dst = pipi_threshold(src, val);
  328. if(dst == NULL)
  329. return -1;
  330. pipi_free(src);
  331. ctx->images[ctx->nimages - 1] = dst;
  332. }
  333. else if(!strcmp(cmd, "hflip"))
  334. {
  335. pipi_image_t *tmp;
  336. if(ctx->nimages < 1)
  337. return -1;
  338. tmp = ctx->images[ctx->nimages - 1];
  339. ctx->images[ctx->nimages - 1] = pipi_hflip(tmp);
  340. pipi_free(tmp);
  341. }
  342. else if(!strcmp(cmd, "vflip"))
  343. {
  344. pipi_image_t *tmp;
  345. if(ctx->nimages < 1)
  346. return -1;
  347. tmp = ctx->images[ctx->nimages - 1];
  348. ctx->images[ctx->nimages - 1] = pipi_vflip(tmp);
  349. pipi_free(tmp);
  350. }
  351. else if(!strcmp(cmd, "rotate90"))
  352. {
  353. pipi_image_t *tmp;
  354. if(ctx->nimages < 1)
  355. return -1;
  356. tmp = ctx->images[ctx->nimages - 1];
  357. ctx->images[ctx->nimages - 1] = pipi_rotate90(tmp);
  358. pipi_free(tmp);
  359. }
  360. else if(!strcmp(cmd, "rotate180"))
  361. {
  362. pipi_image_t *tmp;
  363. if(ctx->nimages < 1)
  364. return -1;
  365. tmp = ctx->images[ctx->nimages - 1];
  366. ctx->images[ctx->nimages - 1] = pipi_rotate180(tmp);
  367. pipi_free(tmp);
  368. }
  369. else if(!strcmp(cmd, "rotate270"))
  370. {
  371. pipi_image_t *tmp;
  372. if(ctx->nimages < 1)
  373. return -1;
  374. tmp = ctx->images[ctx->nimages - 1];
  375. ctx->images[ctx->nimages - 1] = pipi_rotate270(tmp);
  376. pipi_free(tmp);
  377. }
  378. else if(!strcmp(cmd, "order"))
  379. {
  380. pipi_image_t *tmp;
  381. if(ctx->nimages < 1)
  382. return -1;
  383. tmp = ctx->images[ctx->nimages - 1];
  384. ctx->images[ctx->nimages - 1] = pipi_order(tmp);
  385. pipi_free(tmp);
  386. }
  387. else if(!strcmp(cmd, "split"))
  388. {
  389. pipi_image_t *src;
  390. if(ctx->nimages < 1)
  391. return -1;
  392. src = ctx->images[ctx->nimages - 1];
  393. ctx->nimages += 2;
  394. ctx->images[ctx->nimages - 3] = pipi_red(src);
  395. ctx->images[ctx->nimages - 2] = pipi_green(src);
  396. ctx->images[ctx->nimages - 1] = pipi_blue(src);
  397. pipi_free(src);
  398. }
  399. else if(!strcmp(cmd, "combine"))
  400. {
  401. pipi_image_t *dst;
  402. if(ctx->nimages < 3)
  403. return -1;
  404. dst = pipi_rgb(ctx->images[ctx->nimages - 3],
  405. ctx->images[ctx->nimages - 2],
  406. ctx->images[ctx->nimages - 1]);
  407. if(dst == NULL)
  408. return -1;
  409. pipi_free(ctx->images[ctx->nimages - 3]);
  410. pipi_free(ctx->images[ctx->nimages - 2]);
  411. pipi_free(ctx->images[ctx->nimages - 1]);
  412. ctx->images[ctx->nimages - 3] = dst;
  413. ctx->nimages -= 2;
  414. }
  415. else if(!strcmp(cmd, "mean"))
  416. {
  417. pipi_image_t *dst;
  418. if(ctx->nimages < 2)
  419. return -1;
  420. dst = pipi_mean(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, "min"))
  430. {
  431. pipi_image_t *dst;
  432. if(ctx->nimages < 2)
  433. return -1;
  434. dst = pipi_min(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, "max"))
  444. {
  445. pipi_image_t *dst;
  446. if(ctx->nimages < 2)
  447. return -1;
  448. dst = pipi_max(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, "add"))
  458. {
  459. pipi_image_t *dst;
  460. if(ctx->nimages < 2)
  461. return -1;
  462. dst = pipi_add(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, "sub"))
  472. {
  473. pipi_image_t *dst;
  474. if(ctx->nimages < 2)
  475. return -1;
  476. dst = pipi_sub(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, "difference"))
  486. {
  487. pipi_image_t *dst;
  488. if(ctx->nimages < 2)
  489. return -1;
  490. dst = pipi_difference(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, "multiply"))
  500. {
  501. pipi_image_t *dst;
  502. if(ctx->nimages < 2)
  503. return -1;
  504. dst = pipi_multiply(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, "divide"))
  514. {
  515. pipi_image_t *dst;
  516. if(ctx->nimages < 2)
  517. return -1;
  518. dst = pipi_divide(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, "screen"))
  528. {
  529. pipi_image_t *dst;
  530. if(ctx->nimages < 2)
  531. return -1;
  532. dst = pipi_screen(ctx->images[ctx->nimages - 2],
  533. ctx->images[ctx->nimages - 1]);
  534. if(dst == NULL)
  535. return -1;
  536. pipi_free(ctx->images[ctx->nimages - 2]);
  537. pipi_free(ctx->images[ctx->nimages - 1]);
  538. ctx->images[ctx->nimages - 2] = dst;
  539. ctx->nimages--;
  540. }
  541. else if(!strcmp(cmd, "overlay"))
  542. {
  543. pipi_image_t *dst;
  544. if(ctx->nimages < 2)
  545. return -1;
  546. dst = pipi_overlay(ctx->images[ctx->nimages - 2],
  547. ctx->images[ctx->nimages - 1]);
  548. if(dst == NULL)
  549. return -1;
  550. pipi_free(ctx->images[ctx->nimages - 2]);
  551. pipi_free(ctx->images[ctx->nimages - 1]);
  552. ctx->images[ctx->nimages - 2] = dst;
  553. ctx->nimages--;
  554. }
  555. else if(!strcmp(cmd, "wrap"))
  556. {
  557. if(ctx->nimages < 1)
  558. return -1;
  559. ctx->images[ctx->nimages - 1]->wrap = 1;
  560. }
  561. else if(!strcmp(cmd, "autocontrast"))
  562. {
  563. pipi_image_t *tmp;
  564. if(ctx->nimages < 1)
  565. return -1;
  566. tmp = ctx->images[ctx->nimages - 1];
  567. ctx->images[ctx->nimages - 1] = pipi_autocontrast(tmp);
  568. pipi_free(tmp);
  569. }
  570. else if(!strcmp(cmd, "invert"))
  571. {
  572. pipi_image_t *tmp;
  573. if(ctx->nimages < 1)
  574. return -1;
  575. tmp = ctx->images[ctx->nimages - 1];
  576. ctx->images[ctx->nimages - 1] = pipi_invert(tmp);
  577. pipi_free(tmp);
  578. }
  579. else if(!strcmp(cmd, "dilate"))
  580. {
  581. pipi_image_t *tmp;
  582. if(ctx->nimages < 1)
  583. return -1;
  584. tmp = ctx->images[ctx->nimages - 1];
  585. ctx->images[ctx->nimages - 1] = pipi_dilate(tmp);
  586. pipi_free(tmp);
  587. }
  588. else if(!strcmp(cmd, "erode"))
  589. {
  590. pipi_image_t *tmp;
  591. if(ctx->nimages < 1)
  592. return -1;
  593. tmp = ctx->images[ctx->nimages - 1];
  594. ctx->images[ctx->nimages - 1] = pipi_erode(tmp);
  595. pipi_free(tmp);
  596. }
  597. else if(!strcmp(cmd, "gray"))
  598. {
  599. if(ctx->nimages < 1)
  600. return -1;
  601. pipi_getpixels(ctx->images[ctx->nimages - 1], PIPI_PIXELS_Y_F);
  602. }
  603. else if(!strcmp(cmd, "free"))
  604. {
  605. if(ctx->nimages < 1)
  606. return -1;
  607. ctx->nimages--;
  608. pipi_free(ctx->images[ctx->nimages]);
  609. }
  610. else if(!strcmp(cmd, "dup"))
  611. {
  612. if(ctx->nimages < 1)
  613. return -1;
  614. ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
  615. ctx->nimages++;
  616. }
  617. else if(!strcmp(cmd, "swap"))
  618. {
  619. pipi_image_t *tmp;
  620. if(ctx->nimages < 2)
  621. return -1;
  622. tmp = ctx->images[ctx->nimages - 1];
  623. ctx->images[ctx->nimages - 1] = ctx->images[ctx->nimages - 2];
  624. ctx->images[ctx->nimages - 2] = tmp;
  625. }
  626. else if(!strcmp(cmd, "roll"))
  627. {
  628. pipi_image_t *tmp;
  629. char const *arg;
  630. va_list ap;
  631. int val;
  632. va_start(ap, cmd);
  633. arg = va_arg(ap, char const *);
  634. va_end(ap);
  635. val = atoi(arg);
  636. if(val <= 0 || ctx->nimages < val)
  637. return -1;
  638. if(val == 1)
  639. return 0;
  640. tmp = ctx->images[ctx->nimages - val];
  641. memmove(ctx->images + ctx->nimages - val,
  642. ctx->images + ctx->nimages - val + 1,
  643. (val - 1) * sizeof(*ctx->images));
  644. ctx->images[ctx->nimages - 1] = tmp;
  645. }
  646. else if(!strcmp(cmd, "line"))
  647. {
  648. char const *arg;
  649. va_list ap;
  650. int x1, y1, x2, y2, aa = 0, ret;
  651. uint32_t color = 0;
  652. if(ctx->nimages < 1)
  653. return -1;
  654. va_start(ap, cmd);
  655. arg = va_arg(ap, char const *);
  656. va_end(ap);
  657. ret = sscanf(arg, "%d,%d,%d,%d,%08x,%d",
  658. &x1, &y1, &x2, &y2, &color, &aa);
  659. if(ret < 5) return -1;
  660. ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
  661. pipi_draw_line(ctx->images[ctx->nimages],
  662. x1, y1, x2, y2, color, aa);
  663. ctx->nimages++;
  664. }
  665. else
  666. {
  667. return -1;
  668. }
  669. return 0;
  670. }