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

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

Support C99 types on Win32 through the same hacks as in libcaca.

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