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_subtract(), im_avg(), im_min(), im_minpos(), im_copy(), im_embed(),
|
||||||
im_flophor(), im_flipver(), im_insert(), im_insert_noexpand(), im_lrjoin(),
|
im_flophor(), im_flipver(), im_insert(), im_insert_noexpand(), im_lrjoin(),
|
||||||
im_tbjoin(), im_extract_area(), im_extract_bands(), im_extract_areabands(),
|
im_tbjoin(), im_extract_area(), im_extract_bands(), im_extract_areabands(),
|
||||||
im_replicate()
|
im_replicate(), im_clip2fmt()
|
||||||
redone as classes
|
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
|
- generate has a 'stop' param to signal successful early termination
|
||||||
- added optional output args, eg. x/y for min
|
- added optional output args, eg. x/y for min
|
||||||
- CLI supports optional output args
|
- 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
|
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 \
|
join.c \
|
||||||
extract.c \
|
extract.c \
|
||||||
replicate.c \
|
replicate.c \
|
||||||
|
cast.c \
|
||||||
conver_dispatch.c \
|
conver_dispatch.c \
|
||||||
im_black.c \
|
im_black.c \
|
||||||
im_c2amph.c \
|
im_c2amph.c \
|
||||||
im_c2rect.c \
|
im_c2rect.c \
|
||||||
im_c2imag.c \
|
im_c2imag.c \
|
||||||
im_c2real.c \
|
im_c2real.c \
|
||||||
im_clip2fmt.c \
|
|
||||||
im_copy_file.c \
|
im_copy_file.c \
|
||||||
im_falsecolour.c \
|
im_falsecolour.c \
|
||||||
im_gbandjoin.c \
|
im_gbandjoin.c \
|
||||||
|
@ -43,6 +43,8 @@
|
|||||||
* 27/1/10
|
* 27/1/10
|
||||||
* - modernised
|
* - modernised
|
||||||
* - gtk-doc
|
* - gtk-doc
|
||||||
|
* 27/10/11
|
||||||
|
* - redone as a class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -83,6 +85,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include <vips/vips.h>
|
#include <vips/vips.h>
|
||||||
#include <vips/internal.h>
|
#include <vips/internal.h>
|
||||||
@ -105,16 +108,85 @@
|
|||||||
typedef struct _VipsCast {
|
typedef struct _VipsCast {
|
||||||
VipsConversion parent_instance;
|
VipsConversion parent_instance;
|
||||||
|
|
||||||
VipsImage *input;
|
VipsImage *in;
|
||||||
VipsBandFormat format;
|
VipsBandFormat format;
|
||||||
|
|
||||||
|
int underflow; /* Number of underflows */
|
||||||
|
int overflow; /* Number of overflows */
|
||||||
|
|
||||||
} VipsCast;
|
} VipsCast;
|
||||||
|
|
||||||
typedef VipsConversionClass VipsCastClass;
|
typedef VipsConversionClass VipsCastClass;
|
||||||
|
|
||||||
G_DEFINE_TYPE( VipsCast, vips_cast, VIPS_TYPE_CONVERSION );
|
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 ) { \
|
#define VIPS_CLIP_INT_INT( ITYPE, OTYPE, VIPS_CLIP ) { \
|
||||||
ITYPE *p = (ITYPE *) in; \
|
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 ) { \
|
#define VIPS_CLIP_FLOAT_INT( ITYPE, OTYPE, VIPS_CLIP ) { \
|
||||||
ITYPE *p = (ITYPE *) in; \
|
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 ) { \
|
#define VIPS_CLIP_COMPLEX_INT( ITYPE, OTYPE, VIPS_CLIP ) { \
|
||||||
ITYPE *p = (ITYPE *) in; \
|
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 ) { \
|
#define VIPS_CLIP_REAL_FLOAT( ITYPE, OTYPE ) { \
|
||||||
ITYPE *p = (ITYPE *) in; \
|
ITYPE *p = (ITYPE *) in; \
|
||||||
@ -170,7 +242,7 @@ G_DEFINE_TYPE( VipsCast, vips_cast, VIPS_TYPE_CONVERSION );
|
|||||||
q[x] = p[x]; \
|
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 ) { \
|
#define VIPS_CLIP_COMPLEX_FLOAT( ITYPE, OTYPE ) { \
|
||||||
ITYPE *p = (ITYPE *) in; \
|
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 ) { \
|
#define VIPS_CLIP_REAL_COMPLEX( ITYPE, OTYPE ) { \
|
||||||
ITYPE *p = (ITYPE *) in; \
|
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 ) { \
|
#define VIPS_CLIP_COMPLEX_COMPLEX( ITYPE, OTYPE ) { \
|
||||||
ITYPE *p = (ITYPE *) in; \
|
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 ) { \
|
#define BAND_SWITCH_INNER( ITYPE, INT, FLOAT, COMPLEX ) { \
|
||||||
switch( clip->out->BandFmt ) { \
|
switch( conversion->out->BandFmt ) { \
|
||||||
case VIPS_FORMAT_UCHAR: \
|
case VIPS_FORMAT_UCHAR: \
|
||||||
INT( ITYPE, unsigned char, VIPS_CLIP_UCHAR ); \
|
INT( ITYPE, unsigned char, VIPS_CLIP_UCHAR ); \
|
||||||
break; \
|
break; \
|
||||||
|
\
|
||||||
case VIPS_FORMAT_CHAR: \
|
case VIPS_FORMAT_CHAR: \
|
||||||
INT( ITYPE, signed char, VIPS_CLIP_CHAR ); \
|
INT( ITYPE, signed char, VIPS_CLIP_CHAR ); \
|
||||||
break; \
|
break; \
|
||||||
|
\
|
||||||
case VIPS_FORMAT_USHORT: \
|
case VIPS_FORMAT_USHORT: \
|
||||||
INT( ITYPE, unsigned short, VIPS_CLIP_USHORT ); \
|
INT( ITYPE, unsigned short, VIPS_CLIP_USHORT ); \
|
||||||
break; \
|
break; \
|
||||||
|
\
|
||||||
case VIPS_FORMAT_SHORT: \
|
case VIPS_FORMAT_SHORT: \
|
||||||
INT( ITYPE, signed short, VIPS_CLIP_SHORT ); \
|
INT( ITYPE, signed short, VIPS_CLIP_SHORT ); \
|
||||||
break; \
|
break; \
|
||||||
|
\
|
||||||
case VIPS_FORMAT_UINT: \
|
case VIPS_FORMAT_UINT: \
|
||||||
INT( ITYPE, unsigned int, VIPS_CLIP_NONE ); \
|
INT( ITYPE, unsigned int, VIPS_CLIP_NONE ); \
|
||||||
break; \
|
break; \
|
||||||
|
\
|
||||||
case VIPS_FORMAT_INT: \
|
case VIPS_FORMAT_INT: \
|
||||||
INT( ITYPE, signed int, VIPS_CLIP_NONE ); \
|
INT( ITYPE, signed int, VIPS_CLIP_NONE ); \
|
||||||
break; \
|
break; \
|
||||||
|
\
|
||||||
case VIPS_FORMAT_FLOAT: \
|
case VIPS_FORMAT_FLOAT: \
|
||||||
FLOAT( ITYPE, float ); \
|
FLOAT( ITYPE, float ); \
|
||||||
break; \
|
break; \
|
||||||
|
\
|
||||||
case VIPS_FORMAT_DOUBLE: \
|
case VIPS_FORMAT_DOUBLE: \
|
||||||
FLOAT( ITYPE, double ); \
|
FLOAT( ITYPE, double ); \
|
||||||
break; \
|
break; \
|
||||||
|
\
|
||||||
case VIPS_FORMAT_COMPLEX: \
|
case VIPS_FORMAT_COMPLEX: \
|
||||||
COMPLEX( ITYPE, float ); \
|
COMPLEX( ITYPE, float ); \
|
||||||
break; \
|
break; \
|
||||||
|
\
|
||||||
case VIPS_FORMAT_DPCOMPLEX: \
|
case VIPS_FORMAT_DPCOMPLEX: \
|
||||||
COMPLEX( ITYPE, double ); \
|
COMPLEX( ITYPE, double ); \
|
||||||
break; \
|
break; \
|
||||||
|
\
|
||||||
default: \
|
default: \
|
||||||
g_assert( 0 ); \
|
g_assert( 0 ); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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 )
|
gboolean *stop )
|
||||||
{
|
{
|
||||||
VipsRegion *ir = (VipsRegion *) seq;
|
VipsCastSequence *seq = (VipsCastSequence *) vseq;
|
||||||
Clip *clip = (Clip *) b;
|
VipsRegion *ir = seq->ir;
|
||||||
|
VipsCast *cast = (VipsCast *) b;
|
||||||
|
VipsConversion *conversion = (VipsConversion *) b;
|
||||||
VipsRect *r = &or->valid;
|
VipsRect *r = &or->valid;
|
||||||
int le = r->left;
|
int le = r->left;
|
||||||
int to = r->top;
|
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 *in = (PEL *) VIPS_REGION_ADDR( ir, le, y );
|
||||||
PEL *out = (PEL *) VIPS_REGION_ADDR( or, le, y );
|
PEL *out = (PEL *) VIPS_REGION_ADDR( or, le, y );
|
||||||
|
|
||||||
switch( clip->in->BandFmt ) {
|
switch( cast->in->BandFmt ) {
|
||||||
case VIPS_FORMAT_UCHAR:
|
case VIPS_FORMAT_UCHAR:
|
||||||
BAND_SWITCH_INNER( unsigned char,
|
BAND_SWITCH_INNER( unsigned char,
|
||||||
VIPS_CLIP_INT_INT,
|
VIPS_CLIP_INT_INT,
|
||||||
VIPS_CLIP_REAL_FLOAT,
|
VIPS_CLIP_REAL_FLOAT,
|
||||||
VIPS_CLIP_REAL_COMPLEX );
|
VIPS_CLIP_REAL_COMPLEX );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_FORMAT_CHAR:
|
case VIPS_FORMAT_CHAR:
|
||||||
BAND_SWITCH_INNER( signed char,
|
BAND_SWITCH_INNER( signed char,
|
||||||
VIPS_CLIP_INT_INT,
|
VIPS_CLIP_INT_INT,
|
||||||
VIPS_CLIP_REAL_FLOAT,
|
VIPS_CLIP_REAL_FLOAT,
|
||||||
VIPS_CLIP_REAL_COMPLEX );
|
VIPS_CLIP_REAL_COMPLEX );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_FORMAT_USHORT:
|
case VIPS_FORMAT_USHORT:
|
||||||
BAND_SWITCH_INNER( unsigned short,
|
BAND_SWITCH_INNER( unsigned short,
|
||||||
VIPS_CLIP_INT_INT,
|
VIPS_CLIP_INT_INT,
|
||||||
VIPS_CLIP_REAL_FLOAT,
|
VIPS_CLIP_REAL_FLOAT,
|
||||||
VIPS_CLIP_REAL_COMPLEX );
|
VIPS_CLIP_REAL_COMPLEX );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_FORMAT_SHORT:
|
case VIPS_FORMAT_SHORT:
|
||||||
BAND_SWITCH_INNER( signed short,
|
BAND_SWITCH_INNER( signed short,
|
||||||
VIPS_CLIP_INT_INT,
|
VIPS_CLIP_INT_INT,
|
||||||
VIPS_CLIP_REAL_FLOAT,
|
VIPS_CLIP_REAL_FLOAT,
|
||||||
VIPS_CLIP_REAL_COMPLEX );
|
VIPS_CLIP_REAL_COMPLEX );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_FORMAT_UINT:
|
case VIPS_FORMAT_UINT:
|
||||||
BAND_SWITCH_INNER( unsigned int,
|
BAND_SWITCH_INNER( unsigned int,
|
||||||
VIPS_CLIP_INT_INT,
|
VIPS_CLIP_INT_INT,
|
||||||
VIPS_CLIP_REAL_FLOAT,
|
VIPS_CLIP_REAL_FLOAT,
|
||||||
VIPS_CLIP_REAL_COMPLEX );
|
VIPS_CLIP_REAL_COMPLEX );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_FORMAT_INT:
|
case VIPS_FORMAT_INT:
|
||||||
BAND_SWITCH_INNER( signed int,
|
BAND_SWITCH_INNER( signed int,
|
||||||
VIPS_CLIP_INT_INT,
|
VIPS_CLIP_INT_INT,
|
||||||
VIPS_CLIP_REAL_FLOAT,
|
VIPS_CLIP_REAL_FLOAT,
|
||||||
VIPS_CLIP_REAL_COMPLEX );
|
VIPS_CLIP_REAL_COMPLEX );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_FORMAT_FLOAT:
|
case VIPS_FORMAT_FLOAT:
|
||||||
BAND_SWITCH_INNER( float,
|
BAND_SWITCH_INNER( float,
|
||||||
VIPS_CLIP_FLOAT_INT,
|
VIPS_CLIP_FLOAT_INT,
|
||||||
VIPS_CLIP_REAL_FLOAT,
|
VIPS_CLIP_REAL_FLOAT,
|
||||||
VIPS_CLIP_REAL_COMPLEX );
|
VIPS_CLIP_REAL_COMPLEX );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_FORMAT_DOUBLE:
|
case VIPS_FORMAT_DOUBLE:
|
||||||
BAND_SWITCH_INNER( double,
|
BAND_SWITCH_INNER( double,
|
||||||
VIPS_CLIP_FLOAT_INT,
|
VIPS_CLIP_FLOAT_INT,
|
||||||
VIPS_CLIP_REAL_FLOAT,
|
VIPS_CLIP_REAL_FLOAT,
|
||||||
VIPS_CLIP_REAL_COMPLEX );
|
VIPS_CLIP_REAL_COMPLEX );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_FORMAT_COMPLEX:
|
case VIPS_FORMAT_COMPLEX:
|
||||||
BAND_SWITCH_INNER( float,
|
BAND_SWITCH_INNER( float,
|
||||||
VIPS_CLIP_COMPLEX_INT,
|
VIPS_CLIP_COMPLEX_INT,
|
||||||
VIPS_CLIP_COMPLEX_FLOAT,
|
VIPS_CLIP_COMPLEX_FLOAT,
|
||||||
VIPS_CLIP_COMPLEX_COMPLEX );
|
VIPS_CLIP_COMPLEX_COMPLEX );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIPS_FORMAT_DPCOMPLEX:
|
case VIPS_FORMAT_DPCOMPLEX:
|
||||||
BAND_SWITCH_INNER( double,
|
BAND_SWITCH_INNER( double,
|
||||||
VIPS_CLIP_COMPLEX_INT,
|
VIPS_CLIP_COMPLEX_INT,
|
||||||
VIPS_CLIP_COMPLEX_FLOAT,
|
VIPS_CLIP_COMPLEX_FLOAT,
|
||||||
VIPS_CLIP_COMPLEX_COMPLEX );
|
VIPS_CLIP_COMPLEX_COMPLEX );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_assert( 0 );
|
g_assert( 0 );
|
||||||
}
|
}
|
||||||
@ -341,25 +435,34 @@ vips_cast_build( VipsObject *object )
|
|||||||
VipsConversion *conversion = VIPS_CONVERSION( object );
|
VipsConversion *conversion = VIPS_CONVERSION( object );
|
||||||
VipsCast *cast = (VipsCast *) object;
|
VipsCast *cast = (VipsCast *) object;
|
||||||
|
|
||||||
VipsGenerateFn generate_fn;
|
|
||||||
|
|
||||||
if( VIPS_OBJECT_CLASS( vips_cast_parent_class )->build( object ) )
|
if( VIPS_OBJECT_CLASS( vips_cast_parent_class )->build( object ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_image_pio_input( cast->input ) ||
|
/* Trivial case: fall back to im_copy().
|
||||||
vips_image_pio_output( conversion->output ) )
|
*/
|
||||||
|
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 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_image_copy_fields( conversion->output, cast->input ) )
|
if( vips_image_copy_fields( conversion->out, cast->in ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
vips_demand_hint( conversion->output,
|
vips_demand_hint( conversion->out,
|
||||||
VIPS_DEMAND_STYLE_THINSTRIP, cast->input, NULL );
|
VIPS_DEMAND_STYLE_THINSTRIP, cast->in, NULL );
|
||||||
|
|
||||||
conversion->output->BandFmt = cast->format
|
conversion->out->BandFmt = cast->format;
|
||||||
|
|
||||||
if( vips_image_generate( conversion->output,
|
g_signal_connect( cast->in, "preeval",
|
||||||
vips_start_one, generate_fn, vips_stop_one,
|
G_CALLBACK( vips_cast_preeval ), cast );
|
||||||
cast->input, 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( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -380,11 +483,11 @@ vips_cast_class_init( VipsCastClass *class )
|
|||||||
vobject_class->description = _( "cast an image" );
|
vobject_class->description = _( "cast an image" );
|
||||||
vobject_class->build = vips_cast_build;
|
vobject_class->build = vips_cast_build;
|
||||||
|
|
||||||
VIPS_ARG_IMAGE( class, "input", 1,
|
VIPS_ARG_IMAGE( class, "in", 1,
|
||||||
_( "Input" ),
|
_( "Input" ),
|
||||||
_( "Input image" ),
|
_( "Input image" ),
|
||||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsCast, input ) );
|
G_STRUCT_OFFSET( VipsCast, in ) );
|
||||||
|
|
||||||
VIPS_ARG_ENUM( class, "format", 6,
|
VIPS_ARG_ENUM( class, "format", 6,
|
||||||
_( "Format" ),
|
_( "Format" ),
|
||||||
@ -405,7 +508,7 @@ vips_cast( VipsImage *in, VipsImage **out, VipsBandFormat format, ... )
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
va_start( ap, direction );
|
va_start( ap, format );
|
||||||
result = vips_call_split( "cast", ap, in, out, format );
|
result = vips_call_split( "cast", ap, in, out, format );
|
||||||
va_end( ap );
|
va_end( ap );
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ vips_conversion_class_init( VipsConversionClass *class )
|
|||||||
_( "Output" ),
|
_( "Output" ),
|
||||||
_( "Output image" ),
|
_( "Output image" ),
|
||||||
VIPS_ARGUMENT_REQUIRED_OUTPUT,
|
VIPS_ARGUMENT_REQUIRED_OUTPUT,
|
||||||
G_STRUCT_OFFSET( VipsConversion, output ) );
|
G_STRUCT_OFFSET( VipsConversion, out ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -110,6 +110,7 @@ vips_conversion_operation_init( void )
|
|||||||
extern GType vips_extract_area_get_type( void );
|
extern GType vips_extract_area_get_type( void );
|
||||||
extern GType vips_extract_band_get_type( void );
|
extern GType vips_extract_band_get_type( void );
|
||||||
extern GType vips_replicate_get_type( void );
|
extern GType vips_replicate_get_type( void );
|
||||||
|
extern GType vips_cast_get_type( void );
|
||||||
|
|
||||||
vips_copy_get_type();
|
vips_copy_get_type();
|
||||||
vips_embed_get_type();
|
vips_embed_get_type();
|
||||||
@ -119,5 +120,6 @@ vips_conversion_operation_init( void )
|
|||||||
vips_extract_area_get_type();
|
vips_extract_area_get_type();
|
||||||
vips_extract_band_get_type();
|
vips_extract_band_get_type();
|
||||||
vips_replicate_get_type();
|
vips_replicate_get_type();
|
||||||
|
vips_cast_get_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ typedef struct _VipsConversion {
|
|||||||
|
|
||||||
/* All have an output image.
|
/* All have an output image.
|
||||||
*/
|
*/
|
||||||
VipsImage *output;
|
VipsImage *out;
|
||||||
|
|
||||||
} VipsConversion;
|
} VipsConversion;
|
||||||
|
|
||||||
|
@ -94,8 +94,8 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* VipsCopy:
|
* VipsCopy:
|
||||||
* @input: input image
|
* @in: input image
|
||||||
* @output: output image
|
* @out: output image
|
||||||
*
|
*
|
||||||
* Copy an image, optionally modifying the header. VIPS copies images by
|
* Copy an image, optionally modifying the header. VIPS copies images by
|
||||||
* copying pointers, so this operation is fast, even for very large images.
|
* copying pointers, so this operation is fast, even for very large images.
|
||||||
@ -113,7 +113,7 @@ typedef struct _VipsCopy {
|
|||||||
|
|
||||||
/* The input image.
|
/* The input image.
|
||||||
*/
|
*/
|
||||||
VipsImage *input;
|
VipsImage *in;
|
||||||
|
|
||||||
/* Swap bytes on the way through.
|
/* 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 );
|
return( -1 );
|
||||||
|
|
||||||
if( copy->swap ) {
|
if( copy->swap ) {
|
||||||
SwapFn swap = vips_copy_swap_fn[copy->input->BandFmt];
|
SwapFn swap = vips_copy_swap_fn[copy->in->BandFmt];
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
for( y = 0; y < r->height; 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,
|
PEL *q = (PEL *) VIPS_REGION_ADDR( or,
|
||||||
r->left, r->top + y );
|
r->left, r->top + y );
|
||||||
|
|
||||||
swap( p, q, r->width, copy->input );
|
swap( p, q, r->width, copy->in );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -274,14 +274,14 @@ vips_copy_build( VipsObject *object )
|
|||||||
if( VIPS_OBJECT_CLASS( vips_copy_parent_class )->build( object ) )
|
if( VIPS_OBJECT_CLASS( vips_copy_parent_class )->build( object ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_image_pio_input( copy->input ) ||
|
if( vips_image_pio_input( copy->in ) ||
|
||||||
vips_image_pio_output( conversion->output ) )
|
vips_image_pio_output( conversion->out ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_image_copy_fields( conversion->output, copy->input ) )
|
if( vips_image_copy_fields( conversion->out, copy->in ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
vips_demand_hint( conversion->output,
|
vips_demand_hint( conversion->out,
|
||||||
VIPS_DEMAND_STYLE_THINSTRIP, copy->input, NULL );
|
VIPS_DEMAND_STYLE_THINSTRIP, copy->in, NULL );
|
||||||
|
|
||||||
/* Use props to adjust header fields.
|
/* Use props to adjust header fields.
|
||||||
*/
|
*/
|
||||||
@ -306,15 +306,15 @@ vips_copy_build( VipsObject *object )
|
|||||||
g_value_init( &value, type );
|
g_value_init( &value, type );
|
||||||
g_object_get_property( G_OBJECT( object ),
|
g_object_get_property( G_OBJECT( object ),
|
||||||
name, &value );
|
name, &value );
|
||||||
g_object_set_property( G_OBJECT( conversion->output ),
|
g_object_set_property( G_OBJECT( conversion->out ),
|
||||||
name, &value );
|
name, &value );
|
||||||
g_value_unset( &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,
|
vips_start_one, vips_copy_gen, vips_stop_one,
|
||||||
copy->input, copy ) )
|
copy->in, copy ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -339,7 +339,7 @@ vips_copy_class_init( VipsCopyClass *class )
|
|||||||
_( "Input" ),
|
_( "Input" ),
|
||||||
_( "Input image" ),
|
_( "Input image" ),
|
||||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsCopy, input ) );
|
G_STRUCT_OFFSET( VipsCopy, in ) );
|
||||||
|
|
||||||
VIPS_ARG_BOOL( class, "swap", 2,
|
VIPS_ARG_BOOL( class, "swap", 2,
|
||||||
_( "Swap" ),
|
_( "Swap" ),
|
||||||
|
@ -95,7 +95,7 @@ typedef struct _VipsEmbed {
|
|||||||
|
|
||||||
/* The input image.
|
/* The input image.
|
||||||
*/
|
*/
|
||||||
VipsImage *input;
|
VipsImage *in;
|
||||||
|
|
||||||
VipsExtend extend;
|
VipsExtend extend;
|
||||||
int x;
|
int x;
|
||||||
@ -164,7 +164,7 @@ vips_embed_find_edge( VipsEmbed *embed, VipsRect *r, int i, VipsRect *out )
|
|||||||
static void
|
static void
|
||||||
vips_embed_copy_pixel( VipsEmbed *embed, PEL *q, PEL *p, int n )
|
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;
|
int x, b;
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ static void
|
|||||||
vips_embed_paint_edge( VipsEmbed *embed,
|
vips_embed_paint_edge( VipsEmbed *embed,
|
||||||
VipsRegion *or, int i, VipsRect *r, PEL *p, int plsk )
|
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;
|
VipsRect todo;
|
||||||
PEL *q;
|
PEL *q;
|
||||||
@ -326,7 +326,7 @@ vips_embed_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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 )
|
int x, int y, int width, int height )
|
||||||
{
|
{
|
||||||
VipsPoolContext *context = vips_pool_context_new( pool );
|
VipsPoolContext *context = vips_pool_context_new( pool );
|
||||||
@ -335,15 +335,15 @@ vips_embed_repeat( VipsPool *pool, VipsImage *input, VipsImage **output,
|
|||||||
* nicely.
|
* nicely.
|
||||||
*/
|
*/
|
||||||
const int nx = x < 0 ?
|
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 ?
|
const int ny = y < 0 ?
|
||||||
-y % input->Ysize : input->Ysize - y % input->Ysize;
|
-y % in->Ysize : in->Ysize - y % in->Ysize;
|
||||||
|
|
||||||
if(
|
if(
|
||||||
vips_replicate( input, &VIPS_VI( 1 ),
|
vips_replicate( in, &VIPS_VI( 1 ),
|
||||||
width / input->Xsize + 2,
|
width / in->Xsize + 2,
|
||||||
height / input->Ysize + 2, NULL ) ||
|
height / in->Ysize + 2, NULL ) ||
|
||||||
vips_extract_area( VIPS_VI( 1 ), output,
|
vips_extract_area( VIPS_VI( 1 ), out,
|
||||||
nx, ny, width, height, NULL ) )
|
nx, ny, width, height, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
@ -351,7 +351,7 @@ vips_embed_repeat( VipsPool *pool, VipsImage *input, VipsImage **output,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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 )
|
int x, int y, int width, int height )
|
||||||
{
|
{
|
||||||
VipsPoolContext *context = vips_pool_context_new( pool );
|
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
|
/* As repeat, but the tiles are twice the size because of
|
||||||
* mirroring.
|
* mirroring.
|
||||||
*/
|
*/
|
||||||
const int w2 = input->Xsize * 2;
|
const int w2 = in->Xsize * 2;
|
||||||
const int h2 = input->Ysize * 2;
|
const int h2 = in->Ysize * 2;
|
||||||
|
|
||||||
const int nx = x < 0 ? -x % w2 : w2 - x % w2;
|
const int nx = x < 0 ? -x % w2 : w2 - x % w2;
|
||||||
const int ny = y < 0 ? -y % h2 : h2 - y % h2;
|
const int ny = y < 0 ? -y % h2 : h2 - y % h2;
|
||||||
@ -368,9 +368,9 @@ vips_embed_mirror( VipsPool *pool, VipsImage *input, VipsImage **output,
|
|||||||
if(
|
if(
|
||||||
/* Make a 2x2 mirror tile.
|
/* Make a 2x2 mirror tile.
|
||||||
*/
|
*/
|
||||||
vips_flip( input, &VIPS_VI( 1 ),
|
vips_flip( in, &VIPS_VI( 1 ),
|
||||||
VIPS_DIRECTION_HORIZONTAL, NULL ) ||
|
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_DIRECTION_HORIZONTAL, NULL ) ||
|
||||||
vips_flip( VIPS_VI( 2 ), &VIPS_VI( 3 ),
|
vips_flip( VIPS_VI( 2 ), &VIPS_VI( 3 ),
|
||||||
VIPS_DIRECTION_VERTICAL, NULL ) ||
|
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 ),
|
vips_extract_area( VIPS_VI( 5 ), &VIPS_VI( 6 ),
|
||||||
nx, ny, width, height, NULL ) ||
|
nx, ny, width, height, NULL ) ||
|
||||||
|
|
||||||
/* Overwrite the centre with the input, much faster
|
/* Overwrite the centre with the in, much faster
|
||||||
* for centre pixels.
|
* for centre pixels.
|
||||||
*/
|
*/
|
||||||
vips_insert( VIPS_VI( 6 ), input, output,
|
vips_insert( VIPS_VI( 6 ), in, out,
|
||||||
x, y, NULL ) )
|
x, y, NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
@ -407,8 +407,8 @@ vips_embed_build( VipsObject *object )
|
|||||||
if( VIPS_OBJECT_CLASS( vips_embed_parent_class )->build( object ) )
|
if( VIPS_OBJECT_CLASS( vips_embed_parent_class )->build( object ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_image_pio_input( embed->input ) ||
|
if( vips_image_pio_input( embed->in ) ||
|
||||||
vips_image_pio_output( conversion->output ) )
|
vips_image_pio_output( conversion->out ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
if( embed->extend < 0 || embed->extend >= VIPS_EXTEND_LAST ) {
|
if( embed->extend < 0 || embed->extend >= VIPS_EXTEND_LAST ) {
|
||||||
vips_error( "VipsEmbed", "%s", _( "unknown VipsExtend" ) );
|
vips_error( "VipsEmbed", "%s", _( "unknown VipsExtend" ) );
|
||||||
@ -419,9 +419,9 @@ vips_embed_build( VipsObject *object )
|
|||||||
*/
|
*/
|
||||||
if( embed->x == 0 &&
|
if( embed->x == 0 &&
|
||||||
embed->y == 0 &&
|
embed->y == 0 &&
|
||||||
embed->width == embed->input->Xsize &&
|
embed->width == embed->in->Xsize &&
|
||||||
embed->height == embed->input->Ysize )
|
embed->height == embed->in->Ysize )
|
||||||
return( vips_image_write( embed->input, conversion->output ) );
|
return( vips_image_write( embed->in, conversion->out ) );
|
||||||
|
|
||||||
pool = vips_pool_new( "VipsEmbed" );
|
pool = vips_pool_new( "VipsEmbed" );
|
||||||
vips_object_local( object, pool );
|
vips_object_local( object, pool );
|
||||||
@ -431,9 +431,9 @@ vips_embed_build( VipsObject *object )
|
|||||||
{
|
{
|
||||||
VipsPoolContext *context = vips_pool_context_new( pool );
|
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 ) ||
|
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 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,9 +443,9 @@ vips_embed_build( VipsObject *object )
|
|||||||
{
|
{
|
||||||
VipsPoolContext *context = vips_pool_context_new( pool );
|
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 ) ||
|
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 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -453,28 +453,28 @@ vips_embed_build( VipsObject *object )
|
|||||||
case VIPS_EXTEND_BLACK:
|
case VIPS_EXTEND_BLACK:
|
||||||
case VIPS_EXTEND_WHITE:
|
case VIPS_EXTEND_WHITE:
|
||||||
case VIPS_EXTEND_COPY:
|
case VIPS_EXTEND_COPY:
|
||||||
if( vips_image_copy_fields( conversion->output, embed->input ) )
|
if( vips_image_copy_fields( conversion->out, embed->in ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
conversion->output->Xsize = embed->width;
|
conversion->out->Xsize = embed->width;
|
||||||
conversion->output->Ysize = embed->height;
|
conversion->out->Ysize = embed->height;
|
||||||
|
|
||||||
vips_demand_hint( conversion->output,
|
vips_demand_hint( conversion->out,
|
||||||
VIPS_DEMAND_STYLE_SMALLTILE, embed->input, NULL );
|
VIPS_DEMAND_STYLE_SMALLTILE, embed->in, NULL );
|
||||||
|
|
||||||
/* Whole output area.
|
/* Whole output area.
|
||||||
*/
|
*/
|
||||||
embed->rout.left = 0;
|
embed->rout.left = 0;
|
||||||
embed->rout.top = 0;
|
embed->rout.top = 0;
|
||||||
embed->rout.width = conversion->output->Xsize;
|
embed->rout.width = conversion->out->Xsize;
|
||||||
embed->rout.height = conversion->output->Ysize;
|
embed->rout.height = conversion->out->Ysize;
|
||||||
|
|
||||||
/* Rect occupied by image (can be clipped to nothing).
|
/* Rect occupied by image (can be clipped to nothing).
|
||||||
*/
|
*/
|
||||||
want.left = embed->x;
|
want.left = embed->x;
|
||||||
want.top = embed->y;
|
want.top = embed->y;
|
||||||
want.width = embed->input->Xsize;
|
want.width = embed->in->Xsize;
|
||||||
want.height = embed->input->Ysize;
|
want.height = embed->in->Ysize;
|
||||||
vips_rect_intersectrect( &want, &embed->rout, &embed->rsub );
|
vips_rect_intersectrect( &want, &embed->rout, &embed->rsub );
|
||||||
|
|
||||||
/* FIXME ... actually, it can't. embed_find_edge() will fail
|
/* 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].left = VIPS_RECT_RIGHT( &embed->rsub );
|
||||||
embed->border[1].top = embed->rsub.top;
|
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 );
|
VIPS_RECT_RIGHT( &embed->rsub );
|
||||||
embed->border[1].height = embed->rsub.height;
|
embed->border[1].height = embed->rsub.height;
|
||||||
|
|
||||||
embed->border[2].left = embed->rsub.left;
|
embed->border[2].left = embed->rsub.left;
|
||||||
embed->border[2].top = VIPS_RECT_BOTTOM( &embed->rsub );
|
embed->border[2].top = VIPS_RECT_BOTTOM( &embed->rsub );
|
||||||
embed->border[2].width = embed->rsub.width;
|
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 );
|
VIPS_RECT_BOTTOM( &embed->rsub );
|
||||||
|
|
||||||
embed->border[3].left = 0;
|
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].left = VIPS_RECT_RIGHT( &embed->rsub );
|
||||||
embed->border[5].top = 0;
|
embed->border[5].top = 0;
|
||||||
embed->border[5].width = conversion->output->Xsize -
|
embed->border[5].width = conversion->out->Xsize -
|
||||||
VIPS_RECT_RIGHT( &embed->rsub );
|
VIPS_RECT_RIGHT( &embed->rsub );
|
||||||
embed->border[5].height = embed->rsub.top;
|
embed->border[5].height = embed->rsub.top;
|
||||||
|
|
||||||
embed->border[6].left = VIPS_RECT_RIGHT( &embed->rsub );
|
embed->border[6].left = VIPS_RECT_RIGHT( &embed->rsub );
|
||||||
embed->border[6].top = VIPS_RECT_BOTTOM( &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 );
|
VIPS_RECT_RIGHT( &embed->rsub );
|
||||||
embed->border[6].height = conversion->output->Ysize -
|
embed->border[6].height = conversion->out->Ysize -
|
||||||
VIPS_RECT_BOTTOM( &embed->rsub );
|
VIPS_RECT_BOTTOM( &embed->rsub );
|
||||||
|
|
||||||
embed->border[7].left = 0;
|
embed->border[7].left = 0;
|
||||||
embed->border[7].top = VIPS_RECT_BOTTOM( &embed->rsub );
|
embed->border[7].top = VIPS_RECT_BOTTOM( &embed->rsub );
|
||||||
embed->border[7].width = embed->rsub.left;
|
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 );
|
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,
|
vips_start_one, vips_embed_gen, vips_stop_one,
|
||||||
embed->input, embed ) )
|
embed->in, embed ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -571,7 +571,7 @@ vips_embed_class_init( VipsEmbedClass *class )
|
|||||||
_( "Input" ),
|
_( "Input" ),
|
||||||
_( "Input image" ),
|
_( "Input image" ),
|
||||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsEmbed, input ) );
|
G_STRUCT_OFFSET( VipsEmbed, in ) );
|
||||||
|
|
||||||
VIPS_ARG_INT( class, "x", 2,
|
VIPS_ARG_INT( class, "x", 2,
|
||||||
_( "x" ),
|
_( "x" ),
|
||||||
|
@ -86,15 +86,15 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* VipsExtractArea:
|
* VipsExtractArea:
|
||||||
* @input: input image
|
* @in: input image
|
||||||
* @output: output image
|
* @out: output image
|
||||||
* @left: left edge of area to extract
|
* @left: left edge of area to extract
|
||||||
* @top: top edge of area to extract
|
* @top: top edge of area to extract
|
||||||
* @width: width of area to extract
|
* @width: width of area to extract
|
||||||
* @height: height of area to extract
|
* @height: height of area to extract
|
||||||
*
|
*
|
||||||
* Extract an area from an image.
|
* Extract an area from an image.
|
||||||
* Extracting outside @input will trigger an error.
|
* Extracting outside @in will trigger an error.
|
||||||
*
|
*
|
||||||
* See also: VipsExtractBand().
|
* See also: VipsExtractBand().
|
||||||
*/
|
*/
|
||||||
@ -104,7 +104,7 @@ typedef struct _VipsExtractArea {
|
|||||||
|
|
||||||
/* The input image.
|
/* The input image.
|
||||||
*/
|
*/
|
||||||
VipsImage *input;
|
VipsImage *in;
|
||||||
|
|
||||||
int left;
|
int left;
|
||||||
int top;
|
int top;
|
||||||
@ -153,32 +153,32 @@ vips_extract_area_build( VipsObject *object )
|
|||||||
if( VIPS_OBJECT_CLASS( vips_extract_area_parent_class )->build( object ) )
|
if( VIPS_OBJECT_CLASS( vips_extract_area_parent_class )->build( object ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( extract->left + extract->width > extract->input->Xsize ||
|
if( extract->left + extract->width > extract->in->Xsize ||
|
||||||
extract->top + extract->height > extract->input->Ysize ||
|
extract->top + extract->height > extract->in->Ysize ||
|
||||||
extract->left < 0 || extract->top < 0 ||
|
extract->left < 0 || extract->top < 0 ||
|
||||||
extract->width <= 0 || extract->height <= 0 ) {
|
extract->width <= 0 || extract->height <= 0 ) {
|
||||||
im_error( "VipsExtractArea", "%s", _( "bad extract area" ) );
|
im_error( "VipsExtractArea", "%s", _( "bad extract area" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( vips_image_pio_input( extract->input ) ||
|
if( vips_image_pio_input( extract->in ) ||
|
||||||
vips_image_pio_output( conversion->output ) ||
|
vips_image_pio_output( conversion->out ) ||
|
||||||
vips_check_coding_known( "VipsExtractArea", extract->input ) )
|
vips_check_coding_known( "VipsExtractArea", extract->in ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_image_copy_fields( conversion->output, extract->input ) )
|
if( vips_image_copy_fields( conversion->out, extract->in ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
vips_demand_hint( conversion->output,
|
vips_demand_hint( conversion->out,
|
||||||
VIPS_DEMAND_STYLE_THINSTRIP, extract->input, NULL );
|
VIPS_DEMAND_STYLE_THINSTRIP, extract->in, NULL );
|
||||||
|
|
||||||
conversion->output->Xsize = extract->width;
|
conversion->out->Xsize = extract->width;
|
||||||
conversion->output->Ysize = extract->height;
|
conversion->out->Ysize = extract->height;
|
||||||
conversion->output->Xoffset = -extract->left;
|
conversion->out->Xoffset = -extract->left;
|
||||||
conversion->output->Yoffset = -extract->top;
|
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,
|
vips_start_one, vips_extract_area_gen, vips_stop_one,
|
||||||
extract->input, extract ) )
|
extract->in, extract ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -208,7 +208,7 @@ vips_extract_area_class_init( VipsExtractAreaClass *class )
|
|||||||
_( "Input" ),
|
_( "Input" ),
|
||||||
_( "Input image" ),
|
_( "Input image" ),
|
||||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsExtractArea, input ) );
|
G_STRUCT_OFFSET( VipsExtractArea, in ) );
|
||||||
|
|
||||||
VIPS_ARG_INT( class, "left", 2,
|
VIPS_ARG_INT( class, "left", 2,
|
||||||
_( "Left" ),
|
_( "Left" ),
|
||||||
@ -246,14 +246,14 @@ vips_extract_area_init( VipsExtractArea *extract )
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
vips_extract_area( VipsImage *input, VipsImage **output,
|
vips_extract_area( VipsImage *in, VipsImage **out,
|
||||||
int left, int top, int width, int height, ... )
|
int left, int top, int width, int height, ... )
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
va_start( ap, height );
|
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 );
|
left, top, width, height );
|
||||||
va_end( ap );
|
va_end( ap );
|
||||||
|
|
||||||
@ -262,8 +262,8 @@ vips_extract_area( VipsImage *input, VipsImage **output,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* VipsExtractBand:
|
* VipsExtractBand:
|
||||||
* @input: input image
|
* @in: input image
|
||||||
* @output: output image
|
* @out: output image
|
||||||
* @band: band to extract
|
* @band: band to extract
|
||||||
* @n: number of bands to extract
|
* @n: number of bands to extract
|
||||||
*
|
*
|
||||||
@ -277,7 +277,7 @@ typedef struct _VipsExtractBand {
|
|||||||
|
|
||||||
/* The input image.
|
/* The input image.
|
||||||
*/
|
*/
|
||||||
VipsImage *input;
|
VipsImage *in;
|
||||||
|
|
||||||
int band;
|
int band;
|
||||||
int n;
|
int n;
|
||||||
@ -331,26 +331,26 @@ vips_extract_band_build( VipsObject *object )
|
|||||||
if( VIPS_OBJECT_CLASS( vips_extract_band_parent_class )->build( object ) )
|
if( VIPS_OBJECT_CLASS( vips_extract_band_parent_class )->build( object ) )
|
||||||
return( -1 );
|
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" ) );
|
im_error( "VipsExtractBand", "%s", _( "bad extract band" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( vips_image_pio_input( extract->input ) ||
|
if( vips_image_pio_input( extract->in ) ||
|
||||||
vips_image_pio_output( conversion->output ) ||
|
vips_image_pio_output( conversion->out ) ||
|
||||||
vips_check_coding_known( "VipsExtractBand", extract->input ) )
|
vips_check_coding_known( "VipsExtractBand", extract->in ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_image_copy_fields( conversion->output, extract->input ) )
|
if( vips_image_copy_fields( conversion->out, extract->in ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
vips_demand_hint( conversion->output,
|
vips_demand_hint( conversion->out,
|
||||||
VIPS_DEMAND_STYLE_THINSTRIP, extract->input, NULL );
|
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,
|
vips_start_one, vips_extract_band_gen, vips_stop_one,
|
||||||
extract->input, extract ) )
|
extract->in, extract ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -371,11 +371,11 @@ vips_extract_band_class_init( VipsExtractBandClass *class )
|
|||||||
vobject_class->description = _( "extract band from an image" );
|
vobject_class->description = _( "extract band from an image" );
|
||||||
vobject_class->build = vips_extract_band_build;
|
vobject_class->build = vips_extract_band_build;
|
||||||
|
|
||||||
VIPS_ARG_IMAGE( class, "input", 0,
|
VIPS_ARG_IMAGE( class, "in", 0,
|
||||||
_( "Input" ),
|
_( "Input" ),
|
||||||
_( "Input image" ),
|
_( "Input image" ),
|
||||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsExtractBand, input ) );
|
G_STRUCT_OFFSET( VipsExtractBand, in ) );
|
||||||
|
|
||||||
VIPS_ARG_INT( class, "band", 3,
|
VIPS_ARG_INT( class, "band", 3,
|
||||||
_( "Band" ),
|
_( "Band" ),
|
||||||
@ -399,13 +399,13 @@ vips_extract_band_init( VipsExtractBand *extract )
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
vips_extract_band( VipsImage *input, VipsImage **output, int band, ... )
|
vips_extract_band( VipsImage *in, VipsImage **out, int band, ... )
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
va_start( ap, band );
|
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 );
|
va_end( ap );
|
||||||
|
|
||||||
return( result );
|
return( result );
|
||||||
|
@ -66,8 +66,8 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* VipsFlip:
|
* VipsFlip:
|
||||||
* @input: input image
|
* @in: input image
|
||||||
* @output: output image
|
* @out: output image
|
||||||
* @direction: flip horizontally or vertically
|
* @direction: flip horizontally or vertically
|
||||||
*
|
*
|
||||||
* Flips an image left-right or up-down.
|
* Flips an image left-right or up-down.
|
||||||
@ -82,7 +82,7 @@ typedef struct _VipsFlip {
|
|||||||
|
|
||||||
/* The input image.
|
/* The input image.
|
||||||
*/
|
*/
|
||||||
VipsImage *input;
|
VipsImage *in;
|
||||||
|
|
||||||
/* Swap bytes on the way through.
|
/* 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 ) )
|
if( VIPS_OBJECT_CLASS( vips_flip_parent_class )->build( object ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_image_pio_input( flip->input ) ||
|
if( vips_image_pio_input( flip->in ) ||
|
||||||
vips_image_pio_output( conversion->output ) )
|
vips_image_pio_output( conversion->out ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_image_copy_fields( conversion->output, flip->input ) )
|
if( vips_image_copy_fields( conversion->out, flip->in ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
vips_demand_hint( conversion->output,
|
vips_demand_hint( conversion->out,
|
||||||
VIPS_DEMAND_STYLE_THINSTRIP, flip->input, NULL );
|
VIPS_DEMAND_STYLE_THINSTRIP, flip->in, NULL );
|
||||||
|
|
||||||
if( flip->direction == VIPS_DIRECTION_HORIZONTAL ) {
|
if( flip->direction == VIPS_DIRECTION_HORIZONTAL ) {
|
||||||
generate_fn = vips_flip_horizontal_gen;
|
generate_fn = vips_flip_horizontal_gen;
|
||||||
conversion->output->Xoffset = flip->input->Xsize;
|
conversion->out->Xoffset = flip->in->Xsize;
|
||||||
conversion->output->Yoffset = 0;
|
conversion->out->Yoffset = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
generate_fn = vips_flip_vertical_gen;
|
generate_fn = vips_flip_vertical_gen;
|
||||||
conversion->output->Xoffset = 0;
|
conversion->out->Xoffset = 0;
|
||||||
conversion->output->Yoffset = flip->input->Ysize;
|
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,
|
vips_start_one, generate_fn, vips_stop_one,
|
||||||
flip->input, flip ) )
|
flip->in, flip ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -250,11 +250,11 @@ vips_flip_class_init( VipsFlipClass *class )
|
|||||||
vobject_class->description = _( "flip an image" );
|
vobject_class->description = _( "flip an image" );
|
||||||
vobject_class->build = vips_flip_build;
|
vobject_class->build = vips_flip_build;
|
||||||
|
|
||||||
VIPS_ARG_IMAGE( class, "input", 1,
|
VIPS_ARG_IMAGE( class, "in", 1,
|
||||||
_( "Input" ),
|
_( "Input" ),
|
||||||
_( "Input image" ),
|
_( "Input image" ),
|
||||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsFlip, input ) );
|
G_STRUCT_OFFSET( VipsFlip, in ) );
|
||||||
|
|
||||||
VIPS_ARG_ENUM( class, "direction", 6,
|
VIPS_ARG_ENUM( class, "direction", 6,
|
||||||
_( "Direction" ),
|
_( "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 ) ||
|
if( vips_image_pio_input( insert->main ) ||
|
||||||
vips_image_pio_input( insert->sub ) ||
|
vips_image_pio_input( insert->sub ) ||
|
||||||
vips_image_pio_output( conversion->output ) ||
|
vips_image_pio_output( conversion->out ) ||
|
||||||
vips_check_bands_1orn( "VipsInsert",
|
vips_check_bands_1orn( "VipsInsert",
|
||||||
insert->main, insert->sub ) ||
|
insert->main, insert->sub ) ||
|
||||||
vips_check_coding_known( "VipsInsert", insert->main ) ||
|
vips_check_coding_known( "VipsInsert", insert->main ) ||
|
||||||
@ -299,13 +299,13 @@ vips_insert_build( VipsObject *object )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
insert->main_processed = t[2];
|
insert->main_processed = t[2];
|
||||||
insert->sub_processed = t[3];
|
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 )) )
|
insert->main_processed, insert->sub_processed, NULL )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_image_copy_fields_array( conversion->output, arry ) )
|
if( vips_image_copy_fields_array( conversion->out, arry ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
vips_demand_hint_array( conversion->output,
|
vips_demand_hint_array( conversion->out,
|
||||||
VIPS_DEMAND_STYLE_SMALLTILE, arry );
|
VIPS_DEMAND_STYLE_SMALLTILE, arry );
|
||||||
|
|
||||||
/* Calculate geometry.
|
/* Calculate geometry.
|
||||||
@ -337,15 +337,15 @@ vips_insert_build( VipsObject *object )
|
|||||||
else
|
else
|
||||||
insert->rout = insert->rmain;
|
insert->rout = insert->rmain;
|
||||||
|
|
||||||
conversion->output->Xsize = insert->rout.width;
|
conversion->out->Xsize = insert->rout.width;
|
||||||
conversion->output->Ysize = insert->rout.height;
|
conversion->out->Ysize = insert->rout.height;
|
||||||
|
|
||||||
if( !(insert->ink = vips__vector_to_ink(
|
if( !(insert->ink = vips__vector_to_ink(
|
||||||
"VipsInsert", conversion->output,
|
"VipsInsert", conversion->out,
|
||||||
insert->background->data, insert->background->n )) )
|
insert->background->data, insert->background->n )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_image_generate( conversion->output,
|
if( vips_image_generate( conversion->out,
|
||||||
vips_start_many, vips_insert_gen, vips_stop_many,
|
vips_start_many, vips_insert_gen, vips_stop_many,
|
||||||
arry, insert ) )
|
arry, insert ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
@ -72,7 +72,7 @@
|
|||||||
* VipsJoin:
|
* VipsJoin:
|
||||||
* @in1: first input image
|
* @in1: first input image
|
||||||
* @in2: second input image
|
* @in2: second input image
|
||||||
* @output: output image
|
* @out: output image
|
||||||
* @direction: join horizontally or vertically
|
* @direction: join horizontally or vertically
|
||||||
* @expand: %TRUE to expand the output image to hold all of the input pixels
|
* @expand: %TRUE to expand the output image to hold all of the input pixels
|
||||||
* @shim: space between images, in pixels
|
* @shim: space between images, in pixels
|
||||||
@ -83,13 +83,13 @@
|
|||||||
* of @direction.
|
* of @direction.
|
||||||
*
|
*
|
||||||
* If one is taller or wider than the
|
* 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.
|
* 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
|
* Use @align to set the edge that the images align on. By default, they align
|
||||||
* on the edge with the lower value coordinate.
|
* 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.
|
* present in either @in1 or @in2.
|
||||||
*
|
*
|
||||||
* Use @shim to set the spacing between the images. By default this is 0.
|
* 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 );
|
g_object_unref( t );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
@ -310,14 +310,14 @@ vips_join_init( VipsJoin *join )
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
vips_join( VipsImage *in1, VipsImage *in2, VipsImage **output,
|
vips_join( VipsImage *in1, VipsImage *in2, VipsImage **out,
|
||||||
VipsDirection direction, ... )
|
VipsDirection direction, ... )
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
va_start( ap, direction );
|
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 );
|
va_end( ap );
|
||||||
|
|
||||||
return( result );
|
return( result );
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
/**
|
/**
|
||||||
* VipsReplicate:
|
* VipsReplicate:
|
||||||
* @in: input image
|
* @in: input image
|
||||||
* @output: output image
|
* @out: output image
|
||||||
* @across: repeat input this many times across
|
* @across: repeat input this many times across
|
||||||
* @down: repeat input this many times down
|
* @down: repeat input this many times down
|
||||||
*
|
*
|
||||||
@ -72,7 +72,7 @@ typedef struct _VipsReplicate {
|
|||||||
|
|
||||||
/* The input image.
|
/* The input image.
|
||||||
*/
|
*/
|
||||||
VipsImage *input;
|
VipsImage *in;
|
||||||
|
|
||||||
int across;
|
int across;
|
||||||
int down;
|
int down;
|
||||||
@ -170,21 +170,21 @@ vips_replicate_build( VipsObject *object )
|
|||||||
if( VIPS_OBJECT_CLASS( vips_replicate_parent_class )->build( object ) )
|
if( VIPS_OBJECT_CLASS( vips_replicate_parent_class )->build( object ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_image_pio_input( replicate->input ) ||
|
if( vips_image_pio_input( replicate->in ) ||
|
||||||
vips_image_pio_output( conversion->output ) )
|
vips_image_pio_output( conversion->out ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_image_copy_fields( conversion->output, replicate->input ) )
|
if( vips_image_copy_fields( conversion->out, replicate->in ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
vips_demand_hint( conversion->output,
|
vips_demand_hint( conversion->out,
|
||||||
VIPS_DEMAND_STYLE_SMALLTILE, replicate->input, NULL );
|
VIPS_DEMAND_STYLE_SMALLTILE, replicate->in, NULL );
|
||||||
|
|
||||||
conversion->output->Xsize *= replicate->across;
|
conversion->out->Xsize *= replicate->across;
|
||||||
conversion->output->Ysize *= replicate->down;
|
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,
|
vips_start_one, vips_replicate_gen, vips_stop_one,
|
||||||
replicate->input, replicate ) )
|
replicate->in, replicate ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -205,11 +205,11 @@ vips_replicate_class_init( VipsReplicateClass *class )
|
|||||||
vobject_class->description = _( "replicate an image" );
|
vobject_class->description = _( "replicate an image" );
|
||||||
vobject_class->build = vips_replicate_build;
|
vobject_class->build = vips_replicate_build;
|
||||||
|
|
||||||
VIPS_ARG_IMAGE( class, "input", 0,
|
VIPS_ARG_IMAGE( class, "in", 0,
|
||||||
_( "Input" ),
|
_( "Input" ),
|
||||||
_( "Input image" ),
|
_( "Input image" ),
|
||||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsReplicate, input ) );
|
G_STRUCT_OFFSET( VipsReplicate, in ) );
|
||||||
|
|
||||||
VIPS_ARG_INT( class, "across", 4,
|
VIPS_ARG_INT( class, "across", 4,
|
||||||
_( "Across" ),
|
_( "Across" ),
|
||||||
|
@ -1266,3 +1266,20 @@ im_replicate( IMAGE *in, IMAGE *out, int across, int down )
|
|||||||
return( 0 );
|
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));
|
__attribute__((sentinel));
|
||||||
int vips_replicate( VipsImage *in, VipsImage **out, int across, int down, ... )
|
int vips_replicate( VipsImage *in, VipsImage **out, int across, int down, ... )
|
||||||
__attribute__((sentinel));
|
__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_copy_file( VipsImage *in, VipsImage *out );
|
||||||
|
|
||||||
int im_clip2fmt( VipsImage *in, VipsImage *out, VipsBandFormat fmt );
|
|
||||||
int im_scale( VipsImage *in, VipsImage *out );
|
int im_scale( VipsImage *in, VipsImage *out );
|
||||||
int im_msb( VipsImage *in, VipsImage *out );
|
int im_msb( VipsImage *in, VipsImage *out );
|
||||||
int im_msb_band( VipsImage *in, VipsImage *out, int band );
|
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_replicate( VipsImage *in, VipsImage *out, int across, int down );
|
||||||
|
|
||||||
|
int im_clip2fmt( VipsImage *in, VipsImage *out, VipsBandFormat fmt );
|
||||||
|
|
||||||
/* ruby-vips uses this
|
/* ruby-vips uses this
|
||||||
*/
|
*/
|
||||||
#define vips_class_map_concrete_all vips_class_map_all
|
#define vips_class_map_concrete_all vips_class_map_all
|
||||||
|
@ -458,9 +458,9 @@ vips_region_new( VipsImage *image )
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#endif /*DEBUG*/
|
|
||||||
g_assert( vips_object_sanity( VIPS_OBJECT( image ) ) );
|
g_assert( vips_object_sanity( VIPS_OBJECT( image ) ) );
|
||||||
g_assert( vips_object_sanity( VIPS_OBJECT( region ) ) );
|
g_assert( vips_object_sanity( VIPS_OBJECT( region ) ) );
|
||||||
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
return( region );
|
return( region );
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user