svgload from a stream

This commit is contained in:
John Cupitt 2019-11-10 17:23:28 +00:00
parent 41c08b0ffb
commit 441f61f3ff
4 changed files with 26 additions and 46 deletions

View File

@ -473,22 +473,12 @@ G_DEFINE_TYPE( VipsForeignLoadSvgStream, vips_foreign_load_svg_stream,
gboolean gboolean
vips_foreign_load_svg_stream_is_a( VipsStreami *input ) vips_foreign_load_svg_stream_is_a( VipsStreami *input )
{ {
ssize_t n; unsigned char *data;
if( vips_streami_rewind( input ) ) if( !(data = vips_streami_sniff( input, SVG_HEADER_SIZE )) )
return( FALSE ); return( FALSE );
g_byte_array_set_size( input->sniff, SVG_HEADER_SIZE ); return( vips_foreign_load_svg_is_a( data, SVG_HEADER_SIZE ) );
/* Can't use vips_streami_sniff here.
*/
if( (n = vips_streami_read( input, input->sniff->data,
SVG_HEADER_SIZE )) == -1 || n == 0 )
return( FALSE );
g_byte_array_set_size( input->sniff, n );
return( vips_foreign_load_svg_is_a( input->sniff->data, n ) );
} }
static int static int

View File

@ -33,9 +33,6 @@
#ifndef VIPS_STREAM_H #ifndef VIPS_STREAM_H
#define VIPS_STREAM_H #define VIPS_STREAM_H
// TODO: #ifdef HAVE_RSVG (?)
#include <gio/gio.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /*__cplusplus*/ #endif /*__cplusplus*/
@ -297,7 +294,6 @@ int vips_streamib_require( VipsStreamib *streamib, int require );
const unsigned char *vips_streamib_get_line( VipsStreamib *streamib ); const unsigned char *vips_streamib_get_line( VipsStreamib *streamib );
unsigned char *vips_streamib_get_line_copy( VipsStreamib *streamib ); unsigned char *vips_streamib_get_line_copy( VipsStreamib *streamib );
// TODO: #ifdef HAVE_RSVG (?)
#define VIPS_TYPE_STREAMIW (vips_streamiw_get_type()) #define VIPS_TYPE_STREAMIW (vips_streamiw_get_type())
#define VIPS_STREAMIW( obj ) \ #define VIPS_STREAMIW( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \ (G_TYPE_CHECK_INSTANCE_CAST( (obj), \

View File

@ -88,6 +88,7 @@ extern "C" {
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include <gmodule.h> #include <gmodule.h>
#include <glib-object.h> #include <glib-object.h>
#include <gio/gio.h>
/* If we're being parsed by SWIG, remove gcc attributes. /* If we're being parsed by SWIG, remove gcc attributes.
*/ */

View File

@ -32,7 +32,8 @@
/* TODO /* TODO
* *
* - Should we conditionally exclude this class? It's only needed for librsvg. * - should we conditionally exclude this class? It's only needed for librsvg.
* - it pulls in gio.h -- does this change our minimum version for glib?
*/ */
/* /*
@ -66,8 +67,7 @@ G_DEFINE_TYPE_WITH_CODE( VipsStreamiw, vips_streamiw, G_TYPE_INPUT_STREAM,
G_IMPLEMENT_INTERFACE( G_TYPE_SEEKABLE, G_IMPLEMENT_INTERFACE( G_TYPE_SEEKABLE,
vips_streamiw_seekable_iface_init ) ) vips_streamiw_seekable_iface_init ) )
enum enum {
{
PROP_0, PROP_0,
PROP_STREAM PROP_STREAM
}; };
@ -115,15 +115,13 @@ vips_streamiw_finalize( GObject *object )
static goffset static goffset
vips_streamiw_tell( GSeekable *seekable ) vips_streamiw_tell( GSeekable *seekable )
{ {
VipsStreami *streami; VipsStreami *streami = VIPS_STREAMIW( seekable )->streami;
goffset pos;
streami = VIPS_STREAMIW( seekable )->streami; goffset pos;
VIPS_DEBUG_MSG( "vips_streamiw_tell:\n" ); VIPS_DEBUG_MSG( "vips_streamiw_tell:\n" );
pos = vips_streami_seek( streami, 0, SEEK_CUR ); pos = vips_streami_seek( streami, 0, SEEK_CUR );
if( pos == -1 ) if( pos == -1 )
return( 0 ); return( 0 );
@ -164,11 +162,10 @@ vips_streamiw_seek( GSeekable *seekable, goffset offset,
", type = %d\n", offset, type ); ", type = %d\n", offset, type );
if( vips_streami_seek( streami, offset, if( vips_streami_seek( streami, offset,
seek_type_to_lseek( type ) ) == -1 ) seek_type_to_lseek( type ) ) == -1 ) {
{
g_set_error( error, G_IO_ERROR, g_set_error( error, G_IO_ERROR,
G_IO_ERROR_FAILED, G_IO_ERROR_FAILED,
_("Error while seeking: %s"), _( "Error while seeking: %s" ),
vips_error_buffer() ); vips_error_buffer() );
return( FALSE ); return( FALSE );
} }
@ -190,7 +187,7 @@ vips_streamiw_truncate( GSeekable *seekable, goffset offset,
g_set_error_literal( error, g_set_error_literal( error,
G_IO_ERROR, G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED, G_IO_ERROR_NOT_SUPPORTED,
_("Cannot truncate VipsStreamiw") ); _( "Cannot truncate VipsStreamiw" ) );
return( FALSE ); return( FALSE );
} }
@ -212,7 +209,7 @@ vips_streamiw_read( GInputStream *stream, void *buffer, gsize count,
if( (res = vips_streami_read( streami, buffer, count )) == -1 ) if( (res = vips_streami_read( streami, buffer, count )) == -1 )
g_set_error( error, G_IO_ERROR, g_set_error( error, G_IO_ERROR,
G_IO_ERROR_FAILED, G_IO_ERROR_FAILED,
_("Error while reading: %s"), _( "Error while reading: %s" ),
vips_error_buffer() ); vips_error_buffer() );
return( res ); return( res );
@ -234,34 +231,30 @@ vips_streamiw_skip( GInputStream *stream, gsize count,
return( -1 ); return( -1 );
start = vips_streami_seek( streami, 0, SEEK_CUR ); start = vips_streami_seek( streami, 0, SEEK_CUR );
if( start == -1 ) if( start == -1 ) {
{
g_set_error( error, G_IO_ERROR, g_set_error( error, G_IO_ERROR,
G_IO_ERROR_FAILED, G_IO_ERROR_FAILED,
_("Error while seeking: %s"), _( "Error while seeking: %s" ),
vips_error_buffer() ); vips_error_buffer() );
return( -1 ); return( -1 );
} }
end = vips_streami_seek( streami, 0, SEEK_END ); end = vips_streami_seek( streami, 0, SEEK_END );
if( end == -1 ) if( end == -1 ) {
{
g_set_error( error, G_IO_ERROR, g_set_error( error, G_IO_ERROR,
G_IO_ERROR_FAILED, G_IO_ERROR_FAILED,
_("Error while seeking: %s"), _( "Error while seeking: %s" ),
vips_error_buffer() ); vips_error_buffer() );
return( -1 ); return( -1 );
} }
if( end - start > count ) if( end - start > count ) {
{
end = vips_streami_seek( streami, count - (end - start), end = vips_streami_seek( streami, count - (end - start),
SEEK_CUR ); SEEK_CUR );
if( end == -1 ) if( end == -1 ) {
{
g_set_error( error, G_IO_ERROR, g_set_error( error, G_IO_ERROR,
G_IO_ERROR_FAILED, G_IO_ERROR_FAILED,
_("Error while seeking: %s"), _( "Error while seeking: %s" ),
vips_error_buffer() ); vips_error_buffer() );
return( -1 ); return( -1 );
} }
@ -306,11 +299,11 @@ vips_streamiw_class_init( VipsStreamiwClass *class )
istream_class->close_fn = vips_streamiw_close; istream_class->close_fn = vips_streamiw_close;
g_object_class_install_property( gobject_class, PROP_STREAM, g_object_class_install_property( gobject_class, PROP_STREAM,
g_param_spec_object( "input", g_param_spec_object( "input",
_("Input"), _( "Input" ),
_("Stream to wrap"), _( "Stream to wrap" ),
VIPS_TYPE_STREAMI, G_PARAM_CONSTRUCT_ONLY | VIPS_TYPE_STREAMI, G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ) ); G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS ) );
} }
@ -331,6 +324,6 @@ GInputStream *
g_input_stream_new_from_vips( VipsStreami *streami ) g_input_stream_new_from_vips( VipsStreami *streami )
{ {
return( g_object_new( VIPS_TYPE_STREAMIW, return( g_object_new( VIPS_TYPE_STREAMIW,
"input", streami, "input", streami,
NULL ) ); NULL ) );
} }