source: trunk/third/librsvg/rsvg-gz.c @ 20920

Revision 20920, 3.8 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20919, which included commits to RCS files with non-trunk default branches.
Line 
1/* vim: set sw=4: -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2/*
3   rsvg-gz.c: SAX-based renderer for SVGZ files into a GdkPixbuf.
4
5   Copyright (C) 2003 Dom Lachowicz <cinamod@hotmail.com>
6
7   This program is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Library 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   Library General Public License for more details.
16
17   You should have received a copy of the GNU Library 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
23#include "config.h"
24#include "rsvg-gz.h"
25#include "rsvg-private.h"
26
27#ifdef HAVE_SVGZ
28
29#include <gsf/gsf-input-gzip.h>
30#include <gsf/gsf-input-memory.h>
31#include <gsf/gsf-output-memory.h>
32
33/* TODO: this could probably be done about a billion times better */
34
35struct RsvgHandleGz
36{
37        RsvgHandle super;
38        GsfOutput * mem;
39};
40
41typedef struct RsvgHandleGz RsvgHandleGz;
42
43static gboolean
44rsvg_handle_gz_write_impl (RsvgHandle    *handle,
45                                                   const guchar  *buf,
46                                                   gsize          num_bytes,
47                                                   GError       **error)
48{
49        RsvgHandleGz * me = (RsvgHandleGz*)handle;
50        return gsf_output_write (me->mem, num_bytes, buf);
51}
52
53static gboolean
54rsvg_handle_gz_close_impl (RsvgHandle  *handle,
55                                                   GError     **error)
56{
57        RsvgHandleGz * me = (RsvgHandleGz*)handle;
58        GsfInput * gzip;
59        const guchar * bytes;
60        gsize size;
61        gsize remaining;
62
63        bytes = gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (me->mem));
64        size = gsf_output_size (me->mem);
65
66        gzip = GSF_INPUT (gsf_input_gzip_new (GSF_INPUT (gsf_input_memory_new (bytes, size, FALSE)), error));
67        remaining = gsf_input_remaining (gzip);
68        while ((size = MIN (remaining, 1024)) > 0) {
69                guint8 const *buf;
70
71                /* write to parent */
72                buf = gsf_input_read (gzip, size, NULL);
73                if (!buf)
74                {
75                        /* an error occured, so bail */
76                        g_warning ("rsvg_gz_handle_close_impl: gsf_input_read returned NULL");
77                        break;
78                }
79
80                rsvg_handle_write_impl (&(me->super),
81                                                                buf,
82                                                                size, error);
83                /* if we didn't manage to lower remaining number of bytes,
84                 * something is wrong, and we should avoid an endless loop */
85                if (remaining == gsf_input_remaining (gzip))
86                {
87                        g_warning ("rsvg_gz_handle_close_impl: write_impl didn't lower the input_remaining count");
88                        break;
89                }
90                remaining = gsf_input_remaining (gzip);
91        }
92        g_object_unref (G_OBJECT (gzip));
93
94        /* close parent */
95        gsf_output_close (me->mem);
96        return rsvg_handle_close_impl (handle, error);
97}
98
99static void
100rsvg_handle_gz_free_impl (RsvgHandle *handle)
101{
102        RsvgHandleGz * me = (RsvgHandleGz*)handle;
103        g_object_unref (G_OBJECT (me->mem));
104
105        /* free parent */
106        rsvg_handle_free_impl (handle);
107}
108
109static RsvgHandle *
110rsvg_handle_new_gz_impl (void)
111{
112        RsvgHandleGz * me = g_new0 (RsvgHandleGz, 1);
113
114        /* init parent */
115        rsvg_handle_init (&me->super);
116        me->mem = GSF_OUTPUT (gsf_output_memory_new ());
117
118        me->super.write = rsvg_handle_gz_write_impl;
119        me->super.close = rsvg_handle_gz_close_impl;
120        me->super.free  = rsvg_handle_gz_free_impl;
121
122        return (RsvgHandle*)me;
123}
124
125#else
126
127static RsvgHandle *
128rsvg_handle_new_gz_impl (void)
129{
130        g_warning ("Doesn't support GZipped SVG files");
131        return NULL;
132}
133
134#endif
135
136/**
137 * rsvg_handle_new_gz
138 *
139 * See rsvg_handle_new, except that this will handle GZipped SVGs (svgz)
140 * Use the returned handle identically to how you use a handle returned
141 * from rsvg_handle_new()
142 *
143 * Returns: a new SVGZ handle or null if it isn't supported
144 */
145RsvgHandle *
146rsvg_handle_new_gz (void)
147{
148        return rsvg_handle_new_gz_impl ();
149}
Note: See TracBrowser for help on using the repository browser.