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

Revision 2747, 14.9 KB checked in by sam, 5 years ago (diff)
  • color.c: implement pipi_threshold().
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, "mean"))
328    {
329        pipi_image_t *dst;
330
331        if(ctx->nimages < 2)
332            return -1;
333        dst = pipi_mean(ctx->images[ctx->nimages - 2],
334                        ctx->images[ctx->nimages - 1]);
335        if(dst == NULL)
336            return -1;
337        pipi_free(ctx->images[ctx->nimages - 2]);
338        pipi_free(ctx->images[ctx->nimages - 1]);
339        ctx->images[ctx->nimages - 2] = dst;
340        ctx->nimages--;
341    }
342    else if(!strcmp(cmd, "min"))
343    {
344        pipi_image_t *dst;
345
346        if(ctx->nimages < 2)
347            return -1;
348        dst = pipi_min(ctx->images[ctx->nimages - 2],
349                       ctx->images[ctx->nimages - 1]);
350        if(dst == NULL)
351            return -1;
352        pipi_free(ctx->images[ctx->nimages - 2]);
353        pipi_free(ctx->images[ctx->nimages - 1]);
354        ctx->images[ctx->nimages - 2] = dst;
355        ctx->nimages--;
356    }
357    else if(!strcmp(cmd, "max"))
358    {
359        pipi_image_t *dst;
360
361        if(ctx->nimages < 2)
362            return -1;
363        dst = pipi_max(ctx->images[ctx->nimages - 2],
364                       ctx->images[ctx->nimages - 1]);
365        if(dst == NULL)
366            return -1;
367        pipi_free(ctx->images[ctx->nimages - 2]);
368        pipi_free(ctx->images[ctx->nimages - 1]);
369        ctx->images[ctx->nimages - 2] = dst;
370        ctx->nimages--;
371    }
372    else if(!strcmp(cmd, "add"))
373    {
374        pipi_image_t *dst;
375
376        if(ctx->nimages < 2)
377            return -1;
378        dst = pipi_add(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, "sub"))
388    {
389        pipi_image_t *dst;
390
391        if(ctx->nimages < 2)
392            return -1;
393        dst = pipi_sub(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, "difference"))
403    {
404        pipi_image_t *dst;
405
406        if(ctx->nimages < 2)
407            return -1;
408        dst = pipi_difference(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, "multiply"))
418    {
419        pipi_image_t *dst;
420
421        if(ctx->nimages < 2)
422            return -1;
423        dst = pipi_multiply(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, "divide"))
433    {
434        pipi_image_t *dst;
435
436        if(ctx->nimages < 2)
437            return -1;
438        dst = pipi_divide(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, "screen"))
448    {
449        pipi_image_t *dst;
450
451        if(ctx->nimages < 2)
452            return -1;
453        dst = pipi_screen(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, "overlay"))
463    {
464        pipi_image_t *dst;
465
466        if(ctx->nimages < 2)
467            return -1;
468        dst = pipi_overlay(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, "wrap"))
478    {
479        if(ctx->nimages < 1)
480            return -1;
481        ctx->images[ctx->nimages - 1]->wrap = 1;
482    }
483    else if(!strcmp(cmd, "autocontrast"))
484    {
485        pipi_image_t *tmp;
486        if(ctx->nimages < 1)
487            return -1;
488        tmp = ctx->images[ctx->nimages - 1];
489        ctx->images[ctx->nimages - 1] = pipi_autocontrast(tmp);
490        pipi_free(tmp);
491    }
492    else if(!strcmp(cmd, "invert"))
493    {
494        pipi_image_t *tmp;
495        if(ctx->nimages < 1)
496            return -1;
497        tmp = ctx->images[ctx->nimages - 1];
498        ctx->images[ctx->nimages - 1] = pipi_invert(tmp);
499        pipi_free(tmp);
500    }
501    else if(!strcmp(cmd, "dilate"))
502    {
503        pipi_image_t *tmp;
504        if(ctx->nimages < 1)
505            return -1;
506        tmp = ctx->images[ctx->nimages - 1];
507        ctx->images[ctx->nimages - 1] = pipi_dilate(tmp);
508        pipi_free(tmp);
509    }
510    else if(!strcmp(cmd, "erode"))
511    {
512        pipi_image_t *tmp;
513        if(ctx->nimages < 1)
514            return -1;
515        tmp = ctx->images[ctx->nimages - 1];
516        ctx->images[ctx->nimages - 1] = pipi_erode(tmp);
517        pipi_free(tmp);
518    }
519    else if(!strcmp(cmd, "gray"))
520    {
521        if(ctx->nimages < 1)
522            return -1;
523        pipi_getpixels(ctx->images[ctx->nimages - 1], PIPI_PIXELS_Y_F);
524    }
525    else if(!strcmp(cmd, "free"))
526    {
527        if(ctx->nimages < 1)
528            return -1;
529        ctx->nimages--;
530        pipi_free(ctx->images[ctx->nimages]);
531    }
532    else if(!strcmp(cmd, "dup"))
533    {
534        if(ctx->nimages < 1)
535            return -1;
536        ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
537        ctx->nimages++;
538    }
539    else if(!strcmp(cmd, "swap"))
540    {
541        pipi_image_t *tmp;
542        if(ctx->nimages < 2)
543            return -1;
544        tmp = ctx->images[ctx->nimages - 1];
545        ctx->images[ctx->nimages - 1] = ctx->images[ctx->nimages - 2];
546        ctx->images[ctx->nimages - 2] = tmp;
547    }
548    else
549    {
550        return -1;
551    }
552
553    return 0;
554}
555
Note: See TracBrowser for help on using the repository browser.