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

Last change on this file since 2715 was 2715, checked in by Sam Hocevar, 15 years ago
  • blur.c: add an argument to the gaussian convolution to specify an angle. Of course since the kernel is no longer separable, it becomes awfully slow with large images. Here is a tileable brushed metal texture: # pipi pipi:random512x512 --wrap --blur 20x0r25 -o image.png
File size: 10.2 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, "geometry"))
145    {
146        pipi_image_t *src, *dst;
147        char const *arg;
148        va_list ap;
149        int 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 = atoi(arg);
157        arg = strchr(arg, 'x');
158        if(!arg)
159            return -1;
160        h = atoi(arg + 1);
161        if(w <= 0 || h <= 0)
162            return -1;
163        src = ctx->images[ctx->nimages - 1];
164        dst = pipi_resize(src, w, h);
165        if(dst == NULL)
166            return -1;
167        pipi_free(src);
168        ctx->images[ctx->nimages - 1] = dst;
169    }
170    else if(!strcmp(cmd, "mean"))
171    {
172        pipi_image_t *dst;
173
174        if(ctx->nimages < 2)
175            return -1;
176        dst = pipi_mean(ctx->images[ctx->nimages - 2],
177                        ctx->images[ctx->nimages - 1]);
178        if(dst == NULL)
179            return -1;
180        pipi_free(ctx->images[ctx->nimages - 2]);
181        pipi_free(ctx->images[ctx->nimages - 1]);
182        ctx->images[ctx->nimages - 2] = dst;
183        ctx->nimages--;
184    }
185    else if(!strcmp(cmd, "min"))
186    {
187        pipi_image_t *dst;
188
189        if(ctx->nimages < 2)
190            return -1;
191        dst = pipi_min(ctx->images[ctx->nimages - 2],
192                       ctx->images[ctx->nimages - 1]);
193        if(dst == NULL)
194            return -1;
195        pipi_free(ctx->images[ctx->nimages - 2]);
196        pipi_free(ctx->images[ctx->nimages - 1]);
197        ctx->images[ctx->nimages - 2] = dst;
198        ctx->nimages--;
199    }
200    else if(!strcmp(cmd, "max"))
201    {
202        pipi_image_t *dst;
203
204        if(ctx->nimages < 2)
205            return -1;
206        dst = pipi_max(ctx->images[ctx->nimages - 2],
207                       ctx->images[ctx->nimages - 1]);
208        if(dst == NULL)
209            return -1;
210        pipi_free(ctx->images[ctx->nimages - 2]);
211        pipi_free(ctx->images[ctx->nimages - 1]);
212        ctx->images[ctx->nimages - 2] = dst;
213        ctx->nimages--;
214    }
215    else if(!strcmp(cmd, "add"))
216    {
217        pipi_image_t *dst;
218
219        if(ctx->nimages < 2)
220            return -1;
221        dst = pipi_add(ctx->images[ctx->nimages - 2],
222                       ctx->images[ctx->nimages - 1]);
223        if(dst == NULL)
224            return -1;
225        pipi_free(ctx->images[ctx->nimages - 2]);
226        pipi_free(ctx->images[ctx->nimages - 1]);
227        ctx->images[ctx->nimages - 2] = dst;
228        ctx->nimages--;
229    }
230    else if(!strcmp(cmd, "sub"))
231    {
232        pipi_image_t *dst;
233
234        if(ctx->nimages < 2)
235            return -1;
236        dst = pipi_sub(ctx->images[ctx->nimages - 2],
237                       ctx->images[ctx->nimages - 1]);
238        if(dst == NULL)
239            return -1;
240        pipi_free(ctx->images[ctx->nimages - 2]);
241        pipi_free(ctx->images[ctx->nimages - 1]);
242        ctx->images[ctx->nimages - 2] = dst;
243        ctx->nimages--;
244    }
245    else if(!strcmp(cmd, "difference"))
246    {
247        pipi_image_t *dst;
248
249        if(ctx->nimages < 2)
250            return -1;
251        dst = pipi_difference(ctx->images[ctx->nimages - 2],
252                              ctx->images[ctx->nimages - 1]);
253        if(dst == NULL)
254            return -1;
255        pipi_free(ctx->images[ctx->nimages - 2]);
256        pipi_free(ctx->images[ctx->nimages - 1]);
257        ctx->images[ctx->nimages - 2] = dst;
258        ctx->nimages--;
259    }
260    else if(!strcmp(cmd, "multiply"))
261    {
262        pipi_image_t *dst;
263
264        if(ctx->nimages < 2)
265            return -1;
266        dst = pipi_multiply(ctx->images[ctx->nimages - 2],
267                            ctx->images[ctx->nimages - 1]);
268        if(dst == NULL)
269            return -1;
270        pipi_free(ctx->images[ctx->nimages - 2]);
271        pipi_free(ctx->images[ctx->nimages - 1]);
272        ctx->images[ctx->nimages - 2] = dst;
273        ctx->nimages--;
274    }
275    else if(!strcmp(cmd, "divide"))
276    {
277        pipi_image_t *dst;
278
279        if(ctx->nimages < 2)
280            return -1;
281        dst = pipi_divide(ctx->images[ctx->nimages - 2],
282                          ctx->images[ctx->nimages - 1]);
283        if(dst == NULL)
284            return -1;
285        pipi_free(ctx->images[ctx->nimages - 2]);
286        pipi_free(ctx->images[ctx->nimages - 1]);
287        ctx->images[ctx->nimages - 2] = dst;
288        ctx->nimages--;
289    }
290    else if(!strcmp(cmd, "screen"))
291    {
292        pipi_image_t *dst;
293
294        if(ctx->nimages < 2)
295            return -1;
296        dst = pipi_screen(ctx->images[ctx->nimages - 2],
297                          ctx->images[ctx->nimages - 1]);
298        if(dst == NULL)
299            return -1;
300        pipi_free(ctx->images[ctx->nimages - 2]);
301        pipi_free(ctx->images[ctx->nimages - 1]);
302        ctx->images[ctx->nimages - 2] = dst;
303        ctx->nimages--;
304    }
305    else if(!strcmp(cmd, "overlay"))
306    {
307        pipi_image_t *dst;
308
309        if(ctx->nimages < 2)
310            return -1;
311        dst = pipi_overlay(ctx->images[ctx->nimages - 2],
312                           ctx->images[ctx->nimages - 1]);
313        if(dst == NULL)
314            return -1;
315        pipi_free(ctx->images[ctx->nimages - 2]);
316        pipi_free(ctx->images[ctx->nimages - 1]);
317        ctx->images[ctx->nimages - 2] = dst;
318        ctx->nimages--;
319    }
320    else if(!strcmp(cmd, "wrap"))
321    {
322        if(ctx->nimages < 1)
323            return -1;
324        ctx->images[ctx->nimages - 1]->wrap = 1;
325    }
326    else if(!strcmp(cmd, "autocontrast"))
327    {
328        pipi_image_t *tmp;
329        if(ctx->nimages < 1)
330            return -1;
331        tmp = ctx->images[ctx->nimages - 1];
332        ctx->images[ctx->nimages - 1] = pipi_autocontrast(tmp);
333        pipi_free(tmp);
334    }
335    else if(!strcmp(cmd, "gray"))
336    {
337        if(ctx->nimages < 1)
338            return -1;
339        pipi_getpixels(ctx->images[ctx->nimages - 1], PIPI_PIXELS_Y_F);
340    }
341    else if(!strcmp(cmd, "free"))
342    {
343        if(ctx->nimages < 1)
344            return -1;
345        ctx->nimages--;
346        pipi_free(ctx->images[ctx->nimages]);
347    }
348    else if(!strcmp(cmd, "dup"))
349    {
350        if(ctx->nimages < 1)
351            return -1;
352        ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
353        ctx->nimages++;
354    }
355    else if(!strcmp(cmd, "swap"))
356    {
357        pipi_image_t *tmp;
358        if(ctx->nimages < 2)
359            return -1;
360        tmp = ctx->images[ctx->nimages - 1];
361        ctx->images[ctx->nimages - 1] = ctx->images[ctx->nimages - 2];
362        ctx->images[ctx->nimages - 2] = tmp;
363    }
364    else
365    {
366        return -1;
367    }
368
369    return 0;
370}
371
Note: See TracBrowser for help on using the repository browser.