allow symbolic names for flags

you can now use numbers or names for GFlags values, eg.:

$ vips copy 50020484-00001.png x.png[filter=avg]
$ vips copy 50020484-00001.png x.png[filter=64]

was numbers only before
This commit is contained in:
John Cupitt 2014-10-27 11:40:43 +00:00
parent 1589e84360
commit 620bff2d78
8 changed files with 53 additions and 14 deletions

View File

@ -18,6 +18,7 @@
- add support for vips8 plugins
- added "autorotate" option to jpeg load
- added autorot operator
- added @filter option to pngsave (Lovell)
8/10/14 started 7.40.11
- rework extra band handling for colour functions

View File

@ -2487,7 +2487,7 @@ vips_pngload_buffer( void *buf, size_t len, VipsImage **out, ... )
* @compression: compression level
* @interlace: interlace image
* @profile: ICC profile to embed
* @filter: libpng row filter flag(s)
* @filter: #VipsForeignPngFilter row filter flag(s)
*
* Write a VIPS image to a file as PNG.
*
@ -2507,7 +2507,8 @@ vips_pngload_buffer( void *buf, size_t len, VipsImage **out, ... )
* contains an ICC profile named VIPS_META_ICC_NAME ("icc-profile-data"), the
* profile from the VIPS header will be attached.
*
* Use @filter to specify one or more filters (instead of adaptive filtering).
* Use @filter to specify one or more filters (instead of adaptive filtering),
* see #VipsForeignPngFilter.
*
* The image is automatically converted to RGB, RGBA, Monochrome or Mono +
* alpha before saving. Images with more than one byte per band element are

View File

@ -50,6 +50,8 @@
* - more robust error handling from libpng
* 9/8/14
* - don't check profiles, helps with libpng >=1.6.11
* 27/10/14 Lovell
* - add @filter option
*/
/*

View File

@ -438,12 +438,12 @@ int vips_magickload( const char *filename, VipsImage **out, ... )
/**
* VipsForeignPngFilter:
* @VIPS_FOREIGN_PNG_FILTER_NONE
* @VIPS_FOREIGN_PNG_FILTER_SUB
* @VIPS_FOREIGN_PNG_FILTER_UP
* @VIPS_FOREIGN_PNG_FILTER_AVG
* @VIPS_FOREIGN_PNG_FILTER_PAETH
* @VIPS_FOREIGN_PNG_FILTER_ALL
* @VIPS_FOREIGN_PNG_FILTER_NONE: no filtering
* @VIPS_FOREIGN_PNG_FILTER_SUB: difference to the left
* @VIPS_FOREIGN_PNG_FILTER_UP: difference up
* @VIPS_FOREIGN_PNG_FILTER_AVG: average of left and up
* @VIPS_FOREIGN_PNG_FILTER_PAETH: pick best neighbor predictor automatically
* @VIPS_FOREIGN_PNG_FILTER_ALL: adaptive
*
* http://www.w3.org/TR/PNG-Filters.html
* The values mirror those of png.h in libpng.
@ -454,8 +454,7 @@ typedef enum /*< flags >*/ {
VIPS_FOREIGN_PNG_FILTER_UP = 0x20,
VIPS_FOREIGN_PNG_FILTER_AVG = 0x40,
VIPS_FOREIGN_PNG_FILTER_PAETH = 0x80,
VIPS_FOREIGN_PNG_FILTER_ALL = 0xEA,
VIPS_FOREIGN_PNG_FILTER_LAST = 0xFF
VIPS_FOREIGN_PNG_FILTER_ALL = 0xEA
} VipsForeignPngFilter;
int vips_pngload( const char *filename, VipsImage **out, ... )

View File

@ -165,6 +165,7 @@ G_STMT_START { \
const char *vips_enum_string( GType enm, int value );
const char *vips_enum_nick( GType enm, int value );
int vips_enum_from_nick( const char *domain, GType type, const char *str );
int vips_flags_from_nick( const char *domain, GType type, const char *nick );
gboolean vips_slist_equal( GSList *l1, GSList *l2 );
void *vips_slist_map2( GSList *list, VipsSListMap2Fn fn, void *a, void *b );

View File

@ -118,10 +118,9 @@ vips_foreign_png_filter_get_type( void )
{VIPS_FOREIGN_PNG_FILTER_AVG, "VIPS_FOREIGN_PNG_FILTER_AVG", "avg"},
{VIPS_FOREIGN_PNG_FILTER_PAETH, "VIPS_FOREIGN_PNG_FILTER_PAETH", "paeth"},
{VIPS_FOREIGN_PNG_FILTER_ALL, "VIPS_FOREIGN_PNG_FILTER_ALL", "all"},
{VIPS_FOREIGN_PNG_FILTER_LAST, "VIPS_FOREIGN_PNG_FILTER_LAST", "last"},
{0, NULL, NULL}
};
etype = g_flags_register_static( "VipsForeignPngFilter", values );
}

View File

@ -1961,7 +1961,7 @@ vips_object_set_argument_from_string( VipsObject *object,
g_value_set_enum( &gvalue, i );
}
else if( G_IS_PARAM_SPEC_FLAGS( pspec ) ) {
/* Hard to set from a symbolic name. Just take an int.
/* Allow a symbolic name, or an int.
*/
int i;
@ -1970,7 +1970,9 @@ vips_object_set_argument_from_string( VipsObject *object,
return( -1 );
}
if( sscanf( value, "%d", &i ) != 1 ) {
if( sscanf( value, "%d", &i ) != 1 &&
(i = vips_flags_from_nick( class->nickname,
otype, value )) < 0 ) {
vips_error( class->nickname,
_( "'%s' is not an integer" ), value );
return( -1 );

View File

@ -1597,6 +1597,40 @@ vips_enum_from_nick( const char *domain, GType type, const char *nick )
return( -1 );
}
int
vips_flags_from_nick( const char *domain, GType type, const char *nick )
{
GTypeClass *class;
GFlagsClass *gflags;
GFlagsValue *flags_value;
int i;
char str[1000];
VipsBuf buf = VIPS_BUF_STATIC( str );
if( !(class = g_type_class_ref( type )) ) {
vips_error( domain, "%s", _( "no such flag type" ) );
return( -1 );
}
gflags = G_FLAGS_CLASS( class );
if( (flags_value = g_flags_get_value_by_name( gflags, nick )) )
return( flags_value->value );
if( (flags_value = g_flags_get_value_by_nick( gflags, nick )) )
return( flags_value->value );
for( i = 0; i < gflags->n_values; i++ ) {
if( i > 0 )
vips_buf_appends( &buf, ", " );
vips_buf_appends( &buf, gflags->values[i].value_nick );
}
vips_error( domain, _( "flags '%s' has no member '%s', "
"should be one of: %s" ),
g_type_name( type ), nick, vips_buf_all( &buf ) );
return( -1 );
}
/* Scan @buf for the first "%ns" (eg. "%12s") and substitute the
* lowest-numbered one for @sub. @buf is @len bytes in size.
*