move @fail from jpegload into the base load class

and add fail support to csv and openslide

see https://github.com/jcupitt/libvips/issues/546
This commit is contained in:
John Cupitt 2016-11-12 15:33:35 +00:00
parent e72d145ae9
commit bb0a6643f9
11 changed files with 72 additions and 44 deletions

View File

@ -7,6 +7,8 @@
- added vips_image_hasalpha()
- added vips_thumbnail() / vips_thumbnail_buffer()
- better >4gb detect for zip dzsave output [Felix Bünemann]
- all loaders have a @fail option, meaning fail on first warning, though it
only does anything for jpg, csv, openslide
11/11/16 started 8.4.4
- fix crash in vips.exe arg parsing on Windows, thanks Yury

View File

@ -76,7 +76,7 @@ im_csv2vips( const char *filename, IMAGE *out )
}
if( vips__csv_read( name, out,
start_skip, lines, whitespace, separator ) )
start_skip, lines, whitespace, separator, FALSE ) )
return( -1 );
return( 0 );

View File

@ -172,7 +172,7 @@ skip_to_sep( FILE *fp, const char sepmap[256] )
*/
static int
read_double( FILE *fp, const char whitemap[256], const char sepmap[256],
int lineno, int colno, double *out )
int lineno, int colno, double *out, gboolean fail )
{
int ch;
@ -198,6 +198,8 @@ read_double( FILE *fp, const char whitemap[256], const char sepmap[256],
vips_warn( "csv2vips",
_( "error parsing number, line %d, column %d" ),
lineno, colno );
if( fail )
return( EOF );
/* Step over the bad data to the next separator.
*/
@ -222,7 +224,8 @@ read_csv( FILE *fp, VipsImage *out,
int skip,
int lines,
const char *whitespace, const char *separator,
gboolean read_image )
gboolean read_image,
gboolean fail )
{
int i;
char whitemap[256];
@ -265,7 +268,7 @@ read_csv( FILE *fp, VipsImage *out,
}
for( columns = 0;
(ch = read_double( fp, whitemap, sepmap,
skip + 1, columns + 1, &d )) == 0;
skip + 1, columns + 1, &d, fail )) == 0;
columns++ )
;
(void) fsetpos( fp, &pos );
@ -308,7 +311,7 @@ read_csv( FILE *fp, VipsImage *out,
int colno = x + 1;
ch = read_double( fp, whitemap, sepmap,
lineno, colno, &d );
lineno, colno, &d, fail );
if( ch == EOF ) {
vips_error( "csv2vips",
_( "unexpected EOF, line %d col %d" ),
@ -342,13 +345,15 @@ read_csv( FILE *fp, VipsImage *out,
int
vips__csv_read( const char *filename, VipsImage *out,
int skip, int lines, const char *whitespace, const char *separator )
int skip, int lines, const char *whitespace, const char *separator,
gboolean fail )
{
FILE *fp;
if( !(fp = vips__file_open_read( filename, NULL, TRUE )) )
return( -1 );
if( read_csv( fp, out, skip, lines, whitespace, separator, TRUE ) ) {
if( read_csv( fp, out,
skip, lines, whitespace, separator, TRUE, fail ) ) {
fclose( fp );
return( -1 );
}
@ -359,13 +364,15 @@ vips__csv_read( const char *filename, VipsImage *out,
int
vips__csv_read_header( const char *filename, VipsImage *out,
int skip, int lines, const char *whitespace, const char *separator )
int skip, int lines, const char *whitespace, const char *separator,
gboolean fail )
{
FILE *fp;
if( !(fp = vips__file_open_read( filename, NULL, TRUE )) )
return( -1 );
if( read_csv( fp, out, skip, lines, whitespace, separator, FALSE ) ) {
if( read_csv( fp, out,
skip, lines, whitespace, separator, FALSE, fail ) ) {
fclose( fp );
return( -1 );
}

View File

@ -89,7 +89,8 @@ vips_foreign_load_csv_header( VipsForeignLoad *load )
VipsForeignLoadCsv *csv = (VipsForeignLoadCsv *) load;
if( vips__csv_read_header( csv->filename, load->out,
csv->skip, csv->lines, csv->whitespace, csv->separator ) )
csv->skip, csv->lines, csv->whitespace, csv->separator,
load->fail ) )
return( -1 );
VIPS_SETSTR( load->out->filename, csv->filename );
@ -103,7 +104,8 @@ vips_foreign_load_csv_load( VipsForeignLoad *load )
VipsForeignLoadCsv *csv = (VipsForeignLoadCsv *) load;
if( vips__csv_read( csv->filename, load->real,
csv->skip, csv->lines, csv->whitespace, csv->separator ) )
csv->skip, csv->lines, csv->whitespace, csv->separator,
load->fail ) )
return( -1 );
return( 0 );
@ -191,6 +193,7 @@ vips_foreign_load_csv_init( VipsForeignLoadCsv *csv )
* * @lines: read this many lines from file
* * @whitespace: set of whitespace characters
* * @separator: set of separator characters
* * @fail: %gboolean, fail on warnings
*
* Load a CSV (comma-separated values) file. The output image is always 1
* band (monochrome), #VIPS_FORMAT_DOUBLE. Use vips_bandfold() to turn
@ -218,6 +221,8 @@ vips_foreign_load_csv_init( VipsForeignLoadCsv *csv )
* @separator sets the characters that separate fields.
* Default ;,<emphasis>tab</emphasis>. Separators are never run together.
*
* Setting @fail to %TRUE makes the reader fail on any warnings.
*
* See also: vips_image_new_from_file(), vips_bandfold().
*
* Returns: 0 on success, -1 on error.

View File

@ -986,6 +986,13 @@ vips_foreign_load_class_init( VipsForeignLoadClass *class )
G_STRUCT_OFFSET( VipsForeignLoad, sequential ),
FALSE );
VIPS_ARG_BOOL( class, "fail", 11,
_( "Fail" ),
_( "Fail on first warning" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsForeignLoad, fail ),
FALSE );
}
static void

