diff --git a/TODO b/TODO index b03aa06a..dec2d3f7 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,13 @@ +- we will need a fastlineuser, or have to modify nip2 + +- try: + + im = VIPS::Image.new(ARGV[0]) + mask = im.less(240) + columns, rows = mask.project + + with wtc.jpg, segv if libvips is compiled with -O, OK without + - ink to vec etc. should work for complex .. output or accept a double-length vector diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index f84b8087..7cd076e0 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -4554,10 +4554,8 @@ im_draw_line_user( VipsImage *image, int x1, int y1, int x2, int y2, VipsPlotFn plot, void *a, void *b, void *c ) { - im_error( "im_draw_line_user", - "not supported ... use a VipsLine subclass instead, " - "or vips_line_mask()" ); - return( -1 ); + return( vips_line_user( image, x1, y1, x2, y2, + plot, a, b, c, NULL ) ); } int diff --git a/libvips/draw/Makefile.am b/libvips/draw/Makefile.am index ab5486bc..9ab16276 100644 --- a/libvips/draw/Makefile.am +++ b/libvips/draw/Makefile.am @@ -8,6 +8,7 @@ libdraw_la_SOURCES = \ flood.c \ paintmask.c \ linemask.c \ + lineuser.c \ im_draw_image.c \ im_draw_point.c \ im_draw_rect.c \ diff --git a/libvips/draw/draw.c b/libvips/draw/draw.c index 76eb2ea7..3534e89e 100644 --- a/libvips/draw/draw.c +++ b/libvips/draw/draw.c @@ -83,9 +83,10 @@ vips_draw_build( VipsObject *object ) draw->psize = VIPS_IMAGE_SIZEOF_PEL( draw->image ); draw->noclip = FALSE; - if( !(draw->pixel_ink = vips__vector_to_ink( - class->nickname, draw->image, - draw->ink->data, draw->ink->n )) ) + if( draw->ink && + !(draw->pixel_ink = vips__vector_to_ink( + class->nickname, draw->image, + draw->ink->data, draw->ink->n )) ) return( -1 ); return( 0 ); @@ -132,12 +133,14 @@ vips_draw_operation_init( void ) extern GType vips_paintmask_get_type( void ); extern GType vips_line_get_type( void ); extern GType vips_line_mask_get_type( void ); + extern GType vips_line_user_get_type( void ); extern GType vips_circle_get_type( void ); extern GType vips_flood_get_type( void ); vips_paintmask_get_type(); vips_line_get_type(); vips_line_mask_get_type(); + vips_line_user_get_type(); vips_circle_get_type(); vips_flood_get_type(); } diff --git a/libvips/draw/lineuser.c b/libvips/draw/lineuser.c new file mode 100644 index 00000000..47b64386 --- /dev/null +++ b/libvips/draw/lineuser.c @@ -0,0 +1,173 @@ +/* call a user function along a line ... useful for vips7 compat + * + * Copyright: J. Cupitt + * Written: 15/06/1992 + * 22/7/93 JC + * - im_incheck() added + * 16/8/94 JC + * - im_incheck() changed to im_makerw() + * 24/10/03 JC + * - now blends with 0-255 user + * 5/12/06 + * - im_invalidate() after paint + * 6/3/10 + * - don't im_invalidate() after paint, this now needs to be at a higher + * level + * 28/9/10 + * - gtk-doc + * - renamed as im_draw_user() + * - use Draw base class + * 6/2/14 + * - now a subclass of VipsLine + * 9/2/14 + * - from lineuser + */ + + + +/* + + This file is part of VIPS. + + VIPS is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA + + */ + +/* + + These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk + + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /*HAVE_CONFIG_H*/ +#include + +#include +#include + +#include + +#include "pdraw.h" +#include "line.h" + +typedef struct _VipsLineUser { + VipsLine parent_object; + + VipsPlotFn plot_fn; + void *a; + void *b; + void *c; + +} VipsLineUser; + +typedef VipsLineClass VipsLineUserClass; + +G_DEFINE_TYPE( VipsLineUser, vips_line_user, VIPS_TYPE_LINE ); + +static int +vips_line_user_plot_point( VipsLine *line, int x, int y ) +{ + VipsDraw *draw = (VipsDraw *) line; + VipsLineUser *line_user = (VipsLineUser *) line; + + return( line_user->plot_fn( draw->image, + x, y, line_user->a, line_user->b, line_user->c ) ); +} + +static void +vips_line_user_class_init( VipsLineUserClass *class ) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS( class ); + VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class ); + VipsOperationClass *operation_class = (VipsOperationClass *) class; + + gobject_class->set_property = vips_object_set_property; + gobject_class->get_property = vips_object_get_property; + + vobject_class->nickname = "line_user"; + vobject_class->description = _( "call a plot function along a line" ); + + operation_class->flags = VIPS_OPERATION_DEPRECATED; + + class->plot_point = vips_line_user_plot_point; + + VIPS_ARG_POINTER( class, "plot_fn", 7, + _( "Plot" ), + _( "User plot function" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsLineUser, plot_fn ) ); + + VIPS_ARG_POINTER( class, "a", 8, + _( "a" ), + _( "first user argument" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsLineUser, a ) ); + + VIPS_ARG_POINTER( class, "b", 9, + _( "b" ), + _( "second user argument" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsLineUser, b ) ); + + VIPS_ARG_POINTER( class, "c", 10, + _( "c" ), + _( "third user argument" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsLineUser, c ) ); + +} + +static void +vips_line_user_init( VipsLineUser *line_user ) +{ +} + +/** + * vips_line_user: + * @image: image to draw on + * @x1: start of line + * @y1: start of line + * @x2: end of line + * @y2: end of line + * @user: plot function to call along line + * @a: user plot function argument + * @b: user plot function argument + * @c: user plot function argument + * + * Calls a user plot function for every point on a line. This is mostly useful + * for vips7 compatibility. + * + * See also: vips_line(), vips_line_mask(). + * + * Returns: 0 on success, or -1 on error. + */ +int +vips_line_user( VipsImage *image, + int x1, int y1, int x2, int y2, + VipsPlotFn plot_fn, void *a, void *b, void *c, ... ) +{ + va_list ap; + int result; + + va_start( ap, c ); + result = vips_call_split( "line_user", ap, + image, NULL, x1, y1, x2, y2, plot_fn, a, b, c ); + va_end( ap ); + + return( result ); +} diff --git a/libvips/include/vips/draw.h b/libvips/include/vips/draw.h index 6857ca19..1ed06eab 100644 --- a/libvips/include/vips/draw.h +++ b/libvips/include/vips/draw.h @@ -51,6 +51,18 @@ int vips_line( VipsImage *image, int vips_line1( VipsImage *image, double ink, int x1, int y1, int x2, int y2, ... ) __attribute__((sentinel)); +int vips_line_mask( VipsImage *image, + double *ink, int n, int x1, int y1, int x2, int y2, + VipsImage *mask, ... ) + __attribute__((sentinel)); +int vips_line_mask1( VipsImage *image, + double ink, int x1, int y1, int x2, int y2, VipsImage *mask, ... ) + __attribute__((sentinel)); +typedef int (*VipsPlotFn)( VipsImage *, int, int, void *, void *, void * ); +int vips_line_user( VipsImage *image, + int x1, int y1, int x2, int y2, + VipsPlotFn plot_fn, void *a, void *b, void *c, ... ) + __attribute__((sentinel)); int vips_circle( VipsImage *image, double *ink, int n, int cx, int cy, int radius, ... )