start on inplace
This commit is contained in:
parent
c8c532a068
commit
407f036a87
@ -289,6 +289,7 @@ void vips_freqfilt_operation_init( void );
|
|||||||
void vips_create_operation_init( void );
|
void vips_create_operation_init( void );
|
||||||
void vips_morphology_operation_init( void );
|
void vips_morphology_operation_init( void );
|
||||||
void vips_convolution_operation_init( void );
|
void vips_convolution_operation_init( void );
|
||||||
|
void vips_draw_operation_init( void );
|
||||||
|
|
||||||
guint64 vips__parse_size( const char *size_string );
|
guint64 vips__parse_size( const char *size_string );
|
||||||
|
|
||||||
|
@ -44,10 +44,101 @@
|
|||||||
|
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SECTION: inplace
|
||||||
|
* @short_description: in-place paintbox operations: flood, paste, line,
|
||||||
|
* circle
|
||||||
|
* @stability: Stable
|
||||||
|
* @include: vips/vips.h
|
||||||
|
*
|
||||||
|
* These operations directly modify the image. They do not thread, on 32-bit
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
G_DEFINE_ABSTRACT_TYPE( VipsDraw, vips_draw, VIPS_TYPE_OPERATION );
|
||||||
|
|
||||||
|
static int
|
||||||
|
vips_draw_build( VipsObject *object )
|
||||||
|
{
|
||||||
|
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
|
||||||
|
VipsDraw *draw = VIPS_DRAW( object );
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf( "vips_draw_build: " );
|
||||||
|
vips_object_print_name( object );
|
||||||
|
printf( "\n" );
|
||||||
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
|
if( VIPS_OBJECT_CLASS( vips_draw_parent_class )->build( object ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
if( vips_image_inplace( draw->im ) )
|
||||||
|
return( NULL );
|
||||||
|
|
||||||
|
draw->lsize = VIPS_IMAGE_SIZEOF_LINE( draw->im );
|
||||||
|
draw->psize = VIPS_IMAGE_SIZEOF_PEL( draw->im );
|
||||||
|
draw->noclip = FALSE;
|
||||||
|
|
||||||
|
if( !(draw->pixel_ink = vips__vector_to_ink(
|
||||||
|
class->nickname, draw->im,
|
||||||
|
draw->ink->data, draw->ink->n )) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_draw_class_init( VipsDrawClass *class )
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||||
|
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
|
||||||
|
|
||||||
|
gobject_class->set_property = vips_object_set_property;
|
||||||
|
gobject_class->get_property = vips_object_get_property;
|
||||||
|
|
||||||
|
vobject_class->nickname = "draw";
|
||||||
|
vobject_class->description = _( "Draw operations" );
|
||||||
|
vobject_class->build = vips_draw_build;
|
||||||
|
|
||||||
|
VIPS_ARG_IMAGE( class, "im", 1,
|
||||||
|
_( "Image" ),
|
||||||
|
_( "Image to draw on" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsDraw, im ) );
|
||||||
|
|
||||||
|
VIPS_ARG_BOXED( class, "ink", 12,
|
||||||
|
_( "Ink" ),
|
||||||
|
_( "Colour for pixels" ),
|
||||||
|
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsDraw, ink ),
|
||||||
|
VIPS_TYPE_ARRAY_DOUBLE );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_draw_init( VipsDraw *draw )
|
||||||
|
{
|
||||||
|
draw->ink = vips_area_new_array( G_TYPE_DOUBLE, sizeof( double ), 1 );
|
||||||
|
((double *) (draw->ink->data))[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
vips_draw_operation_init( void )
|
||||||
|
{
|
||||||
|
extern GType vips_copy_get_type( void );
|
||||||
|
|
||||||
|
vips_copy_get_type();
|
||||||
|
}
|
||||||
|
|
||||||
/* Fill a scanline between points x1 and x2 inclusive. x1 < x2.
|
/* Fill a scanline between points x1 and x2 inclusive. x1 < x2.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
im__draw_scanline( Draw *draw, int y, int x1, int x2 )
|
vips__draw_scanline( VipsDraw *draw, int y, int x1, int x2 )
|
||||||
{
|
{
|
||||||
VipsPel *mp;
|
VipsPel *mp;
|
||||||
int i;
|
int i;
|
||||||
@ -55,48 +146,24 @@ im__draw_scanline( Draw *draw, int y, int x1, int x2 )
|
|||||||
|
|
||||||
g_assert( x1 <= x2 );
|
g_assert( x1 <= x2 );
|
||||||
|
|
||||||
if( y < 0 || y >= draw->im->Ysize )
|
if( y < 0 ||
|
||||||
|
y >= draw->im->Ysize )
|
||||||
return;
|
return;
|
||||||
if( x1 < 0 && x2 < 0 )
|
if( x1 < 0 &&
|
||||||
|
x2 < 0 )
|
||||||
return;
|
return;
|
||||||
if( x1 >= draw->im->Xsize && x2 >= draw->im->Xsize )
|
if( x1 >= draw->im->Xsize &&
|
||||||
|
x2 >= draw->im->Xsize )
|
||||||
return;
|
return;
|
||||||
x1 = IM_CLIP( 0, x1, draw->im->Xsize - 1 );
|
x1 = VIPS_CLIP( 0, x1, draw->im->Xsize - 1 );
|
||||||
x2 = IM_CLIP( 0, x2, draw->im->Xsize - 1 );
|
x2 = VIPS_CLIP( 0, x2, draw->im->Xsize - 1 );
|
||||||
|
|
||||||
mp = IM_IMAGE_ADDR( draw->im, x1, y );
|
mp = VIPS_IMAGE_ADDR( draw->im, x1, y );
|
||||||
len = x2 - x1 + 1;
|
len = x2 - x1 + 1;
|
||||||
|
|
||||||
for( i = 0; i < len; i++ ) {
|
for( i = 0; i < len; i++ ) {
|
||||||
im__draw_pel( draw, mp );
|
vips__draw_pel( draw, mp );
|
||||||
mp += draw->psize;
|
mp += draw->psize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
im__draw_free( Draw *draw )
|
|
||||||
{
|
|
||||||
IM_FREE( draw->ink );
|
|
||||||
}
|
|
||||||
|
|
||||||
Draw *
|
|
||||||
im__draw_init( Draw *draw, IMAGE *im, VipsPel *ink )
|
|
||||||
{
|
|
||||||
if( im_rwcheck( im ) )
|
|
||||||
return( NULL );
|
|
||||||
|
|
||||||
draw->im = im;
|
|
||||||
draw->ink = NULL;
|
|
||||||
|
|
||||||
draw->lsize = IM_IMAGE_SIZEOF_LINE( im );
|
|
||||||
draw->psize = IM_IMAGE_SIZEOF_PEL( im );
|
|
||||||
draw->noclip = FALSE;
|
|
||||||
|
|
||||||
if( ink ) {
|
|
||||||
if( !(draw->ink = (VipsPel *) im_malloc( NULL, draw->psize )) )
|
|
||||||
return( NULL );
|
|
||||||
memcpy( draw->ink, ink, draw->psize );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( draw );
|
|
||||||
}
|
|
||||||
|
@ -28,65 +28,102 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Our state.
|
#ifndef VIPS_DRAW_H
|
||||||
*/
|
#define VIPS_DRAW_H
|
||||||
typedef struct _Draw {
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /*__cplusplus*/
|
||||||
|
|
||||||
|
#define VIPS_TYPE_DRAW (vips_draw_get_type())
|
||||||
|
#define VIPS_DRAW( obj ) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
|
||||||
|
VIPS_TYPE_DRAW, VipsDraw ))
|
||||||
|
#define VIPS_DRAW_CLASS( klass ) \
|
||||||
|
(G_TYPE_CHECK_CLASS_CAST( (klass), \
|
||||||
|
VIPS_TYPE_DRAW, VipsDrawClass))
|
||||||
|
#define VIPS_IS_DRAW( obj ) \
|
||||||
|
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_DRAW ))
|
||||||
|
#define VIPS_IS_DRAW_CLASS( klass ) \
|
||||||
|
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_DRAW ))
|
||||||
|
#define VIPS_DRAW_GET_CLASS( obj ) \
|
||||||
|
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
|
||||||
|
VIPS_TYPE_DRAW, VipsDrawClass ))
|
||||||
|
|
||||||
|
typedef struct _VipsDraw {
|
||||||
|
VipsOperation parent_instance;
|
||||||
|
|
||||||
/* Parameters.
|
/* Parameters.
|
||||||
*/
|
*/
|
||||||
IMAGE *im; /* Draw here */
|
VipsImage *im; /* Draw here */
|
||||||
VipsPel *ink; /* Copy of ink param */
|
VipsArea *ink; /* With this */
|
||||||
|
|
||||||
/* Derived stuff.
|
/* Derived stuff.
|
||||||
*/
|
*/
|
||||||
size_t lsize;
|
size_t lsize;
|
||||||
size_t psize;
|
size_t psize;
|
||||||
|
|
||||||
|
/* Ink cast to pixel type.
|
||||||
|
*/
|
||||||
|
VipsPel *pixel_ink;
|
||||||
|
|
||||||
/* If the object to draw is entirely within the image, we have a
|
/* If the object to draw is entirely within the image, we have a
|
||||||
* faster noclip path.
|
* faster noclip path.
|
||||||
*/
|
*/
|
||||||
gboolean noclip;
|
gboolean noclip;
|
||||||
} Draw;
|
} VipsDraw;
|
||||||
|
|
||||||
#define DRAW(X) ((Draw *)(X))
|
typedef struct _VipsDrawClass {
|
||||||
|
VipsOperationClass parent_class;
|
||||||
|
|
||||||
|
} VipsDrawClass;
|
||||||
|
|
||||||
|
GType vips_draw_get_type( void );
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
im__draw_pel( Draw *draw, VipsPel *q )
|
vips__draw_pel( VipsDraw *draw, VipsPel *q )
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
/* Faster than memcopy() for n < about 20.
|
/* Faster than memcopy() for n < about 20.
|
||||||
*/
|
*/
|
||||||
for( j = 0; j < draw->psize; j++ )
|
for( j = 0; j < draw->psize; j++ )
|
||||||
q[j] = draw->ink[j];
|
q[j] = draw->pixel_ink[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Paint, with clip.
|
/* Paint, with clip.
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
im__draw_pel_clip( Draw *draw, int x, int y )
|
vips__draw_pel_clip( VipsDraw *draw, int x, int y )
|
||||||
{
|
{
|
||||||
if( x < 0 || x >= draw->im->Xsize )
|
if( x < 0 ||
|
||||||
|
x >= draw->im->Xsize )
|
||||||
return;
|
return;
|
||||||
if( y < 0 || y >= draw->im->Ysize )
|
if( y < 0 ||
|
||||||
|
y >= draw->im->Ysize )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
im__draw_pel( draw, IM_IMAGE_ADDR( draw->im, x, y ) );
|
vips__draw_pel( draw, VIPS_IMAGE_ADDR( draw->im, x, y ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is p painted?
|
/* Is p painted?
|
||||||
*/
|
*/
|
||||||
static inline gboolean
|
static inline gboolean
|
||||||
im__draw_painted( Draw *draw, VipsPel *p )
|
vips__draw_painted( VipsDraw *draw, VipsPel *p )
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for( j = 0; j < draw->psize; j++ )
|
for( j = 0; j < draw->psize; j++ )
|
||||||
if( p[j] != draw->ink[j] )
|
if( p[j] != draw->pixel_ink[j] )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
return( j == draw->psize );
|
return( j == draw->psize );
|
||||||
}
|
}
|
||||||
|
|
||||||
void im__draw_scanline( Draw *draw, int y, int x1, int x2 );
|
void vips__draw_scanline( Draw *draw, int y, int x1, int x2 );
|
||||||
void im__draw_free( Draw *draw );
|
|
||||||
Draw *im__draw_init( Draw *draw, IMAGE *im, VipsPel *ink );
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /*__cplusplus*/
|
||||||
|
|
||||||
|
#endif /*VIPS_DRAW_H*/
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
* level
|
* level
|
||||||
* 27/9/10
|
* 27/9/10
|
||||||
* - use Draw base class
|
* - use Draw base class
|
||||||
|
* 21/1/14
|
||||||
|
* - redo as a class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -97,16 +99,16 @@ typedef struct _Buffer {
|
|||||||
Scan scan[PBUFSIZE];
|
Scan scan[PBUFSIZE];
|
||||||
} Buffer;
|
} Buffer;
|
||||||
|
|
||||||
/* Our state.
|
/* Base class.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct _VipsFlood {
|
||||||
Draw draw;
|
VipsDraw draw;
|
||||||
|
|
||||||
/* Parameters.
|
/* Parameters.
|
||||||
*/
|
*/
|
||||||
IMAGE *test; /* Test this image */
|
VipsImage *test; /* Test this image */
|
||||||
int x, y;
|
int x, y;
|
||||||
Rect *dout; /* Write dirty here at end */
|
VipsRect *dout; /* Write dirty here at end */
|
||||||
|
|
||||||
/* Derived stuff.
|
/* Derived stuff.
|
||||||
*/
|
*/
|
||||||
@ -120,7 +122,11 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
Buffer *in;
|
Buffer *in;
|
||||||
Buffer *out;
|
Buffer *out;
|
||||||
} Flood;
|
} VipsFlood;
|
||||||
|
|
||||||
|
typedef VipsDrawClass VipsFloodClass;
|
||||||
|
|
||||||
|
G_DEFINE_ABSTRACT_TYPE( VipsFlood, vips_flood, VIPS_TYPE_DRAW );
|
||||||
|
|
||||||
/* Alloc a new buffer.
|
/* Alloc a new buffer.
|
||||||
*/
|
*/
|
||||||
@ -154,14 +160,15 @@ buffer_free( Buffer *buf )
|
|||||||
* the new head buffer.
|
* the new head buffer.
|
||||||
*/
|
*/
|
||||||
static inline Buffer *
|
static inline Buffer *
|
||||||
buffer_add( Buffer *buf, Flood *flood, int x1, int x2, int y, int dir )
|
buffer_add( Buffer *buf, VipsFlood *flood, int x1, int x2, int y, int dir )
|
||||||
{
|
{
|
||||||
/* Clip against image size.
|
/* Clip against image size.
|
||||||
*/
|
*/
|
||||||
if( y < 0 || y >= flood->test->Ysize )
|
if( y < 0 ||
|
||||||
|
y >= flood->test->Ysize )
|
||||||
return( buf );
|
return( buf );
|
||||||
x1 = IM_CLIP( 0, x1, flood->test->Xsize - 1 );
|
x1 = VIPS_CLIP( 0, x1, flood->test->Xsize - 1 );
|
||||||
x2 = IM_CLIP( 0, x2, flood->test->Xsize - 1 );
|
x2 = VIPS_CLIP( 0, x2, flood->test->Xsize - 1 );
|
||||||
if( x2 - x1 < 0 )
|
if( x2 - x1 < 0 )
|
||||||
return( buf );
|
return( buf );
|
||||||
|
|
||||||
@ -187,7 +194,7 @@ buffer_add( Buffer *buf, Flood *flood, int x1, int x2, int y, int dir )
|
|||||||
* pixels.
|
* pixels.
|
||||||
*/
|
*/
|
||||||
static inline gboolean
|
static inline gboolean
|
||||||
flood_connected( Flood *flood, VipsPel *tp )
|
flood_connected( VipsFlood *flood, VipsPel *tp )
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
@ -204,24 +211,24 @@ flood_connected( Flood *flood, VipsPel *tp )
|
|||||||
* connected and unpainted.
|
* connected and unpainted.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
flood_scanline( Flood *flood, int x, int y, int *x1, int *x2 )
|
flood_scanline( VipsFlood *flood, int x, int y, int *x1, int *x2 )
|
||||||
{
|
{
|
||||||
Draw *draw = DRAW( flood );
|
VipsDraw *draw = VIPS_DRAW( flood );
|
||||||
const int width = flood->test->Xsize;
|
const int width = flood->test->Xsize;
|
||||||
|
|
||||||
VipsPel *tp;
|
VipsPel *tp;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
g_assert( flood_connected( flood,
|
g_assert( flood_connected( flood,
|
||||||
IM_IMAGE_ADDR( flood->test, x, y ) ) );
|
VIPS_IMAGE_ADDR( flood->test, x, y ) ) );
|
||||||
g_assert( !im__draw_painted( draw,
|
g_assert( !vips__draw_painted( draw,
|
||||||
IM_IMAGE_ADDR( draw->im, x, y ) ) );
|
VIPS_IMAGE_ADDR( draw->im, x, y ) ) );
|
||||||
|
|
||||||
/* Search to the right for the first non-connected pixel. If the start
|
/* Search to the right for the first non-connected pixel. If the start
|
||||||
* pixel is unpainted, we know all the intervening pixels must be
|
* pixel is unpainted, we know all the intervening pixels must be
|
||||||
* unpainted too.
|
* unpainted too.
|
||||||
*/
|
*/
|
||||||
tp = IM_IMAGE_ADDR( flood->test, x + 1, y );
|
tp = VIPS_IMAGE_ADDR( flood->test, x + 1, y );
|
||||||
for( i = x + 1; i < width; i++ ) {
|
for( i = x + 1; i < width; i++ ) {
|
||||||
if( !flood_connected( flood, tp ) )
|
if( !flood_connected( flood, tp ) )
|
||||||
break;
|
break;
|
||||||
@ -231,7 +238,7 @@ flood_scanline( Flood *flood, int x, int y, int *x1, int *x2 )
|
|||||||
|
|
||||||
/* Search left.
|
/* Search left.
|
||||||
*/
|
*/
|
||||||
tp = IM_IMAGE_ADDR( flood->test, x - 1, y );
|
tp = VIPS_IMAGE_ADDR( flood->test, x - 1, y );
|
||||||
for( i = x - 1; i >= 0; i-- ) {
|
for( i = x - 1; i >= 0; i-- ) {
|
||||||
if( !flood_connected( flood, tp ) )
|
if( !flood_connected( flood, tp ) )
|
||||||
break;
|
break;
|
||||||
@ -241,13 +248,13 @@ flood_scanline( Flood *flood, int x, int y, int *x1, int *x2 )
|
|||||||
|
|
||||||
/* Paint the range we discovered.
|
/* Paint the range we discovered.
|
||||||
*/
|
*/
|
||||||
im__draw_scanline( draw, y, *x1, *x2 );
|
vips__draw_scanline( draw, y, *x1, *x2 );
|
||||||
|
|
||||||
if( flood->dout ) {
|
if( flood->dout ) {
|
||||||
flood->left = IM_MIN( flood->left, *x1 );
|
flood->left = VIPS_MIN( flood->left, *x1 );
|
||||||
flood->right = IM_MAX( flood->right, *x2 );
|
flood->right = VIPS_MAX( flood->right, *x2 );
|
||||||
flood->top = IM_MIN( flood->top, y );
|
flood->top = VIPS_MIN( flood->top, y );
|
||||||
flood->bottom = IM_MAX( flood->bottom, y );
|
flood->bottom = VIPS_MAX( flood->bottom, y );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,16 +262,17 @@ flood_scanline( Flood *flood, int x, int y, int *x1, int *x2 )
|
|||||||
* line in this range looking for an edge pixel we can flood from.
|
* line in this range looking for an edge pixel we can flood from.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
flood_around( Flood *flood, Scan *scan )
|
flood_around( VipsFlood *flood, Scan *scan )
|
||||||
{
|
{
|
||||||
Draw *draw = DRAW( flood );
|
VipsDraw *draw = VIPS_DRAW( flood );
|
||||||
|
|
||||||
VipsPel *tp;
|
VipsPel *tp;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
g_assert( scan->dir == 1 || scan->dir == -1 );
|
g_assert( scan->dir == 1 ||
|
||||||
|
scan->dir == -1 );
|
||||||
|
|
||||||
for( tp = IM_IMAGE_ADDR( flood->test, scan->x1, scan->y ),
|
for( tp = VIPS_IMAGE_ADDR( flood->test, scan->x1, scan->y ),
|
||||||
x = scan->x1;
|
x = scan->x1;
|
||||||
x <= scan->x2;
|
x <= scan->x2;
|
||||||
tp += flood->tsize, x++ ) {
|
tp += flood->tsize, x++ ) {
|
||||||
@ -277,10 +285,10 @@ flood_around( Flood *flood, Scan *scan )
|
|||||||
* connected loops.
|
* connected loops.
|
||||||
*/
|
*/
|
||||||
if( draw->im != flood->test ) {
|
if( draw->im != flood->test ) {
|
||||||
VipsPel *mp = IM_IMAGE_ADDR(
|
VipsPel *mp = VIPS_IMAGE_ADDR(
|
||||||
draw->im, x, scan->y );
|
draw->im, x, scan->y );
|
||||||
|
|
||||||
if( im__draw_painted( draw, mp ) )
|
if( vips__draw_painted( draw, mp ) )
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +311,7 @@ flood_around( Flood *flood, Scan *scan )
|
|||||||
scan->dir );
|
scan->dir );
|
||||||
|
|
||||||
x = x2a + 1;
|
x = x2a + 1;
|
||||||
tp = IM_IMAGE_ADDR( flood->test, x, scan->y );
|
tp = VIPS_IMAGE_ADDR( flood->test, x, scan->y );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -335,12 +343,12 @@ flood_all( Flood *flood, int x, int y )
|
|||||||
p->n = 0;
|
p->n = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
IM_SWAP( Buffer *, flood->in, flood->out );
|
VIPS_SWAP( Buffer *, flood->in, flood->out );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
flood_free( Flood *flood )
|
flood_free( VipsFlood *flood )
|
||||||
{
|
{
|
||||||
/* Write dirty back to caller.
|
/* Write dirty back to caller.
|
||||||
*/
|
*/
|
||||||
@ -351,11 +359,10 @@ flood_free( Flood *flood )
|
|||||||
flood->dout->height = flood->bottom - flood->top + 1;
|
flood->dout->height = flood->bottom - flood->top + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
im__draw_free( DRAW( flood ) );
|
VIPS_FREE( flood->edge );
|
||||||
IM_FREE( flood->edge );
|
VIPS_FREEF( buffer_free, flood->in );
|
||||||
IM_FREEF( buffer_free, flood->in );
|
VIPS_FREEF( buffer_free, flood->out );
|
||||||
IM_FREEF( buffer_free, flood->out );
|
vips_free( flood );
|
||||||
im_free( flood );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Flood *
|
static Flood *
|
||||||
|
@ -39,22 +39,6 @@
|
|||||||
|
|
||||||
#include <vips/vips.h>
|
#include <vips/vips.h>
|
||||||
|
|
||||||
/**
|
|
||||||
* SECTION: inplace
|
|
||||||
* @short_description: in-place paintbox operations: flood, paste, line,
|
|
||||||
* circle
|
|
||||||
* @stability: Stable
|
|
||||||
* @include: vips/vips.h
|
|
||||||
*
|
|
||||||
* These operations directly modify the image. They do not thread, on 32-bit
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Calculate a pixel for an image from a vec of double. Valid while im is
|
/* Calculate a pixel for an image from a vec of double. Valid while im is
|
||||||
* valid.
|
* valid.
|
||||||
*/
|
*/
|
||||||
|
@ -272,6 +272,7 @@ vips__init( const char *argv0 )
|
|||||||
vips_convolution_operation_init();
|
vips_convolution_operation_init();
|
||||||
vips_freqfilt_operation_init();
|
vips_freqfilt_operation_init();
|
||||||
vips_morphology_operation_init();
|
vips_morphology_operation_init();
|
||||||
|
vips_draw_operation_init();
|
||||||
|
|
||||||
/* Load up any plugins in the vips libdir. We don't error on failure,
|
/* Load up any plugins in the vips libdir. We don't error on failure,
|
||||||
* it's too annoying to have VIPS refuse to start because of a broken
|
* it's too annoying to have VIPS refuse to start because of a broken
|
||||||
|
Loading…
Reference in New Issue
Block a user