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

Last change on this file since 2750 was 2750, checked in by Sam Hocevar, 12 years ago
  • transform.c: implement pipi_rotate90, pipi_rotate180 and pipi_rotate270.
File size: 16.1 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, "threshold"))
308    {
309        pipi_image_t *src, *dst;
310        char const *arg;
311        va_list ap;
312        double val;
313
314        if(ctx->nimages < 1)
315            return -1;
316        va_start(ap, cmd);
317        arg = va_arg(ap, char const *);
318        va_end(ap);
319        val = atof(arg);
320        src = ctx->images[ctx->nimages - 1];
321        dst = pipi_threshold(src, val);
322        if(dst == NULL)
323            return -1;
324        pipi_free(src);
325        ctx->images[ctx->nimages - 1] = dst;
326    }
327    else if(!strcmp(cmd, "hflip"))
328    {
329        pipi_image_t *tmp;
330        if(ctx->nimages < 1)
331            return -1;
332        tmp = ctx->images[ctx->nimages - 1];
333        ctx->images[ctx->nimages - 1] = pipi_hflip(tmp);
334        pipi_free(tmp);
335    }
336    else if(!strcmp(cmd, "vflip"))
337    {
338        pipi_image_t *tmp;
339        if(ctx->nimages < 1)
340            return -1;
341        tmp = ctx->images[ctx->nimages - 1];
342        ctx->images[ctx->nimages - 1] = pipi_vflip(tmp);
343        pipi_free(tmp);
344    }
345    else if(!strcmp(cmd, "rotate90"))
346    {
347        pipi_image_t *tmp;
348        if(ctx->nimages < 1)
349            return -1;
350        tmp = ctx->images[ctx->nimages - 1];
351        ctx->images[ctx->nimages - 1] = pipi_rotate90(tmp);
352        pipi_free(tmp);
353    }
354    else if(!strcmp(cmd, "rotate180"))
355    {
356        pipi_image_t *tmp;
357        if(ctx->nimages < 1)
358            return -1;
359        tmp = ctx->images[ctx->nimages - 1];
360        ctx->images[ctx->nimages - 1] = pipi_rotate180(tmp);
361        pipi_free(tmp);
362    }
363    else if(!strcmp(cmd, "rotate270"))
364    {
365        pipi_image_t *tmp;
366        if(ctx->nimages < 1)
367            return -1;
368        tmp = ctx->images[ctx->nimages - 1];
369        ctx->images[ctx->nimages - 1] = pipi_rotate270(tmp);
370        pipi_free(tmp);
371    }
372    else if(!strcmp(cmd, "mean"))
373    {
374        pipi_image_t *dst;
375
376        if(ctx->nimages < 2)
377            return -1;
378        dst = pipi_mean(ctx->images[ctx->nimages - 2],
379                        ctx->images[ctx->nimages - 1]);
380        if(dst == NULL)
381            return -1;
382        pipi_free(ctx->images[ctx->nimages - 2]);
383        pipi_free(ctx->images[ctx->nimages - 1]);
384        ctx->images[ctx->nimages - 2] = dst;
385        ctx->nimages--;
386    }
387    else if(!strcmp(cmd, "min"))
388    {
389        pipi_image_t *dst;
390
391        if(ctx->nimages < 2)
392            return -1;
393        dst = pipi_min(ctx->images[ctx->nimages - 2],
394                       ctx->images[ctx->nimages - 1]);
395        if(dst == NULL)
396            return -1;
397        pipi_free(ctx->images[ctx->nimages - 2]);
398        pipi_free(ctx->images[ctx->nimages - 1]);
399        ctx->images[ctx->nimages - 2] = dst;
400        ctx->nimages--;
401    }
402    else if(!strcmp(cmd, "max"))
403    {
404        pipi_image_t *dst;
405
406        if(ctx->nimages < 2)
407            return -1;
408        dst = pipi_max(ctx->images[ctx->nimages - 2],
409                       ctx->images[ctx->nimages - 1]);
410        if(dst == NULL)
411            return -1;
412        pipi_free(ctx->images[ctx->nimages - 2]);
413        pipi_free(ctx->images[ctx->nimages - 1]);
414        ctx->images[ctx->nimages - 2] = dst;
415        ctx->nimages--;
416    }
417    else if(!strcmp(cmd, "add"))
418    {
419        pipi_image_t *dst;
420
421        if(ctx->nimages < 2)
422            return -1;
423        dst = pipi_add(ctx->images[ctx->nimages - 2],
424                       ctx->images[ctx->nimages - 1]);
425        if(dst == NULL)
426            return -1;
427        pipi_free(ctx->images[ctx->nimages - 2]);
428        pipi_free(ctx->images[ctx->nimages - 1]);
429        ctx->images[ctx->nimages - 2] = dst;
430        ctx->nimages--;
431    }
432    else if(!strcmp(cmd, "sub"))
433    {
434        pipi_image_t *dst;
435
436        if(ctx->nimages < 2)
437            return -1;
438        dst = pipi_sub(ctx->images[ctx->nimages - 2],
439                       ctx->images[ctx->nimages - 1]);
440        if(dst == NULL)
441            return -1;
442        pipi_free(ctx->images[ctx->nimages - 2]);
443        pipi_free(ctx->images[ctx->nimages - 1]);
444        ctx->images[ctx->nimages - 2] = dst;
445        ctx->nimages--;
446    }
447    else if(!strcmp(cmd, "difference"))
448    {
449        pipi_image_t *dst;
450
451        if(ctx->nimages < 2)
452            return -1;
453        dst = pipi_difference(ctx->images[ctx->nimages - 2],
454                              ctx->images[ctx->nimages - 1]);
455        if(dst == NULL)
456            return -1;
457        pipi_free(ctx->images[ctx->nimages - 2]);
458        pipi_free(ctx->images[ctx->nimages - 1]);
459        ctx->images[ctx->nimages - 2] = dst;
460        ctx->nimages--;
461    }
462    else if(!strcmp(cmd, "multiply"))
463    {
464        pipi_image_t *dst;
465
466        if(ctx->nimages < 2)
467            return -1;
468        dst = pipi_multiply(ctx->images[ctx->nimages - 2],
469                            ctx->images[ctx->nimages - 1]);
470        if(dst == NULL)
471            return -1;
472        pipi_free(ctx->images[ctx->nimages - 2]);
473        pipi_free(ctx->images[ctx->nimages - 1]);
474        ctx->images[ctx->nimages - 2] = dst;
475        ctx->nimages--;
476    }
477    else if(!strcmp(cmd, "divide"))
478    {
479        pipi_image_t *dst;
480
481        if(ctx->nimages < 2)
482            return -1;
483        dst = pipi_divide(ctx->images[ctx->nimages - 2],
484                          ctx->images[ctx->nimages - 1]);
485        if(dst == NULL)
486            return -1;
487        pipi_free(ctx->images[ctx->nimages - 2]);
488        pipi_free(ctx->images[ctx->nimages - 1]);
489        ctx->images[ctx->nimages - 2] = dst;
490        ctx->nimages--;
491    }
492    else if(!strcmp(cmd, "screen"))
493    {
494        pipi_image_t *dst;
495
496        if(ctx->nimages < 2)
497            return -1;
498        dst = pipi_screen(ctx->images[ctx->nimages - 2],
499                          ctx->images[ctx->nimages - 1]);
500        if(dst == NULL)
501            return -1;
502        pipi_free(ctx->images[ctx->nimages - 2]);
503        pipi_free(ctx->images[ctx->nimages - 1]);
504        ctx->images[ctx->nimages - 2] = dst;
505        ctx->nimages--;
506    }
507    else if(!strcmp(cmd, "overlay"))
508    {
509        pipi_image_t *dst;
510
511        if(ctx->nimages < 2)
512            return -1;
513        dst = pipi_overlay(ctx->images[ctx->nimages - 2],
514                           ctx->images[ctx->nimages - 1]);
515        if(dst == NULL)
516            return -1;
517        pipi_free(ctx->images[ctx->nimages - 2]);
518        pipi_free(ctx->images[ctx->nimages - 1]);
519        ctx->images[ctx->nimages - 2] = dst;
520        ctx->nimages--;
521    }
522    else if(!strcmp(cmd, "wrap"))
523    {
524        if(ctx->nimages < 1)
525            return -1;
526        ctx->images[ctx->nimages - 1]->wrap = 1;
527    }
528    else if(!strcmp(cmd, "autocontrast"))
529    {
530        pipi_image_t *tmp;
531        if(ctx->nimages < 1)
532            return -1;
533        tmp = ctx->images[ctx->nimages - 1];
534        ctx->images[ctx->nimages - 1] = pipi_autocontrast(tmp);
535        pipi_free(tmp);
536    }
537    else if(!strcmp(cmd, "invert"))
538    {
539        pipi_image_t *tmp;
540        if(ctx->nimages < 1)
541            return -1;
542        tmp = ctx->images[ctx->nimages - 1];
543        ctx->images[ctx->nimages - 1] = pipi_invert(tmp);
544        pipi_free(tmp);
545    }
546    else if(!strcmp(cmd, "dilate"))
547    {
548        pipi_image_t *tmp;
549        if(ctx->nimages < 1)
550            return -1;
551        tmp = ctx->images[ctx->nimages - 1];
552        ctx->images[ctx->nimages - 1] = pipi_dilate(tmp);
553        pipi_free(tmp);
554    }
555    else if(!strcmp(cmd, "erode"))
556    {
557        pipi_image_t *tmp;
558        if(ctx->nimages < 1)
559            return -1;
560        tmp = ctx->images[ctx->nimages - 1];
561        ctx->images[ctx->nimages - 1] = pipi_erode(tmp);
562        pipi_free(tmp);
563    }
564    else if(!strcmp(cmd, "gray"))
565    {
566        if(ctx->nimages < 1)
567            return -1;
568        pipi_getpixels(ctx->images[ctx->nimages - 1], PIPI_PIXELS_Y_F);
569    }
570    else if(!strcmp(cmd, "free"))
571    {
572        if(ctx->nimages < 1)
573            return -1;
574        ctx->nimages--;
575        pipi_free(ctx->images[ctx->nimages]);
576    }
577    else if(!strcmp(cmd, "dup"))
578    {
579        if(ctx->nimages < 1)
580            return -1;
581        ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
582        ctx->nimages++;
583    }
584    else if(!strcmp(cmd, "swap"))
585    {
586        pipi_image_t *tmp;
587        if(ctx->nimages < 2)
588            return -1;
589        tmp = ctx->images[ctx->nimages - 1];
590        ctx->images[ctx->nimages - 1] = ctx->images[ctx->nimages - 2];
591        ctx->images[ctx->nimages - 2] = tmp;
592    }
593    else
594    {
595        return -1;
596    }
597
598    return 0;
599}
600
Note: See TracBrowser for help on using the repository browser.