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.
 
 
 
 
 
 

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