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

Last change on this file since 2713 was 2713, checked in by Sam Hocevar, 12 years ago
  • Allow pipi --blur to specify both the X and Y Gaussian sizes. Now we can create some nice, tileable brushed metal textures:

pipi pipi:random15x15 --geometry 512x512 --wrap --blur 40 \

pipi:random512x512 --wrap --blur 10x0 --autocontrast --wrap \
--blur 20x0 --multiply -o image.png

File size: 10.0 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;
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            h = atof(arg + 1);
132        src = ctx->images[ctx->nimages - 1];
133        dst = pipi_gaussian_blur_ext(src, w, h, 0.0, 0.0);
134        if(dst == NULL)
135            return -1;
136        pipi_free(src);
137        ctx->images[ctx->nimages - 1] = dst;
138    }
139    else if(!strcmp(cmd, "geometry"))
140    {
141        pipi_image_t *src, *dst;
142        char const *arg;
143        va_list ap;
144        int w, h;
145
146        if(ctx->nimages < 1)
147            return -1;
148        va_start(ap, cmd);
149        arg = va_arg(ap, char const *);
150        va_end(ap);
151        w = atoi(arg);
152        arg = strchr(arg, 'x');
153        if(!arg)
154            return -1;
155        h = atoi(arg + 1);
156        if(w <= 0 || h <= 0)
157            return -1;
158        src = ctx->images[ctx->nimages - 1];
159        dst = pipi_resize(src, w, h);
160        if(dst == NULL)
161            return -1;
162        pipi_free(src);
163        ctx->images[ctx->nimages - 1] = dst;
164    }
165    else if(!strcmp(cmd, "mean"))
166    {
167        pipi_image_t *dst;
168
169        if(ctx->nimages < 2)
170            return -1;
171        dst = pipi_mean(ctx->images[ctx->nimages - 2],
172                        ctx->images[ctx->nimages - 1]);
173        if(dst == NULL)
174            return -1;
175        pipi_free(ctx->images[ctx->nimages - 2]);
176        pipi_free(ctx->images[ctx->nimages - 1]);
177        ctx->images[ctx->nimages - 2] = dst;
178        ctx->nimages--;
179    }
180    else if(!strcmp(cmd, "min"))
181    {
182        pipi_image_t *dst;
183
184        if(ctx->nimages < 2)
185            return -1;
186        dst = pipi_min(ctx->images[ctx->nimages - 2],
187                       ctx->images[ctx->nimages - 1]);
188        if(dst == NULL)
189            return -1;
190        pipi_free(ctx->images[ctx->nimages - 2]);
191        pipi_free(ctx->images[ctx->nimages - 1]);
192        ctx->images[ctx->nimages - 2] = dst;
193        ctx->nimages--;
194    }
195    else if(!strcmp(cmd, "max"))
196    {
197        pipi_image_t *dst;
198
199        if(ctx->nimages < 2)
200            return -1;
201        dst = pipi_max(ctx->images[ctx->nimages - 2],
202                       ctx->images[ctx->nimages - 1]);
203        if(dst == NULL)
204            return -1;
205        pipi_free(ctx->images[ctx->nimages - 2]);
206        pipi_free(ctx->images[ctx->nimages - 1]);
207        ctx->images[ctx->nimages - 2] = dst;
208        ctx->nimages--;
209    }
210    else if(!strcmp(cmd, "add"))
211    {
212        pipi_image_t *dst;
213
214        if(ctx->nimages < 2)
215            return -1;
216        dst = pipi_add(ctx->images[ctx->nimages - 2],
217                       ctx->images[ctx->nimages - 1]);
218        if(dst == NULL)
219            return -1;
220        pipi_free(ctx->images[ctx->nimages - 2]);
221        pipi_free(ctx->images[ctx->nimages - 1]);
222        ctx->images[ctx->nimages - 2] = dst;
223        ctx->nimages--;
224    }
225    else if(!strcmp(cmd, "sub"))
226    {
227        pipi_image_t *dst;
228
229        if(ctx->nimages < 2)
230            return -1;
231        dst = pipi_sub(ctx->images[ctx->nimages - 2],
232                       ctx->images[ctx->nimages - 1]);
233        if(dst == NULL)
234            return -1;
235        pipi_free(ctx->images[ctx->nimages - 2]);
236        pipi_free(ctx->images[ctx->nimages - 1]);
237        ctx->images[ctx->nimages - 2] = dst;
238        ctx->nimages--;
239    }
240    else if(!strcmp(cmd, "difference"))
241    {
242        pipi_image_t *dst;
243
244        if(ctx->nimages < 2)
245            return -1;
246        dst = pipi_difference(ctx->images[ctx->nimages - 2],
247                              ctx->images[ctx->nimages - 1]);
248        if(dst == NULL)
249            return -1;
250        pipi_free(ctx->images[ctx->nimages - 2]);
251        pipi_free(ctx->images[ctx->nimages - 1]);
252        ctx->images[ctx->nimages - 2] = dst;
253        ctx->nimages--;
254    }
255    else if(!strcmp(cmd, "multiply"))
256    {
257        pipi_image_t *dst;
258
259        if(ctx->nimages < 2)
260            return -1;
261        dst = pipi_multiply(ctx->images[ctx->nimages - 2],
262                            ctx->images[ctx->nimages - 1]);
263        if(dst == NULL)
264            return -1;
265        pipi_free(ctx->images[ctx->nimages - 2]);
266        pipi_free(ctx->images[ctx->nimages - 1]);
267        ctx->images[ctx->nimages - 2] = dst;
268        ctx->nimages--;
269    }
270    else if(!strcmp(cmd, "divide"))
271    {
272        pipi_image_t *dst;
273
274        if(ctx->nimages < 2)
275            return -1;
276        dst = pipi_divide(ctx->images[ctx->nimages - 2],
277                          ctx->images[ctx->nimages - 1]);
278        if(dst == NULL)
279            return -1;
280        pipi_free(ctx->images[ctx->nimages - 2]);
281        pipi_free(ctx->images[ctx->nimages - 1]);
282        ctx->images[ctx->nimages - 2] = dst;
283        ctx->nimages--;
284    }
285    else if(!strcmp(cmd, "screen"))
286    {
287        pipi_image_t *dst;
288
289        if(ctx->nimages < 2)
290            return -1;
291        dst = pipi_screen(ctx->images[ctx->nimages - 2],
292                          ctx->images[ctx->nimages - 1]);
293        if(dst == NULL)
294            return -1;
295        pipi_free(ctx->images[ctx->nimages - 2]);
296        pipi_free(ctx->images[ctx->nimages - 1]);
297        ctx->images[ctx->nimages - 2] = dst;
298        ctx->nimages--;
299    }
300    else if(!strcmp(cmd, "overlay"))
301    {
302        pipi_image_t *dst;
303
304        if(ctx->nimages < 2)
305            return -1;
306        dst = pipi_overlay(ctx->images[ctx->nimages - 2],
307                           ctx->images[ctx->nimages - 1]);
308        if(dst == NULL)
309            return -1;
310        pipi_free(ctx->images[ctx->nimages - 2]);
311        pipi_free(ctx->images[ctx->nimages - 1]);
312        ctx->images[ctx->nimages - 2] = dst;
313        ctx->nimages--;
314    }
315    else if(!strcmp(cmd, "wrap"))
316    {
317        if(ctx->nimages < 1)
318            return -1;
319        ctx->images[ctx->nimages - 1]->wrap = 1;
320    }
321    else if(!strcmp(cmd, "autocontrast"))
322    {
323        pipi_image_t *tmp;
324        if(ctx->nimages < 1)
325            return -1;
326        tmp = ctx->images[ctx->nimages - 1];
327        ctx->images[ctx->nimages - 1] = pipi_autocontrast(tmp);
328        pipi_free(tmp);
329    }
330    else if(!strcmp(cmd, "gray"))
331    {
332        if(ctx->nimages < 1)
333            return -1;
334        pipi_getpixels(ctx->images[ctx->nimages - 1], PIPI_PIXELS_Y_F);
335    }
336    else if(!strcmp(cmd, "free"))
337    {
338        if(ctx->nimages < 1)
339            return -1;
340        ctx->nimages--;
341        pipi_free(ctx->images[ctx->nimages]);
342    }
343    else if(!strcmp(cmd, "dup"))
344    {
345        if(ctx->nimages < 1)
346            return -1;
347        ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
348        ctx->nimages++;
349    }
350    else if(!strcmp(cmd, "swap"))
351    {
352        pipi_image_t *tmp;
353        if(ctx->nimages < 2)
354            return -1;
355        tmp = ctx->images[ctx->nimages - 1];
356        ctx->images[ctx->nimages - 1] = ctx->images[ctx->nimages - 2];
357        ctx->images[ctx->nimages - 2] = tmp;
358    }
359    else
360    {
361        return -1;
362    }
363
364    return 0;
365}
366
Note: See TracBrowser for help on using the repository browser.