source: libpipi/trunk/pipi/context.c

Last change on this file was 4697, checked in by sam, 4 years ago

Add functions to convert from RGB to YUV and back.

File size: 20.5 KB
Line 
1/*
2 *  libpipi       Pathetic image processing interface 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
21#include <stdio.h>
22#include <stdlib.h>
23#include <stdarg.h>
24#include <string.h>
25
26#include "pipi.h"
27#include "pipi_internals.h"
28
29pipi_context_t *pipi_create_context()
30{
31    pipi_context_t *ret;
32
33    ret = malloc(sizeof(pipi_context_t));
34    memset(ret, 0, sizeof(pipi_context_t));
35
36    return ret;
37}
38
39void pipi_destroy_context(pipi_context_t *ctx)
40{
41    free(ctx);
42}
43
44pipi_command_t const *pipi_get_command_list(void)
45{
46    static pipi_command_t const list[] =
47    {
48        { "load", 1 },
49        { "save", 1 },
50
51        { "dup", 0 },
52        { "swap", 0 },
53        { "roll", 1 },
54
55        { "gamma", 1 },
56        { "scale", 1 },
57        { "crop", 1 },
58        { "geometry", 1 },
59        { "tile", 1 },
60        { "dither", 1 },
61        { "blur", 1 },
62        { "boxblur", 1 },
63        { "median", 1 },
64        { "gray", 0 },
65        { "brightness", 1 },
66        { "contrast", 1 },
67        { "autocontrast", 0 },
68        { "order", 0 },
69        { "hflip", 0 },
70        { "vflip", 0 },
71        { "rotate90", 0 },
72        { "rotate180", 0 },
73        { "rotate270", 0 },
74        { "rotate", 1 },
75        { "invert", 0 },
76        { "threshold", 1 },
77        { "dilate", 0 },
78        { "erode", 0 },
79        { "wrap", 0 },
80        { "combine", 0 },
81        { "split", 0 },
82        { "blit", 1 },
83        { "mean", 0 },
84        { "merge", 1 },
85        { "min", 0 },
86        { "max", 0 },
87        { "add", 0 },
88        { "sub", 0 },
89        { "difference", 0 },
90        { "multiply", 0 },
91        { "divide", 0 },
92        { "screen", 0 },
93        { "overlay", 0 },
94        { "line", 1 },
95        { "sine", 1 },
96        { "wave", 1 },
97        { "rgb2yuv", 0 },
98        { "yuv2rgb", 0 },
99
100        /* End marker */
101        { NULL, 0 }
102    };
103
104    return list;
105}
106
107int pipi_command(pipi_context_t *ctx, char const *cmd, ...)
108{
109    if(!strcmp(cmd, "load"))
110    {
111        char const *file;
112        va_list ap;
113
114        va_start(ap, cmd);
115        file = va_arg(ap, char const *);
116        va_end(ap);
117        ctx->images[ctx->nimages] = pipi_load(file);
118        if(ctx->images[ctx->nimages] == NULL)
119            return -1;
120        ctx->nimages++;
121    }
122    else if(!strcmp(cmd, "save"))
123    {
124        char const *file;
125        va_list ap;
126
127        if(ctx->nimages < 1)
128            return -1;
129        ctx->nimages--;
130        va_start(ap, cmd);
131        file = va_arg(ap, char const *);
132        va_end(ap);
133        pipi_save(ctx->images[ctx->nimages], file);
134        pipi_free(ctx->images[ctx->nimages]);
135    }
136    else if(!strcmp(cmd, "gamma"))
137    {
138        char const *val;
139        va_list ap;
140
141        va_start(ap, cmd);
142        val = va_arg(ap, char const *);
143        va_end(ap);
144
145        pipi_set_gamma(atof(val));
146    }
147    else if(!strcmp(cmd, "dither"))
148    {
149        pipi_image_t *src, *dst;
150        char const *method;
151        va_list ap;
152
153        if(ctx->nimages < 1)
154            return -1;
155        va_start(ap, cmd);
156        method = va_arg(ap, char const *);
157        va_end(ap);
158        src = ctx->images[ctx->nimages - 1];
159        dst = NULL;
160        if(!strcmp(method, "ost"))
161            dst = pipi_dither_ostromoukhov(src, 0);
162        else if(!strcmp(method, "sost"))
163            dst = pipi_dither_ostromoukhov(src, 1);
164        else if(!strcmp(method, "ediff"))
165        {
166            if(ctx->nimages < 2)
167                return -1;
168            dst = pipi_dither_ediff(ctx->images[ctx->nimages - 2], src, 0);
169            pipi_free(ctx->images[ctx->nimages - 2]);
170            ctx->nimages--;
171        }
172        else if(!strcmp(method, "sediff"))
173        {
174            if(ctx->nimages < 2)
175                return -1;
176            dst = pipi_dither_ediff(ctx->images[ctx->nimages - 2], src, 1);
177            pipi_free(ctx->images[ctx->nimages - 2]);
178            ctx->nimages--;
179        }
180        else if(!strncmp(method, "ordered", 7))
181        {
182            double scale = 1., angle = .0;
183            if(ctx->nimages < 2)
184                return -1;
185            method = strchr(method, ':');
186            if(method)
187            {
188                scale = atof(method + 1);
189                method = strchr(method + 1, ':');
190                if(method)
191                    angle = atof(method + 1);
192            }
193            if(scale <= 0.)
194                scale = 1.;
195            dst = pipi_dither_ordered_ext(ctx->images[ctx->nimages - 2], src,
196                                          scale, angle);
197            pipi_free(ctx->images[ctx->nimages - 2]);
198            ctx->nimages--;
199        }
200        else if(!strncmp(method, "halftone", 8))
201        {
202            double r, angle = .0;
203            method = strchr(method, ':');
204            if(!method)
205                return -1;
206            r = atof(method + 1);
207            method = strchr(method + 1, ':');
208            if(method)
209                angle = atof(method + 1);
210            if(r < 1.)
211                r = 1.;
212            dst = pipi_dither_halftone(src, r, angle);
213        }
214        else if(!strcmp(method, "random"))
215            dst = pipi_dither_random(src);
216        else if(!strcmp(method, "dbs"))
217            dst = pipi_dither_dbs(src);
218        if(dst == NULL)
219            return -1;
220        pipi_free(src);
221        ctx->images[ctx->nimages - 1] = dst;
222    }
223    else if(!strcmp(cmd, "blur"))
224    {
225        pipi_image_t *src, *dst;
226        char const *arg;
227        va_list ap;
228        double w, h, a = 0.0;
229
230        if(ctx->nimages < 1)
231            return -1;
232        va_start(ap, cmd);
233        arg = va_arg(ap, char const *);
234        va_end(ap);
235        w = h = atof(arg);
236        arg = strchr(arg, 'x');
237        if(arg)
238        {
239            h = atof(arg + 1);
240            arg = strchr(arg, 'r');
241            if(arg)
242                a = atof(arg + 1);
243        }
244        src = ctx->images[ctx->nimages - 1];
245        dst = pipi_gaussian_blur_ext(src, w, h, a, 0.0, 0.0);
246        if(dst == NULL)
247            return -1;
248        pipi_free(src);
249        ctx->images[ctx->nimages - 1] = dst;
250    }
251    else if(!strcmp(cmd, "boxblur") || !strcmp(cmd, "median"))
252    {
253        pipi_image_t *src, *dst = NULL;
254        char const *arg;
255        va_list ap;
256        double w, h;
257
258        if(ctx->nimages < 1)
259            return -1;
260        va_start(ap, cmd);
261        arg = va_arg(ap, char const *);
262        va_end(ap);
263        w = h = atof(arg);
264        arg = strchr(arg, 'x');
265        if(arg)
266            h = atof(arg + 1);
267        src = ctx->images[ctx->nimages - 1];
268        switch(cmd[0])
269        {
270            case 'b': dst = pipi_box_blur_ext(src, w, h); break;
271            case 'm': dst = pipi_median_ext(src, w, h); break;
272        }
273        if(dst == NULL)
274            return -1;
275        pipi_free(src);
276        ctx->images[ctx->nimages - 1] = dst;
277    }
278    else if(!strcmp(cmd, "geometry") || !strcmp(cmd, "tile"))
279    {
280        pipi_image_t *src, *dst = NULL;
281        char const *arg;
282        va_list ap;
283        int w, h;
284
285        if(ctx->nimages < 1)
286            return -1;
287        va_start(ap, cmd);
288        arg = va_arg(ap, char const *);
289        va_end(ap);
290        w = atoi(arg);
291        arg = strchr(arg, 'x');
292        if(!arg)
293            return -1;
294        h = atoi(arg + 1);
295        if(w <= 0 || h <= 0)
296            return -1;
297        src = ctx->images[ctx->nimages - 1];
298        switch(cmd[0])
299        {
300            case 'g': dst = pipi_resize_bicubic(src, w, h); break;
301            case 't': dst = pipi_tile(src, w, h); break;
302        }
303        if(dst == NULL)
304            return -1;
305        pipi_free(src);
306        ctx->images[ctx->nimages - 1] = dst;
307    }
308    else if(!strcmp(cmd, "scale"))
309    {
310        pipi_image_t *src, *dst;
311        char const *arg;
312        va_list ap;
313        double scale;
314        int w, h;
315
316        if(ctx->nimages < 1)
317            return -1;
318        src = ctx->images[ctx->nimages - 1];
319        va_start(ap, cmd);
320        arg = va_arg(ap, char const *);
321        va_end(ap);
322        scale = atof(arg);
323        w = (int)(scale * src->w + 0.5);
324        h = (int)(scale * src->h + 0.5);
325        if(w <= 0 || h <= 0)
326            return -1;
327        dst = pipi_resize_bicubic(src, w, h);
328        if(dst == NULL)
329            return -1;
330        pipi_free(src);
331        ctx->images[ctx->nimages - 1] = dst;
332    }
333    else if(!strcmp(cmd, "crop"))
334    {
335        pipi_image_t *tmp;
336        char const *arg;
337        va_list ap;
338        int w, h, x = 0, y = 0;
339        int ret;
340
341        if(ctx->nimages < 1)
342            return -1;
343
344        va_start(ap, cmd);
345        arg = va_arg(ap, char const *);
346        va_end(ap);
347
348        ret = sscanf(arg, "%dx%d+%d+%d", &w, &h, &x, &y);
349        if(ret < 2)
350            return -1;
351
352        tmp = ctx->images[ctx->nimages - 1];
353        ctx->images[ctx->nimages - 1] = pipi_crop(tmp, w, h, x, y);
354        pipi_free(tmp);
355    }
356    else if(!strcmp(cmd, "brightness") || !strcmp(cmd, "contrast")
357             || !strcmp(cmd, "threshold") || !strcmp(cmd, "rotate"))
358    {
359        pipi_image_t *src, *dst = NULL;
360        char const *arg;
361        va_list ap;
362        double val;
363
364        if(ctx->nimages < 1)
365            return -1;
366        va_start(ap, cmd);
367        arg = va_arg(ap, char const *);
368        va_end(ap);
369        val = atof(arg);
370        src = ctx->images[ctx->nimages - 1];
371        switch(cmd[0])
372        {
373            case 'b': dst = pipi_brightness(src, val); break;
374            case 'c': dst = pipi_contrast(src, val); break;
375            case 'r': dst = pipi_rotate(src, val); break;
376            case 't': dst = pipi_threshold(src, val); break;
377        }
378        if(dst == NULL)
379            return -1;
380        pipi_free(src);
381        ctx->images[ctx->nimages - 1] = dst;
382    }
383    else if(!strcmp(cmd, "hflip"))
384    {
385        pipi_image_t *tmp;
386        if(ctx->nimages < 1)
387            return -1;
388        tmp = ctx->images[ctx->nimages - 1];
389        ctx->images[ctx->nimages - 1] = pipi_hflip(tmp);
390        pipi_free(tmp);
391    }
392    else if(!strcmp(cmd, "vflip"))
393    {
394        pipi_image_t *tmp;
395        if(ctx->nimages < 1)
396            return -1;
397        tmp = ctx->images[ctx->nimages - 1];
398        ctx->images[ctx->nimages - 1] = pipi_vflip(tmp);
399        pipi_free(tmp);
400    }
401    else if(!strcmp(cmd, "rotate90"))
402    {
403        pipi_image_t *tmp;
404        if(ctx->nimages < 1)
405            return -1;
406        tmp = ctx->images[ctx->nimages - 1];
407        ctx->images[ctx->nimages - 1] = pipi_rotate90(tmp);
408        pipi_free(tmp);
409    }
410    else if(!strcmp(cmd, "rotate180"))
411    {
412        pipi_image_t *tmp;
413        if(ctx->nimages < 1)
414            return -1;
415        tmp = ctx->images[ctx->nimages - 1];
416        ctx->images[ctx->nimages - 1] = pipi_rotate180(tmp);
417        pipi_free(tmp);
418    }
419    else if(!strcmp(cmd, "rotate270"))
420    {
421        pipi_image_t *tmp;
422        if(ctx->nimages < 1)
423            return -1;
424        tmp = ctx->images[ctx->nimages - 1];
425        ctx->images[ctx->nimages - 1] = pipi_rotate270(tmp);
426        pipi_free(tmp);
427    }
428    else if(!strcmp(cmd, "order"))
429    {
430        pipi_image_t *tmp;
431        if(ctx->nimages < 1)
432            return -1;
433        tmp = ctx->images[ctx->nimages - 1];
434        ctx->images[ctx->nimages - 1] = pipi_order(tmp);
435        pipi_free(tmp);
436    }
437    else if(!strcmp(cmd, "split"))
438    {
439        pipi_image_t *src;
440
441        if(ctx->nimages < 1)
442            return -1;
443        src = ctx->images[ctx->nimages - 1];
444        ctx->nimages += 2;
445        ctx->images[ctx->nimages - 3] = pipi_red(src);
446        ctx->images[ctx->nimages - 2] = pipi_green(src);
447        ctx->images[ctx->nimages - 1] = pipi_blue(src);
448        pipi_free(src);
449    }
450    else if(!strcmp(cmd, "combine"))
451    {
452        pipi_image_t *dst;
453
454        if(ctx->nimages < 3)
455            return -1;
456        dst = pipi_rgb(ctx->images[ctx->nimages - 3],
457                       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 - 3]);
462        pipi_free(ctx->images[ctx->nimages - 2]);
463        pipi_free(ctx->images[ctx->nimages - 1]);
464        ctx->images[ctx->nimages - 3] = dst;
465        ctx->nimages -= 2;
466    }
467    else if(!strcmp(cmd, "blit"))
468    {
469        pipi_image_t *dst;
470        char const *arg;
471        va_list ap;
472        int x, y;
473
474        if(ctx->nimages < 2)
475            return -1;
476        va_start(ap, cmd);
477        arg = va_arg(ap, char const *);
478        va_end(ap);
479        x = atoi(arg);
480        arg = strchr(arg, 'x');
481        if(!arg)
482            return -1;
483        y = atoi(arg + 1);
484
485        dst = pipi_blit(ctx->images[ctx->nimages - 2],
486                        ctx->images[ctx->nimages - 1], x, y);
487        if(dst == NULL)
488            return -1;
489        pipi_free(ctx->images[ctx->nimages - 2]);
490        pipi_free(ctx->images[ctx->nimages - 1]);
491        ctx->images[ctx->nimages - 2] = dst;
492        ctx->nimages--;
493    }
494    else if(!strcmp(cmd, "merge"))
495    {
496        pipi_image_t *dst;
497        char const *arg;
498        va_list ap;
499        double val;
500
501        if(ctx->nimages < 2)
502            return -1;
503
504        va_start(ap, cmd);
505        arg = va_arg(ap, char const *);
506        va_end(ap);
507        val = atof(arg);
508
509        dst = pipi_merge(ctx->images[ctx->nimages - 2],
510                         ctx->images[ctx->nimages - 1], val);
511        if(dst == NULL)
512            return -1;
513        pipi_free(ctx->images[ctx->nimages - 2]);
514        pipi_free(ctx->images[ctx->nimages - 1]);
515        ctx->images[ctx->nimages - 2] = dst;
516        ctx->nimages--;
517    }
518    else if(!strcmp(cmd, "mean") || !strcmp(cmd, "min") || !strcmp(cmd, "max")
519             || !strcmp(cmd, "add") || !strcmp(cmd, "sub")
520             || !strcmp(cmd, "difference") || !strcmp(cmd, "multiply")
521             || !strcmp(cmd, "divide") || !strcmp(cmd, "screen")
522             || !strcmp(cmd, "overlay"))
523    {
524        pipi_image_t *dst = NULL;
525
526        if(ctx->nimages < 2)
527            return -1;
528        switch(cmd[2])
529        {
530            case 'a': dst = pipi_mean(ctx->images[ctx->nimages - 2],
531                                      ctx->images[ctx->nimages - 1]);
532                      break;
533            case 'n': dst = pipi_min(ctx->images[ctx->nimages - 2],
534                                     ctx->images[ctx->nimages - 1]);
535                      break;
536            case 'x': dst = pipi_max(ctx->images[ctx->nimages - 2],
537                                     ctx->images[ctx->nimages - 1]);
538                      break;
539            case 'd': dst = pipi_add(ctx->images[ctx->nimages - 2],
540                                     ctx->images[ctx->nimages - 1]);
541                      break;
542            case 'b': dst = pipi_sub(ctx->images[ctx->nimages - 2],
543                                     ctx->images[ctx->nimages - 1]);
544                      break;
545            case 'f': dst = pipi_difference(ctx->images[ctx->nimages - 2],
546                                            ctx->images[ctx->nimages - 1]);
547                      break;
548            case 'l': dst = pipi_multiply(ctx->images[ctx->nimages - 2],
549                                          ctx->images[ctx->nimages - 1]);
550                      break;
551            case 'v': dst = pipi_divide(ctx->images[ctx->nimages - 2],
552                                        ctx->images[ctx->nimages - 1]);
553                      break;
554            case 'r': dst = pipi_screen(ctx->images[ctx->nimages - 2],
555                                        ctx->images[ctx->nimages - 1]);
556                      break;
557            case 'e': dst = pipi_overlay(ctx->images[ctx->nimages - 2],
558                                         ctx->images[ctx->nimages - 1]);
559                      break;
560        }
561        if(dst == NULL)
562            return -1;
563        pipi_free(ctx->images[ctx->nimages - 2]);
564        pipi_free(ctx->images[ctx->nimages - 1]);
565        ctx->images[ctx->nimages - 2] = dst;
566        ctx->nimages--;
567    }
568    else if(!strcmp(cmd, "wrap"))
569    {
570        if(ctx->nimages < 1)
571            return -1;
572        ctx->images[ctx->nimages - 1]->wrap = 1;
573    }
574    else if(!strcmp(cmd, "autocontrast"))
575    {
576        pipi_image_t *tmp;
577        if(ctx->nimages < 1)
578            return -1;
579        tmp = ctx->images[ctx->nimages - 1];
580        ctx->images[ctx->nimages - 1] = pipi_autocontrast(tmp);
581        pipi_free(tmp);
582    }
583    else if(!strcmp(cmd, "invert"))
584    {
585        pipi_image_t *tmp;
586        if(ctx->nimages < 1)
587            return -1;
588        tmp = ctx->images[ctx->nimages - 1];
589        ctx->images[ctx->nimages - 1] = pipi_invert(tmp);
590        pipi_free(tmp);
591    }
592    else if(!strcmp(cmd, "dilate"))
593    {
594        pipi_image_t *tmp;
595        if(ctx->nimages < 1)
596            return -1;
597        tmp = ctx->images[ctx->nimages - 1];
598        ctx->images[ctx->nimages - 1] = pipi_dilate(tmp);
599        pipi_free(tmp);
600    }
601    else if(!strcmp(cmd, "erode"))
602    {
603        pipi_image_t *tmp;
604        if(ctx->nimages < 1)
605            return -1;
606        tmp = ctx->images[ctx->nimages - 1];
607        ctx->images[ctx->nimages - 1] = pipi_erode(tmp);
608        pipi_free(tmp);
609    }
610    else if(!strcmp(cmd, "gray"))
611    {
612        if(ctx->nimages < 1)
613            return -1;
614        pipi_get_pixels(ctx->images[ctx->nimages - 1], PIPI_PIXELS_Y_F32);
615    }
616    else if(!strcmp(cmd, "free"))
617    {
618        if(ctx->nimages < 1)
619            return -1;
620        ctx->nimages--;
621        pipi_free(ctx->images[ctx->nimages]);
622    }
623    else if(!strcmp(cmd, "dup"))
624    {
625        if(ctx->nimages < 1)
626            return -1;
627        ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
628        ctx->nimages++;
629    }
630    else if(!strcmp(cmd, "swap"))
631    {
632        pipi_image_t *tmp;
633        if(ctx->nimages < 2)
634            return -1;
635        tmp = ctx->images[ctx->nimages - 1];
636        ctx->images[ctx->nimages - 1] = ctx->images[ctx->nimages - 2];
637        ctx->images[ctx->nimages - 2] = tmp;
638    }
639    else if(!strcmp(cmd, "roll"))
640    {
641        pipi_image_t *tmp;
642        char const *arg;
643        va_list ap;
644        int val;
645
646        va_start(ap, cmd);
647        arg = va_arg(ap, char const *);
648        va_end(ap);
649        val = atoi(arg);
650        if(val <= 0 || ctx->nimages < val)
651            return -1;
652        if(val == 1)
653            return 0;
654        tmp = ctx->images[ctx->nimages - val];
655        memmove(ctx->images + ctx->nimages - val,
656                ctx->images + ctx->nimages - val + 1,
657                (val - 1) * sizeof(*ctx->images));
658        ctx->images[ctx->nimages - 1] = tmp;
659    }
660    else if(!strcmp(cmd, "line"))
661    {
662        char const *arg;
663        va_list ap;
664        int x1, y1, x2, y2, aa = 0, ret;
665        uint32_t color = 0;
666
667        if(ctx->nimages < 1)
668            return -1;
669
670        va_start(ap, cmd);
671        arg = va_arg(ap, char const *);
672        va_end(ap);
673
674        ret = sscanf(arg, "%d,%d,%d,%d,%08x,%d",
675               &x1, &y1, &x2, &y2, &color, &aa);
676        if(ret < 5) return -1;
677
678        ctx->images[ctx->nimages] = pipi_copy(ctx->images[ctx->nimages - 1]);
679        pipi_draw_line(ctx->images[ctx->nimages],
680                       x1,  y1,  x2,  y2, color, aa);
681        ctx->nimages++;
682    }
683    else if(!strcmp(cmd, "sine") || !strcmp(cmd, "wave"))
684    {
685        pipi_image_t *src, *dst = NULL;
686        char const *arg;
687        va_list ap;
688        float dw, dh, d = 0.0, a = 0.0;
689        int ret;
690
691        if(ctx->nimages < 1)
692            return -1;
693
694        va_start(ap, cmd);
695        arg = va_arg(ap, char const *);
696        va_end(ap);
697
698        ret = sscanf(arg, "%gx%g+%gr%g", &dw, &dh, &d, &a);
699        if(ret < 2)
700            return -1;
701
702        src = ctx->images[ctx->nimages - 1];
703        switch(cmd[0])
704        {
705            case 's': dst = pipi_sine(src, dw, dh, d, a); break;
706            case 'w': dst = pipi_wave(src, dw, dh, d, a); break;
707        }
708        if(dst == NULL)
709            return -1;
710        pipi_free(src);
711        ctx->images[ctx->nimages - 1] = dst;
712    }
713    else if(!strcmp(cmd, "rgb2yuv") || !strcmp(cmd, "yuv2rgb"))
714    {
715        pipi_image_t *src, *dst = NULL;
716        if(ctx->nimages < 1)
717            return -1;
718        src = ctx->images[ctx->nimages - 1];
719        switch (cmd[0])
720        {
721            case 'r': dst = pipi_rgb2yuv(src); break;
722            case 'y': dst = pipi_yuv2rgb(src); break;
723        }
724        if(dst == NULL)
725            return -1;
726        pipi_free(src);
727        ctx->images[ctx->nimages - 1] = dst;
728    }
729    else
730    {
731        return -1;
732    }
733
734    return 0;
735}
736
Note: See TracBrowser for help on using the repository browser.