View File

@ -77,10 +77,6 @@ typedef struct _VipsForeignLoadJpeg {
*/
int shrink;
/* Fail on first warning.
*/
gboolean fail;
/* Autorotate using exif orientation tag.
*/
gboolean autorotate;
@ -144,13 +140,6 @@ vips_foreign_load_jpeg_class_init( VipsForeignLoadJpegClass *class )
G_STRUCT_OFFSET( VipsForeignLoadJpeg, shrink ),
1, 16, 1 );
VIPS_ARG_BOOL( class, "fail", 11,
_( "Fail" ),
_( "Fail on first warning" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsForeignLoadJpeg, fail ),
FALSE );
VIPS_ARG_BOOL( class, "autorotate", 12,
_( "Autorotate" ),
_( "Rotate image using exif orientation" ),
@ -201,7 +190,7 @@ vips_foreign_load_jpeg_file_header( VipsForeignLoad *load )
VipsForeignLoadJpegFile *file = (VipsForeignLoadJpegFile *) load;
if( vips__jpeg_read_file( file->filename, load->out,
TRUE, jpeg->shrink, jpeg->fail, FALSE, jpeg->autorotate ) )
TRUE, jpeg->shrink, load->fail, FALSE, jpeg->autorotate ) )
return( -1 );
return( 0 );
@ -214,7 +203,7 @@ vips_foreign_load_jpeg_file_load( VipsForeignLoad *load )
VipsForeignLoadJpegFile *file = (VipsForeignLoadJpegFile *) load;
if( vips__jpeg_read_file( file->filename, load->real,
FALSE, jpeg->shrink, jpeg->fail,
FALSE, jpeg->shrink, load->fail,
load->access == VIPS_ACCESS_SEQUENTIAL, jpeg->autorotate ) )
return( -1 );
@ -283,7 +272,7 @@ vips_foreign_load_jpeg_buffer_header( VipsForeignLoad *load )
VipsForeignLoadJpegBuffer *buffer = (VipsForeignLoadJpegBuffer *) load;
if( vips__jpeg_read_buffer( buffer->buf->data, buffer->buf->length,
load->out, TRUE, jpeg->shrink, jpeg->fail, FALSE,
load->out, TRUE, jpeg->shrink, load->fail, FALSE,
jpeg->autorotate ) )
return( -1 );
@ -297,7 +286,7 @@ vips_foreign_load_jpeg_buffer_load( VipsForeignLoad *load )
VipsForeignLoadJpegBuffer *buffer = (VipsForeignLoadJpegBuffer *) load;
if( vips__jpeg_read_buffer( buffer->buf->data, buffer->buf->length,
load->real, FALSE, jpeg->shrink, jpeg->fail,
load->real, FALSE, jpeg->shrink, load->fail,
load->access == VIPS_ACCESS_SEQUENTIAL, jpeg->autorotate ) )
return( -1 );

View File

