add openslideload_source
This commit is contained in:
parent
e23f0c58f6
commit
babbb086f9
@ -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]
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user