From a96d851ff25165188a17288cc3a10d0d651b4af6 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 1 Nov 2016 11:51:20 +0000 Subject: [PATCH] fix up vipsheader with complex field types "-f name" displays a detailed form, "-a" displays a summary of each field fix a problem with string fields as well --- ChangeLog | 1 + TODO | 6 ------ libvips/iofuncs/buf.c | 36 +++++++++++++++++++++++++++--------- libvips/iofuncs/header.c | 7 +++++-- man/vipsheader.1 | 25 +++++++++++++++---------- tools/vipsheader.c | 9 +++------ 6 files changed, 51 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index 40377268..da65cdf8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ - added tiff save to buffer - added dzsave save to buffer (zip only) - revise header get/set functions +- better vipsheader behaviour with complex field types - added vips_image_hasalpha() 18/10/16 started 8.4.3 diff --git a/TODO b/TODO index 78b50f08..715f4c8f 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,3 @@ -- look at vips_image_get_as_string() vs. vips_buf_appendgv() - - should Hist and getext be true header fields? - - vipsheader is not displaying filename correctly - - not sure about utf8 error messages on win - strange: diff --git a/libvips/iofuncs/buf.c b/libvips/iofuncs/buf.c index 3b2e104e..9cb83bfc 100644 --- a/libvips/iofuncs/buf.c +++ b/libvips/iofuncs/buf.c @@ -493,10 +493,12 @@ vips_buf_appendd( VipsBuf *buf, int d ) * @buf: the buffer * @value: #GValue to format and append * - * Format and append a #GValue. This doesn't use g_strdup_value_contents(): - * that doesn't do what we want for some types and can change too much between - * glib versions. - * + * Format and append a #GValue as a printable thing. We display text line "3144 + * bytes of binary data" for BLOBs like icc-profile-data. + * + * Use vips_image_get_as_string() to make a text representation of a field. + * That will base64-encode blobs, for example. + * * Returns: %FALSE on overflow, %TRUE otherwise. */ gboolean @@ -513,11 +515,16 @@ vips_buf_appendgv( VipsBuf *buf, GValue *value ) switch( fundamental ) { case G_TYPE_STRING: - /* These are GStrings, vips refstrings are handled by boxed, see - * below. +{ + const char *str; + + /* These are GStrings (gchararray). vips refstrings are + * handled by boxed, see below. */ - result = vips_buf_appends( buf, g_value_get_string( value ) ); + str = g_value_get_string( value ); + result = vips_buf_appends( buf, str ); handled = TRUE; +} break; case G_TYPE_OBJECT: @@ -583,15 +590,26 @@ vips_buf_appendgv( VipsBuf *buf, GValue *value ) break; case G_TYPE_BOXED: - if( type == VIPS_TYPE_REF_STRING || - type == VIPS_TYPE_BLOB ) { + if( type == VIPS_TYPE_REF_STRING ) { const char *str; size_t str_len; + /* These should be printable. + */ str = vips_value_get_ref_string( value, &str_len ); result = vips_buf_appends( buf, str ); handled = TRUE; } + else if( type == VIPS_TYPE_BLOB ) { + size_t str_len; + + /* Binary data and not printable. + */ + (void) vips_value_get_ref_string( value, &str_len ); + result = vips_buf_appendf( buf, + _( "%zd bytes of binary data" ), str_len ); + handled = TRUE; + } else if( type == VIPS_TYPE_ARRAY_DOUBLE ) { double *arr; int n; diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index e0376526..78757617 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -966,7 +966,7 @@ vips_set_value_from_pointer( GValue *value, void *data ) else if( fundamental == G_TYPE_ENUM ) g_value_set_enum( value, *((int *) data) ); else if( fundamental == G_TYPE_STRING ) - g_value_set_string( value, ((char *) data) ); + g_value_set_string( value, *((char **) data) ); else g_warning( "%s: unimplemented vips_set_value_from_pointer() " "type %s", @@ -1486,7 +1486,10 @@ vips_image_set_string( VipsImage *image, const char *field, const char *str ) * This function will read any field, returning it as a printable string. * You need to free the string with g_free() when you are done with it. * - * See also: vips_image_get(), vips_image_get_typeof(). + * This will base64-encode BLOBs, for example. Use vips_buf_appendgv() to + * make a string that's for humans. + * + * See also: vips_image_get(), vips_image_get_typeof(), vips_buf_appendgv(). * * Returns: 0 on success, -1 otherwise. */ diff --git a/man/vipsheader.1 b/man/vipsheader.1 index 8de4ecc4..578f55d2 100644 --- a/man/vipsheader.1 +++ b/man/vipsheader.1 @@ -5,23 +5,28 @@ vipsheader \- prints information about an image file vipsheader [OPTIONS ...] files ... .SH DESCRIPTION .B vipsheader(1) -prints image header fields to stdout. +prints image header fields to stdout. .SH OPTIONS + +.TP +.B -a, --all +Show all fields. Fields are displayed to be convenient for humans to read, so +binary data, for example, is summarized rather than simply copied. + .TP .B -f FIELD, --field=FIELD Print value of .B FIELD -from image header. The special field name getext prints -the VIPS extension block: the XML defining the image metadata. You can alter -this, then reattach with -.B vipsedit(1). +from image header. Fields are printed in a way suitable for programs to +understand, so, for example, binary data is base64-encoded and printed as a +stream of characters. -.TP -.B -a, --all -Show all fields. Normally -.B vipsheader -just shows a one-line summary. +The special field name +.B getext +prints the VIPS extension block: the XML defining the image metadata. You can +alter this, then reattach with +.B vipsedit(1). .SH EXAMPLES $ vipsheader -f Xsize ~/pics/*.v diff --git a/tools/vipsheader.c b/tools/vipsheader.c index 41756088..5d2892c4 100644 --- a/tools/vipsheader.c +++ b/tools/vipsheader.c @@ -147,14 +147,11 @@ print_header( VipsImage *im, gboolean many ) else if( strcmp( main_option_field, "Hist" ) == 0 ) printf( "%s", vips_image_get_history( im ) ); else { - GValue value = { 0 }; - char str[256]; - VipsBuf buf = VIPS_BUF_STATIC( str ); + char *str; - vips_image_get( im, main_option_field, &value ); - vips_buf_appendgv( &buf, &value ); + vips_image_get_as_string( im, main_option_field, &str ); printf( "%s\n", str ); - g_value_unset( &value ); + g_free( str ); } return( 0 );