_source loaders should all be nocache
When we image_new_from_source, the source object has some of the loader state: it tracks the current read position of the load library. This means that we mustn't keep source loaders in the operation cache, since a second call could give a different result because the source object read position might have changed. Also: add a rewind to get_flags_source in spngload, and jp2k needs to tag its load region as having no thread ownership or you'll get assert fails in the test suite with debug enabled.
This commit is contained in:
parent
4fd2de5754
commit
cb58d7d960
@ -642,6 +642,7 @@ vips_foreign_load_csv_source_class_init( VipsForeignLoadCsvFileClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -650,6 +651,8 @@ vips_foreign_load_csv_source_class_init( VipsForeignLoadCsvFileClass *class )
|
||||
object_class->nickname = "csvload_source";
|
||||
object_class->build = vips_foreign_load_csv_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source = vips_foreign_load_csv_source_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
|
@ -316,6 +316,7 @@ vips_foreign_load_fits_source_class_init(
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -325,6 +326,8 @@ vips_foreign_load_fits_source_class_init(
|
||||
object_class->description = _( "load FITS from a source" );
|
||||
object_class->build = vips_foreign_load_fits_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source =
|
||||
vips_foreign_load_fits_source_is_a_source;
|
||||
|
||||
|
@ -725,6 +725,11 @@ vips_foreign_find_load_source( VipsSource *source )
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
/* All source loaders should be NOCACHE.
|
||||
*/
|
||||
g_assert( VIPS_OPERATION_CLASS( load_class )->flags &
|
||||
VIPS_OPERATION_NOCACHE );
|
||||
|
||||
return( G_OBJECT_CLASS_NAME( load_class ) );
|
||||
}
|
||||
|
||||
|
@ -1288,6 +1288,7 @@ vips_foreign_load_heif_source_class_init(
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -1296,6 +1297,8 @@ vips_foreign_load_heif_source_class_init(
|
||||
object_class->nickname = "heifload_source";
|
||||
object_class->build = vips_foreign_load_heif_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source = vips_foreign_load_heif_source_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
|
@ -1209,6 +1209,7 @@ vips_foreign_load_jp2k_source_class_init(
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -1217,6 +1218,8 @@ vips_foreign_load_jp2k_source_class_init(
|
||||
object_class->nickname = "jp2kload_source";
|
||||
object_class->build = vips_foreign_load_jp2k_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source = vips_foreign_load_jp2k_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
|
@ -880,9 +880,11 @@ vips_foreign_save_jp2k_build( VipsObject *object )
|
||||
if( !(jp2k->accumulate = VIPS_ARRAY( NULL, sizeof_line, VipsPel )) )
|
||||
return( -1 );
|
||||
|
||||
/* The line of tiles we are building.
|
||||
/* The line of tiles we are building. It's used by the bg thread, so
|
||||
* no ownership.
|
||||
*/
|
||||
jp2k->strip = vips_region_new( save->ready );
|
||||
vips__region_no_ownership( jp2k->strip );
|
||||
|
||||
/* Position strip at the top of the image, the height of a row of
|
||||
* tiles.
|
||||
|
@ -250,6 +250,7 @@ vips_foreign_load_jpeg_source_class_init(
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -259,6 +260,8 @@ vips_foreign_load_jpeg_source_class_init(
|
||||
object_class->description = _( "load image from jpeg source" );
|
||||
object_class->build = vips_foreign_load_jpeg_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source = vips_foreign_load_jpeg_source_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
|
@ -914,6 +914,7 @@ vips_foreign_load_jxl_source_class_init( VipsForeignLoadJxlSourceClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -922,6 +923,8 @@ vips_foreign_load_jxl_source_class_init( VipsForeignLoadJxlSourceClass *class )
|
||||
object_class->nickname = "jxlload_source";
|
||||
object_class->build = vips_foreign_load_jxl_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source = vips_foreign_load_jxl_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
|
@ -449,6 +449,7 @@ vips_foreign_load_matrix_source_class_init(
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -457,6 +458,8 @@ vips_foreign_load_matrix_source_class_init(
|
||||
object_class->nickname = "matrixload_source";
|
||||
object_class->build = vips_foreign_load_matrix_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source = vips_foreign_load_matrix_source_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
|
@ -767,6 +767,7 @@ vips_foreign_load_nifti_source_class_init(
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -776,6 +777,8 @@ vips_foreign_load_nifti_source_class_init(
|
||||
object_class->description = _( "load NIfTI volumes" );
|
||||
object_class->build = vips_foreign_load_nifti_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source =
|
||||
vips_foreign_load_nifti_source_is_a_source;
|
||||
|
||||
|
@ -853,6 +853,7 @@ vips_foreign_load_nsgif_source_class_init(
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -862,6 +863,8 @@ vips_foreign_load_nsgif_source_class_init(
|
||||
object_class->description = _( "load gif from source" );
|
||||
object_class->build = vips_foreign_load_nsgif_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source = vips_foreign_load_nsgif_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
|
@ -1053,6 +1053,7 @@ vips_foreign_load_openslide_source_class_init(
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -1062,6 +1063,8 @@ vips_foreign_load_openslide_source_class_init(
|
||||
object_class->description = _( "load source with OpenSlide" );
|
||||
object_class->build = vips_foreign_load_openslide_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source =
|
||||
vips_foreign_load_openslide_source_is_a_source;
|
||||
|
||||
|
@ -921,6 +921,7 @@ vips_foreign_load_pdf_source_class_init(
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -930,6 +931,8 @@ vips_foreign_load_pdf_source_class_init(
|
||||
object_class->description = _( "load PDF from source" );
|
||||
object_class->build = vips_foreign_load_pdf_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source = vips_foreign_load_pdf_source_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
|
@ -223,6 +223,7 @@ vips_foreign_load_png_source_class_init( VipsForeignLoadPngSourceClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -232,6 +233,8 @@ vips_foreign_load_png_source_class_init( VipsForeignLoadPngSourceClass *class )
|
||||
object_class->description = _( "load png from source" );
|
||||
object_class->build = vips_foreign_load_png_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source = vips_foreign_load_png_source_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
|
@ -815,6 +815,7 @@ vips_foreign_load_pdf_source_class_init(
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -824,6 +825,8 @@ vips_foreign_load_pdf_source_class_init(
|
||||
object_class->description = _( "load PDF from source" );
|
||||
object_class->build = vips_foreign_load_pdf_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source = vips_foreign_load_pdf_source_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
|
@ -872,6 +872,7 @@ vips_foreign_load_ppm_source_class_init( VipsForeignLoadPpmFileClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -880,6 +881,8 @@ vips_foreign_load_ppm_source_class_init( VipsForeignLoadPpmFileClass *class )
|
||||
object_class->nickname = "ppmload_source";
|
||||
object_class->build = vips_foreign_load_ppm_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source = vips_foreign_load_ppm_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
|
@ -184,6 +184,7 @@ vips_foreign_load_rad_source_class_init( VipsForeignLoadRadSourceClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -193,6 +194,8 @@ vips_foreign_load_rad_source_class_init( VipsForeignLoadRadSourceClass *class )
|
||||
object_class->description = _( "load rad from source" );
|
||||
object_class->build = vips_foreign_load_rad_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source = vips_foreign_load_rad_source_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
|
@ -127,6 +127,8 @@ vips_foreign_load_png_get_flags_source( VipsSource *source )
|
||||
|
||||
ctx = spng_ctx_new( SPNG_CTX_IGNORE_ADLER32 );
|
||||
spng_set_crc_action( ctx, SPNG_CRC_USE, SPNG_CRC_USE );
|
||||
if( vips_source_rewind( source ) )
|
||||
return( 0 );
|
||||
spng_set_png_stream( ctx,
|
||||
vips_foreign_load_png_stream, source );
|
||||
if( spng_get_ihdr( ctx, &ihdr ) ) {
|
||||
@ -533,12 +535,12 @@ vips_foreign_load_png_generate( VipsRegion *or,
|
||||
}
|
||||
|
||||
for( y = 0; y < r->height; y++ ) {
|
||||
error = spng_decode_row( png->ctx,
|
||||
VIPS_REGION_ADDR( or, 0, r->top + y ),
|
||||
VIPS_REGION_SIZEOF_LINE( or ) );
|
||||
/* libspng returns EOI when successfully reading the
|
||||
* final line of input.
|
||||
*/
|
||||
error = spng_decode_row( png->ctx,
|
||||
VIPS_REGION_ADDR( or, 0, r->top + y ),
|
||||
VIPS_REGION_SIZEOF_LINE( or ) );
|
||||
if( error != 0 &&
|
||||
error != SPNG_EOI ) {
|
||||
/* We've failed to read some pixels. Knock this
|
||||
@ -739,6 +741,7 @@ vips_foreign_load_png_source_class_init( VipsForeignLoadPngSourceClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -748,6 +751,8 @@ vips_foreign_load_png_source_class_init( VipsForeignLoadPngSourceClass *class )
|
||||
object_class->description = _( "load png from source" );
|
||||
object_class->build = vips_foreign_load_png_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source = vips_foreign_load_png_source_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
|
@ -626,6 +626,7 @@ vips_foreign_load_svg_source_class_init( VipsForeignLoadSvgSourceClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -634,6 +635,8 @@ vips_foreign_load_svg_source_class_init( VipsForeignLoadSvgSourceClass *class )
|
||||
object_class->nickname = "svgload_source";
|
||||
object_class->description = _( "load svg from source" );
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source = vips_foreign_load_svg_source_is_a_source;
|
||||
load_class->header = vips_foreign_load_svg_source_header;
|
||||
load_class->load = vips_foreign_load_svg_source_load;
|
||||
|
@ -272,6 +272,7 @@ vips_foreign_load_tiff_source_class_init(
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -281,6 +282,8 @@ vips_foreign_load_tiff_source_class_init(
|
||||
object_class->description = _( "load tiff from source" );
|
||||
object_class->build = vips_foreign_load_tiff_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source = vips_foreign_load_tiff_source_is_a_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
|
@ -287,6 +287,7 @@ vips_foreign_load_vips_source_class_init( VipsForeignLoadVipsClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -296,6 +297,8 @@ vips_foreign_load_vips_source_class_init( VipsForeignLoadVipsClass *class )
|
||||
object_class->description = _( "load vips from source" );
|
||||
object_class->build = vips_foreign_load_vips_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source =
|
||||
vips_foreign_load_vips_source_is_a_source;
|
||||
|
||||
|
@ -254,6 +254,7 @@ vips_foreign_load_webp_source_class_init(
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -263,6 +264,8 @@ vips_foreign_load_webp_source_class_init(
|
||||
object_class->description = _( "load webp from source" );
|
||||
object_class->build = vips_foreign_load_webp_source_build;
|
||||
|
||||
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||
|
||||
load_class->is_a_source = vips__iswebp_source;
|
||||
|
||||
VIPS_ARG_OBJECT( class, "source", 1,
|
||||
|
Loading…
Reference in New Issue
Block a user