im_clip2fmt() redone as a class
plus some rationalisation of member names
This commit is contained in:
parent
6402fd9487
commit
c027528b82
@ -3,9 +3,9 @@
|
||||
- im_subtract(), im_avg(), im_min(), im_minpos(), im_copy(), im_embed(),
|
||||
im_flophor(), im_flipver(), im_insert(), im_insert_noexpand(), im_lrjoin(),
|
||||
im_tbjoin(), im_extract_area(), im_extract_bands(), im_extract_areabands(),
|
||||
im_replicate()
|
||||
im_replicate(), im_clip2fmt()
|
||||
redone as classes
|
||||
- added VIPS_ARGUMENT_APPEND to help control arg ordering
|
||||
- added argument priorites to help control arg ordering
|
||||
- generate has a 'stop' param to signal successful early termination
|
||||
- added optional output args, eg. x/y for min
|
||||
- CLI supports optional output args
|
||||
|
12
TODO
12
TODO
@ -1,4 +1,5 @@
|
||||
- clip next?
|
||||
- lintra_vec next
|
||||
|
||||
|
||||
|
||||
|
||||
@ -55,6 +56,15 @@
|
||||
|
||||
bodge it for now, fix properly after we merge
|
||||
|
||||
- don't do vips_image_write() at the end of a pipeline, instead try:
|
||||
|
||||
g_object_set( object, "output", t );
|
||||
|
||||
ie. replace the output object
|
||||
|
||||
fails due to "assign once only" rule ... we need "don't assign after
|
||||
written" instead
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -10,13 +10,13 @@ libconversion_la_SOURCES = \
|
||||
join.c \
|
||||
extract.c \
|
||||
replicate.c \
|
||||
cast.c \
|
||||
conver_dispatch.c \
|
||||
im_black.c \
|
||||
im_c2amph.c \
|
||||
im_c2rect.c \
|
||||
im_c2imag.c \
|
||||
im_c2real.c \
|
||||
im_clip2fmt.c \
|
||||
im_copy_file.c \
|
||||
im_falsecolour.c \
|
||||
im_gbandjoin.c \
|
||||
|
@ -43,6 +43,8 @@
|
||||
* 27/1/10
|
||||
* - modernised
|
||||
* - gtk-doc
|
||||
* 27/10/11
|
||||
* - redone as a class
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -83,6 +85,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/internal.h>
|
||||
@ -105,16 +108,85 @@
|
||||
typedef struct _VipsCast {
|
||||
VipsConversion parent_instance;
|
||||
|
||||
VipsImage *input;
|
||||
VipsImage *in;
|
||||
VipsBandFormat format;
|
||||
|
||||
int underflow; /* Number of underflows */
|
||||
int overflow; /* Number of overflows */
|
||||
|
||||
} VipsCast;
|
||||
|
||||
typedef VipsConversionClass VipsCastClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsCast, vips_cast, VIPS_TYPE_CONVERSION );
|
||||
|
||||
/* Clip int types to an int type.
|
||||
static void
|
||||
vips_cast_preeval( VipsImage *image, VipsProgress *progress, VipsCast *cast )
|
||||
{
|
||||
cast->overflow = 0;
|
||||
cast->underflow = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
vips_cast_posteval( VipsImage *image, VipsProgress *progress, VipsCast *cast )
|
||||
{
|
||||
if( cast->overflow || cast->underflow )
|
||||
vips_warn( "VipsCast",
|
||||
_( "%d underflows and %d overflows detected" ),
|
||||
cast->underflow, cast->overflow );
|
||||
}
|
||||
|
||||
/* Our sequence value: the region this sequence is using, and two local stats.
|
||||
*/
|
||||
typedef struct {
|
||||
VipsRegion *ir; /* Input region */
|
||||
|
||||
int underflow; /* Number of underflows */
|
||||
int overflow; /* Number of overflows */
|
||||
} VipsCastSequence;
|
||||
|
||||
/* Destroy a sequence value.
|
||||
*/
|
||||
static int
|
||||
vips_cast_stop( void *vseq, void *a, void *b )
|
||||
{
|
||||
VipsCastSequence *seq = (VipsCastSequence *) vseq;
|
||||
VipsCast *cast = (VipsCast *) b;
|
||||
|
||||
/* Add to global stats.
|
||||
*/
|
||||
cast->underflow += seq->underflow;
|
||||
cast->overflow += seq->overflow;
|
||||
|
||||
VIPS_FREEF( g_object_unref, seq->ir );
|
||||
|
||||
g_free( seq );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Make a sequence value.
|
||||
*/
|
||||
static void *
|
||||
vips_cast_start( VipsImage *out, void *a, void *b )
|
||||
{
|
||||
VipsImage *in = (VipsImage *) a;
|
||||
VipsCastSequence *seq;
|
||||
|
||||
seq = g_new( VipsCastSequence, 1 );
|
||||
seq->ir = vips_region_new( in );
|
||||
seq->overflow = 0;
|
||||
seq->underflow = 0;
|
||||
|
||||
if( !seq->ir ) {
|
||||
vips_cast_stop( seq, NULL, NULL );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
return( seq );
|
||||
}
|
||||
|
||||
/* Cast int types to an int type.
|
||||
*/
|
||||
#define VIPS_CLIP_INT_INT( ITYPE, OTYPE, VIPS_CLIP ) { \
|
||||
ITYPE *p = (ITYPE *) in; \
|
||||
@ -129,7 +201,7 @@ G_DEFINE_TYPE( VipsCast, vips_cast, VIPS_TYPE_CONVERSION );
|
||||
} \
|
||||
}
|
||||
|
||||
/* Clip float types to an int type.
|
||||
/* Cast float types to an int type.
|
||||
*/
|
||||
#define VIPS_CLIP_FLOAT_INT( ITYPE, OTYPE, VIPS_CLIP ) { \
|
||||
ITYPE *p = (ITYPE *) in; \
|
||||
@ -144,7 +216,7 @@ G_DEFINE_TYPE( VipsCast, vips_cast, VIPS_TYPE_CONVERSION );
|
||||
} \
|
||||
}
|
||||
|
||||
/* Clip complex types to an int type. Just take the real part.
|
||||
/* Cast complex types to an int type. Just take the real part.
|
||||
*/
|
||||
#define VIPS_CLIP_COMPLEX_INT( ITYPE, OTYPE, VIPS_CLIP ) { \
|
||||
ITYPE *p = (ITYPE *) in; \
|
||||
@ -160,7 +232,7 @@ G_DEFINE_TYPE( VipsCast, vips_cast, VIPS_TYPE_CONVERSION );
|
||||
} \
|
||||
}
|
||||
|
||||
/* Clip non-complex types to a float type.
|
||||
/* Cast non-complex types to a float type.
|
||||
*/
|
||||
#define VIPS_CLIP_REAL_FLOAT( ITYPE, OTYPE ) { \
|
||||
ITYPE *p = (ITYPE *) in; \
|
||||
@ -170,7 +242,7 @@ G_DEFINE_TYPE( VipsCast, vips_cast, VIPS_TYPE_CONVERSION );
|
||||
q[x] = p[x]; \
|
||||
}
|
||||
|
||||
/* Clip complex types to a float type ... just take real.
|
||||
/* Cast complex types to a float type ... just take real.
|
||||
*/
|
||||
#define VIPS_CLIP_COMPLEX_FLOAT( ITYPE, OTYPE ) { \
|
||||
ITYPE *p = (ITYPE *) in; \
|
||||
@ -182,7 +254,7 @@ G_DEFINE_TYPE( VipsCast, vips_cast, VIPS_TYPE_CONVERSION );
|
||||
} \
|
||||
}
|
||||
|
||||
/* Clip any non-complex to a complex type ... set imaginary to zero.
|
||||
/* Cast any non-complex to a complex type ... set imaginary to zero.
|
||||
*/
|
||||
#define VIPS_CLIP_REAL_COMPLEX( ITYPE, OTYPE ) { \
|
||||
ITYPE *p = (ITYPE *) in; \
|
||||
@ -195,7 +267,7 @@ G_DEFINE_TYPE( VipsCast, vips_cast, VIPS_TYPE_CONVERSION );
|
||||
} \
|
||||
}
|
||||
|
||||
/* Clip any complex to a complex type.
|
||||
/* Cast any complex to a complex type.
|
||||
*/
|
||||
#define VIPS_CLIP_COMPLEX_COMPLEX( ITYPE, OTYPE ) { \
|
||||
ITYPE *p = (ITYPE *) in; \
|
||||
@ -210,48 +282,60 @@ G_DEFINE_TYPE( VipsCast, vips_cast, VIPS_TYPE_CONVERSION );
|
||||
}
|
||||
|
||||
#define BAND_SWITCH_INNER( ITYPE, INT, FLOAT, COMPLEX ) { \
|
||||
switch( clip->out->BandFmt ) { \
|
||||
switch( conversion->out->BandFmt ) { \
|
||||
case VIPS_FORMAT_UCHAR: \
|
||||
INT( ITYPE, unsigned char, VIPS_CLIP_UCHAR ); \
|
||||
break; \
|
||||
\
|
||||
case VIPS_FORMAT_CHAR: \
|
||||
INT( ITYPE, signed char, VIPS_CLIP_CHAR ); \
|
||||
break; \
|
||||
\
|
||||
case VIPS_FORMAT_USHORT: \
|
||||
INT( ITYPE, unsigned short, VIPS_CLIP_USHORT ); \
|
||||
break; \
|
||||
\
|
||||
case VIPS_FORMAT_SHORT: \
|
||||
INT( ITYPE, signed short, VIPS_CLIP_SHORT ); \
|
||||
break; \
|
||||
\
|
||||
case VIPS_FORMAT_UINT: \
|
||||
INT( ITYPE, unsigned int, VIPS_CLIP_NONE ); \
|
||||
break; \
|
||||
\
|
||||
case VIPS_FORMAT_INT: \
|
||||
INT( ITYPE, signed int, VIPS_CLIP_NONE ); \
|
||||
break; \
|
||||
\
|
||||
case VIPS_FORMAT_FLOAT: \
|
||||
FLOAT( ITYPE, float ); \
|
||||
break; \
|
||||
\
|
||||
case VIPS_FORMAT_DOUBLE: \
|
||||
FLOAT( ITYPE, double ); \
|
||||
break; \
|
||||
\
|
||||
case VIPS_FORMAT_COMPLEX: \
|
||||
COMPLEX( ITYPE, float ); \
|
||||
break; \
|
||||
\
|
||||
case VIPS_FORMAT_DPCOMPLEX: \
|
||||
COMPLEX( ITYPE, double ); \
|
||||
break; \
|
||||
\
|
||||
default: \
|
||||
g_assert( 0 ); \
|
||||
} \
|
||||
}
|
||||
|
||||
static int
|
||||
vips_cast_gen( VipsRegion *or, void *seq, void *a, void *b,
|
||||
vips_cast_gen( VipsRegion *or, void *vseq, void *a, void *b,
|
||||
gboolean *stop )
|
||||
{
|
||||
VipsRegion *ir = (VipsRegion *) seq;
|
||||
Clip *clip = (Clip *) b;
|
||||
VipsCastSequence *seq = (VipsCastSequence *) vseq;
|
||||
VipsRegion *ir = seq->ir;
|
||||
VipsCast *cast = (VipsCast *) b;
|
||||
VipsConversion *conversion = (VipsConversion *) b;
|
||||
VipsRect *r = &or->valid;
|
||||
int le = r->left;
|
||||
int to = r->top;
|
||||
@ -266,67 +350,77 @@ vips_cast_gen( VipsRegion *or, void *seq, void *a, void *b,
|
||||
PEL *in = (PEL *) VIPS_REGION_ADDR( ir, le, y );
|
||||
PEL *out = (PEL *) VIPS_REGION_ADDR( or, le, y );
|
||||
|
||||
switch( clip->in->BandFmt ) {
|
||||
switch( cast->in->BandFmt ) {
|
||||
case VIPS_FORMAT_UCHAR:
|
||||
BAND_SWITCH_INNER( unsigned char,
|
||||
VIPS_CLIP_INT_INT,
|
||||
VIPS_CLIP_REAL_FLOAT,
|
||||
VIPS_CLIP_REAL_COMPLEX );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_CHAR:
|
||||
BAND_SWITCH_INNER( signed char,
|
||||
VIPS_CLIP_INT_INT,
|
||||
VIPS_CLIP_REAL_FLOAT,
|
||||
VIPS_CLIP_REAL_COMPLEX );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_USHORT:
|
||||
BAND_SWITCH_INNER( unsigned short,
|
||||
VIPS_CLIP_INT_INT,
|
||||
VIPS_CLIP_REAL_FLOAT,
|
||||
VIPS_CLIP_REAL_COMPLEX );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_SHORT:
|
||||
BAND_SWITCH_INNER( signed short,
|
||||
VIPS_CLIP_INT_INT,
|
||||
VIPS_CLIP_REAL_FLOAT,
|
||||
VIPS_CLIP_REAL_COMPLEX );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_UINT:
|
||||
BAND_SWITCH_INNER( unsigned int,
|
||||
VIPS_CLIP_INT_INT,
|
||||
VIPS_CLIP_REAL_FLOAT,
|
||||
VIPS_CLIP_REAL_COMPLEX );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_INT:
|
||||
BAND_SWITCH_INNER( signed int,
|
||||
VIPS_CLIP_INT_INT,
|
||||
VIPS_CLIP_REAL_FLOAT,
|
||||
VIPS_CLIP_REAL_COMPLEX );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_FLOAT:
|
||||
BAND_SWITCH_INNER( float,
|
||||
VIPS_CLIP_FLOAT_INT,
|
||||
VIPS_CLIP_REAL_FLOAT,
|
||||
VIPS_CLIP_REAL_COMPLEX );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_DOUBLE:
|
||||
BAND_SWITCH_INNER( double,
|
||||
VIPS_CLIP_FLOAT_INT,
|
||||
VIPS_CLIP_REAL_FLOAT,
|
||||
VIPS_CLIP_REAL_COMPLEX );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_COMPLEX:
|
||||
BAND_SWITCH_INNER( float,
|
||||
VIPS_CLIP_COMPLEX_INT,
|
||||
VIPS_CLIP_COMPLEX_FLOAT,
|
||||
VIPS_CLIP_COMPLEX_COMPLEX );
|
||||
break;
|
||||
|
||||
case VIPS_FORMAT_DPCOMPLEX:
|
||||
BAND_SWITCH_INNER( double,
|
||||
VIPS_CLIP_COMPLEX_INT,
|
||||
VIPS_CLIP_COMPLEX_FLOAT,
|
||||
VIPS_CLIP_COMPLEX_COMPLEX );
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert( 0 );
|
||||
}
|
||||
@ -341,25 +435,34 @@ vips_cast_build( VipsObject *object )
|
||||
VipsConversion *conversion = VIPS_CONVERSION( object );
|
||||
VipsCast *cast = (VipsCast *) object;
|
||||
|
||||
VipsGenerateFn generate_fn;
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_cast_parent_class )->build( object ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_image_pio_input( cast->input ) ||
|
||||
vips_image_pio_output( conversion->output ) )
|
||||
/* Trivial case: fall back to im_copy().
|
||||
*/
|
||||
if( cast->in->BandFmt == cast->format )
|
||||
return( vips_image_write( cast->in, conversion->out ) );
|
||||
|
||||
if( vips_check_uncoded( "VipsCast", cast->in ) ||
|
||||
vips_image_pio_input( cast->in ) ||
|
||||
vips_image_pio_output( conversion->out ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_image_copy_fields( conversion->output, cast->input ) )
|
||||
if( vips_image_copy_fields( conversion->out, cast->in ) )
|
||||
return( -1 );
|
||||
vips_demand_hint( conversion->output,
|
||||
VIPS_DEMAND_STYLE_THINSTRIP, cast->input, NULL );
|
||||
vips_demand_hint( conversion->out,
|
||||
VIPS_DEMAND_STYLE_THINSTRIP, cast->in, NULL );
|
||||
|
||||
conversion->output->BandFmt = cast->format
|
||||
conversion->out->BandFmt = cast->format;
|
||||
|
||||
if( vips_image_generate( conversion->output,
|
||||
vips_start_one, generate_fn, vips_stop_one,
|
||||
cast->input, cast ) )
|
||||
g_signal_connect( cast->in, "preeval",
|
||||
G_CALLBACK( vips_cast_preeval ), cast );
|
||||
g_signal_connect( cast->in, "posteval",
|
||||
G_CALLBACK( vips_cast_posteval ), cast );
|
||||
|
||||
if( vips_image_generate( conversion->out,
|
||||
vips_cast_start, vips_cast_gen, vips_cast_stop,
|
||||
cast->in, cast ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -380,11 +483,11 @@ vips_cast_class_init( VipsCastClass *class )
|
||||
vobject_class->description = _( "cast an image" );
|
||||
vobject_class->build = vips_cast_build;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "input", 1,
|
||||
VIPS_ARG_IMAGE( class, "in", 1,
|
||||
_( "Input" ),
|
||||
_( "Input image" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCast, input ) );
|
||||
G_STRUCT_OFFSET( VipsCast, in ) );
|
||||
|
||||
VIPS_ARG_ENUM( class, "format", 6,
|
||||
_( "Format" ),
|
||||
@ -405,7 +508,7 @@ vips_cast( VipsImage *in, VipsImage **out, VipsBandFormat format, ... )
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, direction );
|
||||
va_start( ap, format );
|
||||
result = vips_call_split( "cast", ap, in, out, format );
|
||||
va_end( ap );
|
||||
|
||||
|
@ -88,7 +88,7 @@ vips_conversion_class_init( VipsConversionClass *class )
|
||||
_( "Output" ),
|
||||
_( "Output image" ),
|
||||
VIPS_ARGUMENT_REQUIRED_OUTPUT,
|
||||
G_STRUCT_OFFSET( VipsConversion, output ) );
|
||||
G_STRUCT_OFFSET( VipsConversion, out ) );
|
||||
}
|
||||
|
||||
static void
|
||||
@ -110,6 +110,7 @@ vips_conversion_operation_init( void )
|
||||
extern GType vips_extract_area_get_type( void );
|
||||
extern GType vips_extract_band_get_type( void );
|
||||
extern GType vips_replicate_get_type( void );
|
||||
extern GType vips_cast_get_type( void );
|
||||
|
||||
vips_copy_get_type();
|
||||
vips_embed_get_type();
|
||||
@ -119,5 +120,6 @@ vips_conversion_operation_init( void )
|
||||
vips_extract_area_get_type();
|
||||
vips_extract_band_get_type();
|
||||
vips_replicate_get_type();
|
||||
vips_cast_get_type();
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ typedef struct _VipsConversion {
|
||||
|
||||
/* All have an output image.
|
||||
*/
|
||||
VipsImage *output;
|
||||
VipsImage *out;
|
||||
|
||||
} VipsConversion;
|
||||
|
||||
|
@ -94,8 +94,8 @@
|
||||
|
||||
/**
|
||||
* VipsCopy:
|
||||
* @input: input image
|
||||
* @output: output image
|
||||
* @in: input image
|
||||
* @out: output image
|
||||
*
|
||||
* Copy an image, optionally modifying the header. VIPS copies images by
|
||||
* copying pointers, so this operation is fast, even for very large images.
|
||||
@ -113,7 +113,7 @@ typedef struct _VipsCopy {
|
||||
|
||||
/* The input image.
|
||||
*/
|
||||
VipsImage *input;
|
||||
VipsImage *in;
|
||||
|
||||
/* Swap bytes on the way through.
|
||||
*/
|
||||
@ -227,7 +227,7 @@ vips_copy_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
|
||||
return( -1 );
|
||||
|
||||
if( copy->swap ) {
|
||||
SwapFn swap = vips_copy_swap_fn[copy->input->BandFmt];
|
||||
SwapFn swap = vips_copy_swap_fn[copy->in->BandFmt];
|
||||
int y;
|
||||
|
||||
for( y = 0; y < r->height; y++ ) {
|
||||
@ -236,7 +236,7 @@ vips_copy_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
|
||||
PEL *q = (PEL *) VIPS_REGION_ADDR( or,
|
||||
r->left, r->top + y );
|
||||
|
||||
swap( p, q, r->width, copy->input );
|
||||
swap( p, q, r->width, copy->in );
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -274,14 +274,14 @@ vips_copy_build( VipsObject *object )
|
||||
if( VIPS_OBJECT_CLASS( vips_copy_parent_class )->build( object ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_image_pio_input( copy->input ) ||
|
||||
vips_image_pio_output( conversion->output ) )
|
||||
if( vips_image_pio_input( copy->in ) ||
|
||||
vips_image_pio_output( conversion->out ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_image_copy_fields( conversion->output, copy->input ) )
|
||||
if( vips_image_copy_fields( conversion->out, copy->in ) )
|
||||
return( -1 );
|
||||
vips_demand_hint( conversion->output,
|
||||
VIPS_DEMAND_STYLE_THINSTRIP, copy->input, NULL );
|
||||
vips_demand_hint( conversion->out,
|
||||
VIPS_DEMAND_STYLE_THINSTRIP, copy->in, NULL );
|
||||
|
||||
/* Use props to adjust header fields.
|
||||
*/
|
||||
@ -306,15 +306,15 @@ vips_copy_build( VipsObject *object )
|
||||
g_value_init( &value, type );
|
||||
g_object_get_property( G_OBJECT( object ),
|
||||
name, &value );
|
||||
g_object_set_property( G_OBJECT( conversion->output ),
|
||||
g_object_set_property( G_OBJECT( conversion->out ),
|
||||
name, &value );
|
||||
g_value_unset( &value );
|
||||
}
|
||||
}
|
||||
|
||||
if( vips_image_generate( conversion->output,
|
||||
if( vips_image_generate( conversion->out,
|
||||
vips_start_one, vips_copy_gen, vips_stop_one,
|
||||
copy->input, copy ) )
|
||||
copy->in, copy ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -339,7 +339,7 @@ vips_copy_class_init( VipsCopyClass *class )
|
||||
_( "Input" ),
|
||||
_( "Input image" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, input ) );
|
||||
G_STRUCT_OFFSET( VipsCopy, in ) );
|
||||
|
||||
VIPS_ARG_BOOL( class, "swap", 2,
|
||||
_( "Swap" ),
|
||||
|
@ -95,7 +95,7 @@ typedef struct _VipsEmbed {
|
||||
|
||||
/* The input image.
|
||||
*/
|
||||
VipsImage *input;
|
||||
VipsImage *in;
|
||||
|
||||
VipsExtend extend;
|
||||
int x;
|
||||
@ -164,7 +164,7 @@ vips_embed_find_edge( VipsEmbed *embed, VipsRect *r, int i, VipsRect *out )
|
||||
static void
|
||||
vips_embed_copy_pixel( VipsEmbed *embed, PEL *q, PEL *p, int n )
|
||||
{
|
||||
const int bs = VIPS_IMAGE_SIZEOF_PEL( embed->input );
|
||||
const int bs = VIPS_IMAGE_SIZEOF_PEL( embed->in );
|
||||
|
||||
int x, b;
|
||||
|
||||
@ -181,7 +181,7 @@ static void
|
||||
vips_embed_paint_edge( VipsEmbed *embed,
|
||||
VipsRegion *or, int i, VipsRect *r, PEL *p, int plsk )
|
||||
{
|
||||
const int bs = VIPS_IMAGE_SIZEOF_PEL( embed->input );
|
||||
const int bs = VIPS_IMAGE_SIZEOF_PEL( embed->in );
|
||||
|
||||
VipsRect todo;
|
||||
PEL *q;
|
||||
@ -326,7 +326,7 @@ vips_embed_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
|
||||
}
|
||||
|
||||
static int
|
||||
vips_embed_repeat( VipsPool *pool, VipsImage *input, VipsImage **output,
|
||||
vips_embed_repeat( VipsPool *pool, VipsImage *in, VipsImage **out,
|
||||
int x, int y, int width, int height )
|
||||
{
|
||||
VipsPoolContext *context = vips_pool_context_new( pool );
|
||||
@ -335,15 +335,15 @@ vips_embed_repeat( VipsPool *pool, VipsImage *input, VipsImage **output,
|
||||
* nicely.
|
||||
*/
|
||||
const int nx = x < 0 ?
|
||||
-x % input->Xsize : input->Xsize - x % input->Xsize;
|
||||
-x % in->Xsize : in->Xsize - x % in->Xsize;
|
||||
const int ny = y < 0 ?
|
||||
-y % input->Ysize : input->Ysize - y % input->Ysize;
|
||||
-y % in->Ysize : in->Ysize - y % in->Ysize;
|
||||
|
||||
if(
|
||||
vips_replicate( input, &VIPS_VI( 1 ),
|
||||
width / input->Xsize + 2,
|
||||
height / input->Ysize + 2, NULL ) ||
|
||||
vips_extract_area( VIPS_VI( 1 ), output,
|
||||
vips_replicate( in, &VIPS_VI( 1 ),
|
||||
width / in->Xsize + 2,
|
||||
height / in->Ysize + 2, NULL ) ||
|
||||
vips_extract_area( VIPS_VI( 1 ), out,
|
||||
nx, ny, width, height, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
@ -351,7 +351,7 @@ vips_embed_repeat( VipsPool *pool, VipsImage *input, VipsImage **output,
|
||||
}
|
||||
|
||||
static int
|
||||
vips_embed_mirror( VipsPool *pool, VipsImage *input, VipsImage **output,
|
||||
vips_embed_mirror( VipsPool *pool, VipsImage *in, VipsImage **out,
|
||||
int x, int y, int width, int height )
|
||||
{
|
||||
VipsPoolContext *context = vips_pool_context_new( pool );
|
||||
@ -359,8 +359,8 @@ vips_embed_mirror( VipsPool *pool, VipsImage *input, VipsImage **output,
|
||||
/* As repeat, but the tiles are twice the size because of
|
||||
* mirroring.
|
||||
*/
|
||||
const int w2 = input->Xsize * 2;
|
||||
const int h2 = input->Ysize * 2;
|
||||
const int w2 = in->Xsize * 2;
|
||||
const int h2 = in->Ysize * 2;
|
||||
|
||||
const int nx = x < 0 ? -x % w2 : w2 - x % w2;
|
||||
const int ny = y < 0 ? -y % h2 : h2 - y % h2;
|
||||
@ -368,9 +368,9 @@ vips_embed_mirror( VipsPool *pool, VipsImage *input, VipsImage **output,
|
||||
if(
|
||||
/* Make a 2x2 mirror tile.
|
||||
*/
|
||||
vips_flip( input, &VIPS_VI( 1 ),
|
||||
vips_flip( in, &VIPS_VI( 1 ),
|
||||
VIPS_DIRECTION_HORIZONTAL, NULL ) ||
|
||||
vips_join( input, VIPS_VI( 1 ), &VIPS_VI( 2 ),
|
||||
vips_join( in, VIPS_VI( 1 ), &VIPS_VI( 2 ),
|
||||
VIPS_DIRECTION_HORIZONTAL, NULL ) ||
|
||||
vips_flip( VIPS_VI( 2 ), &VIPS_VI( 3 ),
|
||||
VIPS_DIRECTION_VERTICAL, NULL ) ||
|
||||
@ -385,10 +385,10 @@ vips_embed_mirror( VipsPool *pool, VipsImage *input, VipsImage **output,
|
||||
vips_extract_area( VIPS_VI( 5 ), &VIPS_VI( 6 ),
|
||||
nx, ny, width, height, NULL ) ||
|
||||
|
||||
/* Overwrite the centre with the input, much faster
|
||||
/* Overwrite the centre with the in, much faster
|
||||
* for centre pixels.
|
||||
*/
|
||||
vips_insert( VIPS_VI( 6 ), input, output,
|
||||
vips_insert( VIPS_VI( 6 ), in, out,
|
||||
x, y, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
@ -407,8 +407,8 @@ vips_embed_build( VipsObject *object )
|
||||
if( VIPS_OBJECT_CLASS( vips_embed_parent_class )->build( object ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_image_pio_input( embed->input ) ||
|
||||
vips_image_pio_output( conversion->output ) )
|
||||
if( vips_image_pio_input( embed->in ) ||
|
||||
vips_image_pio_output( conversion->out ) )
|
||||
return( -1 );
|
||||
if( embed->extend < 0 || embed->extend >= VIPS_EXTEND_LAST ) {
|
||||
vips_error( "VipsEmbed", "%s", _( "unknown VipsExtend" ) );
|
||||
@ -419,9 +419,9 @@ vips_embed_build( VipsObject *object )
|
||||
*/
|
||||
if( embed->x == 0 &&
|
||||
embed->y == 0 &&
|
||||
embed->width == embed->input->Xsize &&
|
||||
embed->height == embed->input->Ysize )
|
||||
return( vips_image_write( embed->input, conversion->output ) );
|
||||
embed->width == embed->in->Xsize &&
|
||||
embed->height == embed->in->Ysize )
|
||||
return( vips_image_write( embed->in, conversion->out ) );
|
||||
|
||||
pool = vips_pool_new( "VipsEmbed" );
|
||||
vips_object_local( object, pool );
|
||||
@ -431,9 +431,9 @@ vips_embed_build( VipsObject *object )
|
||||
{
|
||||
VipsPoolContext *context = vips_pool_context_new( pool );
|
||||
|
||||
if( vips_embed_repeat( pool, embed->input, &VIPS_VI( 1 ),
|
||||
if( vips_embed_repeat( pool, embed->in, &VIPS_VI( 1 ),
|
||||
embed->x, embed->y, embed->width, embed->height ) ||
|
||||
vips_image_write( VIPS_VI( 1 ), conversion->output ) )
|
||||
vips_image_write( VIPS_VI( 1 ), conversion->out ) )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
@ -443,9 +443,9 @@ vips_embed_build( VipsObject *object )
|
||||
{
|
||||
VipsPoolContext *context = vips_pool_context_new( pool );
|
||||
|
||||
if( vips_embed_mirror( pool, embed->input, &VIPS_VI( 1 ),
|
||||
if( vips_embed_mirror( pool, embed->in, &VIPS_VI( 1 ),
|
||||
embed->x, embed->y, embed->width, embed->height ) ||
|
||||
vips_image_write( VIPS_VI( 1 ), conversion->output ) )
|
||||
vips_image_write( VIPS_VI( 1 ), conversion->out ) )
|
||||
return( -1 );
|
||||
}
|
||||
break;
|
||||
@ -453,28 +453,28 @@ vips_embed_build( VipsObject *object )
|
||||
case VIPS_EXTEND_BLACK:
|
||||
case VIPS_EXTEND_WHITE:
|
||||
case VIPS_EXTEND_COPY:
|
||||
if( vips_image_copy_fields( conversion->output, embed->input ) )
|
||||
if( vips_image_copy_fields( conversion->out, embed->in ) )
|
||||
return( -1 );
|
||||
|
||||
conversion->output->Xsize = embed->width;
|
||||
conversion->output->Ysize = embed->height;
|
||||
conversion->out->Xsize = embed->width;
|
||||
conversion->out->Ysize = embed->height;
|
||||
|
||||
vips_demand_hint( conversion->output,
|
||||
VIPS_DEMAND_STYLE_SMALLTILE, embed->input, NULL );
|
||||
vips_demand_hint( conversion->out,
|
||||
VIPS_DEMAND_STYLE_SMALLTILE, embed->in, NULL );
|
||||
|
||||
/* Whole output area.
|
||||
*/
|
||||
embed->rout.left = 0;
|
||||
embed->rout.top = 0;
|
||||
embed->rout.width = conversion->output->Xsize;
|
||||
embed->rout.height = conversion->output->Ysize;
|
||||
embed->rout.width = conversion->out->Xsize;
|
||||
embed->rout.height = conversion->out->Ysize;
|
||||
|
||||
/* Rect occupied by image (can be clipped to nothing).
|
||||
*/
|
||||
want.left = embed->x;
|
||||
want.top = embed->y;
|
||||
want.width = embed->input->Xsize;
|
||||
want.height = embed->input->Ysize;
|
||||
want.width = embed->in->Xsize;
|
||||
want.height = embed->in->Ysize;
|
||||
vips_rect_intersectrect( &want, &embed->rout, &embed->rsub );
|
||||
|
||||
/* FIXME ... actually, it can't. embed_find_edge() will fail
|
||||
@ -496,14 +496,14 @@ vips_embed_build( VipsObject *object )
|
||||
|
||||
embed->border[1].left = VIPS_RECT_RIGHT( &embed->rsub );
|
||||
embed->border[1].top = embed->rsub.top;
|
||||
embed->border[1].width = conversion->output->Xsize -
|
||||
embed->border[1].width = conversion->out->Xsize -
|
||||
VIPS_RECT_RIGHT( &embed->rsub );
|
||||
embed->border[1].height = embed->rsub.height;
|
||||
|
||||
embed->border[2].left = embed->rsub.left;
|
||||
embed->border[2].top = VIPS_RECT_BOTTOM( &embed->rsub );
|
||||
embed->border[2].width = embed->rsub.width;
|
||||
embed->border[2].height = conversion->output->Ysize -
|
||||
embed->border[2].height = conversion->out->Ysize -
|
||||
VIPS_RECT_BOTTOM( &embed->rsub );
|
||||
|
||||
embed->border[3].left = 0;
|
||||
@ -521,26 +521,26 @@ vips_embed_build( VipsObject *object )
|
||||
|
||||
embed->border[5].left = VIPS_RECT_RIGHT( &embed->rsub );
|
||||
embed->border[5].top = 0;
|
||||
embed->border[5].width = conversion->output->Xsize -
|
||||
embed->border[5].width = conversion->out->Xsize -
|
||||
VIPS_RECT_RIGHT( &embed->rsub );
|
||||
embed->border[5].height = embed->rsub.top;
|
||||
|
||||
embed->border[6].left = VIPS_RECT_RIGHT( &embed->rsub );
|
||||
embed->border[6].top = VIPS_RECT_BOTTOM( &embed->rsub );
|
||||
embed->border[6].width = conversion->output->Xsize -
|
||||
embed->border[6].width = conversion->out->Xsize -
|
||||
VIPS_RECT_RIGHT( &embed->rsub );
|
||||
embed->border[6].height = conversion->output->Ysize -
|
||||
embed->border[6].height = conversion->out->Ysize -
|
||||
VIPS_RECT_BOTTOM( &embed->rsub );
|
||||
|
||||
embed->border[7].left = 0;
|
||||
embed->border[7].top = VIPS_RECT_BOTTOM( &embed->rsub );
|
||||
embed->border[7].width = embed->rsub.left;
|
||||
embed->border[7].height = conversion->output->Ysize -
|
||||
embed->border[7].height = conversion->out->Ysize -
|
||||
VIPS_RECT_BOTTOM( &embed->rsub );
|
||||
|
||||
if( vips_image_generate( conversion->output,
|
||||
if( vips_image_generate( conversion->out,
|
||||
vips_start_one, vips_embed_gen, vips_stop_one,
|
||||
embed->input, embed ) )
|
||||
embed->in, embed ) )
|
||||
return( -1 );
|
||||
|
||||
break;
|
||||
@ -571,7 +571,7 @@ vips_embed_class_init( VipsEmbedClass *class )
|
||||
_( "Input" ),
|
||||
_( "Input image" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsEmbed, input ) );
|
||||
G_STRUCT_OFFSET( VipsEmbed, in ) );
|
||||
|
||||
VIPS_ARG_INT( class, "x", 2,
|
||||
_( "x" ),
|
||||
|
@ -86,15 +86,15 @@
|
||||
|
||||
/**
|
||||
* VipsExtractArea:
|
||||
* @input: input image
|
||||
* @output: output image
|
||||
* @in: input image
|
||||
* @out: output image
|
||||
* @left: left edge of area to extract
|
||||
* @top: top edge of area to extract
|
||||
* @width: width of area to extract
|
||||
* @height: height of area to extract
|
||||
*
|
||||
* Extract an area from an image.
|
||||
* Extracting outside @input will trigger an error.
|
||||
* Extracting outside @in will trigger an error.
|
||||
*
|
||||
* See also: VipsExtractBand().
|
||||
*/
|
||||
@ -104,7 +104,7 @@ typedef struct _VipsExtractArea {
|
||||
|
||||
/* The input image.
|
||||
*/
|
||||
VipsImage *input;
|
||||
VipsImage *in;
|
||||
|
||||
int left;
|
||||
int top;
|
||||
@ -153,32 +153,32 @@ vips_extract_area_build( VipsObject *object )
|
||||
if( VIPS_OBJECT_CLASS( vips_extract_area_parent_class )->build( object ) )
|
||||
return( -1 );
|
||||
|
||||
if( extract->left + extract->width > extract->input->Xsize ||
|
||||
extract->top + extract->height > extract->input->Ysize ||
|
||||
if( extract->left + extract->width > extract->in->Xsize ||
|
||||
extract->top + extract->height > extract->in->Ysize ||
|
||||
extract->left < 0 || extract->top < 0 ||
|
||||
extract->width <= 0 || extract->height <= 0 ) {
|
||||
im_error( "VipsExtractArea", "%s", _( "bad extract area" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( vips_image_pio_input( extract->input ) ||
|
||||
vips_image_pio_output( conversion->output ) ||
|
||||
vips_check_coding_known( "VipsExtractArea", extract->input ) )
|
||||
if( vips_image_pio_input( extract->in ) ||
|
||||
vips_image_pio_output( conversion->out ) ||
|
||||
vips_check_coding_known( "VipsExtractArea", extract->in ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_image_copy_fields( conversion->output, extract->input ) )
|
||||
if( vips_image_copy_fields( conversion->out, extract->in ) )
|
||||
return( -1 );
|
||||
vips_demand_hint( conversion->output,
|
||||
VIPS_DEMAND_STYLE_THINSTRIP, extract->input, NULL );
|
||||
vips_demand_hint( conversion->out,
|
||||
VIPS_DEMAND_STYLE_THINSTRIP, extract->in, NULL );
|
||||
|
||||
conversion->output->Xsize = extract->width;
|
||||
conversion->output->Ysize = extract->height;
|
||||
conversion->output->Xoffset = -extract->left;
|
||||
conversion->output->Yoffset = -extract->top;
|
||||
conversion->out->Xsize = extract->width;
|
||||
conversion->out->Ysize = extract->height;
|
||||
conversion->out->Xoffset = -extract->left;
|
||||
conversion->out->Yoffset = -extract->top;
|
||||
|
||||
if( vips_image_generate( conversion->output,
|
||||
if( vips_image_generate( conversion->out,
|
||||
vips_start_one, vips_extract_area_gen, vips_stop_one,
|
||||
extract->input, extract ) )
|
||||
extract->in, extract ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -208,7 +208,7 @@ vips_extract_area_class_init( VipsExtractAreaClass *class )
|
||||
_( "Input" ),
|
||||
_( "Input image" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsExtractArea, input ) );
|
||||
G_STRUCT_OFFSET( VipsExtractArea, in ) );
|
||||
|
||||
VIPS_ARG_INT( class, "left", 2,
|
||||
_( "Left" ),
|
||||
@ -246,14 +246,14 @@ vips_extract_area_init( VipsExtractArea *extract )
|
||||
}
|
||||
|
||||
int
|
||||
vips_extract_area( VipsImage *input, VipsImage **output,
|
||||
vips_extract_area( VipsImage *in, VipsImage **out,
|
||||
int left, int top, int width, int height, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, height );
|
||||
result = vips_call_split( "extract_area", ap, input, output,
|
||||
result = vips_call_split( "extract_area", ap, in, out,
|
||||
left, top, width, height );
|
||||
va_end( ap );
|
||||
|
||||
@ -262,8 +262,8 @@ vips_extract_area( VipsImage *input, VipsImage **output,
|
||||
|
||||
/**
|
||||
* VipsExtractBand:
|
||||
* @input: input image
|
||||
* @output: output image
|
||||
* @in: input image
|
||||
* @out: output image
|
||||
* @band: band to extract
|
||||
* @n: number of bands to extract
|
||||
*
|
||||
@ -277,7 +277,7 @@ typedef struct _VipsExtractBand {
|
||||
|
||||
/* The input image.
|
||||
*/
|
||||
VipsImage *input;
|
||||
VipsImage *in;
|
||||
|
||||
int band;
|
||||
int n;
|
||||
@ -331,26 +331,26 @@ vips_extract_band_build( VipsObject *object )
|
||||
if( VIPS_OBJECT_CLASS( vips_extract_band_parent_class )->build( object ) )
|
||||
return( -1 );
|
||||
|
||||
if( extract->band + extract->n > extract->input->Bands ) {
|
||||
if( extract->band + extract->n > extract->in->Bands ) {
|
||||
im_error( "VipsExtractBand", "%s", _( "bad extract band" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( vips_image_pio_input( extract->input ) ||
|
||||
vips_image_pio_output( conversion->output ) ||
|
||||
vips_check_coding_known( "VipsExtractBand", extract->input ) )
|
||||
if( vips_image_pio_input( extract->in ) ||
|
||||
vips_image_pio_output( conversion->out ) ||
|
||||
vips_check_coding_known( "VipsExtractBand", extract->in ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_image_copy_fields( conversion->output, extract->input ) )
|
||||
if( vips_image_copy_fields( conversion->out, extract->in ) )
|
||||
return( -1 );
|
||||
vips_demand_hint( conversion->output,
|
||||
VIPS_DEMAND_STYLE_THINSTRIP, extract->input, NULL );
|
||||
vips_demand_hint( conversion->out,
|
||||
VIPS_DEMAND_STYLE_THINSTRIP, extract->in, NULL );
|
||||
|
||||
conversion->output->Bands = extract->n;
|
||||
conversion->out->Bands = extract->n;
|
||||
|
||||
if( vips_image_generate( conversion->output,
|
||||
if( vips_image_generate( conversion->out,
|
||||
vips_start_one, vips_extract_band_gen, vips_stop_one,
|
||||
extract->input, extract ) )
|
||||
extract->in, extract ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -371,11 +371,11 @@ vips_extract_band_class_init( VipsExtractBandClass *class )
|
||||
vobject_class->description = _( "extract band from an image" );
|
||||
vobject_class->build = vips_extract_band_build;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "input", 0,
|
||||
VIPS_ARG_IMAGE( class, "in", 0,
|
||||
_( "Input" ),
|
||||
_( "Input image" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsExtractBand, input ) );
|
||||
G_STRUCT_OFFSET( VipsExtractBand, in ) );
|
||||
|
||||
VIPS_ARG_INT( class, "band", 3,
|
||||
_( "Band" ),
|
||||
@ -399,13 +399,13 @@ vips_extract_band_init( VipsExtractBand *extract )
|
||||
}
|
||||
|
||||
int
|
||||
vips_extract_band( VipsImage *input, VipsImage **output, int band, ... )
|
||||
vips_extract_band( VipsImage *in, VipsImage **out, int band, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, band );
|
||||
result = vips_call_split( "extract_band", ap, input, output, band );
|
||||
result = vips_call_split( "extract_band", ap, in, out, band );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
|
@ -66,8 +66,8 @@
|
||||
|
||||
/**
|
||||
* VipsFlip:
|
||||
* @input: input image
|
||||
* @output: output image
|
||||
* @in: input image
|
||||
* @out: output image
|
||||
* @direction: flip horizontally or vertically
|
||||
*
|
||||
* Flips an image left-right or up-down.
|
||||
@ -82,7 +82,7 @@ typedef struct _VipsFlip {
|
||||
|
||||
/* The input image.
|
||||
*/
|
||||
VipsImage *input;
|
||||
VipsImage *in;
|
||||
|
||||
/* Swap bytes on the way through.
|
||||
*/
|
||||
@ -207,29 +207,29 @@ vips_flip_build( VipsObject *object )
|
||||
if( VIPS_OBJECT_CLASS( vips_flip_parent_class )->build( object ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_image_pio_input( flip->input ) ||
|
||||
vips_image_pio_output( conversion->output ) )
|
||||
if( vips_image_pio_input( flip->in ) ||
|
||||
vips_image_pio_output( conversion->out ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_image_copy_fields( conversion->output, flip->input ) )
|
||||
if( vips_image_copy_fields( conversion->out, flip->in ) )
|
||||
return( -1 );
|
||||
vips_demand_hint( conversion->output,
|
||||
VIPS_DEMAND_STYLE_THINSTRIP, flip->input, NULL );
|
||||
vips_demand_hint( conversion->out,
|
||||
VIPS_DEMAND_STYLE_THINSTRIP, flip->in, NULL );
|
||||
|
||||
if( flip->direction == VIPS_DIRECTION_HORIZONTAL ) {
|
||||
generate_fn = vips_flip_horizontal_gen;
|
||||
conversion->output->Xoffset = flip->input->Xsize;
|
||||
conversion->output->Yoffset = 0;
|
||||
conversion->out->Xoffset = flip->in->Xsize;
|
||||
conversion->out->Yoffset = 0;
|
||||
}
|
||||
else {
|
||||
generate_fn = vips_flip_vertical_gen;
|
||||
conversion->output->Xoffset = 0;
|
||||
conversion->output->Yoffset = flip->input->Ysize;
|
||||
conversion->out->Xoffset = 0;
|
||||
conversion->out->Yoffset = flip->in->Ysize;
|
||||
}
|
||||
|
||||
if( vips_image_generate( conversion->output,
|
||||
if( vips_image_generate( conversion->out,
|
||||
vips_start_one, generate_fn, vips_stop_one,
|
||||
flip->input, flip ) )
|
||||
flip->in, flip ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -250,11 +250,11 @@ vips_flip_class_init( VipsFlipClass *class )
|
||||
vobject_class->description = _( "flip an image" );
|
||||
vobject_class->build = vips_flip_build;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "input", 1,
|
||||
VIPS_ARG_IMAGE( class, "in", 1,
|
||||
_( "Input" ),
|
||||
_( "Input image" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsFlip, input ) );
|
||||
G_STRUCT_OFFSET( VipsFlip, in ) );
|
||||
|
||||
VIPS_ARG_ENUM( class, "direction", 6,
|
||||
_( "Direction" ),
|
||||
|
@ -1,460 +0,0 @@
|
||||
/* clip.c ... convert BandFmt, clipping values
|
||||
*
|
||||
* Author: Nicos Dessipris
|
||||
* Written on: 07/03/1991
|
||||
* Modified on:
|
||||
* 04/05/1992 JC
|
||||
* - works for char, uchar too
|
||||
* - floating point code removed from integer clip operations
|
||||
* - uses nint() instead of own rounding code
|
||||
* - calculated the number of >255 clips for float/double input
|
||||
* incorrectly
|
||||
* - rejects complex input correctly now
|
||||
* 27/4/93 JC
|
||||
* - adapted to work with partial images
|
||||
* - nint() removed, now just +0.5
|
||||
* - im_warning code removed
|
||||
* 30/6/93 JC
|
||||
* - adapted for partial v2
|
||||
* 31/8/93 JC
|
||||
* - now detects and prints over/underflows
|
||||
* 27/10/93 JC
|
||||
* - unsigned integer clips now faster!
|
||||
* - falls back to im_copy() correctly
|
||||
* 5/5/94 JC
|
||||
* - switched to rint()
|
||||
* 18/8/94 JC
|
||||
* - now uses evalend callback
|
||||
* 9/5/95 JC
|
||||
* - now does complex too
|
||||
* 11/7/95 JC
|
||||
* - now uses IM_RINT() macro
|
||||
* 10/3/01 JC
|
||||
* - slightly faster and simpler
|
||||
* - generalised to im_clip2fmt(), all other clippers now just call
|
||||
* this
|
||||
* 21/4/04 JC
|
||||
* - now does floor(), not rint() ... you'll need to round yourself
|
||||
* before calling this if you want round-to-nearest
|
||||
* 7/11/07
|
||||
* - use new evalstart/evalend system
|
||||
* 26/8/08
|
||||
* - oops, complex->complex conversion was broken
|
||||
* 27/1/10
|
||||
* - modernised
|
||||
* - gtk-doc
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
|
||||
/* Global state. Track over/under-flows for all sequences in this.
|
||||
*/
|
||||
typedef struct {
|
||||
IMAGE *in; /* Parameters */
|
||||
IMAGE *out;
|
||||
int ofmt;
|
||||
|
||||
int underflow; /* Number of underflows */
|
||||
int overflow; /* Number of overflows */
|
||||
} Clip;
|
||||
|
||||
static int
|
||||
clip_evalstart( Clip *clip )
|
||||
{
|
||||
/* Reset counts.
|
||||
*/
|
||||
clip->overflow = 0;
|
||||
clip->underflow = 0;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
clip_evalend( Clip *clip )
|
||||
{
|
||||
/* Print warnings, if necessary.
|
||||
*/
|
||||
if( clip->overflow || clip->underflow )
|
||||
im_warn( "im_clip",
|
||||
_( "%d underflows and %d overflows detected" ),
|
||||
clip->underflow, clip->overflow );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Build a Clip.
|
||||
*/
|
||||
static Clip *
|
||||
clip_new( IMAGE *in, IMAGE *out, int ofmt )
|
||||
{
|
||||
Clip *clip = IM_NEW( out, Clip );
|
||||
|
||||
if( !clip )
|
||||
return( NULL );
|
||||
|
||||
clip->in = in;
|
||||
clip->out = out;
|
||||
clip->ofmt = ofmt;
|
||||
clip->underflow = 0;
|
||||
clip->overflow = 0;
|
||||
|
||||
if( im_add_evalstart_callback( out,
|
||||
(im_callback_fn) clip_evalstart, clip, NULL ) ||
|
||||
im_add_evalend_callback( out,
|
||||
(im_callback_fn) clip_evalend, clip, NULL ) )
|
||||
return( NULL );
|
||||
|
||||
return( clip );
|
||||
}
|
||||
|
||||
/* Our sequence value: the region this sequence is using, and two local stats.
|
||||
*/
|
||||
typedef struct {
|
||||
REGION *ir; /* Input region */
|
||||
int underflow; /* Number of underflows */
|
||||
int overflow; /* Number of overflows */
|
||||
} ClipSequence;
|
||||
|
||||
/* Destroy a sequence value.
|
||||
*/
|
||||
static int
|
||||
clip_stop( void *vseq, void *a, void *b )
|
||||
{
|
||||
ClipSequence *seq = (ClipSequence *) vseq;
|
||||
Clip *clip = (Clip *) b;
|
||||
|
||||
/* Add to global stats.
|
||||
*/
|
||||
clip->underflow += seq->underflow;
|
||||
clip->overflow += seq->overflow;
|
||||
|
||||
IM_FREEF( im_region_free, seq->ir );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Make a sequence value.
|
||||
*/
|
||||
static void *
|
||||
clip_start( IMAGE *out, void *a, void *b )
|
||||
{
|
||||
IMAGE *in = (IMAGE *) a;
|
||||
ClipSequence *seq;
|
||||
|
||||
if( !(seq = IM_NEW( out, ClipSequence )) )
|
||||
return( NULL );
|
||||
|
||||
/* Init!
|
||||
*/
|
||||
seq->ir = NULL;
|
||||
seq->overflow = 0;
|
||||
seq->underflow = 0;
|
||||
|
||||
if( !(seq->ir = im_region_create( in )) )
|
||||
return( NULL );
|
||||
|
||||
return( seq );
|
||||
}
|
||||
|
||||
/* Clip int types to an int type.
|
||||
*/
|
||||
#define IM_CLIP_INT_INT( ITYPE, OTYPE, IM_CLIP ) { \
|
||||
ITYPE *p = (ITYPE *) in; \
|
||||
OTYPE *q = (OTYPE *) out; \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) { \
|
||||
int t = p[x]; \
|
||||
\
|
||||
IM_CLIP( t, seq ); \
|
||||
\
|
||||
q[x] = t; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Clip float types to an int type.
|
||||
*/
|
||||
#define IM_CLIP_FLOAT_INT( ITYPE, OTYPE, IM_CLIP ) { \
|
||||
ITYPE *p = (ITYPE *) in; \
|
||||
OTYPE *q = (OTYPE *) out; \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) { \
|
||||
ITYPE v = floor( p[x] ); \
|
||||
\
|
||||
IM_CLIP( v, seq ); \
|
||||
\
|
||||
q[x] = v; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Clip complex types to an int type. Just take the real part.
|
||||
*/
|
||||
#define IM_CLIP_COMPLEX_INT( ITYPE, OTYPE, IM_CLIP ) { \
|
||||
ITYPE *p = (ITYPE *) in; \
|
||||
OTYPE *q = (OTYPE *) out; \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) { \
|
||||
ITYPE v = floor( p[0] ); \
|
||||
p += 2; \
|
||||
\
|
||||
IM_CLIP( v, seq ); \
|
||||
\
|
||||
q[x] = v; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Clip non-complex types to a float type.
|
||||
*/
|
||||
#define IM_CLIP_REAL_FLOAT( ITYPE, OTYPE ) { \
|
||||
ITYPE *p = (ITYPE *) in; \
|
||||
OTYPE *q = (OTYPE *) out; \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) \
|
||||
q[x] = p[x]; \
|
||||
}
|
||||
|
||||
/* Clip complex types to a float type ... just take real.
|
||||
*/
|
||||
#define IM_CLIP_COMPLEX_FLOAT( ITYPE, OTYPE ) { \
|
||||
ITYPE *p = (ITYPE *) in; \
|
||||
OTYPE *q = (OTYPE *) out; \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) { \
|
||||
q[x] = p[0]; \
|
||||
p += 2; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Clip any non-complex to a complex type ... set imaginary to zero.
|
||||
*/
|
||||
#define IM_CLIP_REAL_COMPLEX( ITYPE, OTYPE ) { \
|
||||
ITYPE *p = (ITYPE *) in; \
|
||||
OTYPE *q = (OTYPE *) out; \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) { \
|
||||
q[0] = p[x]; \
|
||||
q[1] = 0.0; \
|
||||
q += 2; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Clip any complex to a complex type.
|
||||
*/
|
||||
#define IM_CLIP_COMPLEX_COMPLEX( ITYPE, OTYPE ) { \
|
||||
ITYPE *p = (ITYPE *) in; \
|
||||
OTYPE *q = (OTYPE *) out; \
|
||||
\
|
||||
for( x = 0; x < sz; x++ ) { \
|
||||
q[0] = p[0]; \
|
||||
q[1] = p[1]; \
|
||||
p += 2; \
|
||||
q += 2; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define BAND_SWITCH_INNER( ITYPE, INT, FLOAT, COMPLEX ) { \
|
||||
switch( clip->out->BandFmt ) { \
|
||||
case IM_BANDFMT_UCHAR: \
|
||||
INT( ITYPE, unsigned char, IM_CLIP_UCHAR ); \
|
||||
break; \
|
||||
case IM_BANDFMT_CHAR: \
|
||||
INT( ITYPE, signed char, IM_CLIP_CHAR ); \
|
||||
break; \
|
||||
case IM_BANDFMT_USHORT: \
|
||||
INT( ITYPE, unsigned short, IM_CLIP_USHORT ); \
|
||||
break; \
|
||||
case IM_BANDFMT_SHORT: \
|
||||
INT( ITYPE, signed short, IM_CLIP_SHORT ); \
|
||||
break; \
|
||||
case IM_BANDFMT_UINT: \
|
||||
INT( ITYPE, unsigned int, IM_CLIP_NONE ); \
|
||||
break; \
|
||||
case IM_BANDFMT_INT: \
|
||||
INT( ITYPE, signed int, IM_CLIP_NONE ); \
|
||||
break; \
|
||||
case IM_BANDFMT_FLOAT: \
|
||||
FLOAT( ITYPE, float ); \
|
||||
break; \
|
||||
case IM_BANDFMT_DOUBLE: \
|
||||
FLOAT( ITYPE, double ); \
|
||||
break; \
|
||||
case IM_BANDFMT_COMPLEX: \
|
||||
COMPLEX( ITYPE, float ); \
|
||||
break; \
|
||||
case IM_BANDFMT_DPCOMPLEX: \
|
||||
COMPLEX( ITYPE, double ); \
|
||||
break; \
|
||||
default: \
|
||||
g_assert( 0 ); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Clip a small area.
|
||||
*/
|
||||
static int
|
||||
clip_gen( REGION *or, void *vseq, void *a, void *b )
|
||||
{
|
||||
ClipSequence *seq = (ClipSequence *) vseq;
|
||||
Clip *clip = (Clip *) b;
|
||||
REGION *ir = seq->ir;
|
||||
Rect *r = &or->valid;
|
||||
int le = r->left;
|
||||
int to = r->top;
|
||||
int bo = IM_RECT_BOTTOM(r);
|
||||
int sz = IM_REGION_N_ELEMENTS( or );
|
||||
int x, y;
|
||||
|
||||
if( im_prepare( ir, r ) )
|
||||
return( -1 );
|
||||
|
||||
for( y = to; y < bo; y++ ) {
|
||||
PEL *in = (PEL *) IM_REGION_ADDR( ir, le, y );
|
||||
PEL *out = (PEL *) IM_REGION_ADDR( or, le, y );
|
||||
|
||||
switch( clip->in->BandFmt ) {
|
||||
case IM_BANDFMT_UCHAR:
|
||||
BAND_SWITCH_INNER( unsigned char,
|
||||
IM_CLIP_INT_INT,
|
||||
IM_CLIP_REAL_FLOAT,
|
||||
IM_CLIP_REAL_COMPLEX );
|
||||
break;
|
||||
case IM_BANDFMT_CHAR:
|
||||
BAND_SWITCH_INNER( signed char,
|
||||
IM_CLIP_INT_INT,
|
||||
IM_CLIP_REAL_FLOAT,
|
||||
IM_CLIP_REAL_COMPLEX );
|
||||
break;
|
||||
case IM_BANDFMT_USHORT:
|
||||
BAND_SWITCH_INNER( unsigned short,
|
||||
IM_CLIP_INT_INT,
|
||||
IM_CLIP_REAL_FLOAT,
|
||||
IM_CLIP_REAL_COMPLEX );
|
||||
break;
|
||||
case IM_BANDFMT_SHORT:
|
||||
BAND_SWITCH_INNER( signed short,
|
||||
IM_CLIP_INT_INT,
|
||||
IM_CLIP_REAL_FLOAT,
|
||||
IM_CLIP_REAL_COMPLEX );
|
||||
break;
|
||||
case IM_BANDFMT_UINT:
|
||||
BAND_SWITCH_INNER( unsigned int,
|
||||
IM_CLIP_INT_INT,
|
||||
IM_CLIP_REAL_FLOAT,
|
||||
IM_CLIP_REAL_COMPLEX );
|
||||
break;
|
||||
case IM_BANDFMT_INT:
|
||||
BAND_SWITCH_INNER( signed int,
|
||||
IM_CLIP_INT_INT,
|
||||
IM_CLIP_REAL_FLOAT,
|
||||
IM_CLIP_REAL_COMPLEX );
|
||||
break;
|
||||
case IM_BANDFMT_FLOAT:
|
||||
BAND_SWITCH_INNER( float,
|
||||
IM_CLIP_FLOAT_INT,
|
||||
IM_CLIP_REAL_FLOAT,
|
||||
IM_CLIP_REAL_COMPLEX );
|
||||
break;
|
||||
case IM_BANDFMT_DOUBLE:
|
||||
BAND_SWITCH_INNER( double,
|
||||
IM_CLIP_FLOAT_INT,
|
||||
IM_CLIP_REAL_FLOAT,
|
||||
IM_CLIP_REAL_COMPLEX );
|
||||
break;
|
||||
case IM_BANDFMT_COMPLEX:
|
||||
BAND_SWITCH_INNER( float,
|
||||
IM_CLIP_COMPLEX_INT,
|
||||
IM_CLIP_COMPLEX_FLOAT,
|
||||
IM_CLIP_COMPLEX_COMPLEX );
|
||||
break;
|
||||
case IM_BANDFMT_DPCOMPLEX:
|
||||
BAND_SWITCH_INNER( double,
|
||||
IM_CLIP_COMPLEX_INT,
|
||||
IM_CLIP_COMPLEX_FLOAT,
|
||||
IM_CLIP_COMPLEX_COMPLEX );
|
||||
break;
|
||||
default:
|
||||
g_assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_clip2fmt:
|
||||
* @in: input image
|
||||
* @out: output image
|
||||
* @fmt: format to convert to
|
||||
*
|
||||
* Convert @in to @fmt format. You can convert between any pair of formats.
|
||||
* Floats are truncated (not rounded). Out of range values are clipped.
|
||||
*
|
||||
* See also: im_scale(), im_ri2c().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int
|
||||
im_clip2fmt( IMAGE *in, IMAGE *out, VipsBandFmt fmt )
|
||||
{
|
||||
Clip *clip;
|
||||
|
||||
if( im_check_uncoded( "im_clip2fmt", in ) ||
|
||||
im_piocheck( in, out ) )
|
||||
return( -1 );
|
||||
if( fmt < 0 || fmt > IM_BANDFMT_DPCOMPLEX ) {
|
||||
im_error( "im_clip2fmt", "%s", _( "fmt out of range" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* Trivial case: fall back to im_copy().
|
||||
*/
|
||||
if( in->BandFmt == fmt )
|
||||
return( im_copy( in, out ) );
|
||||
|
||||
if( !(clip = clip_new( in, out, fmt )) )
|
||||
return( -1 );
|
||||
if( im_cp_desc( out, in ) )
|
||||
return( -1 );
|
||||
out->BandFmt = fmt;
|
||||
|
||||
if( im_demand_hint( out, IM_THINSTRIP, in, NULL ) ||
|
||||
im_generate( out, clip_start, clip_gen, clip_stop, in, clip ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
@ -281,7 +281,7 @@ vips_insert_build( VipsObject *object )
|
||||
|
||||
if( vips_image_pio_input( insert->main ) ||
|
||||
vips_image_pio_input( insert->sub ) ||
|
||||
vips_image_pio_output( conversion->output ) ||
|
||||
vips_image_pio_output( conversion->out ) ||
|
||||
vips_check_bands_1orn( "VipsInsert",
|
||||
insert->main, insert->sub ) ||
|
||||
vips_check_coding_known( "VipsInsert", insert->main ) ||
|
||||
@ -299,13 +299,13 @@ vips_insert_build( VipsObject *object )
|
||||
return( -1 );
|
||||
insert->main_processed = t[2];
|
||||
insert->sub_processed = t[3];
|
||||
if( !(arry = vips_allocate_input_array( conversion->output,
|
||||
if( !(arry = vips_allocate_input_array( conversion->out,
|
||||
insert->main_processed, insert->sub_processed, NULL )) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_image_copy_fields_array( conversion->output, arry ) )
|
||||
if( vips_image_copy_fields_array( conversion->out, arry ) )
|
||||
return( -1 );
|
||||
vips_demand_hint_array( conversion->output,
|
||||
vips_demand_hint_array( conversion->out,
|
||||
VIPS_DEMAND_STYLE_SMALLTILE, arry );
|
||||
|
||||
/* Calculate geometry.
|
||||
@ -337,15 +337,15 @@ vips_insert_build( VipsObject *object )
|
||||
else
|
||||
insert->rout = insert->rmain;
|
||||
|
||||
conversion->output->Xsize = insert->rout.width;
|
||||
conversion->output->Ysize = insert->rout.height;
|
||||
conversion->out->Xsize = insert->rout.width;
|
||||
conversion->out->Ysize = insert->rout.height;
|
||||
|
||||
if( !(insert->ink = vips__vector_to_ink(
|
||||
"VipsInsert", conversion->output,
|
||||
"VipsInsert", conversion->out,
|
||||
insert->background->data, insert->background->n )) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_image_generate( conversion->output,
|
||||
if( vips_image_generate( conversion->out,
|
||||
vips_start_many, vips_insert_gen, vips_stop_many,
|
||||
arry, insert ) )
|
||||
return( -1 );
|
||||
|
@ -72,7 +72,7 @@
|
||||
* VipsJoin:
|
||||
* @in1: first input image
|
||||
* @in2: second input image
|
||||
* @output: output image
|
||||
* @out: output image
|
||||
* @direction: join horizontally or vertically
|
||||
* @expand: %TRUE to expand the output image to hold all of the input pixels
|
||||
* @shim: space between images, in pixels
|
||||
@ -83,13 +83,13 @@
|
||||
* of @direction.
|
||||
*
|
||||
* If one is taller or wider than the
|
||||
* other, @output will be has high as the smaller. If @expand is %TRUE, then
|
||||
* other, @out will be has high as the smaller. If @expand is %TRUE, then
|
||||
* the output will be expanded to contain all of the input pixels.
|
||||
*
|
||||
* Use @align to set the edge that the images align on. By default, they align
|
||||
* on the edge with the lower value coordinate.
|
||||
*
|
||||
* Use @background to set the colour of any pixels in @output which are not
|
||||
* Use @background to set the colour of any pixels in @out which are not
|
||||
* present in either @in1 or @in2.
|
||||
*
|
||||
* Use @shim to set the spacing between the images. By default this is 0.
|
||||
@ -227,7 +227,7 @@ vips_join_build( VipsObject *object )
|
||||
}
|
||||
|
||||
|
||||
if( vips_image_write( t, conversion->output ) ) {
|
||||
if( vips_image_write( t, conversion->out ) ) {
|
||||
g_object_unref( t );
|
||||
return( -1 );
|
||||
}
|
||||
@ -310,14 +310,14 @@ vips_join_init( VipsJoin *join )
|
||||
}
|
||||
|
||||
int
|
||||
vips_join( VipsImage *in1, VipsImage *in2, VipsImage **output,
|
||||
vips_join( VipsImage *in1, VipsImage *in2, VipsImage **out,
|
||||
VipsDirection direction, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, direction );
|
||||
result = vips_call_split( "join", ap, in1, in2, output, direction );
|
||||
result = vips_call_split( "join", ap, in1, in2, out, direction );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
|
@ -58,7 +58,7 @@
|
||||
/**
|
||||
* VipsReplicate:
|
||||
* @in: input image
|
||||
* @output: output image
|
||||
* @out: output image
|
||||
* @across: repeat input this many times across
|
||||
* @down: repeat input this many times down
|
||||
*
|
||||
@ -72,7 +72,7 @@ typedef struct _VipsReplicate {
|
||||
|
||||
/* The input image.
|
||||
*/
|
||||
VipsImage *input;
|
||||
VipsImage *in;
|
||||
|
||||
int across;
|
||||
int down;
|
||||
@ -170,21 +170,21 @@ vips_replicate_build( VipsObject *object )
|
||||
if( VIPS_OBJECT_CLASS( vips_replicate_parent_class )->build( object ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_image_pio_input( replicate->input ) ||
|
||||
vips_image_pio_output( conversion->output ) )
|
||||
if( vips_image_pio_input( replicate->in ) ||
|
||||
vips_image_pio_output( conversion->out ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_image_copy_fields( conversion->output, replicate->input ) )
|
||||
if( vips_image_copy_fields( conversion->out, replicate->in ) )
|
||||
return( -1 );
|
||||
vips_demand_hint( conversion->output,
|
||||
VIPS_DEMAND_STYLE_SMALLTILE, replicate->input, NULL );
|
||||
vips_demand_hint( conversion->out,
|
||||
VIPS_DEMAND_STYLE_SMALLTILE, replicate->in, NULL );
|
||||
|
||||
conversion->output->Xsize *= replicate->across;
|
||||
conversion->output->Ysize *= replicate->down;
|
||||
conversion->out->Xsize *= replicate->across;
|
||||
conversion->out->Ysize *= replicate->down;
|
||||
|
||||
if( vips_image_generate( conversion->output,
|
||||
if( vips_image_generate( conversion->out,
|
||||
vips_start_one, vips_replicate_gen, vips_stop_one,
|
||||
replicate->input, replicate ) )
|
||||
replicate->in, replicate ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -205,11 +205,11 @@ vips_replicate_class_init( VipsReplicateClass *class )
|
||||
vobject_class->description = _( "replicate an image" );
|
||||
vobject_class->build = vips_replicate_build;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "input", 0,
|
||||
VIPS_ARG_IMAGE( class, "in", 0,
|
||||
_( "Input" ),
|
||||
_( "Input image" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsReplicate, input ) );
|
||||
G_STRUCT_OFFSET( VipsReplicate, in ) );
|
||||
|
||||
VIPS_ARG_INT( class, "across", 4,
|
||||
_( "Across" ),
|
||||
|
@ -1266,3 +1266,20 @@ im_replicate( IMAGE *in, IMAGE *out, int across, int down )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int
|
||||
im_clip2fmt( IMAGE *in, IMAGE *out, VipsBandFmt fmt )
|
||||
{
|
||||
VipsImage *t;
|
||||
|
||||
if( vips_cast( in, &t, fmt,
|
||||
NULL ) )
|
||||
return( -1 );
|
||||
if( vips_image_write( t, out ) ) {
|
||||
g_object_unref( t );
|
||||
return( -1 );
|
||||
}
|
||||
g_object_unref( t );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
@ -134,6 +134,8 @@ int vips_extract_band( VipsImage *input, VipsImage **output, int band, ... )
|
||||
__attribute__((sentinel));
|
||||
int vips_replicate( VipsImage *in, VipsImage **out, int across, int down, ... )
|
||||
__attribute__((sentinel));
|
||||
int vips_cast( VipsImage *in, VipsImage **out, VipsBandFormat format, ... )
|
||||
__attribute__((sentinel));
|
||||
|
||||
|
||||
|
||||
@ -143,7 +145,6 @@ int im_mask2vips( DOUBLEMASK *in, VipsImage *out );
|
||||
|
||||
int im_copy_file( VipsImage *in, VipsImage *out );
|
||||
|
||||
int im_clip2fmt( VipsImage *in, VipsImage *out, VipsBandFormat fmt );
|
||||
int im_scale( VipsImage *in, VipsImage *out );
|
||||
int im_msb( VipsImage *in, VipsImage *out );
|
||||
int im_msb_band( VipsImage *in, VipsImage *out, int band );
|
||||
|
@ -558,6 +558,8 @@ int im_extract_areabands( VipsImage *in, VipsImage *out,
|
||||
|
||||
int im_replicate( VipsImage *in, VipsImage *out, int across, int down );
|
||||
|
||||
int im_clip2fmt( VipsImage *in, VipsImage *out, VipsBandFormat fmt );
|
||||
|
||||
/* ruby-vips uses this
|
||||
*/
|
||||
#define vips_class_map_concrete_all vips_class_map_all
|
||||
|
@ -458,9 +458,9 @@ vips_region_new( VipsImage *image )
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#endif /*DEBUG*/
|
||||
g_assert( vips_object_sanity( VIPS_OBJECT( image ) ) );
|
||||
g_assert( vips_object_sanity( VIPS_OBJECT( region ) ) );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
return( region );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user