@ -115,6 +115,10 @@ typedef struct {
*/
int tile_width;
int tile_height;
/* Quit on warning.
*/
gboolean fail;
} ReadSlide;
int
@ -223,7 +227,7 @@ get_bounds( openslide_t *osr, VipsRect *rect )
static ReadSlide *
readslide_new( const char *filename, VipsImage *out,
int level, gboolean autocrop, const char *associated )
int level, gboolean autocrop, const char *associated, gboolean fail )
{
ReadSlide *rslide;
int64_t w, h;
@ -391,9 +395,9 @@ readslide_new( const char *filename, VipsImage *out,
int
vips__openslide_read_header( const char *filename, VipsImage *out,
int level, gboolean autocrop, char *associated )
int level, gboolean autocrop, char *associated, gboolean fail )
{
if( !readslide_new( filename, out, level, autocrop, associated ) )
if( !readslide_new( filename, out, level, autocrop, associated, fail ) )
return( -1 );
return( 0 );
@ -475,13 +479,14 @@ vips__openslide_generate( VipsRegion *out,
/* Only warn on error: we don't want to make the whole image unreadable
* because of one broken tile.
*
* FIXME ... add a --fail option like jpegload
*/
error = openslide_get_error( rslide->osr );
if( error )
if( error ) {
vips_warn( "openslide2vips",
_( "reading region: %s" ), error );
if( rslide->fail )
return( -1 );
}
/* Since we are inside a cache, we know buf must be continuous.
*/
@ -492,7 +497,7 @@ vips__openslide_generate( VipsRegion *out,
int
vips__openslide_read( const char *filename, VipsImage *out,
int level, gboolean autocrop )
int level, gboolean autocrop, gboolean fail )
{
ReadSlide *rslide;
VipsImage *raw;
@ -505,7 +510,7 @@ vips__openslide_read( const char *filename, VipsImage *out,
vips_object_local( out, raw );
if( !(rslide = readslide_new( filename, raw,
level, autocrop, NULL )) )
level, autocrop, NULL, fail )) )
return( -1 );
if( vips_image_generate( raw,
@ -534,7 +539,7 @@ vips__openslide_read( const char *filename, VipsImage *out,
int
vips__openslide_read_associated( const char *filename, VipsImage *out,
const char *associated )
const char *associated, gboolean fail )
{
ReadSlide *rslide;
VipsImage *raw;
@ -549,7 +554,8 @@ vips__openslide_read_associated( const char *filename, VipsImage *out,
raw = vips_image_new_memory();
vips_object_local( out, raw );
if( !(rslide = readslide_new( filename, raw, 0, FALSE, associated )) ||
if( !(rslide = readslide_new( filename, raw,
0, FALSE, associated, fail )) ||
vips_image_write_prepare( raw ) )
return( -1 );
buf = (uint32_t *) VIPS_IMAGE_ADDR( raw, 0, 0 );

View File

@ -114,7 +114,7 @@ vips_foreign_load_openslide_header( VipsForeignLoad *load )
if( vips__openslide_read_header( openslide->filename, load->out,
openslide->level, openslide->autocrop,
openslide->associated ) )
openslide->associated, load->fail ) )
return( -1 );
VIPS_SETSTR( load->out->filename, openslide->filename );
@ -129,13 +129,13 @@ vips_foreign_load_openslide_load( VipsForeignLoad *load )
if( !openslide->associated ) {
if( vips__openslide_read( openslide->filename, load->real,
openslide->level, openslide->autocrop ) )
openslide->level, openslide->autocrop, load->fail ) )
return( -1 );
}
else {
if( vips__openslide_read_associated(
openslide->filename, load->real,
openslide->associated ) )
openslide->associated, load->fail ) )
return( -1 );
}
@ -231,6 +231,7 @@ vips_foreign_load_openslide_init( VipsForeignLoadOpenslide *openslide )
* * @level: load this level
* * @associated: load this associated image
* * @autocrop: crop to image bounds
* * @fail: %gboolean, fail on warnings
*
* Read a virtual slide supported by the OpenSlide library into a VIPS image.
* OpenSlide supports images in Aperio, Hamamatsu, MIRAX, Sakura, Trestle,
@ -250,6 +251,8 @@ vips_foreign_load_openslide_init( VipsForeignLoadOpenslide *openslide )
*
* The output of this operator is always RGBA.
*
* Setting @fail to %TRUE makes the reader fail on any warnings.
*
* See also: vips_image_new_from_file().
*
* Returns: 0 on success, -1 on error.

View File

@ -87,9 +87,11 @@ int vips__analyze_read( const char *filename, VipsImage *out );
extern const char *vips__foreign_csv_suffs[];
int vips__csv_read( const char *filename, VipsImage *out,
int skip, int lines, const char *whitespace, const char *separator );
int skip, int lines, const char *whitespace, const char *separator,
gboolean fail );
int vips__csv_read_header( const char *filename, VipsImage *out,
int skip, int lines, const char *whitespace, const char *separator );
int skip, int lines, const char *whitespace, const char *separator,
gboolean fail );
int vips__csv_write( VipsImage *in, const char *filename,
const char *separator );
@ -215,11 +217,11 @@ int vips__webp_write_buffer( VipsImage *out, void **buf, size_t *len,
int vips__openslide_isslide( const char *filename );
int vips__openslide_read_header( const char *filename, VipsImage *out,
int level, gboolean autocrop, char *associated );
int level, gboolean autocrop, char *associated, gboolean fail );
int vips__openslide_read( const char *filename, VipsImage *out,
int level, gboolean autocrop );
int level, gboolean autocrop, gboolean fail );
int vips__openslide_read_associated( const char *filename, VipsImage *out,
const char *associated );
const char *associated, gboolean fail );
#ifdef __cplusplus
}

View File

@ -67,6 +67,9 @@ vips__thandler_error( const char *module, const char *fmt, va_list ap )
vips_verror( module, fmt, ap );
}
/* It'd be nice to be able to support the @fail option for the tiff loader, but
* there's no easy way to do this, since libtiff has a global warning handler.
*/
static void
vips__thandler_warning( const char *module, const char *fmt, va_list ap )
{

View File

@ -131,6 +131,10 @@ typedef struct _VipsForeignLoad {
*/
VipsForeignFlags flags;
/* Stop load on first warning.
*/
gboolean fail;
/* Deprecated and unused, just here for compat.
*/
gboolean sequential;