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

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