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

Last change on this file since 3411 was 3411, checked in by Sam Hocevar, 13 years ago

mean.c: rename this file into merge.c and implement pipi_merge() for trivial
image merging.

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