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

Last change on this file since 2781 was 2781, checked in by Jean-Yves Lamoureux, 14 years ago
  • Added line to pipi tool (format x1,y1,x2,y2,color,aa, width coordinates as ints, color as hex quadret, aa as an optionnal bit which controls

antialiasing (default: aliased (bracket)))

File size: 18.9 KB
Line 
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/*
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
45int pipi_command(pipi_context_t *ctx, char const *cmd, ...)
46{
47    if(!strcmp(cmd, "load"))
48    {
49        char const *file;
50        va_list ap;
51
52        va_start(ap, cmd);
53        file = va_arg(ap, char const *);
54        va_end(ap);
55        ctx->images[ctx->nimages] = pipi_load(file);
56        if(ctx->images[ctx->nimages] == NULL)
57            return -1;
58        ctx->nimages++;
59    }
60    else if(!strcmp(cmd, "save"))
61    {
62        char const *file;
63        va_list ap;
64
65        if(ctx->nimages < 1)
66            return -1;
67        ctx->nimages--;
68        va_start(ap, cmd);
69        file = va_arg(ap, char const *);
70        va_end(ap);
71        pipi_save(ctx->images[ctx->nimages], file);
72        pipi_free(ctx->images[ctx->nimages]);
73    }
74    else if(!strcmp(cmd, "dither"))
75    {
76        pipi_image_t *src, *dst;
77        char const *method;
78        va_list ap;
79
80        if(ctx->nimages < 1)
81            return -1;
82        va_start(ap, cmd);
83        method = va_arg(ap, char const *);
84        va_end(ap);
85        src = ctx->images[ctx->nimages - 1];
86        dst = NULL;
87        if(!strcmp(method, "ost"))
88            dst = pipi_dither_ostromoukhov(src, 0);
89        else if(!strcmp(method, "sost"))
90            dst = pipi_dither_ostromoukhov(src, 1);
91        else if(!strcmp(method, "ediff"))
92        {
93            if(ctx->nimages < 2)
94                return -1;
95            dst = pipi_dither_ediff(ctx->images[ctx->nimages - 2], src, 0);
96            pipi_free(ctx->images[ctx->nimages - 2]);
97            ctx->nimages--;
98        }
99        else if(!strcmp(method, "sediff"))
100        {
101            if(ctx->nimages < 2)
102                return -1;
103            dst = pipi_dither_ediff(ctx->images[ctx->nimages - 2], src, 1);
104            pipi_free(ctx->images[ctx->nimages - 2]);
105            ctx->nimages--;
106        }
107        else if(!strcmp(method, "ordered"))
108        {
109            if(ctx->nimages < 2)
110                return -1;
111            dst = pipi_dither_ordered(ctx->images[ctx->nimages - 2], src);
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
145        if(ctx->nimages < 1)
146            return -1;
147        va_start(ap, cmd);
148        arg = va_arg(ap, char const *);
149        va_end(ap);
150        w = h = atof(arg);
151        arg = strchr(arg, 'x');
152        if(arg)
153        {
154            h = atof(arg + 1);
155            arg = strchr(arg, 'r');
156            if(arg)
157                a = atof(arg + 1);
158        }
159        src = ctx->images[ctx->nimages - 1];
160        dst = pipi_gaussian_blur_ext(src, w, h, a, 0.0, 0.0);
161        if(dst == NULL)
162            return -1;
163        pipi_free(src);
164        ctx->images[ctx->nimages - 1] = dst;
165    }
166    else if(!strcmp(cmd, "boxblur"))
167    {
168        pipi_image_t *src, *dst;
169        char const *arg;
170        va_list ap;
171        double w, h;
172
173        if(ctx->nimages < 1)
174            return -1;
175        va_start(ap, cmd);
176        arg = va_arg(ap, char const *);
177        va_end(ap);
178        w = h = atof(arg);
179        arg = strchr(arg, 'x');
180        if(arg)
181            h = atof(arg + 1);
182        src = ctx->images[ctx->nimages - 1];
183        dst = pipi_box_blur_ext(src, w, h);
184        if(dst == NULL)
185            return -1;
186        pipi_free(src);
187        ctx->images[ctx->nimages - 1] = dst;
188    }
189    else if(!strcmp(cmd, "median"))
190    {
191        pipi_image_t *src, *dst;
192        char const *arg;
193        va_list ap;
194        double w, h;
195
196        if(ctx->nimages < 1)
197            return -1;
198        va_start(ap, cmd);
199        arg = va_arg(ap, char const *);
200        va_end(ap);
201        w = h = atof(arg);
202        arg = strchr(arg, 'x');
203        if(arg)
204            h = atof(arg + 1);
205        src = ctx->images[ctx->nimages - 1];
206        dst = pipi_median_ext(src, w, h);
207        if(dst == NULL)
208            return -1;
209        pipi_free(src);
210        ctx->images[ctx->nimages - 1] = dst;
211    }
212    else if(!strcmp(cmd, "geometry"))
213    {
214        pipi_image_t *src, *dst;
215        char const *arg;
216        va_list ap;
217        int w, h;
218
219        if(ctx->nimages < 1)
220            return -1;
221        va_start(ap, cmd);
222        arg = va_arg(ap, char const *);
223        va_end(ap);
224        w = atoi(arg);
225        arg = strchr(arg, 'x');
226        if(!arg)
227            return -1;
228        h = atoi(arg + 1);
229        if(w <= 0 || h <= 0)
230            return -1;
231        src = ctx->images[ctx->nimages - 1];
232        dst = pipi_resize(src, w, h);
233        if(dst == NULL)
234            return -1;
235        pipi_free(src);
236        ctx->images[ctx->nimages - 1] = dst;
237    }
238    else if(!strcmp(cmd, "tile"))
239    {
240        pipi_image_t *src, *dst;
241        char const *arg;
242        va_list ap;
243        int w, h;
244
245        if(ctx->nimages < 1)
246            return -1;
247        va_start(ap, cmd);
248        arg = va_arg(ap, char const *);
249        va_end(ap);
250        w = atoi(arg);
251        arg = strchr(arg, 'x');
252        if(!arg)
253            return -1;
254        h = atoi(arg + 1);
255        if(w <= 0 || h <= 0)
256            return -1;
257        src = ctx->images[ctx->nimages - 1];
258        dst = pipi_tile(src, w, h);
259        if(dst == NULL)
260            return -1;
261        pipi_free(src);
262        ctx->images[ctx->nimages - 1] = dst;
263    }
264    else if(!strcmp(cmd, "scale"))
265    {
266        pipi_image_t *src, *dst;
267        char const *arg;
268        va_list ap;
269        double scale;
270        int w, h;
271
272        if(ctx->nimages < 1)
273            return -1;
274        src = ctx->images[ctx->nimages - 1];
275        va_start(ap, cmd);
276        arg = va_arg(ap, char const *);
277        va_end(ap);
278        scale = atof(arg);
279        w = (int)(scale * src->w + 0.5);
280        h = (int)(scale * src->h + 0.5);
281        if(w <= 0 || h <= 0)
282            return -1;
283        dst = pipi_resize(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, "brightness"))
290    {
291        pipi_image_t *src, *dst;
292        char const *arg;
293        va_list ap;
294        double val;
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        val = atof(arg);
302        src = ctx->images[ctx->nimages - 1];
303        dst = pipi_brightness(src, val);
304        if(dst == NULL)
305            return -1;
306        pipi_free(src);
307        ctx->images[ctx->nimages - 1] = dst;
308    }
309    else if(!strcmp(cmd, "contrast"))
310    {
311        pipi_image_t *src, *dst;
312        char const *arg;
313        va_list ap;
314        double val;
315
316        if(ctx->nimages < 1)
317            return -1;
318        va_start(ap, cmd);
319        arg = va_arg(ap, char const *);
320        va_end(ap);
321        val = atof(arg);
322        src = ctx->images[ctx->nimages - 1];
323        dst = pipi_contrast(src, val);
324        if(dst == NULL)
325            return -1;
326        pipi_free(src);
327        ctx->images[ctx->nimages - 1] = dst;
328    }
329    else if(!strcmp(cmd, "threshold"))
330    {
331        pipi_image_t *src, *dst;
332        char const *arg;
333        va_list ap;
334        double val;
335
336        if(ctx->nimages < 1)
337            return -1;
338        va_start(ap, cmd);
339        arg = va_arg(ap, char const *);
340        va_end(ap);
341        val = atof(arg);
342        src = ctx->images[ctx->nimages - 1];
343        dst = pipi_threshold(src, val);
344        if(dst == NULL)
345            return -1;
346        pipi_free(src);
347        ctx->images[ctx->nimages - 1] = dst;
348    }
349    else if(!strcmp(cmd, "hflip"))
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_hflip(tmp);
356        pipi_free(tmp);
357    }
358    else if(!strcmp(cmd, "vflip"))
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_vflip(tmp);
365        pipi_free(tmp);
366    }
367    else if(!strcmp(cmd, "rotate90"))
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_rotate90(tmp);
374        pipi_free(tmp);
375    }
376    else if(!strcmp(cmd, "rotate180"))
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_rotate180(tmp);
383        pipi_free(tmp);
384    }
385    else if(!strcmp(cmd, "rotate270"))
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_rotate270(tmp);
392        pipi_free(tmp);
393    }
394    else if(!strcmp(cmd, "split"))
395    {
396        pipi_image_t *src;
397
398        if(ctx->nimages < 1)
399            return -1;
400        src = ctx->images[ctx->nimages - 1];
401        ctx->nimages += 2;
402        ctx->images[ctx->nimages - 3] = pipi_red(src);
403        ctx->images[ctx->nimages - 2] = pipi_green(src);
404        ctx->images[ctx->nimages - 1] = pipi_blue(src);
405        pipi_free(src);
406    }
407    else if(!strcmp(cmd, "combine"))
408    {
409        pipi_image_t *dst;
410
411        if(ctx->nimages < 3)
412            return -1;
413        dst = pipi_rgb(ctx->images[ctx->nimages - 3],
414                       ctx->images[ctx->nimages - 2],
415                       ctx->images[ctx->nimages - 1]);
416        if(dst == NULL)
417            return -1;
418        pipi_free(ctx->images[ctx->nimages - 3]);
419        pipi_free(ctx->images[ctx->nimages - 2]);
420        pipi_free(ctx->images[ctx->nimages - 1]);
421        ctx->images[ctx->nimages - 3] = dst;
422        ctx->nimages -= 2;
423    }
424    else if(!strcmp(cmd, "mean"))
425    {
426        pipi_image_t *dst;
427
428        if(ctx->nimages < 2)
429            return -1;
430        dst = pipi_mean(ctx->images[ctx->nimages - 2],
431                        ctx->images[ctx->nimages - 1]);
432        if(dst == NULL)
433            return -1;
434        pipi_free(ctx->images[ctx->nimages - 2]);
435        pipi_free(ctx->images[ctx->nimages - 1]);
436        ctx->images[ctx->nimages - 2] = dst;
437        ctx->nimages--;
438    }
439    else if(!strcmp(cmd, "min"))
440    {
441        pipi_image_t *dst;
442
443        if(ctx->nimages < 2)
444            return -1;
445        dst = pipi_min(ctx->images[ctx->nimages - 2],
446                       ctx->images[ctx->nimages - 1]);
447        if(dst == NULL)
448            return -1;
449        pipi_free(ctx->images[ctx->nimages - 2]);
450        pipi_free(ctx->images[ctx->nimages - 1]);
451        ctx->images[ctx->nimages - 2] = dst;
452        ctx->nimages--;
453    }
454    else if(!strcmp(cmd, "max"))
455    {
456        pipi_image_t *dst;
457
458        if(ctx->nimages < 2)
459            return -1;
460        dst = pipi_max(ctx->images[ctx->nimages - 2],
461                       ctx->images[ctx->nimages - 1]);
462        if(dst == NULL)
463            return -1;
464        pipi_free(ctx->images[ctx->nimages - 2]);
465        pipi_free(ctx->images[ctx->nimages - 1]);
466        ctx->images[ctx->nimages - 2] = dst;
467        ctx->nimages--;
468    }
469    else if(!strcmp(cmd, "add"))
470    {
471        pipi_image_t *dst;
472
473        if(ctx->nimages < 2)
474            return -1;
475        dst = pipi_add(ctx->images[ctx->nimages - 2],
476                       ctx->images[ctx->nimages - 1]);
477        if(dst == NULL)
478            return -1;
479        pipi_free(ctx->images[ctx->nimages - 2]);
480        pipi_free(ctx->images[ctx->nimages - 1]);
481        ctx->images[ctx->nimages - 2] = dst;
482        ctx->nimages--;
483    }
484    else if(!strcmp(cmd, "sub"))
485    {
486        pipi_image_t *dst;
487
488        if(ctx->nimages < 2)
489            return -1;
490        dst = pipi_sub(ctx->images[ctx->nimages - 2],
491                       ctx->images[ctx->nimages - 1]);
492        if(dst == NULL)
493            return -1;
494        pipi_free(ctx->images[ctx->nimages - 2]);
495        pipi_free(ctx->images[ctx->nimages - 1]);
496        ctx->images[ctx->nimages - 2] = dst;
497        ctx->nimages--;
498    }
499    else if(!strcmp(cmd, "difference"))
500    {
501        pipi_image_t *dst;
502
503        if(ctx->nimages < 2)
504            return -1;
505        dst = pipi_difference(ctx->images[ctx->nimages - 2],
506                              ctx->images[ctx->nimages - 1]);
507        if(dst == NULL)
508            return -1;
509        pipi_free(ctx->images[ctx->nimages - 2]);
510        pipi_free(ctx->images[ctx->nimages - 1]);
511        ctx->images[ctx->nimages - 2] = dst;
512        ctx->nimages--;
513    }
514    else if(!strcmp(cmd, "multiply"))
515    {
516        pipi_image_t *dst;
517
518        if(ctx->nimages < 2)
519            return -1;
520        dst = pipi_multiply(ctx->images[ctx->nimages - 2],
521                            ctx->images[ctx->nimages - 1]);
522        if(dst == NULL)
523            return -1;
524        pipi_free(ctx->images[ctx->nimages - 2]);
525        pipi_free(ctx->images[ctx->nimages - 1]);
526        ctx->images[ctx->nimages - 2] = dst;
527        ctx->nimages--;
528    }
529    else if(!strcmp(cmd, "divide"))
530    {
531        pipi_image_t *dst;
532
533        if(ctx->nimages < 2)
534            return -1;
535        dst = pipi_divide(ctx->images[ctx->nimages - 2],
536                          ctx->images[ctx->nimages - 1]);
537        if(dst == NULL)
538            return -1;
539        pipi_free(ctx->images[ctx->nimages - 2]);
540        pipi_free(ctx->images[ctx->nimages - 1]);
541        ctx->images[ctx->nimages - 2] = dst;
542        ctx->nimages--;
543    }
544    else if(!strcmp(cmd, "screen"))
545    {
546        pipi_image_t *dst;
547
548        if(ctx->nimages < 2)
549            return -1;
550        dst = pipi_screen(ctx->images[ctx->nimages - 2],
551                          ctx->images[ctx->nimages - 1]);
552        if(dst == NULL)
553            return -1;
554        pipi_free(ctx->images[ctx->nimages - 2]);
555        pipi_free(ctx->images[ctx->nimages - 1]);
556        ctx->images[ctx->nimages - 2] = dst;
557        ctx->nimages--;
558    }
559    else if(!strcmp(cmd, "overlay"))
560    {
561        pipi_image_t *dst;
562
563        if(ctx->nimages < 2)
564            return -1;
565        dst = pipi_overlay(ctx->images[ctx->nimages - 2],
566                           ctx->images[ctx->nimages - 1]);
567        if(dst == NULL)
568            return -1;
569        pipi_free(ctx->images[ctx->nimages - 2]);
570        pipi_free(ctx->images[ctx->nimages - 1]);
571        ctx->images[ctx->nimages - 2] = dst;
572        ctx->nimages--;
573    }
574    else if(!strcmp(cmd, "wrap"))
575    {
576        if(ctx->nimages < 1)
577            return -1;
578        ctx->images[ctx->nimages - 1]->wrap = 1;
579    }
580    else if(!strcmp(cmd, "autocontrast"))
581    {
582        pipi_image_t *tmp;
583        if(ctx->nimages < 1)
584            return -1;
585        tmp = ctx->images[ctx->nimages - 1];
586        ctx->images[ctx->nimages - 1] = pipi_autocontrast(tmp);
587        pipi_free(tmp);
588    }
589    else if(!strcmp(cmd, "invert"))
590    {
591        pipi_image_t *tmp;
592        if(ctx->nimages < 1)
593            return -1;
594        tmp = ctx->images[ctx->nimages - 1];
595        ctx->images[ctx->nimages - 1] = pipi_invert(tmp);
596        pipi_free(tmp);
597    }
598    else if(!strcmp(cmd, "dilate"))
599    {
600        pipi_image_t *tmp;
601        if(ctx->nimages < 1)
602            return -1;
603        tmp = ctx->images[ctx->nimages - 1];
604        ctx->images[ctx->nimages - 1] = pipi_dilate(tmp);
605        pipi_free(tmp);
606    }
607    else if(!strcmp(cmd, "erode"))
608    {
609        pipi_image_t *tmp;
610        if(ctx->nimages < 1)
611            return -1;
612        tmp = ctx->images[ctx->nimages - 1];
613        ctx->images[ctx->nimages - 1] = pipi_erode(tmp);
614        pipi_free(tmp);
615    }
616    else if(!strcmp(cmd, "gray"))
617    {
618        if(ctx->nimages < 1)
619            return -1;
620        pipi_getpixels(ctx->images[ctx->nimages - 1], PIPI_PIXELS_Y_F);
621    }
622    else if(!strcmp(cmd, "free"))
623    {
624        if(ctx->nimages < 1)
625            return -1;
626        ctx->nimages--;
627        pipi_free(ctx->images[ctx->nimages]);
628    }
629    else if(!strcmp(cmd, "dup"))
630    {
631        if(ctx->nimages < 1)
632            return -1;
633        ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
634        ctx->nimages++;
635    }
636    else if(!strcmp(cmd, "swap"))
637    {
638        pipi_image_t *tmp;
639        if(ctx->nimages < 2)
640            return -1;
641        tmp = ctx->images[ctx->nimages - 1];
642        ctx->images[ctx->nimages - 1] = ctx->images[ctx->nimages - 2];
643        ctx->images[ctx->nimages - 2] = tmp;
644    }
645    else if(!strcmp(cmd, "roll"))
646    {
647        pipi_image_t *tmp;
648        char const *arg;
649        va_list ap;
650        int val;
651
652        va_start(ap, cmd);
653        arg = va_arg(ap, char const *);
654        va_end(ap);
655        val = atoi(arg);
656        if(val <= 0 || ctx->nimages < val)
657            return -1;
658        if(val == 1)
659            return 0;
660        tmp = ctx->images[ctx->nimages - val];
661        memmove(ctx->images + ctx->nimages - val,
662                ctx->images + ctx->nimages - val + 1,
663                (val - 1) * sizeof(*ctx->images));
664        ctx->images[ctx->nimages - 1] = tmp;
665    }
666    else if(!strcmp(cmd, "line"))
667    {
668        char const *arg;
669        va_list ap;
670        int x1, y1, x2, y2, aa = 0, ret;
671        uint32_t color = 0;
672
673        if(ctx->nimages < 1)
674            return -1;
675
676        va_start(ap, cmd);
677        arg = va_arg(ap, char const *);
678        va_end(ap);
679
680        ret = sscanf(arg, "%d,%d,%d,%d,%08x,%d",
681               &x1, &y1, &x2, &y2, &color, &aa);
682        if(ret < 5) return -1;
683
684        ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
685        pipi_draw_line(ctx->images[ctx->nimages],
686                       x1,  y1,  x2,  y2, color, aa);
687        ctx->nimages++;
688    }
689    else
690    {
691        return -1;
692    }
693
694    return 0;
695}
696
Note: See TracBrowser for help on using the repository browser.