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

Last change on this file since 2744 was 2744, checked in by Sam Hocevar, 12 years ago
  • median.c: add a median filter. Highly unoptimised for now.
File size: 13.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, "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, "ost"))
96            dst = pipi_dither_ostromoukhov(src, 0);
97        else if(!strcmp(method, "sost"))
98            dst = pipi_dither_ostromoukhov(src, 1);
99        else if(!strcmp(method, "ordered"))
100        {
101            if(ctx->nimages < 2)
102                return -1;
103            dst = pipi_dither_ordered(ctx->images[ctx->nimages - 2], src);
104            pipi_free(ctx->images[ctx->nimages - 2]);
105            ctx->nimages--;
106        }
107        else if(!strcmp(method, "random"))
108            dst = pipi_dither_random(src);
109        else if(!strcmp(method, "dbs"))
110            dst = pipi_dither_dbs(src);
111        if(dst == NULL)
112            return -1;
113        pipi_free(src);
114        ctx->images[ctx->nimages - 1] = dst;
115    }
116    else if(!strcmp(cmd, "blur"))
117    {
118        pipi_image_t *src, *dst;
119        char const *arg;
120        va_list ap;
121        double w, h, a = 0.0;
122
123        if(ctx->nimages < 1)
124            return -1;
125        va_start(ap, cmd);
126        arg = va_arg(ap, char const *);
127        va_end(ap);
128        w = h = atof(arg);
129        arg = strchr(arg, 'x');
130        if(arg)
131        {
132            h = atof(arg + 1);
133            arg = strchr(arg, 'r');
134            if(arg)
135                a = atof(arg + 1);
136        }
137        src = ctx->images[ctx->nimages - 1];
138        dst = pipi_gaussian_blur_ext(src, w, h, a, 0.0, 0.0);
139        if(dst == NULL)
140            return -1;
141        pipi_free(src);
142        ctx->images[ctx->nimages - 1] = dst;
143    }
144    else if(!strcmp(cmd, "boxblur"))
145    {
146        pipi_image_t *src, *dst;
147        char const *arg;
148        va_list ap;
149        double w, h;
150
151        if(ctx->nimages < 1)
152            return -1;
153        va_start(ap, cmd);
154        arg = va_arg(ap, char const *);
155        va_end(ap);
156        w = h = atof(arg);
157        arg = strchr(arg, 'x');
158        if(arg)
159            h = atof(arg + 1);
160        src = ctx->images[ctx->nimages - 1];
161        dst = pipi_box_blur_ext(src, w, h);
162        if(dst == NULL)
163            return -1;
164        pipi_free(src);
165        ctx->images[ctx->nimages - 1] = dst;
166    }
167    else if(!strcmp(cmd, "median"))
168    {
169        pipi_image_t *src, *dst;
170        char const *arg;
171        va_list ap;
172        double w, h;
173
174        if(ctx->nimages < 1)
175            return -1;
176        va_start(ap, cmd);
177        arg = va_arg(ap, char const *);
178        va_end(ap);
179        w = h = atof(arg);
180        arg = strchr(arg, 'x');
181        if(arg)
182            h = atof(arg + 1);
183        src = ctx->images[ctx->nimages - 1];
184        dst = pipi_median_ext(src, w, h);
185        if(dst == NULL)
186            return -1;
187        pipi_free(src);
188        ctx->images[ctx->nimages - 1] = dst;
189    }
190    else if(!strcmp(cmd, "geometry"))
191    {
192        pipi_image_t *src, *dst;
193        char const *arg;
194        va_list ap;
195        int w, h;
196
197        if(ctx->nimages < 1)
198            return -1;
199        va_start(ap, cmd);
200        arg = va_arg(ap, char const *);
201        va_end(ap);
202        w = atoi(arg);
203        arg = strchr(arg, 'x');
204        if(!arg)
205            return -1;
206        h = atoi(arg + 1);
207        if(w <= 0 || h <= 0)
208            return -1;
209        src = ctx->images[ctx->nimages - 1];
210        dst = pipi_resize(src, w, h);
211        if(dst == NULL)
212            return -1;
213        pipi_free(src);
214        ctx->images[ctx->nimages - 1] = dst;
215    }
216    else if(!strcmp(cmd, "tile"))
217    {
218        pipi_image_t *src, *dst;
219        char const *arg;
220        va_list ap;
221        int w, h;
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 = atoi(arg);
229        arg = strchr(arg, 'x');
230        if(!arg)
231            return -1;
232        h = atoi(arg + 1);
233        if(w <= 0 || h <= 0)
234            return -1;
235        src = ctx->images[ctx->nimages - 1];
236        dst = pipi_tile(src, w, h);
237        if(dst == NULL)
238            return -1;
239        pipi_free(src);
240        ctx->images[ctx->nimages - 1] = dst;
241    }
242    else if(!strcmp(cmd, "scale"))
243    {
244        pipi_image_t *src, *dst;
245        char const *arg;
246        va_list ap;
247        double scale;
248        int w, h;
249
250        if(ctx->nimages < 1)
251            return -1;
252        src = ctx->images[ctx->nimages - 1];
253        va_start(ap, cmd);
254        arg = va_arg(ap, char const *);
255        va_end(ap);
256        scale = atof(arg);
257        w = (int)(scale * src->w + 0.5);
258        h = (int)(scale * src->h + 0.5);
259        if(w <= 0 || h <= 0)
260            return -1;
261        dst = pipi_resize(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, "brightness"))
268    {
269        pipi_image_t *src, *dst;
270        char const *arg;
271        va_list ap;
272        double val;
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        val = atof(arg);
280        src = ctx->images[ctx->nimages - 1];
281        dst = pipi_brightness(src, val);
282        if(dst == NULL)
283            return -1;
284        pipi_free(src);
285        ctx->images[ctx->nimages - 1] = dst;
286    }
287    else if(!strcmp(cmd, "contrast"))
288    {
289        pipi_image_t *src, *dst;
290        char const *arg;
291        va_list ap;
292        double val;
293
294        if(ctx->nimages < 1)
295            return -1;
296        va_start(ap, cmd);
297        arg = va_arg(ap, char const *);
298        va_end(ap);
299        val = atof(arg);
300        src = ctx->images[ctx->nimages - 1];
301        dst = pipi_contrast(src, val);
302        if(dst == NULL)
303            return -1;
304        pipi_free(src);
305        ctx->images[ctx->nimages - 1] = dst;
306    }
307    else if(!strcmp(cmd, "mean"))
308    {
309        pipi_image_t *dst;
310
311        if(ctx->nimages < 2)
312            return -1;
313        dst = pipi_mean(ctx->images[ctx->nimages - 2],
314                        ctx->images[ctx->nimages - 1]);
315        if(dst == NULL)
316            return -1;
317        pipi_free(ctx->images[ctx->nimages - 2]);
318        pipi_free(ctx->images[ctx->nimages - 1]);
319        ctx->images[ctx->nimages - 2] = dst;
320        ctx->nimages--;
321    }
322    else if(!strcmp(cmd, "min"))
323    {
324        pipi_image_t *dst;
325
326        if(ctx->nimages < 2)
327            return -1;
328        dst = pipi_min(ctx->images[ctx->nimages - 2],
329                       ctx->images[ctx->nimages - 1]);
330        if(dst == NULL)
331            return -1;
332        pipi_free(ctx->images[ctx->nimages - 2]);
333        pipi_free(ctx->images[ctx->nimages - 1]);
334        ctx->images[ctx->nimages - 2] = dst;
335        ctx->nimages--;
336    }
337    else if(!strcmp(cmd, "max"))
338    {
339        pipi_image_t *dst;
340
341        if(ctx->nimages < 2)
342            return -1;
343        dst = pipi_max(ctx->images[ctx->nimages - 2],
344                       ctx->images[ctx->nimages - 1]);
345        if(dst == NULL)
346            return -1;
347        pipi_free(ctx->images[ctx->nimages - 2]);
348        pipi_free(ctx->images[ctx->nimages - 1]);
349        ctx->images[ctx->nimages - 2] = dst;
350        ctx->nimages--;
351    }
352    else if(!strcmp(cmd, "add"))
353    {
354        pipi_image_t *dst;
355
356        if(ctx->nimages < 2)
357            return -1;
358        dst = pipi_add(ctx->images[ctx->nimages - 2],
359                       ctx->images[ctx->nimages - 1]);
360        if(dst == NULL)
361            return -1;
362        pipi_free(ctx->images[ctx->nimages - 2]);
363        pipi_free(ctx->images[ctx->nimages - 1]);
364        ctx->images[ctx->nimages - 2] = dst;
365        ctx->nimages--;
366    }
367    else if(!strcmp(cmd, "sub"))
368    {
369        pipi_image_t *dst;
370
371        if(ctx->nimages < 2)
372            return -1;
373        dst = pipi_sub(ctx->images[ctx->nimages - 2],
374                       ctx->images[ctx->nimages - 1]);
375        if(dst == NULL)
376            return -1;
377        pipi_free(ctx->images[ctx->nimages - 2]);
378        pipi_free(ctx->images[ctx->nimages - 1]);
379        ctx->images[ctx->nimages - 2] = dst;
380        ctx->nimages--;
381    }
382    else if(!strcmp(cmd, "difference"))
383    {
384        pipi_image_t *dst;
385
386        if(ctx->nimages < 2)
387            return -1;
388        dst = pipi_difference(ctx->images[ctx->nimages - 2],
389                              ctx->images[ctx->nimages - 1]);
390        if(dst == NULL)
391            return -1;
392        pipi_free(ctx->images[ctx->nimages - 2]);
393        pipi_free(ctx->images[ctx->nimages - 1]);
394        ctx->images[ctx->nimages - 2] = dst;
395        ctx->nimages--;
396    }
397    else if(!strcmp(cmd, "multiply"))
398    {
399        pipi_image_t *dst;
400
401        if(ctx->nimages < 2)
402            return -1;
403        dst = pipi_multiply(ctx->images[ctx->nimages - 2],
404                            ctx->images[ctx->nimages - 1]);
405        if(dst == NULL)
406            return -1;
407        pipi_free(ctx->images[ctx->nimages - 2]);
408        pipi_free(ctx->images[ctx->nimages - 1]);
409        ctx->images[ctx->nimages - 2] = dst;
410        ctx->nimages--;
411    }
412    else if(!strcmp(cmd, "divide"))
413    {
414        pipi_image_t *dst;
415
416        if(ctx->nimages < 2)
417            return -1;
418        dst = pipi_divide(ctx->images[ctx->nimages - 2],
419                          ctx->images[ctx->nimages - 1]);
420        if(dst == NULL)
421            return -1;
422        pipi_free(ctx->images[ctx->nimages - 2]);
423        pipi_free(ctx->images[ctx->nimages - 1]);
424        ctx->images[ctx->nimages - 2] = dst;
425        ctx->nimages--;
426    }
427    else if(!strcmp(cmd, "screen"))
428    {
429        pipi_image_t *dst;
430
431        if(ctx->nimages < 2)
432            return -1;
433        dst = pipi_screen(ctx->images[ctx->nimages - 2],
434                          ctx->images[ctx->nimages - 1]);
435        if(dst == NULL)
436            return -1;
437        pipi_free(ctx->images[ctx->nimages - 2]);
438        pipi_free(ctx->images[ctx->nimages - 1]);
439        ctx->images[ctx->nimages - 2] = dst;
440        ctx->nimages--;
441    }
442    else if(!strcmp(cmd, "overlay"))
443    {
444        pipi_image_t *dst;
445
446        if(ctx->nimages < 2)
447            return -1;
448        dst = pipi_overlay(ctx->images[ctx->nimages - 2],
449                           ctx->images[ctx->nimages - 1]);
450        if(dst == NULL)
451            return -1;
452        pipi_free(ctx->images[ctx->nimages - 2]);
453        pipi_free(ctx->images[ctx->nimages - 1]);
454        ctx->images[ctx->nimages - 2] = dst;
455        ctx->nimages--;
456    }
457    else if(!strcmp(cmd, "wrap"))
458    {
459        if(ctx->nimages < 1)
460            return -1;
461        ctx->images[ctx->nimages - 1]->wrap = 1;
462    }
463    else if(!strcmp(cmd, "autocontrast"))
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_autocontrast(tmp);
470        pipi_free(tmp);
471    }
472    else if(!strcmp(cmd, "invert"))
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_invert(tmp);
479        pipi_free(tmp);
480    }
481    else if(!strcmp(cmd, "gray"))
482    {
483        if(ctx->nimages < 1)
484            return -1;
485        pipi_getpixels(ctx->images[ctx->nimages - 1], PIPI_PIXELS_Y_F);
486    }
487    else if(!strcmp(cmd, "free"))
488    {
489        if(ctx->nimages < 1)
490            return -1;
491        ctx->nimages--;
492        pipi_free(ctx->images[ctx->nimages]);
493    }
494    else if(!strcmp(cmd, "dup"))
495    {
496        if(ctx->nimages < 1)
497            return -1;
498        ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
499        ctx->nimages++;
500    }
501    else if(!strcmp(cmd, "swap"))
502    {
503        pipi_image_t *tmp;
504        if(ctx->nimages < 2)
505            return -1;
506        tmp = ctx->images[ctx->nimages - 1];
507        ctx->images[ctx->nimages - 1] = ctx->images[ctx->nimages - 2];
508        ctx->images[ctx->nimages - 2] = tmp;
509    }
510    else
511    {
512        return -1;
513    }
514
515    return 0;
516}
517
Note: See TracBrowser for help on using the repository browser.