diff --git a/libvips/Makefile.am b/libvips/Makefile.am index d0240d68..7640d325 100644 --- a/libvips/Makefile.am +++ b/libvips/Makefile.am @@ -21,7 +21,7 @@ SUBDIRS = \ $(C_COMPILE_DIR) \ freqfilt \ histogram \ - inplace \ + draw \ iofuncs \ morphology \ mosaicing \ @@ -54,7 +54,7 @@ libvips_la_LIBADD = \ foreign/libforeign.la \ freqfilt/libfreqfilt.la \ histogram/libhistogram.la \ - inplace/libinplace.la \ + draw/libdraw.la \ iofuncs/libiofuncs.la \ morphology/libmorphology.la \ mosaicing/libmosaicing.la \ diff --git a/libvips/inplace/Makefile.am b/libvips/draw/Makefile.am similarity index 78% rename from libvips/inplace/Makefile.am rename to libvips/draw/Makefile.am index 1210f4cd..b8070fb1 100644 --- a/libvips/inplace/Makefile.am +++ b/libvips/draw/Makefile.am @@ -1,8 +1,8 @@ -noinst_LTLIBRARIES = libinplace.la +noinst_LTLIBRARIES = libdraw.la -libinplace_la_SOURCES = \ +libdraw_la_SOURCES = \ draw.c \ - draw.h \ + pdraw.h \ flood.c \ im_draw_circle.c \ im_draw_line.c \ diff --git a/libvips/draw/circle.c b/libvips/draw/circle.c new file mode 100644 index 00000000..50f6fbb7 --- /dev/null +++ b/libvips/draw/circle.c @@ -0,0 +1,288 @@ +/* draw a circle on an image + * + * Author N. Dessipris + * Written on 30/05/1990 + * Updated on: + * 22/7/93 JC + * - im_incheck() call added + * 16/8/94 JC + * - im_incheck() changed to im_makerw() + * 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 + * 18/8/10 + * - gtkdoc + * - rewritten: clips, fills, any bands, any format + * 27/9/10 + * - break base out to Draw + * 3/2/14 + * - redo as a class + */ + +/* + + 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 "pdraw.h" + +G_DEFINE_TYPE( VipsCircle, vips_circle, VIPS_TYPE_DRAW ); + +typedef struct _VipsCircle { + VipsDraw parent_object; + + int x, y; + int radius; + gboolean fill; + + VipsPel *centre; +} VipsCircle; + +typedef VipsDrawClass VipsCircleClass; + +static int +vips_circle_build( VipsObject *object ) +{ + VipsConversion *conversion = VIPS_CONVERSION( object ); + VipsCircle *circle = (VipsCircle *) object; + + if( VIPS_OBJECT_CLASS( vips_falsecolour_parent_class )-> + build( object ) ) + return( -1 ); + if( x + radius >= 0 && x - radius < image->Xsize && + y + radius >= 0 && y - radius < image->Ysize ) { + VipsCircle *circle; + + if( !(circle = circle_new( image, x, y, radius, fill, ink )) ) + return( -1 ); + circle_draw( circle ); + + circle_free( circle ); + } + + return( 0 ); +} + + + return( 0 ); +} + +static void +vips_circle_class_init( VipsFalsecolourClass *class ) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS( class ); + VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class ); + VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class ); + + gobject_class->set_property = vips_object_set_property; + gobject_class->get_property = vips_object_get_property; + + vobject_class->nickname = "circle"; + vobject_class->description = _( "draw a circle on an image" ); + vobject_class->build = vips_circle_build; + + VIPS_ARG_INT( class, "x", 2, + _( "x" ), + _( "Centre of circle" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsCircle, x ), + -1000000000, 1000000000, 0 ); + + VIPS_ARG_INT( class, "y", 3, + _( "y" ), + _( "Centre of circle" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsCircle, y ), + -1000000000, 1000000000, 0 ); + + VIPS_ARG_INT( class, "radius", 3, + _( "radius" ), + _( "Radius in pixels" ), + VIPS_ARGUMENT_REQUIRED_INPUT, + G_STRUCT_OFFSET( VipsCircle, radius ), + 0, 1000000000, 0 ); + + VIPS_ARG_BOOL( class, "fill", 3, + _( "fill" ), + _( "Draw a solid object" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsCircle, fill ), + 0, 1000000000, 0 ); + +} + +static void +vips_circle_init( VipsCircle *circle ) +{ +} + + + + + +static void +vips_circle_octants( VipsCircle *circle, int x, int y ) +{ + Draw *draw = DRAW( circle ); + + if( circle->fill ) { + const int cx = circle->cx; + const int cy = circle->cy; + + im__draw_scanline( draw, cy + y, cx - x, cx + x ); + im__draw_scanline( draw, cy - y, cx - x, cx + x ); + im__draw_scanline( draw, cy + x, cx - y, cx + y ); + im__draw_scanline( draw, cy - x, cx - y, cx + y ); + } + else if( DRAW( circle )->noclip ) { + const size_t lsize = draw->lsize; + const size_t psize = draw->psize; + VipsPel *centre = circle->centre; + + im__draw_pel( draw, centre + lsize * y - psize * x ); + im__draw_pel( draw, centre + lsize * y + psize * x ); + im__draw_pel( draw, centre - lsize * y - psize * x ); + im__draw_pel( draw, centre - lsize * y + psize * x ); + im__draw_pel( draw, centre + lsize * x - psize * y ); + im__draw_pel( draw, centre + lsize * x + psize * y ); + im__draw_pel( draw, centre - lsize * x - psize * y ); + im__draw_pel( draw, centre - lsize * x + psize * y ); + } + else { + const int cx = circle->cx; + const int cy = circle->cy; + + im__draw_pel_clip( draw, cx + y, cy - x ); + im__draw_pel_clip( draw, cx + y, cy + x ); + im__draw_pel_clip( draw, cx - y, cy - x ); + im__draw_pel_clip( draw, cx - y, cy + x ); + im__draw_pel_clip( draw, cx + x, cy - y ); + im__draw_pel_clip( draw, cx + x, cy + y ); + im__draw_pel_clip( draw, cx - x, cy - y ); + im__draw_pel_clip( draw, cx - x, cy + y ); + } +} + +static void +vips_circle_free( VipsCircle *circle ) +{ + im__draw_free( DRAW( circle ) ); + im_free( circle ); +} + +static VipsCircle * +vips_circle_new( IMAGE *im, int cx, int cy, int radius, gboolean fill, VipsPel *ink ) +{ + VipsCircle *circle; + + if( im_check_coding_known( "im_draw_circle", im ) ) + return( NULL ); + if( !(circle = IM_NEW( NULL, VipsCircle )) ) + return( NULL ); + if( !im__draw_init( DRAW( circle ), im, ink ) ) { + circle_free( circle ); + return( NULL ); + } + + circle->cx = cx; + circle->cy = cy; + circle->radius = radius; + circle->fill = fill; + circle->centre = IM_IMAGE_ADDR( im, cx, cy ); + + if( cx - radius >= 0 && cx + radius < im->Xsize && + cy - radius >= 0 && cy + radius < im->Ysize ) + DRAW( circle )->noclip = TRUE; + + return( circle ); +} + +static void +vips_circle_draw( VipsCircle *circle ) +{ + int x, y, d; + + y = circle->radius; + d = 3 - 2 * circle->radius; + + for( x = 0; x < y; x++ ) { + circle_octants( circle, x, y ); + + if( d < 0 ) + d += 4 * x + 6; + else { + d += 4 * (x - y) + 10; + y--; + } + } + + if( x == y ) + circle_octants( circle, x, y ); +} + +/** + * vips_circle: + * @image: image to draw on + * @x: centre of circle + * @y: centre of circle + * @radius: circle radius + * @fill: fill the circle + * @ink: value to draw + * + * Draws a circle on @image. If @fill is %TRUE then the circle is filled, + * otherwise a 1-pixel-wide perimeter is drawn. + * + * @ink is an array of bytes containing a valid pixel for the image's format. + * It must have at least IM_IMAGE_SIZEOF_PEL( @image ) bytes. + * + * See also: im_draw_line(). + * + * Returns: 0 on success, or -1 on error. + */ +int +vips_circle( VipsImage *image, + int x, int y, int radius, gboolean fill, VipsPel *ink ) +{ + va_list ap; + int result; + + va_start( ap, out ); + result = vips_call_split( "circle", ap, in, out ); + va_end( ap ); + + return( result ); +} + diff --git a/libvips/inplace/draw.c b/libvips/draw/draw.c similarity index 94% rename from libvips/inplace/draw.c rename to libvips/draw/draw.c index c39b696c..4ebac8e3 100644 --- a/libvips/inplace/draw.c +++ b/libvips/draw/draw.c @@ -45,9 +45,8 @@ #include "draw.h" /** - * SECTION: inplace - * @short_description: in-place paintbox operations: flood, paste, line, - * circle + * SECTION: draw + * @short_description: drawing operations: flood, paste, line, circle * @stability: Stable * @include: vips/vips.h * @@ -55,9 +54,7 @@ * machines they will be limited to 2GB images, and a little care needs to be * taken if you use them as part of an image pipeline. * - * They are mostly supposed to be useful - * for paintbox-style programs. - * + * They are mostly supposed to be useful for paintbox-style programs. */ G_DEFINE_ABSTRACT_TYPE( VipsDraw, vips_draw, VIPS_TYPE_OPERATION ); @@ -105,7 +102,7 @@ vips_draw_class_init( VipsDrawClass *class ) vobject_class->description = _( "Draw operations" ); vobject_class->build = vips_draw_build; - VIPS_ARG_IMAGE( class, "im", 1, + VIPS_ARG_IMAGE( class, "image", 1, _( "Image" ), _( "Image to draw on" ), VIPS_ARGUMENT_REQUIRED_INPUT, diff --git a/libvips/inplace/flood.c b/libvips/draw/flood.c similarity index 100% rename from libvips/inplace/flood.c rename to libvips/draw/flood.c diff --git a/libvips/inplace/im_draw_circle.c b/libvips/draw/im_draw_circle.c similarity index 100% rename from libvips/inplace/im_draw_circle.c rename to libvips/draw/im_draw_circle.c diff --git a/libvips/inplace/im_draw_image.c b/libvips/draw/im_draw_image.c similarity index 100% rename from libvips/inplace/im_draw_image.c rename to libvips/draw/im_draw_image.c diff --git a/libvips/inplace/im_draw_line.c b/libvips/draw/im_draw_line.c similarity index 100% rename from libvips/inplace/im_draw_line.c rename to libvips/draw/im_draw_line.c diff --git a/libvips/inplace/im_draw_mask.c b/libvips/draw/im_draw_mask.c similarity index 100% rename from libvips/inplace/im_draw_mask.c rename to libvips/draw/im_draw_mask.c diff --git a/libvips/inplace/im_draw_point.c b/libvips/draw/im_draw_point.c similarity index 100% rename from libvips/inplace/im_draw_point.c rename to libvips/draw/im_draw_point.c diff --git a/libvips/inplace/im_draw_rect.c b/libvips/draw/im_draw_rect.c similarity index 100% rename from libvips/inplace/im_draw_rect.c rename to libvips/draw/im_draw_rect.c diff --git a/libvips/inplace/im_draw_smudge.c b/libvips/draw/im_draw_smudge.c similarity index 100% rename from libvips/inplace/im_draw_smudge.c rename to libvips/draw/im_draw_smudge.c diff --git a/libvips/inplace/inplace_dispatch.c b/libvips/draw/inplace_dispatch.c similarity index 100% rename from libvips/inplace/inplace_dispatch.c rename to libvips/draw/inplace_dispatch.c diff --git a/libvips/inplace/draw.h b/libvips/draw/pdraw.h similarity index 94% rename from libvips/inplace/draw.h rename to libvips/draw/pdraw.h index f2c9a0d8..ad31a225 100644 --- a/libvips/inplace/draw.h +++ b/libvips/draw/pdraw.h @@ -28,8 +28,8 @@ */ -#ifndef VIPS_DRAW_H -#define VIPS_DRAW_H +#ifndef VIPS_PDRAW_H +#define VIPS_PDRAW_H #ifdef __cplusplus extern "C" { @@ -55,7 +55,7 @@ typedef struct _VipsDraw { /* Parameters. */ - VipsImage *im; /* Draw here */ + VipsImage *image; /* Draw here */ VipsArea *ink; /* With this */ /* Derived stuff. @@ -120,10 +120,10 @@ vips__draw_painted( VipsDraw *draw, VipsPel *p ) return( j == draw->psize ); } -void vips__draw_scanline( Draw *draw, int y, int x1, int x2 ); +void vips__draw_scanline( VipsDraw *draw, int y, int x1, int x2 ); #ifdef __cplusplus } #endif /*__cplusplus*/ -#endif /*VIPS_DRAW_H*/ +#endif /*VIPS_PDRAW_H*/ diff --git a/libvips/include/vips/Makefile.am b/libvips/include/vips/Makefile.am index 6ced549d..9f7b796e 100644 --- a/libvips/include/vips/Makefile.am +++ b/libvips/include/vips/Makefile.am @@ -16,7 +16,7 @@ pkginclude_HEADERS = \ operation.h \ format.h \ foreign.h \ - inplace.h \ + draw.h \ generate.h \ header.h \ histogram.h \ diff --git a/libvips/include/vips/inplace.h b/libvips/include/vips/draw.h similarity index 96% rename from libvips/include/vips/inplace.h rename to libvips/include/vips/draw.h index 0e2c3bb3..11f26bc9 100644 --- a/libvips/include/vips/inplace.h +++ b/libvips/include/vips/draw.h @@ -1,4 +1,4 @@ -/* inplace.h +/* draw.h * * 3/11/09 * - from proto.h @@ -31,8 +31,8 @@ */ -#ifndef IM_INPLACE_H -#define IM_INPLACE_H +#ifndef VIPS_DRAW_H +#define VIPS_DRAW_H #ifdef __cplusplus extern "C" { @@ -74,4 +74,4 @@ int im_draw_smudge( VipsImage *image, } #endif /*__cplusplus*/ -#endif /*IM_INPLACE_H*/ +#endif /*VIPS_DRAW_H*/