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

Last change on this file since 2717 was 2717, checked in by sam, 6 years ago
  • Add pipi_tile, to create image mosaics.
File size: 11.5 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, "tile"))
171    {
172        pipi_image_t *src, *dst;
173        char const *arg;
174        va_list ap;
175        int w, h;
176
177        if(ctx->nimages < 1)
178            return -1;
179        va_start(ap, cmd);
180        arg = va_arg(ap, char const *);
181        va_end(ap);
182        w = atoi(arg);
183        arg = strchr(arg, 'x');
184        if(!arg)
185            return -1;
186        h = atoi(arg + 1);
187        if(w <= 0 || h <= 0)
188            return -1;
189        src = ctx->images[ctx->nimages - 1];
190        dst = pipi_tile(src, w, h);
191        if(dst == NULL)
192            return -1;
193        pipi_free(src);
194        ctx->images[ctx->nimages - 1] = dst;
195    }
196    else if(!strcmp(cmd, "scale"))
197    {
198        pipi_image_t *src, *dst;
199        char const *arg;
200        va_list ap;
201        double scale;
202        int w, h;
203
204        if(ctx->nimages < 1)
205            return -1;
206        src = ctx->images[ctx->nimages - 1];
207        va_start(ap, cmd);
208        arg = va_arg(ap, char const *);
209        va_end(ap);
210        scale = atof(arg);
211        w = (int)(scale * src->w + 0.5);
212        h = (int)(scale * src->h + 0.5);
213        if(w <= 0 || h <= 0)
214            return -1;
215        dst = pipi_resize(src, w, h);
216        if(dst == NULL)
217            return -1;
218        pipi_free(src);
219        ctx->images[ctx->nimages - 1] = dst;
220    }
221    else if(!strcmp(cmd, "mean"))
222    {
223        pipi_image_t *dst;
224
225        if(ctx->nimages < 2)
226            return -1;
227        dst = pipi_mean(ctx->images[ctx->nimages - 2],
228                        ctx->images[ctx->nimages - 1]);
229        if(dst == NULL)
230            return -1;
231        pipi_free(ctx->images[ctx->nimages - 2]);
232        pipi_free(ctx->images[ctx->nimages - 1]);
233        ctx->images[ctx->nimages - 2] = dst;
234        ctx->nimages--;
235    }
236    else if(!strcmp(cmd, "min"))
237    {
238        pipi_image_t *dst;
239
240        if(ctx->nimages < 2)
241            return -1;
242        dst = pipi_min(ctx->images[ctx->nimages - 2],
243                       ctx->images[ctx->nimages - 1]);
244        if(dst == NULL)
245            return -1;
246        pipi_free(ctx->images[ctx->nimages - 2]);
247        pipi_free(ctx->images[ctx->nimages - 1]);
248        ctx->images[ctx->nimages - 2] = dst;
249        ctx->nimages--;
250    }
251    else if(!strcmp(cmd, "max"))
252    {
253        pipi_image_t *dst;
254
255        if(ctx->nimages < 2)
256            return -1;
257        dst = pipi_max(ctx->images[ctx->nimages - 2],
258                       ctx->images[ctx->nimages - 1]);
259        if(dst == NULL)
260            return -1;
261        pipi_free(ctx->images[ctx->nimages - 2]);
262        pipi_free(ctx->images[ctx->nimages - 1]);
263        ctx->images[ctx->nimages - 2] = dst;
264        ctx->nimages--;
265    }
266    else if(!strcmp(cmd, "add"))
267    {
268        pipi_image_t *dst;
269
270        if(ctx->nimages < 2)
271            return -1;
272        dst = pipi_add(ctx->images[ctx->nimages - 2],
273                       ctx->images[ctx->nimages - 1]);
274        if(dst == NULL)
275            return -1;
276        pipi_free(ctx->images[ctx->nimages - 2]);
277        pipi_free(ctx->images[ctx->nimages - 1]);
278        ctx->images[ctx->nimages - 2] = dst;
279        ctx->nimages--;
280    }
281    else if(!strcmp(cmd, "sub"))
282    {
283        pipi_image_t *dst;
284
285        if(ctx->nimages < 2)
286            return -1;
287        dst = pipi_sub(ctx->images[ctx->nimages - 2],
288                       ctx->images[ctx->nimages - 1]);
289        if(dst == NULL)
290            return -1;
291        pipi_free(ctx->images[ctx->nimages - 2]);
292        pipi_free(ctx->images[ctx->nimages - 1]);
293        ctx->images[ctx->nimages - 2] = dst;
294        ctx->nimages--;
295    }
296    else if(!strcmp(cmd, "difference"))
297    {
298        pipi_image_t *dst;
299
300        if(ctx->nimages < 2)
301            return -1;
302        dst = pipi_difference(ctx->images[ctx->nimages - 2],
303                              ctx->images[ctx->nimages - 1]);
304        if(dst == NULL)
305            return -1;
306        pipi_free(ctx->images[ctx->nimages - 2]);
307        pipi_free(ctx->images[ctx->nimages - 1]);
308        ctx->images[ctx->nimages - 2] = dst;
309        ctx->nimages--;
310    }
311    else if(!strcmp(cmd, "multiply"))
312    {
313        pipi_image_t *dst;
314
315        if(ctx->nimages < 2)
316            return -1;
317        dst = pipi_multiply(ctx->images[ctx->nimages - 2],
318                            ctx->images[ctx->nimages - 1]);
319        if(dst == NULL)
320            return -1;
321        pipi_free(ctx->images[ctx->nimages - 2]);
322        pipi_free(ctx->images[ctx->nimages - 1]);
323        ctx->images[ctx->nimages - 2] = dst;
324        ctx->nimages--;
325    }
326    else if(!strcmp(cmd, "divide"))
327    {
328        pipi_image_t *dst;
329
330        if(ctx->nimages < 2)
331            return -1;
332        dst = pipi_divide(ctx->images[ctx->nimages - 2],
333                          ctx->images[ctx->nimages - 1]);
334        if(dst == NULL)
335            return -1;
336        pipi_free(ctx->images[ctx->nimages - 2]);
337        pipi_free(ctx->images[ctx->nimages - 1]);
338        ctx->images[ctx->nimages - 2] = dst;
339        ctx->nimages--;
340    }
341    else if(!strcmp(cmd, "screen"))
342    {
343        pipi_image_t *dst;
344
345        if(ctx->nimages < 2)
346            return -1;
347        dst = pipi_screen(ctx->images[ctx->nimages - 2],
348                          ctx->images[ctx->nimages - 1]);
349        if(dst == NULL)
350            return -1;
351        pipi_free(ctx->images[ctx->nimages - 2]);
352        pipi_free(ctx->images[ctx->nimages - 1]);
353        ctx->images[ctx->nimages - 2] = dst;
354        ctx->nimages--;
355    }
356    else if(!strcmp(cmd, "overlay"))
357    {
358        pipi_image_t *dst;
359
360        if(ctx->nimages < 2)
361            return -1;
362        dst = pipi_overlay(ctx->images[ctx->nimages - 2],
363                           ctx->images[ctx->nimages - 1]);
364        if(dst == NULL)
365            return -1;
366        pipi_free(ctx->images[ctx->nimages - 2]);
367        pipi_free(ctx->images[ctx->nimages - 1]);
368        ctx->images[ctx->nimages - 2] = dst;
369        ctx->nimages--;
370    }
371    else if(!strcmp(cmd, "wrap"))
372    {
373        if(ctx->nimages < 1)
374            return -1;
375        ctx->images[ctx->nimages - 1]->wrap = 1;
376    }
377    else if(!strcmp(cmd, "autocontrast"))
378    {
379        pipi_image_t *tmp;
380        if(ctx->nimages < 1)
381            return -1;
382        tmp = ctx->images[ctx->nimages - 1];
383        ctx->images[ctx->nimages - 1] = pipi_autocontrast(tmp);
384        pipi_free(tmp);
385    }
386    else if(!strcmp(cmd, "gray"))
387    {
388        if(ctx->nimages < 1)
389            return -1;
390        pipi_getpixels(ctx->images[ctx->nimages - 1], PIPI_PIXELS_Y_F);
391    }
392    else if(!strcmp(cmd, "free"))
393    {
394        if(ctx->nimages < 1)
395            return -1;
396        ctx->nimages--;
397        pipi_free(ctx->images[ctx->nimages]);
398    }
399    else if(!strcmp(cmd, "dup"))
400    {
401        if(ctx->nimages < 1)
402            return -1;
403        ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
404        ctx->nimages++;
405    }
406    else if(!strcmp(cmd, "swap"))
407    {
408        pipi_image_t *tmp;
409        if(ctx->nimages < 2)
410            return -1;
411        tmp = ctx->images[ctx->nimages - 1];
412        ctx->images[ctx->nimages - 1] = ctx->images[ctx->nimages - 2];
413        ctx->images[ctx->nimages - 2] = tmp;
414    }
415    else
416    {
417        return -1;
418    }
419
420    return 0;
421}
422
Note: See TracBrowser for help on using the repository browser.