source: libpipi/trunk/pipi/context.c @ 2857

Last change on this file since 2857 was 2857, checked in by Sam Hocevar, 11 years ago

Hide the list of available commands in pipi/context.c, so that the
pipi source code doesn't need to know about them.

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