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

Last change on this file since 2725 was 2725, checked in by Sam Hocevar, 14 years ago
  • color.c: implement pipi_brightness() and pipi_contrast().
  • pipi.c: add --brightness and --contrast.
File size: 12.7 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, "brightness"))
222    {
223        pipi_image_t *src, *dst;
224        char const *arg;
225        va_list ap;
226        double val;
227
228        if(ctx->nimages < 1)
229            return -1;
230        va_start(ap, cmd);
231        arg = va_arg(ap, char const *);
232        va_end(ap);
233        val = atof(arg);
234        src = ctx->images[ctx->nimages - 1];
235        dst = pipi_brightness(src, val);
236        if(dst == NULL)
237            return -1;
238        pipi_free(src);
239        ctx->images[ctx->nimages - 1] = dst;
240    }
241    else if(!strcmp(cmd, "contrast"))
242    {
243        pipi_image_t *src, *dst;
244        char const *arg;
245        va_list ap;
246        double val;
247
248        if(ctx->nimages < 1)
249            return -1;
250        va_start(ap, cmd);
251        arg = va_arg(ap, char const *);
252        va_end(ap);
253        val = atof(arg);
254        src = ctx->images[ctx->nimages - 1];
255        dst = pipi_contrast(src, val);
256        if(dst == NULL)
257            return -1;
258        pipi_free(src);
259        ctx->images[ctx->nimages - 1] = dst;
260    }
261    else if(!strcmp(cmd, "mean"))
262    {
263        pipi_image_t *dst;
264
265        if(ctx->nimages < 2)
266            return -1;
267        dst = pipi_mean(ctx->images[ctx->nimages - 2],
268                        ctx->images[ctx->nimages - 1]);
269        if(dst == NULL)
270            return -1;
271        pipi_free(ctx->images[ctx->nimages - 2]);
272        pipi_free(ctx->images[ctx->nimages - 1]);
273        ctx->images[ctx->nimages - 2] = dst;
274        ctx->nimages--;
275    }
276    else if(!strcmp(cmd, "min"))
277    {
278        pipi_image_t *dst;
279
280        if(ctx->nimages < 2)
281            return -1;
282        dst = pipi_min(ctx->images[ctx->nimages - 2],
283                       ctx->images[ctx->nimages - 1]);
284        if(dst == NULL)
285            return -1;
286        pipi_free(ctx->images[ctx->nimages - 2]);
287        pipi_free(ctx->images[ctx->nimages - 1]);
288        ctx->images[ctx->nimages - 2] = dst;
289        ctx->nimages--;
290    }
291    else if(!strcmp(cmd, "max"))
292    {
293        pipi_image_t *dst;
294
295        if(ctx->nimages < 2)
296            return -1;
297        dst = pipi_max(ctx->images[ctx->nimages - 2],
298                       ctx->images[ctx->nimages - 1]);
299        if(dst == NULL)
300            return -1;
301        pipi_free(ctx->images[ctx->nimages - 2]);
302        pipi_free(ctx->images[ctx->nimages - 1]);
303        ctx->images[ctx->nimages - 2] = dst;
304        ctx->nimages--;
305    }
306    else if(!strcmp(cmd, "add"))
307    {
308        pipi_image_t *dst;
309
310        if(ctx->nimages < 2)
311            return -1;
312        dst = pipi_add(ctx->images[ctx->nimages - 2],
313                       ctx->images[ctx->nimages - 1]);
314        if(dst == NULL)
315            return -1;
316        pipi_free(ctx->images[ctx->nimages - 2]);
317        pipi_free(ctx->images[ctx->nimages - 1]);
318        ctx->images[ctx->nimages - 2] = dst;
319        ctx->nimages--;
320    }
321    else if(!strcmp(cmd, "sub"))
322    {
323        pipi_image_t *dst;
324
325        if(ctx->nimages < 2)
326            return -1;
327        dst = pipi_sub(ctx->images[ctx->nimages - 2],
328                       ctx->images[ctx->nimages - 1]);
329        if(dst == NULL)
330            return -1;
331        pipi_free(ctx->images[ctx->nimages - 2]);
332        pipi_free(ctx->images[ctx->nimages - 1]);
333        ctx->images[ctx->nimages - 2] = dst;
334        ctx->nimages--;
335    }
336    else if(!strcmp(cmd, "difference"))
337    {
338        pipi_image_t *dst;
339
340        if(ctx->nimages < 2)
341            return -1;
342        dst = pipi_difference(ctx->images[ctx->nimages - 2],
343                              ctx->images[ctx->nimages - 1]);
344        if(dst == NULL)
345            return -1;
346        pipi_free(ctx->images[ctx->nimages - 2]);
347        pipi_free(ctx->images[ctx->nimages - 1]);
348        ctx->images[ctx->nimages - 2] = dst;
349        ctx->nimages--;
350    }
351    else if(!strcmp(cmd, "multiply"))
352    {
353        pipi_image_t *dst;
354
355        if(ctx->nimages < 2)
356            return -1;
357        dst = pipi_multiply(ctx->images[ctx->nimages - 2],
358                            ctx->images[ctx->nimages - 1]);
359        if(dst == NULL)
360            return -1;
361        pipi_free(ctx->images[ctx->nimages - 2]);
362        pipi_free(ctx->images[ctx->nimages - 1]);
363        ctx->images[ctx->nimages - 2] = dst;
364        ctx->nimages--;
365    }
366    else if(!strcmp(cmd, "divide"))
367    {
368        pipi_image_t *dst;
369
370        if(ctx->nimages < 2)
371            return -1;
372        dst = pipi_divide(ctx->images[ctx->nimages - 2],
373                          ctx->images[ctx->nimages - 1]);
374        if(dst == NULL)
375            return -1;
376        pipi_free(ctx->images[ctx->nimages - 2]);
377        pipi_free(ctx->images[ctx->nimages - 1]);
378        ctx->images[ctx->nimages - 2] = dst;
379        ctx->nimages--;
380    }
381    else if(!strcmp(cmd, "screen"))
382    {
383        pipi_image_t *dst;
384
385        if(ctx->nimages < 2)
386            return -1;
387        dst = pipi_screen(ctx->images[ctx->nimages - 2],
388                          ctx->images[ctx->nimages - 1]);
389        if(dst == NULL)
390            return -1;
391        pipi_free(ctx->images[ctx->nimages - 2]);
392        pipi_free(ctx->images[ctx->nimages - 1]);
393        ctx->images[ctx->nimages - 2] = dst;
394        ctx->nimages--;
395    }
396    else if(!strcmp(cmd, "overlay"))
397    {
398        pipi_image_t *dst;
399
400        if(ctx->nimages < 2)
401            return -1;
402        dst = pipi_overlay(ctx->images[ctx->nimages - 2],
403                           ctx->images[ctx->nimages - 1]);
404        if(dst == NULL)
405            return -1;
406        pipi_free(ctx->images[ctx->nimages - 2]);
407        pipi_free(ctx->images[ctx->nimages - 1]);
408        ctx->images[ctx->nimages - 2] = dst;
409        ctx->nimages--;
410    }
411    else if(!strcmp(cmd, "wrap"))
412    {
413        if(ctx->nimages < 1)
414            return -1;
415        ctx->images[ctx->nimages - 1]->wrap = 1;
416    }
417    else if(!strcmp(cmd, "autocontrast"))
418    {
419        pipi_image_t *tmp;
420        if(ctx->nimages < 1)
421            return -1;
422        tmp = ctx->images[ctx->nimages - 1];
423        ctx->images[ctx->nimages - 1] = pipi_autocontrast(tmp);
424        pipi_free(tmp);
425    }
426    else if(!strcmp(cmd, "invert"))
427    {
428        pipi_image_t *tmp;
429        if(ctx->nimages < 1)
430            return -1;
431        tmp = ctx->images[ctx->nimages - 1];
432        ctx->images[ctx->nimages - 1] = pipi_invert(tmp);
433        pipi_free(tmp);
434    }
435    else if(!strcmp(cmd, "gray"))
436    {
437        if(ctx->nimages < 1)
438            return -1;
439        pipi_getpixels(ctx->images[ctx->nimages - 1], PIPI_PIXELS_Y_F);
440    }
441    else if(!strcmp(cmd, "free"))
442    {
443        if(ctx->nimages < 1)
444            return -1;
445        ctx->nimages--;
446        pipi_free(ctx->images[ctx->nimages]);
447    }
448    else if(!strcmp(cmd, "dup"))
449    {
450        if(ctx->nimages < 1)
451            return -1;
452        ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
453        ctx->nimages++;
454    }
455    else if(!strcmp(cmd, "swap"))
456    {
457        pipi_image_t *tmp;
458        if(ctx->nimages < 2)
459            return -1;
460        tmp = ctx->images[ctx->nimages - 1];
461        ctx->images[ctx->nimages - 1] = ctx->images[ctx->nimages - 2];
462        ctx->images[ctx->nimages - 2] = tmp;
463    }
464    else
465    {
466        return -1;
467    }
468
469    return 0;
470}
471
Note: See TracBrowser for help on using the repository browser.