added VipsEmbed
added VipsEmbed class, new macros for arg boilerplate, new priority thing for arg ordering
This commit is contained in:
parent
fba3d000a3
commit
8dfb3056ac
@ -22,6 +22,9 @@
|
||||
- added vips_image_write(), old one becomes vips_image_write_to_file()
|
||||
- jpeg read/write copies over XMP data
|
||||
- handle offset correctly in separable convolutions (thanks Nicolas)
|
||||
- macros for class arg boilerplate
|
||||
- class arg order set by new 'priority' param
|
||||
- VipsExtend enum added
|
||||
|
||||
12/9/11 started 7.26.4
|
||||
- fallback vips_init()
|
||||
|
52
TODO
52
TODO
@ -1,3 +1,55 @@
|
||||
- embed args are in the wrong order
|
||||
|
||||
$ vips embed
|
||||
vips_embed_class_init
|
||||
VipsEmbed (embed), embed an image in a larger image
|
||||
embed input type x y width height out
|
||||
where:
|
||||
input :: VipsImage (input)
|
||||
type :: gint (input)
|
||||
x :: gint (input)
|
||||
y :: gint (input)
|
||||
width :: gint (input)
|
||||
height :: gint (input)
|
||||
out :: VipsImage (output)
|
||||
|
||||
how can we fix this?
|
||||
|
||||
need to give an extra arg to vips_object_class_install_argument() to
|
||||
specify 'argument priority' ... show args in priority order
|
||||
|
||||
|
||||
|
||||
- try some macros for arg specification
|
||||
|
||||
pspec = g_param_spec_int( "y", "Y",
|
||||
_( "Top edge of input in output" ),
|
||||
0, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_Y, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsEmbed, y ) );
|
||||
|
||||
could become
|
||||
|
||||
VIPS_ARG_INT( class, "y", "Y",
|
||||
_( "Top edge of input in output" ),
|
||||
0, 1000000, 0,
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsEmbed, y ) );
|
||||
|
||||
could get rid of PROP_ enums as well
|
||||
|
||||
|
||||
doing binary.c next
|
||||
|
||||
|
||||
|
||||
- make 'type' field to embed an enum?
|
||||
|
||||
|
||||
|
||||
- vips_object_set_argument_from_string() needs more arg types
|
||||
|
||||
must be some way to make this more automatic
|
||||
|
@ -53,15 +53,6 @@
|
||||
|
||||
#include "arithmetic.h"
|
||||
|
||||
/* Properties.
|
||||
*/
|
||||
enum {
|
||||
PROP_OUTPUT = 1,
|
||||
PROP_BOOLTEST = 2,
|
||||
PROP_IMTEST = 3,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE( VipsArithmetic, vips_arithmetic, VIPS_TYPE_OPERATION );
|
||||
|
||||
static int
|
||||
@ -96,8 +87,6 @@ vips_arithmetic_class_init( VipsArithmeticClass *class )
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
|
||||
|
||||
GParamSpec *pspec;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
@ -105,33 +94,22 @@ vips_arithmetic_class_init( VipsArithmeticClass *class )
|
||||
vobject_class->description = _( "arithmetic operations" );
|
||||
vobject_class->build = vips_arithmetic_build;
|
||||
|
||||
pspec = g_param_spec_object( "out", "Output",
|
||||
VIPS_ARG_IMAGE( class, "out", 1,
|
||||
_( "Output" ),
|
||||
_( "Output image" ),
|
||||
VIPS_TYPE_IMAGE,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_OUTPUT, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_REQUIRED_OUTPUT,
|
||||
G_STRUCT_OFFSET( VipsArithmetic, output ) );
|
||||
|
||||
pspec = g_param_spec_boolean( "booltest", "Bool test",
|
||||
VIPS_ARG_BOOL( class, "booltest", 2,
|
||||
_( "Bool test" ),
|
||||
_( "Test optional boolean argument" ),
|
||||
FALSE,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_BOOLTEST, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsArithmetic, booltest ) );
|
||||
G_STRUCT_OFFSET( VipsArithmetic, booltest ),
|
||||
FALSE );
|
||||
|
||||
pspec = g_param_spec_object( "imtest", "Image test",
|
||||
VIPS_ARG_IMAGE( class, "imtest", 3,
|
||||
_( "Image test" ),
|
||||
_( "Test optional image argument" ),
|
||||
VIPS_TYPE_IMAGE,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_IMTEST, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsArithmetic, imtest ) );
|
||||
}
|
||||
|
@ -86,13 +86,6 @@
|
||||
* See also: im_stats(), im_bandmean(), im_deviate(), im_rank()
|
||||
*/
|
||||
|
||||
/* Properties.
|
||||
*/
|
||||
enum {
|
||||
PROP_OUTPUT = 1,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
typedef struct _VipsAvg {
|
||||
VipsStatistic parent_instance;
|
||||
|
||||
@ -228,8 +221,6 @@ vips_avg_class_init( VipsAvgClass *class )
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsStatisticClass *sclass = VIPS_STATISTIC_CLASS( class );
|
||||
|
||||
GParamSpec *pspec;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
@ -241,17 +232,12 @@ vips_avg_class_init( VipsAvgClass *class )
|
||||
sclass->scan = vips_avg_scan;
|
||||
sclass->stop = vips_avg_stop;
|
||||
|
||||
pspec = g_param_spec_double( "out", "Output",
|
||||
VIPS_ARG_DOUBLE( class, "out", 2,
|
||||
_( "Output" ),
|
||||
_( "Output value" ),
|
||||
-G_MAXDOUBLE,
|
||||
G_MAXDOUBLE,
|
||||
0.0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_OUTPUT, pspec );
|
||||
vips_object_class_install_argument( object_class, pspec,
|
||||
VIPS_ARGUMENT_REQUIRED_OUTPUT | VIPS_ARGUMENT_APPEND,
|
||||
G_STRUCT_OFFSET( VipsAvg, avg ) );
|
||||
VIPS_ARGUMENT_REQUIRED_OUTPUT,
|
||||
G_STRUCT_OFFSET( VipsAvg, avg ),
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0 );
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -50,14 +50,6 @@
|
||||
#include "arithmetic.h"
|
||||
#include "binary.h"
|
||||
|
||||
/* Properties.
|
||||
*/
|
||||
enum {
|
||||
PROP_LEFT = 1,
|
||||
PROP_RIGHT,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE( VipsBinary, vips_binary, VIPS_TYPE_ARITHMETIC );
|
||||
|
||||
/* Save a bit of typing.
|
||||
@ -348,8 +340,6 @@ vips_binary_class_init( VipsBinaryClass *class )
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
|
||||
|
||||
GParamSpec *pspec;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
@ -359,23 +349,15 @@ vips_binary_class_init( VipsBinaryClass *class )
|
||||
|
||||
/* Create properties.
|
||||
*/
|
||||
pspec = g_param_spec_object( "right",
|
||||
"Right", "Right-hand image argument",
|
||||
VIPS_TYPE_IMAGE,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_RIGHT, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARG_IMAGE( class, "right", 1,
|
||||
_( "Right" ),
|
||||
_( "Right-hand image argument" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsBinary, right ) );
|
||||
|
||||
pspec = g_param_spec_object( "left",
|
||||
"Left", "Left-hand image argument",
|
||||
VIPS_TYPE_IMAGE,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_LEFT, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARG_IMAGE( class, "left", 2,
|
||||
_( "Left" ),
|
||||
_( "Left-hand image argument" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsBinary, left ) );
|
||||
}
|
||||
|
@ -83,15 +83,6 @@
|
||||
* See also: #VipsAvg, im_stats(), im_bandmean(), im_deviate(), im_rank()
|
||||
*/
|
||||
|
||||
/* Properties.
|
||||
*/
|
||||
enum {
|
||||
PROP_OUTPUT = 1,
|
||||
PROP_X, /* Position of minimum */
|
||||
PROP_Y,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
typedef struct _VipsMin {
|
||||
VipsStatistic parent_instance;
|
||||
|
||||
@ -291,8 +282,6 @@ vips_min_class_init( VipsMinClass *class )
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsStatisticClass *sclass = VIPS_STATISTIC_CLASS( class );
|
||||
|
||||
GParamSpec *pspec;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
@ -304,37 +293,26 @@ vips_min_class_init( VipsMinClass *class )
|
||||
sclass->scan = vips_min_scan;
|
||||
sclass->stop = vips_min_stop;
|
||||
|
||||
pspec = g_param_spec_double( "out", "Output",
|
||||
VIPS_ARG_DOUBLE( class, "out", 1,
|
||||
_( "Output" ),
|
||||
_( "Output value" ),
|
||||
-G_MAXDOUBLE,
|
||||
G_MAXDOUBLE,
|
||||
0.0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_OUTPUT, pspec );
|
||||
vips_object_class_install_argument( object_class, pspec,
|
||||
VIPS_ARGUMENT_REQUIRED_OUTPUT | VIPS_ARGUMENT_APPEND,
|
||||
G_STRUCT_OFFSET( VipsMin, min ) );
|
||||
VIPS_ARGUMENT_REQUIRED_OUTPUT,
|
||||
G_STRUCT_OFFSET( VipsMin, min ),
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0 );
|
||||
|
||||
pspec = g_param_spec_int( "x", "x",
|
||||
VIPS_ARG_INT( class, "x", 2,
|
||||
_( "x" ),
|
||||
_( "Horizontal position of minimum" ),
|
||||
0, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_X, pspec );
|
||||
vips_object_class_install_argument( object_class, pspec,
|
||||
VIPS_ARGUMENT_OPTIONAL_OUTPUT,
|
||||
G_STRUCT_OFFSET( VipsMin, x ) );
|
||||
G_STRUCT_OFFSET( VipsMin, x ),
|
||||
0, 1000000, 0 );
|
||||
|
||||
pspec = g_param_spec_int( "y", "y",
|
||||
VIPS_ARG_INT( class, "y", 2,
|
||||
_( "y" ),
|
||||
_( "Vertical position of minimum" ),
|
||||
0, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_Y, pspec );
|
||||
vips_object_class_install_argument( object_class, pspec,
|
||||
VIPS_ARGUMENT_OPTIONAL_OUTPUT,
|
||||
G_STRUCT_OFFSET( VipsMin, y ) );
|
||||
G_STRUCT_OFFSET( VipsMin, y ),
|
||||
0, 1000000, 0 );
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -52,13 +52,6 @@
|
||||
|
||||
#include "statistic.h"
|
||||
|
||||
/* Properties.
|
||||
*/
|
||||
enum {
|
||||
PROP_INPUT = 1,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE( VipsStatistic, vips_statistic, VIPS_TYPE_OPERATION );
|
||||
|
||||
static void *
|
||||
@ -147,8 +140,6 @@ vips_statistic_class_init( VipsStatisticClass *class )
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
|
||||
|
||||
GParamSpec *pspec;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
@ -156,14 +147,10 @@ vips_statistic_class_init( VipsStatisticClass *class )
|
||||
vobject_class->description = _( "VIPS statistic operations" );
|
||||
vobject_class->build = vips_statistic_build;
|
||||
|
||||
pspec = g_param_spec_object( "in", "Input",
|
||||
VIPS_ARG_IMAGE( class, "in", 1,
|
||||
_( "Input" ),
|
||||
_( "Input image" ),
|
||||
VIPS_TYPE_IMAGE,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_INPUT, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsStatistic, input ) );
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ libconversion_la_SOURCES = \
|
||||
conversion.c \
|
||||
conversion.h \
|
||||
copy.c \
|
||||
embed.c \
|
||||
conver_dispatch.c \
|
||||
im_black.c \
|
||||
im_c2amph.c \
|
||||
|
@ -50,13 +50,6 @@
|
||||
|
||||
#include "conversion.h"
|
||||
|
||||
/* Properties.
|
||||
*/
|
||||
enum {
|
||||
PROP_OUTPUT = 1,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE( VipsConversion, vips_conversion, VIPS_TYPE_OPERATION );
|
||||
|
||||
static int
|
||||
@ -84,8 +77,6 @@ vips_conversion_class_init( VipsConversionClass *class )
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
|
||||
|
||||
GParamSpec *pspec;
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
@ -93,13 +84,9 @@ vips_conversion_class_init( VipsConversionClass *class )
|
||||
vobject_class->description = _( "conversion operations" );
|
||||
vobject_class->build = vips_conversion_build;
|
||||
|
||||
pspec = g_param_spec_object( "out", "Output",
|
||||
VIPS_ARG_IMAGE( class, "out", 1,
|
||||
_( "Output" ),
|
||||
_( "Output image" ),
|
||||
VIPS_TYPE_IMAGE,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_OUTPUT, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_REQUIRED_OUTPUT,
|
||||
G_STRUCT_OFFSET( VipsConversion, output ) );
|
||||
}
|
||||
@ -116,7 +103,9 @@ void
|
||||
vips_conversion_operation_init( void )
|
||||
{
|
||||
extern GType vips_copy_get_type( void );
|
||||
extern GType vips_embed_get_type( void );
|
||||
|
||||
vips_copy_get_type();
|
||||
vips_embed_get_type();
|
||||
}
|
||||
|
||||
|
@ -74,8 +74,8 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
#define VIPS_DEBUG
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
@ -108,24 +108,6 @@
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
|
||||
/* Properties.
|
||||
*/
|
||||
enum {
|
||||
PROP_INPUT = 1,
|
||||
PROP_SWAP,
|
||||
PROP_WIDTH,
|
||||
PROP_HEIGHT,
|
||||
PROP_BANDS,
|
||||
PROP_FORMAT,
|
||||
PROP_CODING,
|
||||
PROP_INTERPRETATION,
|
||||
PROP_XRES,
|
||||
PROP_YRES,
|
||||
PROP_XOFFSET,
|
||||
PROP_YOFFSET,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
typedef struct _VipsCopy {
|
||||
VipsConversion parent_instance;
|
||||
|
||||
@ -344,8 +326,6 @@ vips_copy_class_init( VipsCopyClass *class )
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
|
||||
|
||||
GParamSpec *pspec;
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_copy_class_init\n" );
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
@ -355,116 +335,88 @@ vips_copy_class_init( VipsCopyClass *class )
|
||||
vobject_class->description = _( "copy an image" );
|
||||
vobject_class->build = vips_copy_build;
|
||||
|
||||
pspec = g_param_spec_object( "input",
|
||||
"Input", "Input image argument",
|
||||
VIPS_TYPE_IMAGE,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_INPUT, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARG_IMAGE( class, "in", 1,
|
||||
_( "Input" ),
|
||||
_( "Input image" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, input ) );
|
||||
|
||||
pspec = g_param_spec_boolean( "swap", "Swap",
|
||||
VIPS_ARG_BOOL( class, "swap", 2,
|
||||
_( "Swap" ),
|
||||
_( "Swap bytes in image between little and big-endian" ),
|
||||
FALSE,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_SWAP, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, swap ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, swap ),
|
||||
FALSE );
|
||||
|
||||
pspec = g_param_spec_int( "width", "Width",
|
||||
VIPS_ARG_INT( class, "width", 2,
|
||||
_( "Width" ),
|
||||
_( "Image width in pixels" ),
|
||||
0, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_WIDTH, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, width ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, width ),
|
||||
0, 1000000, 0 );
|
||||
|
||||
pspec = g_param_spec_int( "height", "Height",
|
||||
VIPS_ARG_INT( class, "height", 3,
|
||||
_( "Height" ),
|
||||
_( "Image height in pixels" ),
|
||||
0, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_HEIGHT, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, height ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, height ),
|
||||
0, 1000000, 0 );
|
||||
|
||||
pspec = g_param_spec_int( "bands", "Bands",
|
||||
VIPS_ARG_INT( class, "bands", 4,
|
||||
_( "Bands" ),
|
||||
_( "Number of bands in image" ),
|
||||
0, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_BANDS, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, bands ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, bands ),
|
||||
0, 1000000, 0 );
|
||||
|
||||
pspec = g_param_spec_enum( "format", "Format",
|
||||
VIPS_ARG_ENUM( class, "format", 5,
|
||||
_( "Format" ),
|
||||
_( "Pixel format in image" ),
|
||||
VIPS_TYPE_BAND_FORMAT, VIPS_FORMAT_UCHAR,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_FORMAT, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, format ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, format ),
|
||||
VIPS_TYPE_BAND_FORMAT, VIPS_FORMAT_UCHAR );
|
||||
|
||||
pspec = g_param_spec_enum( "coding", "Coding",
|
||||
VIPS_ARG_ENUM( class, "coding", 6,
|
||||
_( "Coding" ),
|
||||
_( "Pixel coding" ),
|
||||
VIPS_TYPE_CODING, VIPS_CODING_NONE,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_CODING, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, coding ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, coding ),
|
||||
VIPS_TYPE_CODING, VIPS_CODING_NONE );
|
||||
|
||||
pspec = g_param_spec_enum( "interpretation", "Interpretation",
|
||||
VIPS_ARG_ENUM( class, "interpretation", 7,
|
||||
_( "Interpretation" ),
|
||||
_( "Pixel interpretation" ),
|
||||
VIPS_TYPE_INTERPRETATION, VIPS_INTERPRETATION_MULTIBAND,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_INTERPRETATION, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, interpretation ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, interpretation ),
|
||||
VIPS_TYPE_INTERPRETATION, VIPS_INTERPRETATION_MULTIBAND );
|
||||
|
||||
pspec = g_param_spec_double( "xres", "XRes",
|
||||
VIPS_ARG_DOUBLE( class, "xres", 8,
|
||||
_( "Xres" ),
|
||||
_( "Horizontal resolution in pixels/mm" ),
|
||||
0, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_XRES, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, xres ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, xres ),
|
||||
0, 1000000, 0 );
|
||||
|
||||
pspec = g_param_spec_double( "yres", "YRes",
|
||||
VIPS_ARG_DOUBLE( class, "yres", 9,
|
||||
_( "Yres" ),
|
||||
_( "Vertical resolution in pixels/mm" ),
|
||||
0, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_YRES, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, yres ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, yres ),
|
||||
0, 1000000, 0 );
|
||||
|
||||
pspec = g_param_spec_int( "xoffset", "XOffset",
|
||||
VIPS_ARG_INT( class, "xoffset", 10,
|
||||
_( "Xoffset" ),
|
||||
_( "Horizontal offset of origin" ),
|
||||
-10000000, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_XOFFSET, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, xoffset ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, xoffset ),
|
||||
-1000000, 1000000, 0 );
|
||||
|
||||
pspec = g_param_spec_int( "yoffset", "YOffset",
|
||||
VIPS_ARG_INT( class, "yoffset", 11,
|
||||
_( "Yoffset" ),
|
||||
_( "Vertical offset of origin" ),
|
||||
-10000000, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_YOFFSET, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, yoffset ) );
|
||||
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsCopy, yoffset ),
|
||||
-1000000, 1000000, 0 );
|
||||
}
|
||||
|
||||
static void
|
||||
|
617
libvips/conversion/embed.c
Normal file
617
libvips/conversion/embed.c
Normal file
@ -0,0 +1,617 @@
|
||||
/* im_embed
|
||||
*
|
||||
* Author: J. Cupitt
|
||||
* Written on: 21/2/95
|
||||
* Modified on:
|
||||
* 6/4/04
|
||||
* - added extend pixels from edge mode
|
||||
* - sets Xoffset / Yoffset to x / y
|
||||
* 15/4/04
|
||||
* - added replicate and mirror modes
|
||||
* 4/3/05
|
||||
* - added solid white mode
|
||||
* 4/1/07
|
||||
* - degenerate to im_copy() for 0/0/w/h
|
||||
* 1/8/07
|
||||
* - more general ... x and y can be negative
|
||||
* 24/3/09
|
||||
* - added IM_CODING_RAD support
|
||||
* 5/11/09
|
||||
* - gtkdoc
|
||||
* 27/1/10
|
||||
* - use im_region_paint()
|
||||
* - cleanups
|
||||
* 15/10/11
|
||||
* - rewrite as a class
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This file is part of VIPS.
|
||||
|
||||
VIPS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
#define VIPS_DEBUG
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/internal.h>
|
||||
#include <vips/debug.h>
|
||||
|
||||
#include "conversion.h"
|
||||
|
||||
/**
|
||||
* VipsEmbed:
|
||||
* @in: input image
|
||||
* @out: output image
|
||||
* @type: how to generate the edge pixels
|
||||
* @x: place @in at this x position in @out
|
||||
* @y: place @in at this y position in @out
|
||||
* @width: @out should be this many pixels across
|
||||
* @height: @out should be this many pixels down
|
||||
*
|
||||
* The opposite of im_extract(): embed an image within a larger image. @type
|
||||
* controls what appears in the new pels, see #VipsExtend.
|
||||
*
|
||||
* See also: im_extract_area(), im_insert().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
|
||||
typedef struct _VipsEmbed {
|
||||
VipsConversion parent_instance;
|
||||
|
||||
/* The input image.
|
||||
*/
|
||||
VipsImage *input;
|
||||
|
||||
VipsExtend type;
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
/* Geometry calculations.
|
||||
*/
|
||||
Rect rout; /* Whole output area */
|
||||
Rect rsub; /* Rect occupied by image */
|
||||
|
||||
/* The 8 border pieces. The 4 borders strictly up/down/left/right of
|
||||
* the main image, and the 4 corner pieces.
|
||||
*/
|
||||
Rect border[8];
|
||||
} VipsEmbed;
|
||||
|
||||
typedef VipsConversionClass VipsEmbedClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsEmbed, vips_embed, VIPS_TYPE_CONVERSION );
|
||||
|
||||
/* r is the bit we are trying to paint, guaranteed to be entirely within
|
||||
* border area i. Set out to be the edge of the image we need to paint the
|
||||
* pixels in r.
|
||||
*/
|
||||
static void
|
||||
vips_embed_find_edge( VipsEmbed *embed, VipsRect *r, int i, VipsRect *out )
|
||||
{
|
||||
/* Expand the border by 1 pixel, intersect with the image area, and we
|
||||
* get the edge. Usually too much though: eg. we could make the entire
|
||||
* right edge.
|
||||
*/
|
||||
*out = embed->border[i];
|
||||
vips_rect_marginadjust( out, 1 );
|
||||
vips_rect_intersectrect( out, &embed->rsub, out );
|
||||
|
||||
/* Usually too much though: eg. we could make the entire
|
||||
* right edge. If we're strictly up/down/left/right of the image, we
|
||||
* can trim.
|
||||
*/
|
||||
if( i == 0 || i == 2 ) {
|
||||
VipsRect extend;
|
||||
|
||||
/* Above or below.
|
||||
*/
|
||||
extend = *r;
|
||||
extend.top = 0;
|
||||
extend.height = embed->height;
|
||||
vips_rect_intersectrect( out, &extend, out );
|
||||
}
|
||||
if( i == 1 || i == 3 ) {
|
||||
VipsRect extend;
|
||||
|
||||
/* Left or right.
|
||||
*/
|
||||
extend = *r;
|
||||
extend.left = 0;
|
||||
extend.width = embed->width;
|
||||
vips_rect_intersectrect( out, &extend, out );
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy a single pixel sideways into a line of pixels.
|
||||
*/
|
||||
static void
|
||||
vips_embed_copy_pixel( VipsEmbed *embed, PEL *q, PEL *p, int n )
|
||||
{
|
||||
const int bs = VIPS_IMAGE_SIZEOF_PEL( embed->input );
|
||||
|
||||
int x, b;
|
||||
|
||||
for( x = 0; x < n; x++ )
|
||||
for( b = 0; b < bs; b++ )
|
||||
*q++ = p[b];
|
||||
}
|
||||
|
||||
/* Paint r of region or. It's a border area, lying entirely within
|
||||
* embed->border[i]. p points to the top-left source pixel to fill with.
|
||||
* plsk is the line stride.
|
||||
*/
|
||||
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 );
|
||||
|
||||
VipsRect todo;
|
||||
PEL *q;
|
||||
int y;
|
||||
|
||||
/* Pixels left to paint.
|
||||
*/
|
||||
todo = *r;
|
||||
|
||||
/* Corner pieces ... copy the single pixel to paint the top line of
|
||||
* todo, then use the line copier below to paint the rest of it.
|
||||
*/
|
||||
if( i > 3 ) {
|
||||
q = (PEL *) VIPS_REGION_ADDR( or, todo.left, todo.top );
|
||||
vips_embed_copy_pixel( embed, q, p, todo.width );
|
||||
|
||||
p = q;
|
||||
todo.top += 1;
|
||||
todo.height -= 1;
|
||||
}
|
||||
|
||||
if( i == 1 || i == 3 ) {
|
||||
/* Vertical line of pixels to copy.
|
||||
*/
|
||||
for( y = 0; y < todo.height; y++ ) {
|
||||
q = (PEL *) VIPS_REGION_ADDR( or,
|
||||
todo.left, todo.top + y );
|
||||
vips_embed_copy_pixel( embed, q, p, todo.width );
|
||||
p += plsk;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Horizontal line of pixels to copy.
|
||||
*/
|
||||
for( y = 0; y < todo.height; y++ ) {
|
||||
q = (PEL *) VIPS_REGION_ADDR( or,
|
||||
todo.left, todo.top + y );
|
||||
memcpy( q, p, bs * todo.width );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
vips_embed_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop )
|
||||
{
|
||||
VipsRegion *ir = (VipsRegion *) seq;
|
||||
VipsEmbed *embed = (VipsEmbed *) b;
|
||||
VipsRect *r = &or->valid;
|
||||
|
||||
Rect ovl;
|
||||
int i;
|
||||
PEL *p;
|
||||
int plsk;
|
||||
|
||||
/* Entirely within the input image? Generate the subimage and copy
|
||||
* pointers.
|
||||
*/
|
||||
if( vips_rect_includesrect( &embed->rsub, r ) ) {
|
||||
VipsRect need;
|
||||
|
||||
need = *r;
|
||||
need.left -= embed->x;
|
||||
need.top -= embed->y;
|
||||
if( vips_region_prepare( ir, &need ) ||
|
||||
vips_region_region( or, ir, r, need.left, need.top ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* Does any of the input image appear in the area we have been asked
|
||||
* to make? Paste it in.
|
||||
*/
|
||||
vips_rect_intersectrect( r, &embed->rsub, &ovl );
|
||||
if( !vips_rect_isempty( &ovl ) ) {
|
||||
/* Paint the bits coming from the input image.
|
||||
*/
|
||||
ovl.left -= embed->x;
|
||||
ovl.top -= embed->y;
|
||||
if( vips_region_prepare_to( ir, or, &ovl,
|
||||
ovl.left + embed->x, ovl.top + embed->y ) )
|
||||
return( -1 );
|
||||
ovl.left += embed->x;
|
||||
ovl.top += embed->y;
|
||||
}
|
||||
|
||||
switch( embed->type ) {
|
||||
case 0:
|
||||
case 4:
|
||||
/* Paint the borders a solid value.
|
||||
*/
|
||||
for( i = 0; i < 8; i++ )
|
||||
vips_region_paint( or, &embed->border[i],
|
||||
embed->type == 0 ? 0 : 255 );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* Extend the borders.
|
||||
*/
|
||||
for( i = 0; i < 8; i++ ) {
|
||||
VipsRect todo;
|
||||
VipsRect edge;
|
||||
|
||||
vips_rect_intersectrect( r, &embed->border[i], &todo );
|
||||
if( !vips_rect_isempty( &todo ) ) {
|
||||
vips_embed_find_edge( embed, &todo, i, &edge );
|
||||
|
||||
/* Did we paint any of the input image? If we
|
||||
* did, we can fetch the edge pixels from
|
||||
* that.
|
||||
*/
|
||||
if( !vips_rect_isempty( &ovl ) ) {
|
||||
p = (PEL *) VIPS_REGION_ADDR( or,
|
||||
edge.left, edge.top );
|
||||
plsk = VIPS_REGION_LSKIP( or );
|
||||
}
|
||||
else {
|
||||
/* No pixels painted ... fetch
|
||||
* directly from the input image.
|
||||
*/
|
||||
edge.left -= embed->x;
|
||||
edge.top -= embed->y;
|
||||
if( vips_region_prepare( ir, &edge ) )
|
||||
return( -1 );
|
||||
p = (PEL *) VIPS_REGION_ADDR( ir,
|
||||
edge.left, edge.top );
|
||||
plsk = VIPS_REGION_LSKIP( ir );
|
||||
}
|
||||
|
||||
vips_embed_paint_edge( embed,
|
||||
or, i, &todo, p, plsk );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert( 0 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_embed_build( VipsObject *object )
|
||||
{
|
||||
VipsConversion *conversion = VIPS_CONVERSION( object );
|
||||
VipsEmbed *embed = (VipsEmbed *) object;
|
||||
|
||||
VipsRect want;
|
||||
|
||||
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 ) )
|
||||
return( -1 );
|
||||
if( embed->type < 0 || embed->type > 4 ) {
|
||||
vips_error( "VipsEmbed", "%s", _( "unknown type" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* nip can generate this quite often ... just copy.
|
||||
*/
|
||||
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 ) );
|
||||
|
||||
switch( embed->type ) {
|
||||
case 2:
|
||||
{
|
||||
/* Clock arithmetic: we want negative x/y to wrap around
|
||||
* nicely.
|
||||
*/
|
||||
const int nx = embed->x < 0 ?
|
||||
-embed->x % embed->input->Xsize :
|
||||
embed->input->Xsize - embed->x % embed->input->Xsize;
|
||||
const int ny = embed->y < 0 ?
|
||||
-embed->y % embed->input->Ysize :
|
||||
embed->input->Ysize - embed->y % embed->input->Ysize;
|
||||
|
||||
VipsImage *t[1];
|
||||
|
||||
if( im_open_local_array( conversion->output,
|
||||
t, 1, "embed-type2", "p" ) ||
|
||||
im_replicate( embed->input, t[0],
|
||||
embed->width / embed->input->Xsize + 2,
|
||||
embed->height / embed->input->Ysize + 2 ) ||
|
||||
im_extract_area( t[0], conversion->output,
|
||||
nx, ny, embed->width, embed->height ) )
|
||||
return( -1 );
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
{
|
||||
/* As case 2, but the tiles are twice the size because of
|
||||
* mirroring.
|
||||
*/
|
||||
const int w2 = embed->input->Xsize * 2;
|
||||
const int h2 = embed->input->Ysize * 2;
|
||||
|
||||
const int nx = embed->x < 0 ?
|
||||
-embed->x % w2 : w2 - embed->x % w2;
|
||||
const int ny = embed->y < 0 ?
|
||||
-embed->y % h2 : h2 - embed->y % h2;
|
||||
|
||||
VipsImage *t[7];
|
||||
|
||||
if( im_open_local_array( conversion->output,
|
||||
t, 7, "embed-type3", "p" ) ||
|
||||
/* Cache the edges of in, since we may well be reusing
|
||||
* them repeatedly. Will only help for tiny borders
|
||||
* (up to 20 pixels?), but that's our typical case
|
||||
* with im_conv() etc.
|
||||
im_cache( in, t[0], IM__TILE_WIDTH, IM__TILE_HEIGHT,
|
||||
3 * (in->Xsize / IM__TILE_WIDTH + 1) +
|
||||
3 * (in->Ysize / IM__TILE_HEIGHT + 1) ) ||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
FIXME ... alternatively, don't cache, hmm,
|
||||
need to time this for typical cases
|
||||
|
||||
*/
|
||||
im_copy( embed->input, t[0] ) ||
|
||||
|
||||
/* Make a 2x2 mirror tile.
|
||||
*/
|
||||
im_fliphor( t[0], t[1] ) ||
|
||||
im_lrjoin( t[0], t[1], t[2] ) ||
|
||||
im_flipver( t[2], t[3] ) ||
|
||||
im_tbjoin( t[2], t[3], t[4] ) ||
|
||||
|
||||
/* Repeat, then cut out the centre.
|
||||
*/
|
||||
im_replicate( t[4], t[5],
|
||||
embed->width / t[4]->Xsize + 2,
|
||||
embed->height / t[4]->Ysize + 2 ) ||
|
||||
im_extract_area( t[5], t[6], nx, ny,
|
||||
embed->width, embed->height ) ||
|
||||
|
||||
/* Overwrite the centre with the input, much faster
|
||||
* for centre pixels.
|
||||
*/
|
||||
im_insert_noexpand( t[6], embed->input,
|
||||
conversion->output, embed->x, embed->y ) )
|
||||
return( -1 );
|
||||
}
|
||||
break;
|
||||
|
||||
case 0:
|
||||
case 1:
|
||||
case 4:
|
||||
if( vips_image_copy_fields( conversion->output, embed->input ) )
|
||||
return( -1 );
|
||||
|
||||
conversion->output->Xsize = embed->width;
|
||||
conversion->output->Ysize = embed->height;
|
||||
|
||||
vips_demand_hint( conversion->output,
|
||||
VIPS_DEMAND_STYLE_SMALLTILE, embed->input, NULL );
|
||||
|
||||
/* Whole output area.
|
||||
*/
|
||||
embed->rout.left = 0;
|
||||
embed->rout.top = 0;
|
||||
embed->rout.width = conversion->output->Xsize;
|
||||
embed->rout.height = conversion->output->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;
|
||||
im_rect_intersectrect( &want, &embed->rout, &embed->rsub );
|
||||
|
||||
/* FIXME ... actually, it can't. embed_find_edge() will fail
|
||||
* if rsub is empty. Make this more general at some point
|
||||
* and remove this test.
|
||||
*/
|
||||
if( vips_rect_isempty( &embed->rsub ) ) {
|
||||
vips_error( "VipsEmbed", "%s", _( "bad dimensions" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* Edge rects of new pixels ... top, right, bottom, left. Order
|
||||
* important. Can be empty.
|
||||
*/
|
||||
embed->border[0].left = embed->rsub.left;
|
||||
embed->border[0].top = 0;
|
||||
embed->border[0].width = embed->rsub.width;
|
||||
embed->border[0].height = embed->rsub.top;
|
||||
|
||||
embed->border[1].left = VIPS_RECT_RIGHT( &embed->rsub );
|
||||
embed->border[1].top = embed->rsub.top;
|
||||
embed->border[1].width = conversion->output->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 -
|
||||
VIPS_RECT_BOTTOM( &embed->rsub );
|
||||
|
||||
embed->border[3].left = 0;
|
||||
embed->border[3].top = embed->rsub.top;
|
||||
embed->border[3].width = embed->rsub.left;
|
||||
embed->border[3].height = embed->rsub.height;
|
||||
|
||||
/* Corner rects. Top-left, top-right, bottom-right,
|
||||
* bottom-left. Order important.
|
||||
*/
|
||||
embed->border[4].left = 0;
|
||||
embed->border[4].top = 0;
|
||||
embed->border[4].width = embed->rsub.left;
|
||||
embed->border[4].height = embed->rsub.top;
|
||||
|
||||
embed->border[5].left = VIPS_RECT_RIGHT( &embed->rsub );
|
||||
embed->border[5].top = 0;
|
||||
embed->border[5].width = conversion->output->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 -
|
||||
VIPS_RECT_RIGHT( &embed->rsub );
|
||||
embed->border[6].height = conversion->output->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 -
|
||||
VIPS_RECT_BOTTOM( &embed->rsub );
|
||||
|
||||
if( vips_image_generate( conversion->output,
|
||||
vips_start_one, vips_embed_gen, vips_stop_one,
|
||||
embed->input, embed ) )
|
||||
return( -1 );
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert( 0 );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_embed_class_init( VipsEmbedClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_embed_class_init\n" );
|
||||
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
vobject_class->nickname = "embed";
|
||||
vobject_class->description = _( "embed an image in a larger image" );
|
||||
vobject_class->build = vips_embed_build;
|
||||
|
||||
VIPS_ARG_IMAGE( class, "in", -1,
|
||||
_( "Input" ),
|
||||
_( "Input image" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsEmbed, input ) );
|
||||
|
||||
VIPS_ARG_INT( class, "width", 2,
|
||||
_( "Width" ),
|
||||
_( "Image width in pixels" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsEmbed, width ),
|
||||
0, 1000000, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "height", 3,
|
||||
_( "Height" ),
|
||||
_( "Image height in pixels" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsEmbed, height ),
|
||||
0, 1000000, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "x", 4,
|
||||
_( "x" ),
|
||||
_( "Left edge of input in output" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsEmbed, x ),
|
||||
-1000000, 1000000, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "y", 5,
|
||||
_( "y" ),
|
||||
_( "Top edge of input in output" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsEmbed, y ),
|
||||
-1000000, 1000000, 0 );
|
||||
|
||||
VIPS_ARG_ENUM( class, "type", 6,
|
||||
_( "type" ),
|
||||
_( "How to generate the extra pixels" ),
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsEmbed, type ),
|
||||
VIPS_TYPE_EXTEND, VIPS_EXTEND_BLACK );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_embed_init( VipsEmbed *embed )
|
||||
{
|
||||
/* Init our instance fields.
|
||||
*/
|
||||
}
|
||||
|
||||
int
|
||||
vips_embed( VipsImage *in, VipsImage **out,
|
||||
int x, int y, int width, int height, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, height );
|
||||
result = vips_call_split( "embed", ap,
|
||||
in, out, x, y, width, height );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
@ -775,7 +775,7 @@ vips_wrap7_subclass_class_init( VipsWrap7Class *class )
|
||||
(type->flags & IM_TYPE_OUTPUT) ?
|
||||
VIPS_ARGUMENT_REQUIRED_OUTPUT :
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
i );
|
||||
i, i );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -57,6 +57,7 @@ EXTRA_DIST = version.h.in internal.h enumtemplate
|
||||
# well
|
||||
vips_scan_headers = \
|
||||
${top_srcdir}/libvips/include/vips/memory.h \
|
||||
${top_srcdir}/libvips/include/vips/conversion.h \
|
||||
${top_srcdir}/libvips/include/vips/util.h \
|
||||
${top_srcdir}/libvips/include/vips/buf.h \
|
||||
${top_srcdir}/libvips/include/vips/image.h \
|
||||
|
@ -37,7 +37,49 @@
|
||||
extern "C" {
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
int vips_copy( VipsImage *in, VipsImage **out, ... );
|
||||
/**
|
||||
* VipsExtend:
|
||||
* @VIPS_EXTEND_BLACK; extend with black (all 0) pixels
|
||||
* @VIPS_EXTEND_COPY; copy the image edges
|
||||
* @VIPS_EXTEND_REPEAT; repeat the whole image
|
||||
* @VIPS_EXTEND_MIRROR; mirror the whole image
|
||||
* @VIPS_EXTEND_WHITE; extend with white (all bits set) pixels
|
||||
*
|
||||
* See vips_embed(), vips_conv(), vips_affine() and so on.
|
||||
*
|
||||
* When the edges of an image are extended, you can specify
|
||||
* how you want the extension done.
|
||||
*
|
||||
* #VIPS_EXTEND_BLACK --- new pixels are black, ie. all bits are zero.
|
||||
*
|
||||
* #VIPS_EXTEND_COPY --- each new pixel takes the value of the nearest edge
|
||||
* pixel
|
||||
*
|
||||
* #VIPS_EXTEND_REPEAT --- the image is tiled to fill the new area
|
||||
*
|
||||
* #VIPS_EXTEND_MIRROR --- the image is reflected and tiled to reduce hash
|
||||
* edges
|
||||
*
|
||||
* #VIPS_EXTEND_WHITE --- new pixels are white, ie. all bits are set
|
||||
*
|
||||
* We have to specify the exact value of each enum member since we have to
|
||||
* keep these frozen for back compat with vips7.
|
||||
*
|
||||
* See also: vips_embed().
|
||||
*/
|
||||
typedef enum {
|
||||
VIPS_EXTEND_BLACK = 0,
|
||||
VIPS_EXTEND_COPY = 1,
|
||||
VIPS_EXTEND_REPEAT = 2,
|
||||
VIPS_EXTEND_MIRROR = 3,
|
||||
VIPS_EXTEND_WHITE = 4
|
||||
} VipsExtend;
|
||||
|
||||
int vips_copy( VipsImage *in, VipsImage **out, ... )
|
||||
__attribute__((sentinel));
|
||||
int vips_embed( VipsImage *in, VipsImage **out,
|
||||
int x, int y, int width, int height, ... )
|
||||
__attribute__((sentinel));
|
||||
|
||||
|
||||
|
||||
|
@ -6,6 +6,9 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* enumerations from "../../../libvips/include/vips/conversion.h" */
|
||||
GType vips_extend_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_EXTEND (vips_extend_get_type())
|
||||
/* enumerations from "../../../libvips/include/vips/util.h" */
|
||||
GType vips_token_get_type (void) G_GNUC_CONST;
|
||||
#define VIPS_TYPE_TOKEN (vips_token_get_type())
|
||||
|
@ -62,23 +62,23 @@ extern "C" {
|
||||
* will use the most restrictive of the styles requested by the operations
|
||||
* in the pipeline.
|
||||
*
|
||||
* VIPS_DEMAND_STYLE_THINSTRIP --- This operation would like to output strips
|
||||
* #VIPS_DEMAND_STYLE_THINSTRIP --- This operation would like to output strips
|
||||
* the width of the image and a few pels high. This is option suitable for
|
||||
* point-to-point operations, such as those in the arithmetic package.
|
||||
*
|
||||
* This option is only efficient for cases where each output pel depends
|
||||
* upon the pel in the corresponding position in the input image.
|
||||
*
|
||||
* VIPS_DEMAND_STYLE_FATSTRIP --- This operation would like to output strips
|
||||
* #VIPS_DEMAND_STYLE_FATSTRIP --- This operation would like to output strips
|
||||
* the width of the image and as high as possible. This option is suitable
|
||||
* for area operations which do not violently transform coordinates, such
|
||||
* as im_conv().
|
||||
*
|
||||
* VIPS_DEMAND_STYLE_SMALLTILE --- This is the most general demand format.
|
||||
* #VIPS_DEMAND_STYLE_SMALLTILE --- This is the most general demand format.
|
||||
* Output is demanded in small (around 100x100 pel) sections. This style works
|
||||
* reasonably efficiently, even for bizzare operations like 45 degree rotate.
|
||||
*
|
||||
* VIPS_DEMAND_STYLE_ANY --- This image is not being demand-read from a disc
|
||||
* #VIPS_DEMAND_STYLE_ANY --- This image is not being demand-read from a disc
|
||||
* file (even indirectly) so any demand style is OK. It's used for things like
|
||||
* im_black() where the pixels are calculated.
|
||||
*
|
||||
|
@ -52,7 +52,6 @@ typedef struct _VipsObjectClass VipsObjectClass;
|
||||
* @VIPS_ARGUMENT_SET_ONCE: can only be set once
|
||||
* @VIPS_ARGUMENT_INPUT: is an input argument (one we depend on)
|
||||
* @VIPS_ARGUMENT_OUTPUT: is an output argument (depends on us)
|
||||
* @VIPS_ARGUMENT_APPEND: add to end of arg list (default is prepend)
|
||||
*
|
||||
* Flags we associate with each object argument.
|
||||
*
|
||||
@ -67,8 +66,7 @@ typedef enum {
|
||||
VIPS_ARGUMENT_CONSTRUCT = 2,
|
||||
VIPS_ARGUMENT_SET_ONCE = 4,
|
||||
VIPS_ARGUMENT_INPUT = 8,
|
||||
VIPS_ARGUMENT_OUTPUT = 16,
|
||||
VIPS_ARGUMENT_APPEND = 32
|
||||
VIPS_ARGUMENT_OUTPUT = 16
|
||||
} VipsArgumentFlags;
|
||||
|
||||
/* Useful flag combinations. User-visible ones are:
|
||||
@ -108,6 +106,96 @@ VIPS_ARGUMENT_OPTIONAL_OUTPUT Eg. the x pos of the image minimum
|
||||
VIPS_ARGUMENT_CONSTRUCT | \
|
||||
VIPS_ARGUMENT_SET_ONCE)
|
||||
|
||||
extern int _vips__argument_id;
|
||||
|
||||
#define VIPS_ARG_IMAGE( CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET ) { \
|
||||
GParamSpec *pspec; \
|
||||
\
|
||||
pspec = g_param_spec_object( (NAME), (LONG), (DESC), \
|
||||
VIPS_TYPE_IMAGE, \
|
||||
G_PARAM_READWRITE ); \
|
||||
g_object_class_install_property( G_OBJECT_CLASS( CLASS ), \
|
||||
_vips__argument_id++, pspec ); \
|
||||
vips_object_class_install_argument( VIPS_OBJECT_CLASS( CLASS ), \
|
||||
pspec, (FLAGS), (PRIORITY), (OFFSET) ); \
|
||||
}
|
||||
|
||||
#define VIPS_ARG_BOOL( CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET, \
|
||||
VALUE ) { \
|
||||
GParamSpec *pspec; \
|
||||
\
|
||||
pspec = g_param_spec_boolean( (NAME), (LONG), (DESC), \
|
||||
(VALUE), \
|
||||
G_PARAM_READWRITE ); \
|
||||
g_object_class_install_property( G_OBJECT_CLASS( CLASS ), \
|
||||
_vips__argument_id++, pspec ); \
|
||||
vips_object_class_install_argument( VIPS_OBJECT_CLASS( CLASS ), \
|
||||
pspec, (FLAGS), (PRIORITY), (OFFSET) ); \
|
||||
}
|
||||
|
||||
#define VIPS_ARG_DOUBLE( CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET, \
|
||||
MIN, MAX, VALUE ) { \
|
||||
GParamSpec *pspec; \
|
||||
\
|
||||
pspec = g_param_spec_double( (NAME), (LONG), (DESC), \
|
||||
(MIN), (MAX), (VALUE), \
|
||||
G_PARAM_READWRITE );\
|
||||
g_object_class_install_property( G_OBJECT_CLASS( CLASS ), \
|
||||
_vips__argument_id++, pspec ); \
|
||||
vips_object_class_install_argument( VIPS_OBJECT_CLASS( CLASS ), \
|
||||
pspec, (FLAGS), (PRIORITY), (OFFSET) ); \
|
||||
}
|
||||
|
||||
#define VIPS_ARG_INT( CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET, \
|
||||
MIN, MAX, VALUE ) { \
|
||||
GParamSpec *pspec; \
|
||||
\
|
||||
pspec = g_param_spec_int( (NAME), (LONG), (DESC), \
|
||||
(MIN), (MAX), (VALUE), \
|
||||
G_PARAM_READWRITE );\
|
||||
g_object_class_install_property( G_OBJECT_CLASS( CLASS ), \
|
||||
_vips__argument_id++, pspec ); \
|
||||
vips_object_class_install_argument( VIPS_OBJECT_CLASS( CLASS ), \
|
||||
pspec, (FLAGS), (PRIORITY), (OFFSET) ); \
|
||||
}
|
||||
|
||||
#define VIPS_ARG_ENUM( CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET, \
|
||||
TYPE, VALUE ) { \
|
||||
GParamSpec *pspec; \
|
||||
\
|
||||
pspec = g_param_spec_enum( (NAME), (LONG), (DESC), \
|
||||
(TYPE), (VALUE), \
|
||||
G_PARAM_READWRITE );\
|
||||
g_object_class_install_property( G_OBJECT_CLASS( CLASS ), \
|
||||
_vips__argument_id++, pspec ); \
|
||||
vips_object_class_install_argument( VIPS_OBJECT_CLASS( CLASS ), \
|
||||
pspec, (FLAGS), (PRIORITY), (OFFSET) ); \
|
||||
}
|
||||
|
||||
#define VIPS_ARG_STRING( CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET, \
|
||||
VALUE ) { \
|
||||
GParamSpec *pspec; \
|
||||
\
|
||||
pspec = g_param_spec_string( (NAME), (LONG), (DESC), \
|
||||
(VALUE), \
|
||||
G_PARAM_READWRITE ); \
|
||||
g_object_class_install_property( G_OBJECT_CLASS( CLASS ), \
|
||||
_vips__argument_id++, pspec ); \
|
||||
vips_object_class_install_argument( VIPS_OBJECT_CLASS( CLASS ), \
|
||||
pspec, (FLAGS), (PRIORITY), (OFFSET) ); \
|
||||
}
|
||||
|
||||
#define VIPS_ARG_POINTER( CLASS, NAME, PRIORITY, LONG, DESC, FLAGS, OFFSET ) { \
|
||||
GParamSpec *pspec; \
|
||||
\
|
||||
pspec = g_param_spec_pointer( (NAME), (LONG), (DESC), \
|
||||
G_PARAM_READWRITE ); \
|
||||
g_object_class_install_property( gobject_class, \
|
||||
_vips__argument_id++, pspec ); \
|
||||
vips_object_class_install_argument( VIPS_OBJECT_CLASS( CLASS ), \
|
||||
pspec, (FLAGS), (PRIORITY), (OFFSET) ); \
|
||||
}
|
||||
|
||||
/* Keep one of these for every argument.
|
||||
*/
|
||||
typedef struct _VipsArgument {
|
||||
@ -126,6 +214,7 @@ typedef struct _VipsArgumentClass {
|
||||
VipsObjectClass *object_class;
|
||||
|
||||
VipsArgumentFlags flags;
|
||||
int priority; /* Order args by this */
|
||||
guint offset; /* G_STRUCT_OFFSET of member in object */
|
||||
} VipsArgumentClass;
|
||||
|
||||
@ -332,8 +421,8 @@ gboolean vips_object_sanity( VipsObject *object );
|
||||
|
||||
GType vips_object_get_type( void );
|
||||
|
||||
void vips_object_class_install_argument( VipsObjectClass *,
|
||||
GParamSpec *pspec, VipsArgumentFlags flags, guint offset );
|
||||
void vips_object_class_install_argument( VipsObjectClass *, GParamSpec *pspec,
|
||||
VipsArgumentFlags flags, int priority, guint offset );
|
||||
int vips_object_set_argument_from_string( VipsObject *object,
|
||||
const char *name, const char *value );
|
||||
gboolean vips_object_get_argument_needs_string( VipsObject *object,
|
||||
|
@ -41,6 +41,7 @@ INCLUDES = -I${top_srcdir}/libvips/include @VIPS_CFLAGS@ @VIPS_INCLUDES@
|
||||
# well
|
||||
vips_scan_headers = \
|
||||
${top_srcdir}/libvips/include/vips/memory.h \
|
||||
${top_srcdir}/libvips/include/vips/conversion.h \
|
||||
${top_srcdir}/libvips/include/vips/util.h \
|
||||
${top_srcdir}/libvips/include/vips/buf.h \
|
||||
${top_srcdir}/libvips/include/vips/image.h \
|
||||
|
@ -4,6 +4,27 @@
|
||||
/* auto-generated enums for vips introspection */
|
||||
|
||||
#include <vips/vips.h>
|
||||
/* enumerations from "../../libvips/include/vips/conversion.h" */
|
||||
GType
|
||||
vips_extend_get_type( void )
|
||||
{
|
||||
static GType etype = 0;
|
||||
|
||||
if( etype == 0 ) {
|
||||
static const GEnumValue values[] = {
|
||||
{VIPS_EXTEND_BLACK, "VIPS_EXTEND_BLACK", "black"},
|
||||
{VIPS_EXTEND_COPY, "VIPS_EXTEND_COPY", "copy"},
|
||||
{VIPS_EXTEND_REPEAT, "VIPS_EXTEND_REPEAT", "repeat"},
|
||||
{VIPS_EXTEND_MIRROR, "VIPS_EXTEND_MIRROR", "mirror"},
|
||||
{VIPS_EXTEND_WHITE, "VIPS_EXTEND_WHITE", "white"},
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
|
||||
etype = g_enum_register_static( "VipsExtend", values );
|
||||
}
|
||||
|
||||
return( etype );
|
||||
}
|
||||
/* enumerations from "../../libvips/include/vips/util.h" */
|
||||
GType
|
||||
vips_token_get_type( void )
|
||||
@ -158,7 +179,6 @@ vips_argument_flags_get_type( void )
|
||||
{VIPS_ARGUMENT_SET_ONCE, "VIPS_ARGUMENT_SET_ONCE", "set-once"},
|
||||
{VIPS_ARGUMENT_INPUT, "VIPS_ARGUMENT_INPUT", "input"},
|
||||
{VIPS_ARGUMENT_OUTPUT, "VIPS_ARGUMENT_OUTPUT", "output"},
|
||||
{VIPS_ARGUMENT_APPEND, "VIPS_ARGUMENT_APPEND", "append"},
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -143,28 +143,6 @@
|
||||
* Returns: The address of pixel (x,y) in the image.
|
||||
*/
|
||||
|
||||
/* Properties.
|
||||
*/
|
||||
enum {
|
||||
PROP_WIDTH = 1,
|
||||
PROP_HEIGHT,
|
||||
PROP_BANDS,
|
||||
PROP_FORMAT,
|
||||
PROP_CODING,
|
||||
PROP_INTERPRETATION,
|
||||
PROP_XRES,
|
||||
PROP_YRES,
|
||||
PROP_XOFFSET,
|
||||
PROP_YOFFSET,
|
||||
PROP_FILENAME,
|
||||
PROP_KILL,
|
||||
PROP_MODE,
|
||||
PROP_DEMAND,
|
||||
PROP_SIZEOF_HEADER,
|
||||
PROP_FOREIGN_BUFFER,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
/* Our signals.
|
||||
*/
|
||||
enum {
|
||||
@ -938,12 +916,11 @@ vips_image_class_init( VipsImageClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
|
||||
GParamSpec *pspec;
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_image_class_init:\n" );
|
||||
|
||||
/* Pass in a nonsense name for argv0 ... this init world is only here
|
||||
* for old programs which are missing an vips_init() call. We must
|
||||
* for old programs which are missing a vips_init() call. We must
|
||||
* have threads set up before we can process.
|
||||
*/
|
||||
if( vips_init( "vips" ) )
|
||||
@ -972,149 +949,114 @@ vips_image_class_init( VipsImageClass *class )
|
||||
/* Create properties.
|
||||
*/
|
||||
|
||||
/* Width / height / bands can be zero for unintialised.
|
||||
*/
|
||||
pspec = g_param_spec_int( "width", "Width",
|
||||
VIPS_ARG_INT( class, "width", 2,
|
||||
_( "Width" ),
|
||||
_( "Image width in pixels" ),
|
||||
0, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_WIDTH, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_SET_ONCE,
|
||||
G_STRUCT_OFFSET( VipsImage, Xsize ) );
|
||||
pspec = g_param_spec_int( "height", "Height",
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsImage, Xsize ),
|
||||
0, 1000000, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "height", 3,
|
||||
_( "Height" ),
|
||||
_( "Image height in pixels" ),
|
||||
0, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_HEIGHT, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_SET_ONCE,
|
||||
G_STRUCT_OFFSET( VipsImage, Ysize ) );
|
||||
pspec = g_param_spec_int( "bands", "Bands",
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsImage, Ysize ),
|
||||
0, 1000000, 0 );
|
||||
|
||||
VIPS_ARG_INT( class, "bands", 4,
|
||||
_( "Bands" ),
|
||||
_( "Number of bands in image" ),
|
||||
0, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_BANDS, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_SET_ONCE,
|
||||
G_STRUCT_OFFSET( VipsImage, Bands ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsImage, Bands ),
|
||||
0, 1000000, 0 );
|
||||
|
||||
pspec = g_param_spec_enum( "format", "Format",
|
||||
VIPS_ARG_ENUM( class, "format", 5,
|
||||
_( "Format" ),
|
||||
_( "Pixel format in image" ),
|
||||
VIPS_TYPE_BAND_FORMAT, VIPS_FORMAT_UCHAR,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_FORMAT, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_SET_ONCE,
|
||||
G_STRUCT_OFFSET( VipsImage, BandFmt ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsImage, BandFmt ),
|
||||
VIPS_TYPE_BAND_FORMAT, VIPS_FORMAT_UCHAR );
|
||||
|
||||
pspec = g_param_spec_enum( "coding", "Coding",
|
||||
VIPS_ARG_ENUM( class, "coding", 6,
|
||||
_( "Coding" ),
|
||||
_( "Pixel coding" ),
|
||||
VIPS_TYPE_CODING, VIPS_CODING_NONE,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_CODING, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_SET_ONCE,
|
||||
G_STRUCT_OFFSET( VipsImage, Coding ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsImage, Coding ),
|
||||
VIPS_TYPE_CODING, VIPS_CODING_NONE );
|
||||
|
||||
pspec = g_param_spec_enum( "interpretation", "Interpretation",
|
||||
VIPS_ARG_ENUM( class, "interpretation", 7,
|
||||
_( "Interpretation" ),
|
||||
_( "Pixel interpretation" ),
|
||||
VIPS_TYPE_INTERPRETATION, VIPS_INTERPRETATION_MULTIBAND,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_INTERPRETATION, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_SET_ONCE,
|
||||
G_STRUCT_OFFSET( VipsImage, Type ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsImage, Type ),
|
||||
VIPS_TYPE_INTERPRETATION, VIPS_INTERPRETATION_MULTIBAND );
|
||||
|
||||
pspec = g_param_spec_double( "xres", "XRes",
|
||||
VIPS_ARG_DOUBLE( class, "xres", 8,
|
||||
_( "Xres" ),
|
||||
_( "Horizontal resolution in pixels/mm" ),
|
||||
0, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_XRES, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_SET_ONCE,
|
||||
G_STRUCT_OFFSET( VipsImage, Xres ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsImage, Xres ),
|
||||
0, 1000000, 0 );
|
||||
|
||||
pspec = g_param_spec_double( "yres", "YRes",
|
||||
VIPS_ARG_DOUBLE( class, "yres", 9,
|
||||
_( "Yres" ),
|
||||
_( "Vertical resolution in pixels/mm" ),
|
||||
0, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_YRES, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_SET_ONCE,
|
||||
G_STRUCT_OFFSET( VipsImage, Yres ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsImage, Yres ),
|
||||
0, 1000000, 0 );
|
||||
|
||||
pspec = g_param_spec_int( "xoffset", "XOffset",
|
||||
VIPS_ARG_INT( class, "xoffset", 10,
|
||||
_( "Xoffset" ),
|
||||
_( "Horizontal offset of origin" ),
|
||||
-10000000, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_XOFFSET, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_SET_ONCE,
|
||||
G_STRUCT_OFFSET( VipsImage, Xoffset ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsImage, Xoffset ),
|
||||
-1000000, 1000000, 0 );
|
||||
|
||||
pspec = g_param_spec_int( "yoffset", "YOffset",
|
||||
VIPS_ARG_INT( class, "yoffset", 11,
|
||||
_( "Yoffset" ),
|
||||
_( "Vertical offset of origin" ),
|
||||
-10000000, 1000000, 0,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_YOFFSET, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_SET_ONCE,
|
||||
G_STRUCT_OFFSET( VipsImage, Yoffset ) );
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT,
|
||||
G_STRUCT_OFFSET( VipsImage, Yoffset ),
|
||||
-1000000, 1000000, 0 );
|
||||
|
||||
pspec = g_param_spec_string( "filename", "Filename",
|
||||
VIPS_ARG_STRING( class, "filename", 12,
|
||||
_( "Filename" ),
|
||||
_( "Image filename" ),
|
||||
NULL,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_FILENAME, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_CONSTRUCT,
|
||||
G_STRUCT_OFFSET( VipsImage, filename ) );
|
||||
G_STRUCT_OFFSET( VipsImage, filename ),
|
||||
NULL );
|
||||
|
||||
pspec = g_param_spec_string( "mode", "Mode",
|
||||
VIPS_ARG_STRING( class, "mode", 13,
|
||||
_( "Mode" ),
|
||||
_( "Open mode" ),
|
||||
"p", /* Default to partial */
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_MODE, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_CONSTRUCT,
|
||||
G_STRUCT_OFFSET( VipsImage, mode ) );
|
||||
G_STRUCT_OFFSET( VipsImage, filename ),
|
||||
"p" );
|
||||
|
||||
pspec = g_param_spec_boolean( "kill", "Kill",
|
||||
VIPS_ARG_BOOL( class, "kill", 14,
|
||||
_( "Kill" ),
|
||||
_( "Block evaluation on this image" ),
|
||||
FALSE,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_KILL, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_NONE,
|
||||
G_STRUCT_OFFSET( VipsImage, kill ) );
|
||||
G_STRUCT_OFFSET( VipsImage, kill ),
|
||||
FALSE );
|
||||
|
||||
pspec = g_param_spec_enum( "demand", "Demand",
|
||||
VIPS_ARG_ENUM( class, "demand", 15,
|
||||
_( "Demand style" ),
|
||||
_( "Preferred demand style for this image" ),
|
||||
VIPS_TYPE_DEMAND_STYLE, VIPS_DEMAND_STYLE_SMALLTILE,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class, PROP_DEMAND, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_NONE,
|
||||
G_STRUCT_OFFSET( VipsImage, dhint ) );
|
||||
VIPS_ARGUMENT_NONE,
|
||||
G_STRUCT_OFFSET( VipsImage, dhint ),
|
||||
VIPS_TYPE_DEMAND_STYLE, VIPS_DEMAND_STYLE_SMALLTILE );
|
||||
|
||||
pspec = g_param_spec_int( "sizeof_header", "Size of header",
|
||||
VIPS_ARG_INT( class, "sizeof_header", 16,
|
||||
_( "Size of header" ),
|
||||
_( "Offset in bytes from start of file" ),
|
||||
0, 1000000, VIPS_SIZEOF_HEADER,
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_SIZEOF_HEADER, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARGUMENT_SET_ONCE | VIPS_ARGUMENT_CONSTRUCT,
|
||||
G_STRUCT_OFFSET( VipsImage, sizeof_header ) );
|
||||
G_STRUCT_OFFSET( VipsImage, sizeof_header ),
|
||||
0, 1000000, VIPS_SIZEOF_HEADER );
|
||||
|
||||
pspec = g_param_spec_pointer( "foreign_buffer", "Foreign buffer",
|
||||
"Pointer to foreign pixels",
|
||||
G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_FOREIGN_BUFFER, pspec );
|
||||
vips_object_class_install_argument( vobject_class, pspec,
|
||||
VIPS_ARG_POINTER( class, "foreign_buffer", 17,
|
||||
_( "Foreign buffer" ),
|
||||
_( "Pointer to foreign pixels" ),
|
||||
VIPS_ARGUMENT_SET_ONCE | VIPS_ARGUMENT_CONSTRUCT,
|
||||
G_STRUCT_OFFSET( VipsImage, data ) );
|
||||
|
||||
|
@ -48,14 +48,6 @@
|
||||
#include <vips/internal.h>
|
||||
#include <vips/debug.h>
|
||||
|
||||
/* Properties.
|
||||
*/
|
||||
enum {
|
||||
PROP_NICKNAME = 1,/* Class properties as object props */
|
||||
PROP_DESCRIPTION,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
/* Our signals.
|
||||
*/
|
||||
enum {
|
||||
@ -72,6 +64,8 @@ static GMutex *vips__object_all_lock = NULL;
|
||||
|
||||
static guint vips_object_signals[SIG_LAST] = { 0 };
|
||||
|
||||
int _vips__argument_id = 0;
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE( VipsObject, vips_object, G_TYPE_OBJECT );
|
||||
|
||||
void
|
||||
@ -1058,8 +1052,6 @@ vips_object_class_init( VipsObjectClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
|
||||
GParamSpec *pspec;
|
||||
|
||||
if( !vips__object_all ) {
|
||||
vips__object_all = g_hash_table_new(
|
||||
g_direct_hash, g_direct_equal );
|
||||
@ -1092,29 +1084,19 @@ vips_object_class_init( VipsObjectClass *class )
|
||||
g_value_register_transform_func( G_TYPE_STRING, G_TYPE_DOUBLE,
|
||||
transform_string_double );
|
||||
|
||||
/* Create properties.
|
||||
*/
|
||||
pspec = g_param_spec_string( "nickname",
|
||||
VIPS_ARG_STRING( class, "nickname", 1,
|
||||
_( "Nickname" ),
|
||||
_( "Class nickname" ),
|
||||
"",
|
||||
(GParamFlags) G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_NICKNAME, pspec );
|
||||
vips_object_class_install_argument( class, pspec,
|
||||
VIPS_ARGUMENT_SET_ONCE,
|
||||
G_STRUCT_OFFSET( VipsObject, nickname ) );
|
||||
G_STRUCT_OFFSET( VipsObject, nickname ),
|
||||
"" );
|
||||
|
||||
pspec = g_param_spec_string( "description",
|
||||
VIPS_ARG_STRING( class, "description", 2,
|
||||
_( "Description" ),
|
||||
_( "Class description" ),
|
||||
"",
|
||||
(GParamFlags) G_PARAM_READWRITE );
|
||||
g_object_class_install_property( gobject_class,
|
||||
PROP_DESCRIPTION, pspec );
|
||||
vips_object_class_install_argument( class, pspec,
|
||||
VIPS_ARGUMENT_SET_ONCE,
|
||||
G_STRUCT_OFFSET( VipsObject, description ) );
|
||||
G_STRUCT_OFFSET( VipsObject, description ),
|
||||
"" );
|
||||
|
||||
vips_object_signals[SIG_PRECLOSE] = g_signal_new( "preclose",
|
||||
G_TYPE_FROM_CLASS( class ),
|
||||
@ -1154,11 +1136,20 @@ vips_object_init( VipsObject *object )
|
||||
g_mutex_unlock( vips__object_all_lock );
|
||||
}
|
||||
|
||||
static gint
|
||||
traverse_sort( gconstpointer a, gconstpointer b )
|
||||
{
|
||||
VipsArgumentClass *class1 = (VipsArgumentClass *) a;
|
||||
VipsArgumentClass *class2 = (VipsArgumentClass *) b;
|
||||
|
||||
return( class1->priority - class2->priority );
|
||||
}
|
||||
|
||||
/* Add a vipsargument ... automate some stuff with this.
|
||||
*/
|
||||
void
|
||||
vips_object_class_install_argument( VipsObjectClass *object_class,
|
||||
GParamSpec *pspec, VipsArgumentFlags flags, guint offset )
|
||||
GParamSpec *pspec, VipsArgumentFlags flags, int priority, guint offset )
|
||||
{
|
||||
VipsArgumentClass *argument_class = g_new( VipsArgumentClass, 1 );
|
||||
|
||||
@ -1181,16 +1172,15 @@ vips_object_class_install_argument( VipsObjectClass *object_class,
|
||||
((VipsArgument *) argument_class)->pspec = pspec;
|
||||
argument_class->object_class = object_class;
|
||||
argument_class->flags = flags;
|
||||
argument_class->priority = priority;
|
||||
argument_class->offset = offset;
|
||||
|
||||
vips_argument_table_replace( object_class->argument_table,
|
||||
(VipsArgument *) argument_class );
|
||||
if( flags & VIPS_ARGUMENT_APPEND )
|
||||
object_class->argument_table_traverse = g_slist_append(
|
||||
object_class->argument_table_traverse, argument_class );
|
||||
else
|
||||
object_class->argument_table_traverse = g_slist_prepend(
|
||||
object_class->argument_table_traverse, argument_class );
|
||||
object_class->argument_table_traverse = g_slist_prepend(
|
||||
object_class->argument_table_traverse, argument_class );
|
||||
object_class->argument_table_traverse = g_slist_sort(
|
||||
object_class->argument_table_traverse, traverse_sort );
|
||||
}
|
||||
|
||||
/* Set a named arg from a string.
|
||||
|
Loading…
Reference in New Issue
Block a user