add vipsload_source
plus small openslideload_source fixes
This commit is contained in:
parent
233609368b
commit
42af1cec36
|
@ -10,7 +10,7 @@
|
|||
- add _source load support for pdfium
|
||||
- add "seed" param to perlin, worley and gaussnoise
|
||||
- add vips_source_g_input_stream_new() to load images from a GInputStream
|
||||
- add openslideload_source()
|
||||
- add openslideload_source(), vipsload_source()
|
||||
|
||||
22/12/20 start 8.10.6
|
||||
- don't seek on bad file descriptors [kleisauke]
|
||||
|
|
|
@ -424,6 +424,18 @@ vips_foreign_map( const char *base, VipsSListMap2Fn fn, void *a, void *b )
|
|||
(VipsClassMapFn) file_add_class, (void *) &files );
|
||||
|
||||
files = g_slist_sort( files, (GCompareFunc) file_compare );
|
||||
#ifdef DEBUG
|
||||
{
|
||||
GSList *p;
|
||||
|
||||
printf( "vips_foreign_map: search order\n" );
|
||||
for( p = files; p; p = p->next ) {
|
||||
VipsForeignClass *class = (VipsForeignClass *) p->data;
|
||||
|
||||
printf( "\t%s\n", VIPS_OBJECT_CLASS( class )->nickname );
|
||||
}
|
||||
}
|
||||
#endif /*DEBUG*/
|
||||
result = vips_slist_map2( files, fn, a, b );
|
||||
g_slist_free( files );
|
||||
|
||||
|
@ -2077,9 +2089,13 @@ vips_foreign_operation_init( void )
|
|||
|
||||
extern GType vips_foreign_load_openexr_get_type( void );
|
||||
|
||||
extern GType vips_foreign_load_openslide_get_type( void );
|
||||
extern GType vips_foreign_load_openslide_file_get_type( void );
|
||||
extern GType vips_foreign_load_openslide_source_get_type( void );
|
||||
|
||||
extern GType vips_foreign_load_vips_file_get_type( void );
|
||||
extern GType vips_foreign_load_vips_source_get_type( void );
|
||||
extern GType vips_foreign_save_vips_get_type( void );
|
||||
|
||||
extern GType vips_foreign_load_jpeg_file_get_type( void );
|
||||
extern GType vips_foreign_load_jpeg_buffer_get_type( void );
|
||||
extern GType vips_foreign_load_jpeg_source_get_type( void );
|
||||
|
@ -2094,9 +2110,6 @@ vips_foreign_operation_init( void )
|
|||
extern GType vips_foreign_save_tiff_file_get_type( void );
|
||||
extern GType vips_foreign_save_tiff_buffer_get_type( void );
|
||||
|
||||
extern GType vips_foreign_load_vips_get_type( void );
|
||||
extern GType vips_foreign_save_vips_get_type( void );
|
||||
|
||||
extern GType vips_foreign_load_raw_get_type( void );
|
||||
extern GType vips_foreign_save_raw_get_type( void );
|
||||
extern GType vips_foreign_save_raw_fd_get_type( void );
|
||||
|
@ -2152,7 +2165,8 @@ vips_foreign_operation_init( void )
|
|||
vips_foreign_load_raw_get_type();
|
||||
vips_foreign_save_raw_get_type();
|
||||
vips_foreign_save_raw_fd_get_type();
|
||||
vips_foreign_load_vips_get_type();
|
||||
vips_foreign_load_vips_file_get_type();
|
||||
vips_foreign_load_vips_source_get_type();
|
||||
vips_foreign_save_vips_get_type();
|
||||
|
||||
#ifdef HAVE_ANALYZE
|
||||
|
@ -2251,7 +2265,7 @@ vips_foreign_operation_init( void )
|
|||
#endif /*HAVE_TIFF*/
|
||||
|
||||
#ifdef HAVE_OPENSLIDE
|
||||
vips_foreign_load_openslide_get_type();
|
||||
vips_foreign_load_openslide_file_get_type();
|
||||
vips_foreign_load_openslide_source_get_type();
|
||||
#endif /*HAVE_OPENSLIDE*/
|
||||
|
||||
|
|
|
@ -114,21 +114,24 @@ vips_foreign_load_openslide_build( VipsObject *object )
|
|||
VipsForeignLoadOpenslide *openslide =
|
||||
(VipsForeignLoadOpenslide *) object;
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_foreign_load_openslide_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
/* We can only open source which have an associated filename, since
|
||||
* the openslide library works in terms of filenames.
|
||||
*/
|
||||
openslide->filename = vips_connection_filename( VIPS_CONNECTION(
|
||||
openslide->source ) );
|
||||
if( !openslide->filename ) {
|
||||
vips_error( class->nickname, "%s",
|
||||
_( "no filename available" ) );
|
||||
return( -1 );
|
||||
if( openslide->source ) {
|
||||
openslide->filename =
|
||||
vips_connection_filename( VIPS_CONNECTION(
|
||||
openslide->source ) );
|
||||
if( !openslide->filename ) {
|
||||
vips_error( class->nickname, "%s",
|
||||
_( "no filename available" ) );
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_foreign_load_openslide_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
|
|
@ -48,29 +48,38 @@
|
|||
typedef struct _VipsForeignLoadVips {
|
||||
VipsForeignLoad parent_object;
|
||||
|
||||
char *filename;
|
||||
/* Source to load from (set by subclasses).
|
||||
*/
|
||||
VipsSource *source;
|
||||
|
||||
} VipsForeignLoadVips;
|
||||
|
||||
typedef VipsForeignLoadClass VipsForeignLoadVipsClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignLoadVips, vips_foreign_load_vips,
|
||||
G_DEFINE_ABSTRACT_TYPE( VipsForeignLoadVips, vips_foreign_load_vips,
|
||||
VIPS_TYPE_FOREIGN_LOAD );
|
||||
|
||||
static gboolean
|
||||
vips_foreign_load_vips_is_a( const char *filename )
|
||||
static void
|
||||
vips_foreign_load_vips_dispose( GObject *gobject )
|
||||
{
|
||||
return( vips__file_magic( filename ) );
|
||||
VipsForeignLoadVips *vips = (VipsForeignLoadVips *) gobject;
|
||||
|
||||
VIPS_UNREF( vips->source );
|
||||
|
||||
G_OBJECT_CLASS( vips_foreign_load_vips_parent_class )->
|
||||
dispose( gobject );
|
||||
}
|
||||
|
||||
static VipsForeignFlags
|
||||
vips_foreign_load_vips_get_flags_filename( const char *filename )
|
||||
vips_foreign_load_vips_get_flags_source( VipsSource *source )
|
||||
{
|
||||
unsigned char *data;
|
||||
VipsForeignFlags flags;
|
||||
|
||||
flags = VIPS_FOREIGN_PARTIAL;
|
||||
|
||||
if( vips__file_magic( filename ) == VIPS_MAGIC_SPARC )
|
||||
if( vips_source_sniff_at_most( source, &data, 4 ) == 4 &&
|
||||
*((guint32 *) data) == VIPS_MAGIC_SPARC )
|
||||
flags |= VIPS_FOREIGN_BIGENDIAN;
|
||||
|
||||
return( flags );
|
||||
|
@ -81,34 +90,120 @@ vips_foreign_load_vips_get_flags( VipsForeignLoad *load )
|
|||
{
|
||||
VipsForeignLoadVips *vips = (VipsForeignLoadVips *) load;
|
||||
|
||||
return( vips_foreign_load_vips_get_flags_filename( vips->filename ) );
|
||||
return( vips_foreign_load_vips_get_flags_source( vips->source ) );
|
||||
}
|
||||
|
||||
static VipsForeignFlags
|
||||
vips_foreign_load_vips_get_flags_filename( const char *filename )
|
||||
{
|
||||
VipsSource *source;
|
||||
VipsForeignFlags flags;
|
||||
|
||||
if( !(source = vips_source_new_from_file( filename )) )
|
||||
return( 0 );
|
||||
flags = vips_foreign_load_vips_get_flags_source( source );
|
||||
VIPS_UNREF( source );
|
||||
|
||||
return( flags );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_foreign_load_vips_header( VipsForeignLoad *load )
|
||||
{
|
||||
VipsForeignLoadVips *vips = (VipsForeignLoadVips *) load;
|
||||
VipsImage *out;
|
||||
VipsImage *out2;
|
||||
|
||||
if( !(out2 = vips_image_new_mode( vips->filename, "r" )) )
|
||||
const char *filename;
|
||||
VipsImage *image;
|
||||
|
||||
if( (filename =
|
||||
vips_connection_filename( VIPS_CONNECTION( vips->source ) )) ) {
|
||||
if( !(image = vips_image_new_mode( filename, "r" )) )
|
||||
return( -1 );
|
||||
}
|
||||
else {
|
||||
/* We could add load vips from memory, fd, via mmap etc. here.
|
||||
* We should perhaps move iofuncs/vips.c into this file.
|
||||
*
|
||||
* For now, just fail unless there's a filename associated
|
||||
* with this source.
|
||||
*/
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
g_object_set( load, "out", image, NULL );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_vips_class_init( VipsForeignLoadVipsClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->dispose = vips_foreign_load_vips_dispose;
|
||||
|
||||
object_class->nickname = "vipsload_base";
|
||||
object_class->description = _( "load vips base class" );
|
||||
|
||||
/* We are fast at is_a(), so high priority.
|
||||
*/
|
||||
foreign_class->priority = 200;
|
||||
|
||||
load_class->get_flags = vips_foreign_load_vips_get_flags;
|
||||
load_class->get_flags_filename =
|
||||
vips_foreign_load_vips_get_flags_filename;
|
||||
load_class->header = vips_foreign_load_vips_header;
|
||||
load_class->load = NULL;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_vips_init( VipsForeignLoadVips *vips )
|
||||
{
|
||||
}
|
||||
|
||||
typedef struct _VipsForeignLoadVipsFile {
|
||||
VipsForeignLoadVips parent_object;
|
||||
|
||||
char *filename;
|
||||
|
||||
} VipsForeignLoadVipsFile;
|
||||
|
||||
typedef VipsForeignLoadVipsClass VipsForeignLoadVipsFileClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignLoadVipsFile, vips_foreign_load_vips_file,
|
||||
vips_foreign_load_vips_get_type() );
|
||||
|
||||
static int
|
||||
vips_foreign_load_vips_file_build( VipsObject *object )
|
||||
{
|
||||
VipsForeignLoadVips *vips = (VipsForeignLoadVips *) object;
|
||||
VipsForeignLoadVipsFile *file = (VipsForeignLoadVipsFile *) object;
|
||||
|
||||
if( file->filename &&
|
||||
!(vips->source = vips_source_new_from_file( file->filename )) )
|
||||
return( -1 );
|
||||
|
||||
/* Remove the @out that's there now.
|
||||
*/
|
||||
g_object_get( load, "out", &out, NULL );
|
||||
g_object_unref( out );
|
||||
g_object_unref( out );
|
||||
|
||||
g_object_set( load, "out", out2, NULL );
|
||||
if( VIPS_OBJECT_CLASS( vips_foreign_load_vips_file_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
const char *vips__suffs[] = { ".v", ".vips", NULL };
|
||||
|
||||
static gboolean
|
||||
vips_foreign_load_vips_file_is_a( const char *filename )
|
||||
{
|
||||
return( vips__file_magic( filename ) );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_vips_class_init( VipsForeignLoadVipsClass *class )
|
||||
vips_foreign_load_vips_file_class_init( VipsForeignLoadVipsClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
|
@ -120,33 +215,98 @@ vips_foreign_load_vips_class_init( VipsForeignLoadVipsClass *class )
|
|||
|
||||
object_class->nickname = "vipsload";
|
||||
object_class->description = _( "load vips from file" );
|
||||
object_class->build = vips_foreign_load_vips_file_build;
|
||||
|
||||
foreign_class->suffs = vips__suffs;
|
||||
|
||||
/* We are fast at is_a(), so high priority.
|
||||
*/
|
||||
foreign_class->priority = 200;
|
||||
|
||||
load_class->is_a = vips_foreign_load_vips_is_a;
|
||||
load_class->get_flags = vips_foreign_load_vips_get_flags;
|
||||
load_class->get_flags_filename =
|
||||
vips_foreign_load_vips_get_flags_filename;
|
||||
load_class->header = vips_foreign_load_vips_header;
|
||||
load_class->load = NULL;
|
||||
load_class->is_a = vips_foreign_load_vips_file_is_a;
|
||||
|
||||
VIPS_ARG_STRING( class, "filename", 1,
|
||||
_( "Filename" ),
|
||||
_( "Filename to load from" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadVips, filename ),
|
||||
G_STRUCT_OFFSET( VipsForeignLoadVipsFile, filename ),
|
||||
NULL );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_vips_init( VipsForeignLoadVips *vips )
|
||||
vips_foreign_load_vips_file_init( VipsForeignLoadVipsFile *file )
|
||||
{
|
||||
}
|
||||
|
||||
typedef struct _VipsForeignLoadVipsSource {
|
||||
VipsForeignLoadVips parent_object;
|
||||
|
||||
VipsSource *source;
|
||||
|
||||
} VipsForeignLoadVipsSource;
|
||||
|
||||
typedef VipsForeignLoadVipsClass VipsForeignLoadVipsSourceClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignLoadVipsSource, vips_foreign_load_vips_source,
|
||||
vips_foreign_load_vips_get_type() );
|
||||
|
||||
static int
|
||||
vips_foreign_load_vips_source_build( VipsObject *object )
|
||||
{
|
||||
VipsForeignLoadVips *vips = (VipsForeignLoadVips *) object;
|
||||
VipsForeignLoadVipsSource *source =
|
||||
(VipsForeignLoadVipsSource *) object;
|
||||
|
||||
if( source->source ) {
|
||||
vips->source = source->source;
|
||||
g_object_ref( vips->source );
|
||||
}
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_foreign_load_vips_source_parent_class )->
|
||||
build( object ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vips_foreign_load_vips_source_is_a_source( VipsSource *source )
|
||||
{
|
||||
const char *filename;
|
||||
|
||||
return( (filename =
|
||||
vips_connection_filename( VIPS_CONNECTION( source ) )) &&
|
||||
vips__file_magic( filename ) );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_vips_source_class_init( VipsForeignLoadVipsClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
object_class->nickname = "vipsload_source";
|
||||
object_class->description = _( "load vips from source" );
|
||||
object_class->build = vips_foreign_load_vips_source_build;
|
||||
|
||||
load_class->is_a_source =
|
||||
vips_foreign_load_vips_source_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
_( "Source" ),
|
||||
_( "Source to load from" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadVipsSource, source ),
|
||||
VIPS_TYPE_SOURCE );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_vips_source_init( VipsForeignLoadVipsSource *source )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* vips_vipsload:
|
||||
* @filename: file to load
|
||||
|
@ -171,3 +331,26 @@ vips_vipsload( const char *filename, VipsImage **out, ... )
|
|||
|
||||
return( result );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_vipsload_source:
|
||||
* @source: source to load from
|
||||
* @out: (out): decompressed image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Exactly as vips_vipsload(), but read from a source.
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_vipsload_source( VipsSource *source, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "vipsload_source", ap, source, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
||||
|
|
|
@ -358,6 +358,8 @@ const char *vips_foreign_find_save_target( const char *suffix );
|
|||
|
||||
int vips_vipsload( const char *filename, VipsImage **out, ... )
|
||||
__attribute__((sentinel));
|
||||
int vips_vipsload_source( VipsSource *source, VipsImage **out, ... )
|
||||
__attribute__((sentinel));
|
||||
int vips_vipssave( VipsImage *in, const char *filename, ... )
|
||||
__attribute__((sentinel));
|
||||
|
||||
|
|
|
@ -773,7 +773,7 @@ class TestForeign:
|
|||
|
||||
source = pyvips.Source.new_from_file(OPENSLIDE_FILE)
|
||||
x = pyvips.Image.new_from_source(source, "")
|
||||
assert openslide_valid(x)
|
||||
openslide_valid(x)
|
||||
|
||||
@skip_if_no("pdfload")
|
||||
def test_pdfload(self):
|
||||
|
|
Loading…
Reference in New Issue