add openslideload_source

This commit is contained in:
John Cupitt 2020-12-30 14:14:08 +00:00
parent e23f0c58f6
commit babbb086f9
4 changed files with 258 additions and 28 deletions

View File

@ -10,6 +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()
22/12/20 start 8.10.6
- don't seek on bad file descriptors [kleisauke]

View File

@ -2078,6 +2078,7 @@ 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_source_get_type( void );
extern GType vips_foreign_load_jpeg_file_get_type( void );
extern GType vips_foreign_load_jpeg_buffer_get_type( void );
@ -2251,6 +2252,7 @@ vips_foreign_operation_init( void )
#ifdef HAVE_OPENSLIDE
vips_foreign_load_openslide_get_type();
vips_foreign_load_openslide_source_get_type();
#endif /*HAVE_OPENSLIDE*/
#ifdef ENABLE_MAGICKLOAD

View File

@ -64,9 +64,13 @@
typedef struct _VipsForeignLoadOpenslide {
VipsForeignLoad parent_object;
/* Filename for load.
/* Source to load from (set by subclasses).
*/
char *filename;
VipsSource *source;
/* Filename from source.
*/
const char *filename;
/* Load this level.
*/
@ -88,13 +92,50 @@ typedef struct _VipsForeignLoadOpenslide {
typedef VipsForeignLoadClass VipsForeignLoadOpenslideClass;
G_DEFINE_TYPE( VipsForeignLoadOpenslide, vips_foreign_load_openslide,
G_DEFINE_ABSTRACT_TYPE( VipsForeignLoadOpenslide, vips_foreign_load_openslide,
VIPS_TYPE_FOREIGN_LOAD );
static VipsForeignFlags
vips_foreign_load_openslide_get_flags_filename( const char *filename )
static void
vips_foreign_load_openslide_dispose( GObject *gobject )
{
/* We can't tell from just the filename, we need to know what part of
VipsForeignLoadOpenslide *openslide =
(VipsForeignLoadOpenslide *) gobject;
VIPS_UNREF( openslide->source );
G_OBJECT_CLASS( vips_foreign_load_openslide_parent_class )->
dispose( gobject );
}
static int
vips_foreign_load_openslide_build( VipsObject *object )
{
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( 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 );
}
return( 0 );
}
static VipsForeignFlags
vips_foreign_load_openslide_get_flags_source( VipsSource *source )
{
/* We can't tell from just the source, we need to know what part of
* the file the user wants. But it'll usually be partial.
*/
return( VIPS_FOREIGN_PARTIAL );
@ -113,6 +154,20 @@ vips_foreign_load_openslide_get_flags( VipsForeignLoad *load )
return( flags );
}
static VipsForeignFlags
vips_foreign_load_openslide_get_flags_filename( const char *filename )
{
VipsSource *source;
VipsForeignFlags flags;
if( !(source = vips_source_new_from_file( filename )) )
return( 0 );
flags = vips_foreign_load_openslide_get_flags_source( source );
VIPS_UNREF( source );
return( flags );
}
static int
vips_foreign_load_openslide_header( VipsForeignLoad *load )
{
@ -148,17 +203,6 @@ vips_foreign_load_openslide_load( VipsForeignLoad *load )
return( 0 );
}
static const char *vips_foreign_openslide_suffs[] = {
".svs", /* Aperio */
".vms", ".vmu", ".ndpi", /* Hamamatsu */
".scn", /* Leica */
".mrxs", /* MIRAX */
".svslide", /* Sakura */
".tif", /* Trestle */
".bif", /* Ventana */
NULL
};
static void
vips_foreign_load_openslide_class_init( VipsForeignLoadOpenslideClass *class )
{
@ -167,11 +211,13 @@ vips_foreign_load_openslide_class_init( VipsForeignLoadOpenslideClass *class )
VipsForeignClass *foreign_class = (VipsForeignClass *) class;
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
gobject_class->dispose = vips_foreign_load_openslide_dispose;
gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property;
object_class->nickname = "openslideload";
object_class->description = _( "load file with OpenSlide" );
object_class->nickname = "openslideload_base";
object_class->description = _( "load OpenSlide base class" );
object_class->build = vips_foreign_load_openslide_build;
/* We need to be ahead of the tiff sniffer since many OpenSlide
* formats are tiff derivatives. If we see a tiff which would be
@ -181,22 +227,13 @@ vips_foreign_load_openslide_class_init( VipsForeignLoadOpenslideClass *class )
* JPEGs.
*/
foreign_class->priority = 100;
foreign_class->suffs = vips_foreign_openslide_suffs;
load_class->is_a = vips__openslide_isslide;
load_class->get_flags_filename =
vips_foreign_load_openslide_get_flags_filename;
load_class->get_flags = vips_foreign_load_openslide_get_flags;
load_class->header = vips_foreign_load_openslide_header;
load_class->load = vips_foreign_load_openslide_load;
VIPS_ARG_STRING( class, "filename", 1,
_( "Filename" ),
_( "Filename to load from" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsForeignLoadOpenslide, filename ),
NULL );
VIPS_ARG_INT( class, "level", 20,
_( "Level" ),
_( "Load this level from the file" ),
@ -232,6 +269,164 @@ vips_foreign_load_openslide_init( VipsForeignLoadOpenslide *openslide )
{
}
typedef struct _VipsForeignLoadOpenslideFile {
VipsForeignLoadOpenslide parent_object;
/* Filename for load.
*/
char *filename;
} VipsForeignLoadOpenslideFile;
typedef VipsForeignLoadOpenslideClass VipsForeignLoadOpenslideFileClass;
G_DEFINE_TYPE( VipsForeignLoadOpenslideFile, vips_foreign_load_openslide_file,
vips_foreign_load_openslide_get_type() );
static int
vips_foreign_load_openslide_file_build( VipsObject *object )
{
VipsForeignLoadOpenslide *openslide =
(VipsForeignLoadOpenslide *) object;
VipsForeignLoadOpenslideFile *file =
(VipsForeignLoadOpenslideFile *) object;
if( file->filename &&
!(openslide->source =
vips_source_new_from_file( file->filename )) )
return( -1 );
if( VIPS_OBJECT_CLASS( vips_foreign_load_openslide_file_parent_class )->
build( object ) )
return( -1 );
return( 0 );
}
static const char *vips_foreign_openslide_suffs[] = {
".svs", /* Aperio */
".vms", ".vmu", ".ndpi", /* Hamamatsu */
".scn", /* Leica */
".mrxs", /* MIRAX */
".svslide", /* Sakura */
".tif", /* Trestle */
".bif", /* Ventana */
NULL
};
static void
vips_foreign_load_openslide_file_class_init(
VipsForeignLoadOpenslideFileClass *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->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property;
object_class->nickname = "openslideload";
object_class->description = _( "load file with OpenSlide" );
object_class->build = vips_foreign_load_openslide_file_build;
foreign_class->suffs = vips_foreign_openslide_suffs;
load_class->is_a = vips__openslide_isslide;
VIPS_ARG_STRING( class, "filename", 1,
_( "Filename" ),
_( "Filename to load from" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsForeignLoadOpenslideFile, filename ),
NULL );
}
static void
vips_foreign_load_openslide_file_init( VipsForeignLoadOpenslideFile *openslide )
{
}
typedef struct _VipsForeignLoadOpenslideSource {
VipsForeignLoadOpenslide parent_object;
/* Load from a source.
*/
VipsSource *source;
} VipsForeignLoadOpenslideSource;
typedef VipsForeignLoadOpenslideClass VipsForeignLoadOpenslideSourceClass;
G_DEFINE_TYPE( VipsForeignLoadOpenslideSource,
vips_foreign_load_openslide_source,
vips_foreign_load_openslide_get_type() );
static int
vips_foreign_load_openslide_source_build( VipsObject *object )
{
VipsForeignLoadOpenslide *openslide =
(VipsForeignLoadOpenslide *) object;
VipsForeignLoadOpenslideSource *source =
(VipsForeignLoadOpenslideSource *) object;
if( source->source ) {
openslide->source = source->source;
g_object_ref( openslide->source );
}
if( VIPS_OBJECT_CLASS(
vips_foreign_load_openslide_source_parent_class )->
build( object ) )
return( -1 );
return( 0 );
}
static gboolean
vips_foreign_load_openslide_source_is_a_source( VipsSource *source )
{
const char *filename;
return( (filename =
vips_connection_filename( VIPS_CONNECTION( source ) )) &&
vips__openslide_isslide( filename ) );
}
static void
vips_foreign_load_openslide_source_class_init(
VipsForeignLoadOpenslideSourceClass *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 = "openslideload_source";
object_class->description = _( "load source with OpenSlide" );
object_class->build = vips_foreign_load_openslide_source_build;
load_class->is_a_source =
vips_foreign_load_openslide_source_is_a_source;
VIPS_ARG_OBJECT( class, "source", 1,
_( "Source" ),
_( "Source to load from" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsForeignLoadOpenslideSource, source ),
VIPS_TYPE_SOURCE );
}
static void
vips_foreign_load_openslide_source_init(
VipsForeignLoadOpenslideSource *openslide )
{
}
#endif /*HAVE_OPENSLIDE*/
/**
@ -286,3 +481,33 @@ vips_openslideload( const char *filename, VipsImage **out, ... )
return( result );
}
/**
* vips_openslideload_source:
* @source: source to load from
* @out: (out): decompressed image
* @...: %NULL-terminated list of optional named arguments
*
* Optional arguments:
*
* * @level: %gint, load this level
* * @associated: %gchararray, load this associated image
* * @attach_associated: %gboolean, attach all associated images as metadata
* * @autocrop: %gboolean, crop to image bounds
*
* Exactly as vips_openslideload(), but read from a source.
*
* Returns: 0 on success, -1 on error.
*/
int
vips_openslideload_source( VipsSource *source, VipsImage **out, ... )
{
va_list ap;
int result;
va_start( ap, out );
result = vips_call_split( "openslideload_source", ap, source, out );
va_end( ap );
return( result );
}

View File

@ -363,6 +363,8 @@ int vips_vipssave( VipsImage *in, const char *filename, ... )
int vips_openslideload( const char *filename, VipsImage **out, ... )
__attribute__((sentinel));
int vips_openslideload_source( VipsSource *source, VipsImage **out, ... )
__attribute__((sentinel));
/**
* VipsForeignJpegSubsample: