source: trunk/third/librsvg/test-rsvg.c @ 17277

Revision 17277, 5.8 KB checked in by amb, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r17276, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
2
3   test-rsvg.c: Command line utility for exercising rsvg.
4 
5   Copyright (C) 2000 Eazel, Inc.
6 
7   This program is free software; you can redistribute it and/or
8   modify it under the terms of the GNU General Public License as
9   published by the Free Software Foundation; either version 2 of the
10   License, or (at your option) any later version.
11 
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   General Public License for more details.
16 
17   You should have received a copy of the GNU General Public
18   License along with this program; if not, write to the
19   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20   Boston, MA 02111-1307, USA.
21 
22   Author: Raph Levien <raph@artofcode.com>
23*/
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <png.h>
28#include <popt.h>
29
30#include <gdk-pixbuf/gdk-pixbuf.h>
31
32#include "rsvg.h"
33
34
35/* The following routine is lifted wholesale from nautilus-icon-factory.c.
36   It should find a permanent home somewhere else, at which point it should
37   be deleted here and simply linked. -RLL
38*/
39
40/* utility routine for saving a pixbuf to a png file.
41 * This was adapted from Iain Holmes' code in gnome-iconedit, and probably
42 * should be in a utility library, possibly in gdk-pixbuf itself.
43 *
44 * It is split up into save_pixbuf_to_file and save_pixbuf_to_file_internal
45 * to work around a gcc warning about handle possibly getting clobbered by
46 * longjmp. Declaring handle 'volatile FILE *' didn't work as it should have.
47 */
48static gboolean
49save_pixbuf_to_file_internal (GdkPixbuf *pixbuf, char *filename, FILE *handle)
50{
51        char *buffer;
52        gboolean has_alpha;
53        int width, height, depth, rowstride;
54        guchar *pixels;
55        png_structp png_ptr;
56        png_infop info_ptr;
57        png_text text[2];
58        int i;
59       
60        png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
61        if (png_ptr == NULL) {
62                return FALSE;
63        }
64
65        info_ptr = png_create_info_struct (png_ptr);
66        if (info_ptr == NULL) {
67                png_destroy_write_struct (&png_ptr, (png_infopp)NULL);
68                return FALSE;
69        }
70
71        if (setjmp (png_ptr->jmpbuf)) {
72                png_destroy_write_struct (&png_ptr, &info_ptr);
73                return FALSE;
74        }
75
76        png_init_io (png_ptr, (FILE *)handle);
77
78        has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
79        width = gdk_pixbuf_get_width (pixbuf);
80        height = gdk_pixbuf_get_height (pixbuf);
81        depth = gdk_pixbuf_get_bits_per_sample (pixbuf);
82        pixels = gdk_pixbuf_get_pixels (pixbuf);
83        rowstride = gdk_pixbuf_get_rowstride (pixbuf);
84
85        png_set_IHDR (png_ptr, info_ptr, width, height,
86                        depth, PNG_COLOR_TYPE_RGB_ALPHA,
87                        PNG_INTERLACE_NONE,
88                        PNG_COMPRESSION_TYPE_DEFAULT,
89                        PNG_FILTER_TYPE_DEFAULT);
90
91        /* Some text to go with the png image */
92        text[0].key = "Title";
93        text[0].text = filename;
94        text[0].compression = PNG_TEXT_COMPRESSION_NONE;
95        text[1].key = "Software";
96        text[1].text = "Test-Rsvg";
97        text[1].compression = PNG_TEXT_COMPRESSION_NONE;
98        png_set_text (png_ptr, info_ptr, text, 2);
99
100        /* Write header data */
101        png_write_info (png_ptr, info_ptr);
102
103        /* if there is no alpha in the data, allocate buffer to expand into */
104        if (has_alpha) {
105                buffer = NULL;
106        } else {
107                buffer = g_malloc(4 * width);
108        }
109       
110        /* pump the raster data into libpng, one scan line at a time */
111        for (i = 0; i < height; i++) {
112                if (has_alpha) {
113                        png_bytep row_pointer = pixels;
114                        png_write_row (png_ptr, row_pointer);
115                } else {
116                        /* expand RGB to RGBA using an opaque alpha value */
117                        int x;
118                        char *buffer_ptr = buffer;
119                        char *source_ptr = pixels;
120                        for (x = 0; x < width; x++) {
121                                *buffer_ptr++ = *source_ptr++;
122                                *buffer_ptr++ = *source_ptr++;
123                                *buffer_ptr++ = *source_ptr++;
124                                *buffer_ptr++ = 255;
125                        }
126                        png_write_row (png_ptr, (png_bytep) buffer);           
127                }
128                pixels += rowstride;
129        }
130       
131        png_write_end (png_ptr, info_ptr);
132        png_destroy_write_struct (&png_ptr, &info_ptr);
133       
134        g_free (buffer);
135
136        return TRUE;
137}
138
139static gboolean
140save_pixbuf_to_file (GdkPixbuf *pixbuf, char *filename)
141{
142        FILE *handle;
143        gboolean result;
144
145        g_return_val_if_fail (pixbuf != NULL, FALSE);
146        g_return_val_if_fail (filename != NULL, FALSE);
147        g_return_val_if_fail (filename[0] != '\0', FALSE);
148
149        if (!strcmp (filename, "-")) {
150                handle = stdout;
151        } else {
152                handle = fopen (filename, "wb");
153        }
154
155        if (handle == NULL) {
156                return FALSE;
157        }
158
159        result = save_pixbuf_to_file_internal (pixbuf, filename, handle);
160        if (!result || handle != stdout)
161                fclose (handle);
162
163        return result;
164}
165
166int
167main (int argc, char **argv)
168{
169        FILE *f;
170        char *out_fn;
171        GdkPixbuf *pixbuf;
172        char *zoom_str = "1.0";
173        int n_iter = 1;
174        poptContext optCtx;
175        struct poptOption optionsTable[] = {
176                { "zoom", 'z', POPT_ARG_STRING, &zoom_str, 0, NULL, "zoom factor" },
177                { "num-iter", 'n', POPT_ARG_INT, &n_iter, 0, NULL, "number of iterations" },
178                POPT_AUTOHELP
179                { NULL, 0, 0, NULL, 0 }
180        };
181        char c;
182        const char * const *args;
183        int i;
184
185        optCtx = poptGetContext ("test-rsvg", argc, (const char **)argv, optionsTable, 0);
186
187        c = poptGetNextOpt (optCtx);
188        args = poptGetArgs (optCtx);
189
190        for (i = 0; i < n_iter; i++) {
191                if (args == NULL || args[0] == NULL) {
192                        if (n_iter > 1) {
193                                fprintf (stderr, "Can't do multiple iterations on stdin\n");
194                                exit (1);
195                        }
196
197                        f = stdin;
198                        out_fn = "-";
199                } else {
200                        f = fopen(args[0], "r");
201                        if (f == NULL) {
202                                fprintf(stderr, "Error opening source file %s\n", argv[0]);
203                                exit (1);
204                        }
205                        if (args[1] == NULL)
206                                out_fn = "-";
207                        else
208                                out_fn = (char *)args[1];
209                }
210
211                pixbuf = rsvg_render_file (f, atof (zoom_str));
212
213                if (f != stdin)
214                        fclose(f);
215
216                if (pixbuf != NULL) {
217                        if (n_iter > 1)
218                                gdk_pixbuf_unref (pixbuf);
219                        else
220                                save_pixbuf_to_file (pixbuf, out_fn);
221                } else {
222                        fprintf (stderr, "Error loading SVG file.\n");
223                        return 1;
224                }
225        }
226
227        return 0;
228}
Note: See TracBrowser for help on using the repository browser.