From e6bbfe4672d958bd92f8f349fa579eb4287f9c60 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 15 Mar 2017 12:08:52 +0000 Subject: [PATCH] more centos5 fixes can't use GRegexp if we need to support centos5 ... vipsthumbnail was using it to parse geometry strings new geo parser, plus some tests see https://github.com/jcupitt/libvips/issues/622 --- test/test_cli.sh | 29 +++++++++ tools/vipsthumbnail.c | 138 ++++++++++++++++++++---------------------- 2 files changed, 96 insertions(+), 71 deletions(-) diff --git a/test/test_cli.sh b/test/test_cli.sh index 601557a7..95f2a48d 100755 --- a/test/test_cli.sh +++ b/test/test_cli.sh @@ -58,3 +58,32 @@ echo "testing with $(basename $image)" for i in nearest bicubic bilinear nohalo lbb; do test_rotate $image $i done + +test_thumbnail() { + geo=$1 + correct_width=$2 + correct_height=$3 + + printf "testing thumbnail -s $geo ... " + $vipsthumbnail $image -s "$geo" -o $tmp/t1.jpg + width=$(vipsheader -f width $tmp/t1.jpg) + height=$(vipsheader -f height $tmp/t1.jpg) + if [ $width -ne $correct_width ]; then + echo width is $width, not $correct_width + exit 1 + fi + if [ $height -ne $correct_height ]; then + echo width is $height, not $correct_height + exit 1 + fi + + echo "ok" +} + +test_thumbnail 100 100 75 +test_thumbnail 100x100 100 75 +test_thumbnail x100 133 100 +test_thumbnail "100x100<" 1024 768 +test_thumbnail "2000<" 2000 1500 +test_thumbnail "100x100>" 100 75 +test_thumbnail "2000>" 1024 768 diff --git a/tools/vipsthumbnail.c b/tools/vipsthumbnail.c index ccbfbba8..a369c514 100644 --- a/tools/vipsthumbnail.c +++ b/tools/vipsthumbnail.c @@ -102,6 +102,7 @@ #include #include #include +#include #include #include @@ -271,91 +272,86 @@ thumbnail_process( VipsObject *process, const char *filename ) return( 0 ); } -/* Fetch a match_info string, NULL for "". - */ -static const char * -fetch_match( GMatchInfo *match_info, int n ) -{ - const char *str = g_match_info_fetch( match_info, n ); - - return( str && strcmp( str, "" ) == 0 ? NULL : str ); -} - /* Parse a geometry string and set thumbnail_width and thumbnail_height. */ static int thumbnail_parse_geometry( const char *geometry ) { - GRegex *regex; - GMatchInfo *match_info; - gboolean handled; + /* Geometry strings have a regex like: + * + * ^(\\d+)? (x)? (\\d+)? ([<>])?$ + * + * Sadly GRegex is 2.14 and later, and we need to work with 2.6. + */ - handled = FALSE; + const char *p; - regex = g_regex_new( "^(\\d+)? (x)? (\\d+)? ([<>])?$", - G_REGEX_CASELESS | G_REGEX_EXTENDED, 0, NULL ); - g_regex_match( regex, geometry, 0, &match_info ); - if( g_match_info_matches( match_info ) ) { - const char *w = fetch_match( match_info, 1 ); - const char *x = fetch_match( match_info, 2 ); - const char *h = fetch_match( match_info, 3 ); - const char *s = fetch_match( match_info, 4 ); + /* w or h missing means replace with a huuuge value to prevent + * reduction or enlargement in that axis. + */ + thumbnail_width = VIPS_MAX_COORD; + thumbnail_height = VIPS_MAX_COORD; - /* If --crop is set, both width and height must be specified, - * since we'll need a complete bounding box to fill. + p = geometry; + + /* Get the width. + */ + while( isspace( *p ) ) + p++; + if( isdigit ( *p ) ) { + /* We have a number! vipsthumbnail history means that "-s 200" + * means "200x200", not "200xhuge" */ - if( crop_image && - x && - (!w || !h) ) { - vips_error( "thumbnail", - "both width and height must be given if " - "--crop is enabled" ); - return( -1 ); - } + thumbnail_width = thumbnail_height = atoi( p ); - if( !x ) { - /* No "x" means we only allow a single number and it - * sets both width and height. - */ - if( w && !h ) { - thumbnail_width = thumbnail_height = atoi( w ); - handled = TRUE; - } - if( !w && h ) { - thumbnail_width = thumbnail_height = atoi( h ); - handled = TRUE; - } - } - else { - /* w or h missing means replace with a huuuge value - * to prevent reduction or enlargement in that axis. - */ - thumbnail_width = VIPS_MAX_COORD; - thumbnail_height = VIPS_MAX_COORD; - if( w ) { - thumbnail_width = atoi( w ); - handled = TRUE; - } - if( h ) { - thumbnail_height = atoi( h ); - handled = TRUE; - } - } - - if( s && strcmp( s, ">" ) == 0 ) - size_restriction = VIPS_SIZE_DOWN; - if( s && strcmp( s, "<" ) == 0 ) - size_restriction = VIPS_SIZE_UP; + /* And skip over it. + */ + while( isdigit( *p ) ) + p++; } - g_match_info_free( match_info ); - g_regex_unref( regex ); + /* Get the optional 'x'. + */ + while( isspace( *p ) ) + p++; + if( *p == 'x' ) + p += 1; + while( isspace( *p ) ) + p++; - if( !handled ) { + /* Get the height. + */ + if( isdigit( *p ) ) { + thumbnail_height = atoi( p ); + + while( isdigit( *p ) ) + p++; + } + + /* Get the final < or >. + */ + while( isspace( *p ) ) + p++; + if( *p == '<' ) + size_restriction = VIPS_SIZE_UP; + else if( *p == '>' ) + size_restriction = VIPS_SIZE_DOWN; + else if( *p != '\0' || + (thumbnail_width == VIPS_MAX_COORD && + thumbnail_height == VIPS_MAX_COORD) ) { + vips_error( "thumbnail", "%s", _( "bad geometry spec" ) ); + return( -1 ); + } + + /* If --crop is set, both width and height must be specified, + * since we'll need a complete bounding box to fill. + */ + if( (crop_image || smartcrop_image) && + (thumbnail_width == VIPS_MAX_COORD || + thumbnail_height == VIPS_MAX_COORD) ) { vips_error( "thumbnail", - "unable to parse size \"%s\" -- " - "use eg. 128 or 200x300>", geometry ); - + "both width and height must be given if " + "crop is enabled" ); return( -1 ); }