all done, I think
This commit is contained in:
parent
e958de7814
commit
2fa3736722
@ -19,6 +19,8 @@
|
|||||||
VIPS_LIBRARY_AGE
|
VIPS_LIBRARY_AGE
|
||||||
- better support for bscale / bzero in fits images
|
- better support for bscale / bzero in fits images
|
||||||
- deprecate vips_warn() / vips_info(); use g_warning() / g_info() instead
|
- deprecate vips_warn() / vips_info(); use g_warning() / g_info() instead
|
||||||
|
- vipsthumbnail supports much fancier geometry strings
|
||||||
|
- vips_thumbnail() has new @size option
|
||||||
|
|
||||||
8/12/16 started 8.4.5
|
8/12/16 started 8.4.5
|
||||||
- allow libgsf-1.14.26 to help centos, thanks tdiprima
|
- allow libgsf-1.14.26 to help centos, thanks tdiprima
|
||||||
|
32
TODO
32
TODO
@ -1,3 +1,35 @@
|
|||||||
|
- </>
|
||||||
|
|
||||||
|
convert k2.jpg -resize "100x100<" x.jpg
|
||||||
|
|
||||||
|
downsize, ie. factor < 1
|
||||||
|
does not resize
|
||||||
|
|
||||||
|
convert x.jpg -resize "200x200<" y.jpg
|
||||||
|
|
||||||
|
upsize, ie. factor > 1
|
||||||
|
resizes
|
||||||
|
|
||||||
|
convert k2.jpg -resize "100x100>" x.jpg
|
||||||
|
|
||||||
|
downsize, ie. factor < 1
|
||||||
|
resizes
|
||||||
|
|
||||||
|
convert x.jpg -resize "200x200>" y.jpg
|
||||||
|
|
||||||
|
upsize, ie. factor > 1
|
||||||
|
does not resize
|
||||||
|
|
||||||
|
so: < means only resize if input size is less than, > means only resize if
|
||||||
|
input size is > than
|
||||||
|
|
||||||
|
awkward to fit inside vipsthumbnail.c, since we'd have to copy/paste all the
|
||||||
|
resize calcs
|
||||||
|
|
||||||
|
have to add another param to thumbnail ... up or down, only up, only down
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- vipsdisp-tiny makes stripes if the image is not tagged correctly
|
- vipsdisp-tiny makes stripes if the image is not tagged correctly
|
||||||
|
|
||||||
is one of the colourspace functions not reading format?
|
is one of the colourspace functions not reading format?
|
||||||
|
@ -9,6 +9,8 @@ G_BEGIN_DECLS
|
|||||||
/* enumerations from "../../../libvips/include/vips/resample.h" */
|
/* enumerations from "../../../libvips/include/vips/resample.h" */
|
||||||
GType vips_kernel_get_type (void) G_GNUC_CONST;
|
GType vips_kernel_get_type (void) G_GNUC_CONST;
|
||||||
#define VIPS_TYPE_KERNEL (vips_kernel_get_type())
|
#define VIPS_TYPE_KERNEL (vips_kernel_get_type())
|
||||||
|
GType vips_size_get_type (void) G_GNUC_CONST;
|
||||||
|
#define VIPS_TYPE_SIZE (vips_size_get_type())
|
||||||
/* enumerations from "../../../libvips/include/vips/foreign.h" */
|
/* enumerations from "../../../libvips/include/vips/foreign.h" */
|
||||||
GType vips_foreign_flags_get_type (void) G_GNUC_CONST;
|
GType vips_foreign_flags_get_type (void) G_GNUC_CONST;
|
||||||
#define VIPS_TYPE_FOREIGN_FLAGS (vips_foreign_flags_get_type())
|
#define VIPS_TYPE_FOREIGN_FLAGS (vips_foreign_flags_get_type())
|
||||||
|
@ -47,6 +47,13 @@ typedef enum {
|
|||||||
VIPS_KERNEL_LAST
|
VIPS_KERNEL_LAST
|
||||||
} VipsKernel;
|
} VipsKernel;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIPS_SIZE_BOTH,
|
||||||
|
VIPS_SIZE_UP,
|
||||||
|
VIPS_SIZE_DOWN,
|
||||||
|
VIPS_SIZE_LAST
|
||||||
|
} VipsSize;
|
||||||
|
|
||||||
int vips_shrink( VipsImage *in, VipsImage **out,
|
int vips_shrink( VipsImage *in, VipsImage **out,
|
||||||
double hshrink, double vshrink, ... )
|
double hshrink, double vshrink, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
|
@ -26,6 +26,25 @@ vips_kernel_get_type( void )
|
|||||||
|
|
||||||
return( etype );
|
return( etype );
|
||||||
}
|
}
|
||||||
|
GType
|
||||||
|
vips_size_get_type( void )
|
||||||
|
{
|
||||||
|
static GType etype = 0;
|
||||||
|
|
||||||
|
if( etype == 0 ) {
|
||||||
|
static const GEnumValue values[] = {
|
||||||
|
{VIPS_SIZE_BOTH, "VIPS_SIZE_BOTH", "both"},
|
||||||
|
{VIPS_SIZE_UP, "VIPS_SIZE_UP", "up"},
|
||||||
|
{VIPS_SIZE_DOWN, "VIPS_SIZE_DOWN", "down"},
|
||||||
|
{VIPS_SIZE_LAST, "VIPS_SIZE_LAST", "last"},
|
||||||
|
{0, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
etype = g_enum_register_static( "VipsSize", values );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( etype );
|
||||||
|
}
|
||||||
/* enumerations from "../../libvips/include/vips/foreign.h" */
|
/* enumerations from "../../libvips/include/vips/foreign.h" */
|
||||||
GType
|
GType
|
||||||
vips_foreign_flags_get_type( void )
|
vips_foreign_flags_get_type( void )
|
||||||
|
@ -82,6 +82,18 @@
|
|||||||
* Finally, vips_mapim() can apply arbitrary 2D image transforms to an image.
|
* Finally, vips_mapim() can apply arbitrary 2D image transforms to an image.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VipsSize:
|
||||||
|
* @VIPS_SIZE_BOTH: size both up and down
|
||||||
|
* @VIPS_SIZE_UP: only upsize
|
||||||
|
* @VIPS_SIZE_DOWN: only downsize
|
||||||
|
*
|
||||||
|
* Controls whether an operation should upsize, downsize, or both up and
|
||||||
|
* downsize.
|
||||||
|
*
|
||||||
|
* See also: vips_thumbnail().
|
||||||
|
*/
|
||||||
|
|
||||||
G_DEFINE_ABSTRACT_TYPE( VipsResample, vips_resample, VIPS_TYPE_OPERATION );
|
G_DEFINE_ABSTRACT_TYPE( VipsResample, vips_resample, VIPS_TYPE_OPERATION );
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
*
|
*
|
||||||
* 2/11/16
|
* 2/11/16
|
||||||
* - from vipsthumbnail.c
|
* - from vipsthumbnail.c
|
||||||
|
* 6/1/17
|
||||||
|
* - add @size parameter
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -68,6 +70,7 @@ typedef struct _VipsThumbnail {
|
|||||||
VipsImage *out;
|
VipsImage *out;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
VipsSize size;
|
||||||
|
|
||||||
gboolean auto_rotate;
|
gboolean auto_rotate;
|
||||||
gboolean crop;
|
gboolean crop;
|
||||||
@ -122,6 +125,7 @@ vips_thumbnail_calculate_shrink( VipsThumbnail *thumbnail,
|
|||||||
input_width : input_height;
|
input_width : input_height;
|
||||||
|
|
||||||
VipsDirection direction;
|
VipsDirection direction;
|
||||||
|
double shrink;
|
||||||
|
|
||||||
/* Calculate the horizontal and vertical shrink we'd need to fit the
|
/* Calculate the horizontal and vertical shrink we'd need to fit the
|
||||||
* image to the bounding box, and pick the biggest.
|
* image to the bounding box, and pick the biggest.
|
||||||
@ -145,8 +149,17 @@ vips_thumbnail_calculate_shrink( VipsThumbnail *thumbnail,
|
|||||||
direction = VIPS_DIRECTION_HORIZONTAL;
|
direction = VIPS_DIRECTION_HORIZONTAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return( direction == VIPS_DIRECTION_HORIZONTAL ?
|
shrink = direction == VIPS_DIRECTION_HORIZONTAL ?
|
||||||
horizontal : vertical );
|
horizontal : vertical;
|
||||||
|
|
||||||
|
/* Restrict to only upsize, only downsize, or both.
|
||||||
|
*/
|
||||||
|
if( thumbnail->size == VIPS_SIZE_UP )
|
||||||
|
shrink = VIPS_MIN( 1, shrink );
|
||||||
|
if( thumbnail->size == VIPS_SIZE_DOWN )
|
||||||
|
shrink = VIPS_MAX( 1, shrink );
|
||||||
|
|
||||||
|
return( shrink );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the best jpeg preload shrink.
|
/* Find the best jpeg preload shrink.
|
||||||
@ -497,35 +510,42 @@ vips_thumbnail_class_init( VipsThumbnailClass *class )
|
|||||||
G_STRUCT_OFFSET( VipsThumbnail, height ),
|
G_STRUCT_OFFSET( VipsThumbnail, height ),
|
||||||
1, VIPS_MAX_COORD, 1 );
|
1, VIPS_MAX_COORD, 1 );
|
||||||
|
|
||||||
VIPS_ARG_BOOL( class, "auto_rotate", 114,
|
VIPS_ARG_ENUM( class, "size", 114,
|
||||||
|
_( "size" ),
|
||||||
|
_( "Only upsize, only downsize, or both" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsThumbnail, size ),
|
||||||
|
VIPS_TYPE_SIZE, VIPS_SIZE_BOTH );
|
||||||
|
|
||||||
|
VIPS_ARG_BOOL( class, "auto_rotate", 115,
|
||||||
_( "Auto rotate" ),
|
_( "Auto rotate" ),
|
||||||
_( "Use orientation tags to rotate image upright" ),
|
_( "Use orientation tags to rotate image upright" ),
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsThumbnail, auto_rotate ),
|
G_STRUCT_OFFSET( VipsThumbnail, auto_rotate ),
|
||||||
TRUE );
|
TRUE );
|
||||||
|
|
||||||
VIPS_ARG_BOOL( class, "crop", 115,
|
VIPS_ARG_BOOL( class, "crop", 116,
|
||||||
_( "Crop" ),
|
_( "Crop" ),
|
||||||
_( "Reduce to fill target rectangle, then crop" ),
|
_( "Reduce to fill target rectangle, then crop" ),
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsThumbnail, crop ),
|
G_STRUCT_OFFSET( VipsThumbnail, crop ),
|
||||||
FALSE );
|
FALSE );
|
||||||
|
|
||||||
VIPS_ARG_BOOL( class, "linear", 116,
|
VIPS_ARG_BOOL( class, "linear", 117,
|
||||||
_( "Linear" ),
|
_( "Linear" ),
|
||||||
_( "Reduce in linear light" ),
|
_( "Reduce in linear light" ),
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsThumbnail, linear ),
|
G_STRUCT_OFFSET( VipsThumbnail, linear ),
|
||||||
FALSE );
|
FALSE );
|
||||||
|
|
||||||
VIPS_ARG_STRING( class, "import_profile", 117,
|
VIPS_ARG_STRING( class, "import_profile", 118,
|
||||||
_( "Import profile" ),
|
_( "Import profile" ),
|
||||||
_( "Fallback import profile" ),
|
_( "Fallback import profile" ),
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsThumbnail, import_profile ),
|
G_STRUCT_OFFSET( VipsThumbnail, import_profile ),
|
||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
VIPS_ARG_STRING( class, "export_profile", 118,
|
VIPS_ARG_STRING( class, "export_profile", 119,
|
||||||
_( "Export profile" ),
|
_( "Export profile" ),
|
||||||
_( "Fallback export profile" ),
|
_( "Fallback export profile" ),
|
||||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
@ -643,6 +663,7 @@ vips_thumbnail_file_init( VipsThumbnailFile *file )
|
|||||||
* Optional arguments:
|
* Optional arguments:
|
||||||
*
|
*
|
||||||
* * @height: %gint, target height in pixels
|
* * @height: %gint, target height in pixels
|
||||||
|
* * @size: #VipsSize, upsize, downsize or both
|
||||||
* * @auto_rotate: %gboolean, rotate upright using orientation tag
|
* * @auto_rotate: %gboolean, rotate upright using orientation tag
|
||||||
* * @crop: %gboolean, shrink and crop to fill target
|
* * @crop: %gboolean, shrink and crop to fill target
|
||||||
* * @linear: %gboolean, perform shrink in linear light
|
* * @linear: %gboolean, perform shrink in linear light
|
||||||
@ -658,11 +679,18 @@ vips_thumbnail_file_init( VipsThumbnailFile *file )
|
|||||||
* See vips_thumbnail_buffer() to thumbnail from a memory source.
|
* See vips_thumbnail_buffer() to thumbnail from a memory source.
|
||||||
*
|
*
|
||||||
* The output image will fit within a square of size @width x @width. You can
|
* The output image will fit within a square of size @width x @width. You can
|
||||||
* specify a height with the @height option.
|
* specify a separate height with the @height option.
|
||||||
*
|
*
|
||||||
* If you set @crop, then the output image will fill the whole of the @width x
|
* If you set @crop, then the output image will fill the whole of the @width x
|
||||||
* @height rectangle, with any excess cropped away.
|
* @height rectangle, with any excess cropped away.
|
||||||
*
|
*
|
||||||
|
* Normally the operation will upsize or downsize as required. If @size is set
|
||||||
|
* to #VIPS_SIZE_UP, the operation will only upsize and will just
|
||||||
|
* copy if asked to downsize.
|
||||||
|
* If @size is set
|
||||||
|
* to #VIPS_SIZE_DOWN, the operation will only downsize and will just
|
||||||
|
* copy if asked to upsize.
|
||||||
|
*
|
||||||
* Normally any orientation tags on the input image (such as EXIF tags) are
|
* Normally any orientation tags on the input image (such as EXIF tags) are
|
||||||
* interpreted to rotate the image upright. If you set @auto_rotate to %FALSE,
|
* interpreted to rotate the image upright. If you set @auto_rotate to %FALSE,
|
||||||
* these tags will not be interpreted.
|
* these tags will not be interpreted.
|
||||||
@ -803,6 +831,7 @@ vips_thumbnail_buffer_init( VipsThumbnailBuffer *buffer )
|
|||||||
* Optional arguments:
|
* Optional arguments:
|
||||||
*
|
*
|
||||||
* * @height: %gint, target height in pixels
|
* * @height: %gint, target height in pixels
|
||||||
|
* * @size: #VipsSize, upsize, downsize or both
|
||||||
* * @auto_rotate: %gboolean, rotate upright using orientation tag
|
* * @auto_rotate: %gboolean, rotate upright using orientation tag
|
||||||
* * @crop: %gboolean, shrink and crop to fill target
|
* * @crop: %gboolean, shrink and crop to fill target
|
||||||
* * @linear: %gboolean, perform shrink in linear light
|
* * @linear: %gboolean, perform shrink in linear light
|
||||||
|
@ -26,7 +26,7 @@ and write thumbnails to the files
|
|||||||
and
|
and
|
||||||
.B tn_jim.jpg.
|
.B tn_jim.jpg.
|
||||||
|
|
||||||
$ vipsthumbnail --size=64 -f thumbnails/%s.png fred.jpg
|
$ vipsthumbnail --size=64 -o thumbnails/%s.png fred.jpg
|
||||||
|
|
||||||
will read image file
|
will read image file
|
||||||
.B fred.jpg
|
.B fred.jpg
|
||||||
@ -42,10 +42,12 @@ x
|
|||||||
.B N
|
.B N
|
||||||
pixels. You can use MxN to specify a rectangular bounding box.
|
pixels. You can use MxN to specify a rectangular bounding box.
|
||||||
The image is shrunk so that it just fits within this area, images
|
The image is shrunk so that it just fits within this area, images
|
||||||
which are smaller than this are expanded.
|
which are smaller than this are expanded. Use "xN" or "Mx" to just resize on
|
||||||
|
one axis. Append "<" to only resize if the input image is smaller than the
|
||||||
|
target, append ">" to only resize if the input image is larger than the target.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B -f FORMAT, --format=FORMAT
|
.B -o FORMAT, --output=FORMAT
|
||||||
Set the output format string. The input filename has any file type suffix
|
Set the output format string. The input filename has any file type suffix
|
||||||
removed, then that value is substitued into
|
removed, then that value is substitued into
|
||||||
.B FORMAT
|
.B FORMAT
|
||||||
@ -65,27 +67,6 @@ prepended. You can add format options too, for example
|
|||||||
.B tn_%s.jpg[Q=20]
|
.B tn_%s.jpg[Q=20]
|
||||||
will write JPEG images with Q set to 20.
|
will write JPEG images with Q set to 20.
|
||||||
|
|
||||||
.TP
|
|
||||||
.B -p I, --interpolator=I
|
|
||||||
Resample with interpolator
|
|
||||||
.B I.
|
|
||||||
Use
|
|
||||||
.B vips --list classes
|
|
||||||
to see a list of valid interpolators. The default is
|
|
||||||
.B bilinear.
|
|
||||||
|
|
||||||
.TP
|
|
||||||
.B -r, --sharpen=none|mild|MASKFILE
|
|
||||||
Images can look a little soft after shrinking. This option lets you specify
|
|
||||||
a sharpening mask. Use "none" to disable sharpening, or "mild" to sharpen
|
|
||||||
lightly, or give the filename of a custom mask file to use. The default is
|
|
||||||
"mild". The built-in mild sharpen mask is:
|
|
||||||
|
|
||||||
3 3 24 0
|
|
||||||
-1 -1 -1
|
|
||||||
-1 32 -1
|
|
||||||
-1 -1 -1
|
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B -e PROFILE, --eprofile=PROFILE
|
.B -e PROFILE, --eprofile=PROFILE
|
||||||
Export thumbnails with this ICC profile. Images are only colour-transformed if
|
Export thumbnails with this ICC profile. Images are only colour-transformed if
|
||||||
@ -114,10 +95,12 @@ Delete the output profile from the image. This can save a small amount of
|
|||||||
space.
|
space.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B -v, --verbose
|
.B -t, --rotate
|
||||||
.B vipsthumbnail(1)
|
Auto-rotate images using EXIF orientation tags.
|
||||||
normally runs silently, except for warning and error messages. This option
|
|
||||||
makes it print a list of the operations it performs on each image.
|
.TP
|
||||||
|
.B -a, --linear
|
||||||
|
Shrink images in linear light colour space. This can be much slower.
|
||||||
|
|
||||||
.SH RETURN VALUE
|
.SH RETURN VALUE
|
||||||
returns 0 on success and non-zero on error. Error can mean one or more
|
returns 0 on success and non-zero on error. Error can mean one or more
|
||||||
|
@ -85,6 +85,11 @@
|
|||||||
* - use scRGB as the working space in linear mode
|
* - use scRGB as the working space in linear mode
|
||||||
* 15/8/16
|
* 15/8/16
|
||||||
* - can now remove 0.1 rounding adjustment
|
* - can now remove 0.1 rounding adjustment
|
||||||
|
* 2/11/16
|
||||||
|
* - use vips_thumbnail(), most code moved there
|
||||||
|
* 6/1/17
|
||||||
|
* - fancy geometry strings
|
||||||
|
* - support VipSize restrictions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
@ -108,6 +113,7 @@
|
|||||||
static char *thumbnail_size = "128";
|
static char *thumbnail_size = "128";
|
||||||
static int thumbnail_width = 128;
|
static int thumbnail_width = 128;
|
||||||
static int thumbnail_height = 128;
|
static int thumbnail_height = 128;
|
||||||
|
static VipsSize size_restriction = VIPS_SIZE_BOTH;
|
||||||
static char *output_format = "tn_%s.jpg";
|
static char *output_format = "tn_%s.jpg";
|
||||||
static char *export_profile = NULL;
|
static char *export_profile = NULL;
|
||||||
static char *import_profile = NULL;
|
static char *import_profile = NULL;
|
||||||
@ -229,10 +235,11 @@ thumbnail_write( VipsObject *process, VipsImage *im, const char *filename )
|
|||||||
static int
|
static int
|
||||||
thumbnail_process( VipsObject *process, const char *filename )
|
thumbnail_process( VipsObject *process, const char *filename )
|
||||||
{
|
{
|
||||||
VipsImage *in;
|
VipsImage *image;
|
||||||
|
|
||||||
if( vips_thumbnail( filename, &in, thumbnail_width,
|
if( vips_thumbnail( filename, &image, thumbnail_width,
|
||||||
"height", thumbnail_height,
|
"height", thumbnail_height,
|
||||||
|
"size", size_restriction,
|
||||||
"auto_rotate", rotate_image,
|
"auto_rotate", rotate_image,
|
||||||
"crop", crop_image,
|
"crop", crop_image,
|
||||||
"linear", linear_processing,
|
"linear", linear_processing,
|
||||||
@ -241,52 +248,103 @@ thumbnail_process( VipsObject *process, const char *filename )
|
|||||||
NULL ) )
|
NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( thumbnail_write( process, in, filename ) ) {
|
if( thumbnail_write( process, image, filename ) ) {
|
||||||
g_object_unref( in );
|
g_object_unref( image );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref( in );
|
g_object_unref( image );
|
||||||
|
|
||||||
return( 0 );
|
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( strcmp( str, "" ) == 0 ? NULL : str );
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse a geometry string and set thumbnail_width and thumbnail_height.
|
/* Parse a geometry string and set thumbnail_width and thumbnail_height.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
thumbnail_parse_geometry( const char *geometry )
|
thumbnail_parse_geometry( const char *geometry )
|
||||||
{
|
{
|
||||||
GRegEx *regex;
|
GRegex *regex;
|
||||||
|
GMatchInfo *match_info;
|
||||||
regex = g_regex_new( "^(\d+)? (x)? (\d+)? ([<>])?$",
|
|
||||||
G_REGEX_CASELESS | G_REGEX_EXTENDED, 0, NULL );
|
|
||||||
g_regex_match( regex, geometry, 0, &match_info );
|
|
||||||
if(
|
|
||||||
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
/* Up to 'x'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int w, h;
|
|
||||||
gboolean handled;
|
gboolean handled;
|
||||||
|
|
||||||
handled = FALSE;
|
handled = FALSE;
|
||||||
|
|
||||||
if( sscanf( geometry, "%d x %d <", &w, &h ) == 2 ) {
|
regex = g_regex_new( "^(\\d+)? (x)? (\\d+)? ([<>])?$",
|
||||||
thumbnail_width = w;
|
G_REGEX_CASELESS | G_REGEX_EXTENDED, 0, NULL );
|
||||||
thumbnail_height = h;
|
g_regex_match( regex, geometry, 0, &match_info );
|
||||||
crop_image = FALSE;
|
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 );
|
||||||
|
|
||||||
|
/* If --crop is set, both width and height must be specified,
|
||||||
|
* since we'll need a complete bounding box to fill.
|
||||||
|
*/
|
||||||
|
if( crop_image && x && (!w || !h) ) {
|
||||||
|
vips_error( "thumbnail",
|
||||||
|
"both width and height must be given if "
|
||||||
|
"--crop is enabled" );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( sscanf( geometry, "%d x %d >", &w, &h ) == 2 ) {
|
g_match_info_free( match_info );
|
||||||
thumbnail_width = w;
|
g_regex_unref( regex );
|
||||||
thumbnail_height = h;
|
|
||||||
crop_image = TRUE;
|
if( !handled ) {
|
||||||
|
vips_error( "thumbnail",
|
||||||
|
"unable to parse size \"%s\" -- "
|
||||||
|
"use eg. 128 or 200x300>", geometry );
|
||||||
|
|
||||||
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -334,40 +392,15 @@ main( int argc, char **argv )
|
|||||||
|
|
||||||
g_option_context_free( context );
|
g_option_context_free( context );
|
||||||
|
|
||||||
/*
|
if( thumbnail_parse_geometry( thumbnail_size ) )
|
||||||
if( sscanf( thumbnail_size, "%d x %d",
|
vips_error_exit( NULL );
|
||||||
&thumbnail_width, &thumbnail_height ) == 2 ) {
|
|
||||||
if( sscanf( thumbnail_size, "%d", &thumbnail_width ) != 1 )
|
|
||||||
vips_error_exit( "unable to parse size \"%s\" -- "
|
|
||||||
"use eg. 128 or 200x300", thumbnail_size );
|
|
||||||
|
|
||||||
thumbnail_height = thumbnail_width;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if( sscanf( thumbnail_size, "%d x %d",
|
|
||||||
&thumbnail_width, &thumbnail_height ) == 2 ) {
|
|
||||||
if( sscanf( thumbnail_size, "%d", &thumbnail_width ) != 1 )
|
|
||||||
vips_error_exit( "unable to parse size \"%s\" -- "
|
|
||||||
"use eg. 128 or 200x300", thumbnail_size );
|
|
||||||
|
|
||||||
thumbnail_height = thumbnail_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( sscanf( thumbnail_size, "%d", &thumbnail_width ) != 1 )
|
|
||||||
|
|
||||||
thumbnail_height = thumbnail_width;
|
|
||||||
}
|
|
||||||
vips_error_exit( "unable to parse size \"%s\" -- "
|
|
||||||
"use eg. 128 or 200x300", thumbnail_size );
|
|
||||||
|
|
||||||
if( rotate_image ) {
|
|
||||||
#ifndef HAVE_EXIF
|
#ifndef HAVE_EXIF
|
||||||
|
if( rotate_image )
|
||||||
g_warning( "%s",
|
g_warning( "%s",
|
||||||
_( "auto-rotate disabled: "
|
_( "auto-rotate disabled: "
|
||||||
"libvips built without exif support" ) );
|
"libvips built without exif support" ) );
|
||||||
#endif /*!HAVE_EXIF*/
|
#endif /*!HAVE_EXIF*/
|
||||||
}
|
|
||||||
|
|
||||||
result = 0;
|
result = 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user