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

Last change on this file since 2752 was 2752, checked in by Sam Hocevar, 14 years ago
  • pipi.c: implement --roll, RPL-style.
File size: 16.9 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, "atkinson"))
96            dst = pipi_dither_atkinson(src, 0);
97        else if(!strcmp(method, "satkinson"))
98            dst = pipi_dither_atkinson(src, 1);
99        else if(!strcmp(method, "ost"))
100            dst = pipi_dither_ostromoukhov(src, 0);
101        else if(!strcmp(method, "sost"))
102            dst = pipi_dither_ostromoukhov(src, 1);
103        else if(!strcmp(method, "ordered"))
104        {
105            if(ctx->nimages < 2)
106                return -1;
107            dst = pipi_dither_ordered(ctx->images[ctx->nimages - 2], src);
108            pipi_free(ctx->images[ctx->nimages - 2]);
109            ctx->nimages--;
110        }
111        else if(!strcmp(method, "random"))
112            dst = pipi_dither_random(src);
113        else if(!strcmp(method, "dbs"))
114            dst = pipi_dither_dbs(src);
115        if(dst == NULL)
116            return -1;
117        pipi_free(src);
118        ctx->images[ctx->nimages - 1] = dst;
119    }
120    else if(!strcmp(cmd, "blur"))
121    {
122        pipi_image_t *src, *dst;
123        char const *arg;
124        va_list ap;
125        double w, h, a = 0.0;
126
127        if(ctx->nimages < 1)
128            return -1;
129        va_start(ap, cmd);
130        arg = va_arg(ap, char const *);
131        va_end(ap);
132        w = h = atof(arg);
133        arg = strchr(arg, 'x');
134        if(arg)
135        {
136            h = atof(arg + 1);
137            arg = strchr(arg, 'r');
138            if(arg)
139                a = atof(arg + 1);
140        }
141        src = ctx->images[ctx->nimages - 1];
142        dst = pipi_gaussian_blur_ext(src, w, h, a, 0.0, 0.0);
143        if(dst == NULL)
144            return -1;
145        pipi_free(src);
146        ctx->images[ctx->nimages - 1] = dst;
147    }
148    else if(!strcmp(cmd, "boxblur"))
149    {
150        pipi_image_t *src, *dst;
151        char const *arg;
152        va_list ap;
153        double w, h;
154
155        if(ctx->nimages < 1)
156            return -1;
157        va_start(ap, cmd);
158        arg = va_arg(ap, char const *);
159        va_end(ap);
160        w = h = atof(arg);
161        arg = strchr(arg, 'x');
162        if(arg)
163            h = atof(arg + 1);
164        src = ctx->images[ctx->nimages - 1];
165        dst = pipi_box_blur_ext(src, w, h);
166        if(dst == NULL)
167            return -1;
168        pipi_free(src);
169        ctx->images[ctx->nimages - 1] = dst;
170    }
171    else if(!strcmp(cmd, "median"))
172    {
173        pipi_image_t *src, *dst;
174        char const *arg;
175        va_list ap;
176        double w, h;
177
178        if(ctx->nimages < 1)
179            return -1;
180        va_start(ap, cmd);
181        arg = va_arg(ap, char const *);
182        va_end(ap);
183        w = h = atof(arg);
184        arg = strchr(arg, 'x');
185        if(arg)
186            h = atof(arg + 1);
187        src = ctx->images[ctx->nimages - 1];
188        dst = pipi_median_ext(src, w, h);
189        if(dst == NULL)
190            return -1;
191        pipi_free(src);
192        ctx->images[ctx->nimages - 1] = dst;
193    }
194    else if(!strcmp(cmd, "geometry"))
195    {
196        pipi_image_t *src, *dst;
197        char const *arg;
198        va_list ap;
199        int w, h;
200
201        if(ctx->nimages < 1)
202            return -1;
203        va_start(ap, cmd);
204        arg = va_arg(ap, char const *);
205        va_end(ap);
206        w = atoi(arg);
207        arg = strchr(arg, 'x');
208        if(!arg)
209            return -1;
210        h = atoi(arg + 1);
211        if(w <= 0 || h <= 0)
212            return -1;
213        src = ctx->images[ctx->nimages - 1];
214        dst = pipi_resize(src, w, h);
215        if(dst == NULL)
216            return -1;
217        pipi_free(src);
218        ctx->images[ctx->nimages - 1] = dst;
219    }
220    else if(!strcmp(cmd, "tile"))
221    {
222        pipi_image_t *src, *dst;
223        char const *arg;
224        va_list ap;
225        int w, h;
226
227        if(ctx->nimages < 1)
228            return -1;
229        va_start(ap, cmd);
230        arg = va_arg(ap, char const *);
231        va_end(ap);
232        w = atoi(arg);
233        arg = strchr(arg, 'x');
234        if(!arg)
235            return -1;
236        h = atoi(arg + 1);
237        if(w <= 0 || h <= 0)
238            return -1;
239        src = ctx->images[ctx->nimages - 1];
240        dst = pipi_tile(src, w, h);
241        if(dst == NULL)
242            return -1;
243        pipi_free(src);
244        ctx->images[ctx->nimages - 1] = dst;
245    }
246    else if(!strcmp(cmd, "scale"))
247    {
248        pipi_image_t *src, *dst;
249        char const *arg;
250        va_list ap;
251        double scale;
252        int w, h;
253
254        if(ctx->nimages < 1)
255            return -1;
256        src = ctx->images[ctx->nimages - 1];
257        va_start(ap, cmd);
258        arg = va_arg(ap, char const *);
259        va_end(ap);
260        scale = atof(arg);
261        w = (int)(scale * src->w + 0.5);
262        h = (int)(scale * src->h + 0.5);
263        if(w <= 0 || h <= 0)
264            return -1;
265        dst = pipi_resize(src, w, h);
266        if(dst == NULL)
267            return -1;
268        pipi_free(src);
269        ctx->images[ctx->nimages - 1] = dst;
270    }
271    else if(!strcmp(cmd, "brightness"))
272    {
273        pipi_image_t *src, *dst;
274        char const *arg;
275        va_list ap;
276        double val;
277
278        if(ctx->nimages < 1)
279            return -1;
280        va_start(ap, cmd);
281        arg = va_arg(ap, char const *);
282        va_end(ap);
283        val = atof(arg);
284        src = ctx->images[ctx->nimages - 1];
285        dst = pipi_brightness(src, val);
286        if(dst == NULL)
287            return -1;
288        pipi_free(src);
289        ctx->images[ctx->nimages - 1] = dst;
290    }
291    else if(!strcmp(cmd, "contrast"))
292    {
293        pipi_image_t *src, *dst;
294        char const *arg;
295        va_list ap;
296        double val;
297
298        if(ctx->nimages < 1)
299            return -1;
300        va_start(ap, cmd);
301        arg = va_arg(ap, char const *);
302        va_end(ap);
303        val = atof(arg);
304        src = ctx->images[ctx->nimages - 1];
305        dst = pipi_contrast(src, val);
306        if(dst == NULL)
307            return -1;
308        pipi_free(src);
309        ctx->images[ctx->nimages - 1] = dst;
310    }
311    else if(!strcmp(cmd, "threshold"))
312    {
313        pipi_image_t *src, *dst;
314        char const *arg;
315        va_list ap;
316        double val;
317
318        if(ctx->nimages < 1)
319            return -1;
320        va_start(ap, cmd);
321        arg = va_arg(ap, char const *);
322        va_end(ap);
323        val = atof(arg);
324        src = ctx->images[ctx->nimages - 1];
325        dst = pipi_threshold(src, val);
326        if(dst == NULL)
327            return -1;
328        pipi_free(src);
329        ctx->images[ctx->nimages - 1] = dst;
330    }
331    else if(!strcmp(cmd, "hflip"))
332    {
333        pipi_image_t *tmp;
334        if(ctx->nimages < 1)
335            return -1;
336        tmp = ctx->images[ctx->nimages - 1];
337        ctx->images[ctx->nimages - 1] = pipi_hflip(tmp);
338        pipi_free(tmp);
339    }
340    else if(!strcmp(cmd, "vflip"))
341    {
342        pipi_image_t *tmp;
343        if(ctx->nimages < 1)
344            return -1;
345        tmp = ctx->images[ctx->nimages - 1];
346        ctx->images[ctx->nimages - 1] = pipi_vflip(tmp);
347        pipi_free(tmp);
348    }
349    else if(!strcmp(cmd, "rotate90"))
350    {
351        pipi_image_t *tmp;
352        if(ctx->nimages < 1)
353            return -1;
354        tmp = ctx->images[ctx->nimages - 1];
355        ctx->images[ctx->nimages - 1] = pipi_rotate90(tmp);
356        pipi_free(tmp);
357    }
358    else if(!strcmp(cmd, "rotate180"))
359    {
360        pipi_image_t *tmp;
361        if(ctx->nimages < 1)
362            return -1;
363        tmp = ctx->images[ctx->nimages - 1];
364        ctx->images[ctx->nimages - 1] = pipi_rotate180(tmp);
365        pipi_free(tmp);
366    }
367    else if(!strcmp(cmd, "rotate270"))
368    {
369        pipi_image_t *tmp;
370        if(ctx->nimages < 1)
371            return -1;
372        tmp = ctx->images[ctx->nimages - 1];
373        ctx->images[ctx->nimages - 1] = pipi_rotate270(tmp);
374        pipi_free(tmp);
375    }
376    else if(!strcmp(cmd, "mean"))
377    {
378        pipi_image_t *dst;
379
380        if(ctx->nimages < 2)
381            return -1;
382        dst = pipi_mean(ctx->images[ctx->nimages - 2],
383                        ctx->images[ctx->nimages - 1]);
384        if(dst == NULL)
385            return -1;
386        pipi_free(ctx->images[ctx->nimages - 2]);
387        pipi_free(ctx->images[ctx->nimages - 1]);
388        ctx->images[ctx->nimages - 2] = dst;
389        ctx->nimages--;
390    }
391    else if(!strcmp(cmd, "min"))
392    {
393        pipi_image_t *dst;
394
395        if(ctx->nimages < 2)
396            return -1;
397        dst = pipi_min(ctx->images[ctx->nimages - 2],
398                       ctx->images[ctx->nimages - 1]);
399        if(dst == NULL)
400            return -1;
401        pipi_free(ctx->images[ctx->nimages - 2]);
402        pipi_free(ctx->images[ctx->nimages - 1]);
403        ctx->images[ctx->nimages - 2] = dst;
404        ctx->nimages--;
405    }
406    else if(!strcmp(cmd, "max"))
407    {
408        pipi_image_t *dst;
409
410        if(ctx->nimages < 2)
411            return -1;
412        dst = pipi_max(ctx->images[ctx->nimages - 2],
413                       ctx->images[ctx->nimages - 1]);
414        if(dst == NULL)
415            return -1;
416        pipi_free(ctx->images[ctx->nimages - 2]);
417        pipi_free(ctx->images[ctx->nimages - 1]);
418        ctx->images[ctx->nimages - 2] = dst;
419        ctx->nimages--;
420    }
421    else if(!strcmp(cmd, "add"))
422    {
423        pipi_image_t *dst;
424
425        if(ctx->nimages < 2)
426            return -1;
427        dst = pipi_add(ctx->images[ctx->nimages - 2],
428                       ctx->images[ctx->nimages - 1]);
429        if(dst == NULL)
430            return -1;
431        pipi_free(ctx->images[ctx->nimages - 2]);
432        pipi_free(ctx->images[ctx->nimages - 1]);
433        ctx->images[ctx->nimages - 2] = dst;
434        ctx->nimages--;
435    }
436    else if(!strcmp(cmd, "sub"))
437    {
438        pipi_image_t *dst;
439
440        if(ctx->nimages < 2)
441            return -1;
442        dst = pipi_sub(ctx->images[ctx->nimages - 2],
443                       ctx->images[ctx->nimages - 1]);
444        if(dst == NULL)
445            return -1;
446        pipi_free(ctx->images[ctx->nimages - 2]);
447        pipi_free(ctx->images[ctx->nimages - 1]);
448        ctx->images[ctx->nimages - 2] = dst;
449        ctx->nimages--;
450    }
451    else if(!strcmp(cmd, "difference"))
452    {
453        pipi_image_t *dst;
454
455        if(ctx->nimages < 2)
456            return -1;
457        dst = pipi_difference(ctx->images[ctx->nimages - 2],
458                              ctx->images[ctx->nimages - 1]);
459        if(dst == NULL)
460            return -1;
461        pipi_free(ctx->images[ctx->nimages - 2]);
462        pipi_free(ctx->images[ctx->nimages - 1]);
463        ctx->images[ctx->nimages - 2] = dst;
464        ctx->nimages--;
465    }
466    else if(!strcmp(cmd, "multiply"))
467    {
468        pipi_image_t *dst;
469
470        if(ctx->nimages < 2)
471            return -1;
472        dst = pipi_multiply(ctx->images[ctx->nimages - 2],
473                            ctx->images[ctx->nimages - 1]);
474        if(dst == NULL)
475            return -1;
476        pipi_free(ctx->images[ctx->nimages - 2]);
477        pipi_free(ctx->images[ctx->nimages - 1]);
478        ctx->images[ctx->nimages - 2] = dst;
479        ctx->nimages--;
480    }
481    else if(!strcmp(cmd, "divide"))
482    {
483        pipi_image_t *dst;
484
485        if(ctx->nimages < 2)
486            return -1;
487        dst = pipi_divide(ctx->images[ctx->nimages - 2],
488                          ctx->images[ctx->nimages - 1]);
489        if(dst == NULL)
490            return -1;
491        pipi_free(ctx->images[ctx->nimages - 2]);
492        pipi_free(ctx->images[ctx->nimages - 1]);
493        ctx->images[ctx->nimages - 2] = dst;
494        ctx->nimages--;
495    }
496    else if(!strcmp(cmd, "screen"))
497    {
498        pipi_image_t *dst;
499
500        if(ctx->nimages < 2)
501            return -1;
502        dst = pipi_screen(ctx->images[ctx->nimages - 2],
503                          ctx->images[ctx->nimages - 1]);
504        if(dst == NULL)
505            return -1;
506        pipi_free(ctx->images[ctx->nimages - 2]);
507        pipi_free(ctx->images[ctx->nimages - 1]);
508        ctx->images[ctx->nimages - 2] = dst;
509        ctx->nimages--;
510    }
511    else if(!strcmp(cmd, "overlay"))
512    {
513        pipi_image_t *dst;
514
515        if(ctx->nimages < 2)
516            return -1;
517        dst = pipi_overlay(ctx->images[ctx->nimages - 2],
518                           ctx->images[ctx->nimages - 1]);
519        if(dst == NULL)
520            return -1;
521        pipi_free(ctx->images[ctx->nimages - 2]);
522        pipi_free(ctx->images[ctx->nimages - 1]);
523        ctx->images[ctx->nimages - 2] = dst;
524        ctx->nimages--;
525    }
526    else if(!strcmp(cmd, "wrap"))
527    {
528        if(ctx->nimages < 1)
529            return -1;
530        ctx->images[ctx->nimages - 1]->wrap = 1;
531    }
532    else if(!strcmp(cmd, "autocontrast"))
533    {
534        pipi_image_t *tmp;
535        if(ctx->nimages < 1)
536            return -1;
537        tmp = ctx->images[ctx->nimages - 1];
538        ctx->images[ctx->nimages - 1] = pipi_autocontrast(tmp);
539        pipi_free(tmp);
540    }
541    else if(!strcmp(cmd, "invert"))
542    {
543        pipi_image_t *tmp;
544        if(ctx->nimages < 1)
545            return -1;
546        tmp = ctx->images[ctx->nimages - 1];
547        ctx->images[ctx->nimages - 1] = pipi_invert(tmp);
548        pipi_free(tmp);
549    }
550    else if(!strcmp(cmd, "dilate"))
551    {
552        pipi_image_t *tmp;
553        if(ctx->nimages < 1)
554            return -1;
555        tmp = ctx->images[ctx->nimages - 1];
556        ctx->images[ctx->nimages - 1] = pipi_dilate(tmp);
557        pipi_free(tmp);
558    }
559    else if(!strcmp(cmd, "erode"))
560    {
561        pipi_image_t *tmp;
562        if(ctx->nimages < 1)
563            return -1;
564        tmp = ctx->images[ctx->nimages - 1];
565        ctx->images[ctx->nimages - 1] = pipi_erode(tmp);
566        pipi_free(tmp);
567    }
568    else if(!strcmp(cmd, "gray"))
569    {
570        if(ctx->nimages < 1)
571            return -1;
572        pipi_getpixels(ctx->images[ctx->nimages - 1], PIPI_PIXELS_Y_F);
573    }
574    else if(!strcmp(cmd, "free"))
575    {
576        if(ctx->nimages < 1)
577            return -1;
578        ctx->nimages--;
579        pipi_free(ctx->images[ctx->nimages]);
580    }
581    else if(!strcmp(cmd, "dup"))
582    {
583        if(ctx->nimages < 1)
584            return -1;
585        ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
586        ctx->nimages++;
587    }
588    else if(!strcmp(cmd, "swap"))
589    {
590        pipi_image_t *tmp;
591        if(ctx->nimages < 2)
592            return -1;
593        tmp = ctx->images[ctx->nimages - 1];
594        ctx->images[ctx->nimages - 1] = ctx->images[ctx->nimages - 2];
595        ctx->images[ctx->nimages - 2] = tmp;
596    }
597    else if(!strcmp(cmd, "roll"))
598    {
599        pipi_image_t *tmp;
600        char const *arg;
601        va_list ap;
602        int val;
603
604        va_start(ap, cmd);
605        arg = va_arg(ap, char const *);
606        va_end(ap);
607        val = atoi(arg);
608        if(val <= 0 || ctx->nimages < val)
609            return -1;
610        if(val == 1)
611            return 0;
612        tmp = ctx->images[ctx->nimages - val];
613        memmove(ctx->images + ctx->nimages - val,
614                ctx->images + ctx->nimages - val + 1,
615                (val - 1) * sizeof(*ctx->images));
616        ctx->images[ctx->nimages - 1] = tmp;
617    }
618    else
619    {
620        return -1;
621    }
622
623    return 0;
624}
625
Note: See TracBrowser for help on using the repository browser.