gmic uses an imagevec for input images

This commit is contained in:
John Cupitt 2014-10-06 21:52:27 +01:00
parent ae7d81d748
commit 3788c85e54
7 changed files with 82 additions and 129 deletions

View File

@ -15,6 +15,8 @@
- better extra band handling by colour, again
- move zoomify ImageProperties file, now a better match to the offical tool
- rename VIPS_ANGLE_180 as VIPS_ANGLE_D180 etc. to help python
- update cimg
- add gmic
8/9/14 started 7.40.10
- icc_import and icc_transform checks the input profile for compatibility

View File

@ -42,35 +42,20 @@
#include <iostream>
/* CImg needs to call pthread directly, this is the preproc magic they
* prefer.
#if defined(sun) || defined(__sun) || defined(linux) || defined(__linux) \
|| defined(__linux__) || defined(__CYGWIN__) || defined(BSD) || defined(__FreeBSD__) \
|| defined(__OPENBSD__) || defined(__MACOSX__) || defined(__APPLE__) || defined(sgi) \
|| defined(__sgi)
#include <pthread.h>
#endif
*/
#include "CImg.h"
#include "gmic.h"
using namespace cimg_library;
//#define gmic_image cimg_library::CImg
#define GMIC_MAX_INPUT_IMAGES 10
typedef struct _VipsGMic {
VipsOperation parent_instance;
VipsImage* in[GMIC_MAX_INPUT_IMAGES];
int ninput;
VipsImage* out;
char* command;
int padding;
double x_scale;
double y_scale;
VipsOperation parent_instance;
VipsArrayImage *in;
VipsImage *out;
char *command;
int padding;
double x_scale;
double y_scale;
} VipsGMic;
typedef VipsOperationClass VipsGMicClass;
@ -152,6 +137,7 @@ _gmic_gen( VipsRegion *oreg, void *seq, void *a, void *b, gboolean *stop )
{
VipsRegion **ir = (VipsRegion **) seq;
VipsGMic *vipsgmic = (VipsGMic *) b;
int ninput = VIPS_AREA( vipsgmic->in )->n;
const int tile_border = gmic_get_tile_border( vipsgmic );
@ -185,7 +171,7 @@ _gmic_gen( VipsRegion *oreg, void *seq, void *a, void *b, gboolean *stop )
gmic_list<T> images; // List of images, will contain all images pixel data.
gmic_list<char> images_names; // List of images names. Can be left empty if no names are associated to images.
try {
images.assign( (unsigned int)vipsgmic->ninput );
images.assign( (unsigned int)ninput );
for( int i = 0; ir[i]; i++ ) {
gmic_image<T>& img = images._data[i];
img.assign(need->width,need->height,1,ir[i]->im->Bands);
@ -193,7 +179,7 @@ _gmic_gen( VipsRegion *oreg, void *seq, void *a, void *b, gboolean *stop )
}
printf("G'MIC command: %s\n",vipsgmic->command);
std::cout<<" ninput="<<vipsgmic->ninput
std::cout<<" ninput="<<ninput
<<std::endl;
std::cout<<" padding="<<vipsgmic->padding
<<" x scale="<<vipsgmic->x_scale<<std::endl;
@ -265,34 +251,27 @@ static int _gmic_build( VipsObject *object )
VipsObjectClass *klass = VIPS_OBJECT_GET_CLASS( object );
//VipsOperation *operation = VIPS_OPERATION( object );
VipsGMic *vipsgmic = (VipsGMic *) object;
VipsImage **in;
int ninput;
int i;
if( vipsgmic->ninput < 1 ) return -1;
if( !(vipsgmic->in[0]) ) return -1;
if( VIPS_OBJECT_CLASS( vips_gmic_parent_class )->build( object ) )
return( -1 );
for( i = 0; i < vipsgmic->ninput; i++ ) {
if( vips_image_pio_input( vipsgmic->in[i] ) ||
vips_check_coding_known( klass->nickname, vipsgmic->in[i] ) )
in = vips_array_image_get( vipsgmic->in, &ninput );
for( i = 0; i < ninput; i++ ) {
if( vips_image_pio_input( in[i] ) ||
vips_check_coding_known( klass->nickname, in[i] ) )
return( -1 );
}
/* Get ready to write to @out. @out must be set via g_object_set() so
* that vips can see the assignment. It'll complain that @out hasn't
* been set otherwise.
*/
g_object_set( vipsgmic, "out", vips_image_new(), NULL );
VipsImage** in = (VipsImage**)im_malloc( vipsgmic->out, sizeof(VipsImage*)*(vipsgmic->ninput+1) );
if( !in ) return( -1 );
for( i = 0; i < vipsgmic->ninput; i++ ) {
in[i] = vipsgmic->in[i];
}
in[vipsgmic->ninput] = NULL;
/* Set demand hints.
*/
if( vips_image_pipeline_array( vipsgmic->out,
@ -300,18 +279,13 @@ static int _gmic_build( VipsObject *object )
in ) )
return( -1 );
vips_image_init_fields( vipsgmic->out,
in[0]->Xsize, in[0]->Ysize,
in[0]->Bands, in[0]->BandFmt,
in[0]->Coding, in[0]->Type,
1.0, 1.0);
if(vipsgmic->ninput > 0) {
if(ninput > 0) {
if( vips_image_generate( vipsgmic->out,
vips_start_many, gmic_gen, vips_stop_many,
in, vipsgmic ) )
return( -1 );
} else {
}
else {
if( vips_image_generate( vipsgmic->out,
NULL, gmic_gen, NULL, NULL, vipsgmic ) )
return( -1 );
@ -327,6 +301,7 @@ vips_gmic_class_init( VipsGMicClass *klass )
GObjectClass *gobject_class = G_OBJECT_CLASS( klass );
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( klass );
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( klass );
gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property;
vobject_class->nickname = "gmic";
@ -334,12 +309,12 @@ vips_gmic_class_init( VipsGMicClass *klass )
vobject_class->build = _gmic_build;
operation_class->flags = VIPS_OPERATION_SEQUENTIAL_UNBUFFERED;
VIPS_ARG_INT( klass, "ninput", 0,
_( "NInput" ),
_( "Number of input images" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsGMic, ninput ),
0, GMIC_MAX_INPUT_IMAGES, 0 );
VIPS_ARG_BOXED( klass, "in", 0,
_( "Input" ),
_( "Array of input images" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsGMic, in ),
VIPS_TYPE_ARRAY_IMAGE );
VIPS_ARG_IMAGE( klass, "out", 1,
_( "Output" ),
@ -374,37 +349,27 @@ vips_gmic_class_init( VipsGMicClass *klass )
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsGMic, command ),
NULL );
char tstr[100];
char tstr2[100];
char tstr3[100];
for( int imgid = 0; imgid < GMIC_MAX_INPUT_IMAGES; imgid++ ) {
snprintf(tstr,99,"in%d",imgid);
snprintf(tstr2,99,"Input%d",imgid);
snprintf(tstr3,99,"Input image %d",imgid);
VIPS_ARG_IMAGE( klass, tstr, imgid+11,
_( tstr2 ),
_( tstr3 ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsGMic, in )+sizeof(VipsImage*)*imgid );
}
}
static void
vips_gmic_init( VipsGMic *vipsgmic )
{
}
int
vips_gmic(int n, VipsImage** out, const char* command, int padding, float x_scale, float y_scale,...)
vips_gmic( VipsImage **in, VipsImage **out, int n,
int padding, double x_scale, double y_scale, const char *command, ...)
{
va_list ap;
int result;
va_start( ap, y_scale );
//result = vips_call_split( "vips_gmic", ap, n, out, command, padding, x_scale, y_scale );
result = vips_call_split( "gmic", ap, n, out, padding, x_scale, y_scale, command );
va_end( ap );
return( result );
VipsArrayImage *array;
va_list ap;
int result;
array = vips_array_image_new( in, n );
va_start( ap, command );
result = vips_call_split( "gmic", ap, array, out,
padding, x_scale, y_scale, command );
va_end( ap );
vips_area_unref( VIPS_AREA( array ) );
return( result );
}

View File

@ -130,8 +130,7 @@ vips_bandjoin_build( VipsObject *object )
VipsBandjoin *bandjoin = (VipsBandjoin *) object;
if( bandjoin->in ) {
bandary->in = VIPS_AREA( bandjoin->in )->data;
bandary->n = VIPS_AREA( bandjoin->in )->n;
bandary->in = vips_array_image_get( bandjoin->in, &bandary->n );
if( bandary->n == 1 )
return( vips_bandary_copy( bandary ) );

View File

@ -463,13 +463,13 @@ gboolean vips_band_format_iscomplex( VipsBandFormat format );
int vips_system( const char *cmd_format, ... )
__attribute__((sentinel));
/* Defined in type.c, but declared here since they use VipsImage.
/* Defined in type.c but declared here, since they use VipsImage.
*/
VipsArrayImage *vips_array_image_new( VipsImage **array, int n );
VipsArrayImage *vips_array_image_newv( int n, ... );
VipsImage **vips_array_image_get( VipsArrayImage *array, int *n );
VipsImage **vips_value_get_array_image( const GValue *value, int *n );
int vips_value_set_array_image( GValue *value, VipsImage **array, int n );
void vips_value_set_array_image( GValue *value, int n );
#ifdef __cplusplus
}

View File

@ -210,7 +210,7 @@ void vips_value_set_save_stringf( GValue *value, const char *fmt, ... )
__attribute__((format(printf, 2, 3)));
const char *vips_value_get_ref_string( const GValue *value, size_t *length );
int vips_value_set_ref_string( GValue *value, const char *str );
void vips_value_set_ref_string( GValue *value, const char *str );
void *vips_value_get_blob( const GValue *value, size_t *length );
void vips_value_set_blob( GValue *value,
@ -222,13 +222,13 @@ void *vips_value_get_array( const GValue *value,
int *n, GType *type, size_t *sizeof_type );
double *vips_value_get_array_double( const GValue *value, int *n );
int vips_value_set_array_double( GValue *value, const double *array, int n );
void vips_value_set_array_double( GValue *value, const double *array, int n );
int *vips_value_get_array_int( const GValue *value, int *n );
int vips_value_set_array_int( GValue *value, const int *array, int n );
void vips_value_set_array_int( GValue *value, const int *array, int n );
GObject **vips_value_get_array_object( const GValue *value, int *n );
int vips_value_set_array_object( GValue *value, int n );
void vips_value_set_array_object( GValue *value, int n );
/* See also image.h, that has vips_array_image_get(), vips_array_image_new(),
* vips_value_get_array_image() and vips_value_set_array_image(). They need

View File

@ -285,6 +285,8 @@ vips_init( const char *argv0 )
vips_morphology_operation_init();
vips_draw_operation_init();
vips_mosaicing_operation_init();
extern int vips_gmic_get_type( void );
vips_gmic_get_type();
/* Load up any plugins in the vips libdir. We don't error on failure,

View File

@ -322,6 +322,9 @@ vips_area_free_array_object( GObject **array, VipsArea *area )
* An area which holds an array of %GObjects. See vips_area_new_array(). When
* the area is freed, each %GObject will be unreffed.
*
* Add an extra NULL element at the end, handy for eg.
* vips_image_pipeline_array() etc.
*
* See also: vips_area_unref().
*
* Returns: (transfer full): the new #VipsArea.
@ -332,7 +335,7 @@ vips_area_new_array_object( int n )
GObject **array;
VipsArea *area;
array = g_new0( GObject *, n );
array = g_new0( GObject *, n + 1 );
area = vips_area_new( (VipsCallbackFn) vips_area_free_array_object,
array );
area->n = n;
@ -962,7 +965,7 @@ transform_g_string_array_image( const GValue *src_value, GValue *dest_value )
int n;
char *p, *q;
int i;
GObject **array;
VipsImage **array;
/* We need a copy of the string, since we insert \0 during
* scan.
@ -975,17 +978,16 @@ transform_g_string_array_image( const GValue *src_value, GValue *dest_value )
g_free( str );
vips_value_set_array_object( dest_value, n );
array = vips_value_get_array_object( dest_value, NULL );
vips_value_set_array_image( dest_value, n );
array = vips_value_get_array_image( dest_value, NULL );
str = g_value_dup_string( src_value );
for( i = 0, p = str; (q = vips_break_token( p, " " )); i++, p = q )
if( !(array[i] = G_OBJECT( vips_image_new_from_file( p,
NULL ) )) ) {
if( !(array[i] = vips_image_new_from_file( p, NULL )) ) {
/* Set the dest to length zero to indicate error.
*/
vips_value_set_array_object( dest_value, 0 );
vips_value_set_array_image( dest_value, 0 );
g_free( str );
return;
}
@ -1005,6 +1007,9 @@ transform_g_string_array_image( const GValue *src_value, GValue *dest_value )
* will be automatically unreffed for you by
* vips_area_unref().
*
* Add an extra NULL element at the end, handy for eg.
* vips_image_pipeline_array() etc.
*
* See also: #VipsArea.
*
* Returns: (transfer full): A new #VipsArrayImage.
@ -1040,6 +1045,9 @@ vips_array_image_new( VipsImage **array, int n )
* will be automatically unreffed for you by
* vips_area_unref().
*
* Add an extra NULL element at the end, handy for eg.
* vips_image_pipeline_array() etc.
*
* See also: vips_array_image_new()
*
* Returns: (transfer full): A new #VipsArrayImage.
@ -1219,10 +1227,8 @@ vips_value_get_ref_string( const GValue *value, size_t *length )
* vips_ref_string are immutable C strings that are copied between images by
* copying reference-counted pointers, making the much more efficient than
* regular %GValue strings.
*
* Returns: 0 on success, -1 otherwise.
*/
int
void
vips_value_set_ref_string( GValue *value, const char *str )
{
VipsArea *area;
@ -1239,8 +1245,6 @@ vips_value_set_ref_string( GValue *value, const char *str )
g_value_set_boxed( value, area );
vips_area_unref( area );
return( 0 );
}
/**
@ -1380,10 +1384,8 @@ vips_value_get_array_int( const GValue *value, int *n )
* Set @value to hold a copy of @array. Pass in the array length in @n.
*
* See also: vips_array_int_get().
*
* Returns: 0 on success, -1 otherwise.
*/
int
void
vips_value_set_array_int( GValue *value, const int *array, int n )
{
int *array_copy;
@ -1392,8 +1394,6 @@ vips_value_set_array_int( GValue *value, const int *array, int n )
vips_value_set_array( value, n, G_TYPE_INT, sizeof( int ) );
array_copy = vips_value_get_array_int( value, NULL );
memcpy( array_copy, array, n * sizeof( int ) );
return( 0 );
}
/**
@ -1423,10 +1423,8 @@ vips_value_get_array_double( const GValue *value, int *n )
* Set @value to hold a copy of @array. Pass in the array length in @n.
*
* See also: vips_array_double_get().
*
* Returns: 0 on success, -1 otherwise.
*/
int
void
vips_value_set_array_double( GValue *value, const double *array, int n )
{
double *array_copy;
@ -1435,8 +1433,6 @@ vips_value_set_array_double( GValue *value, const double *array, int n )
vips_value_set_array( value, n, G_TYPE_DOUBLE, sizeof( double ) );
array_copy = vips_value_get_array_double( value, NULL );
memcpy( array_copy, array, n * sizeof( double ) );
return( 0 );
}
/**
@ -1460,27 +1456,21 @@ vips_value_get_array_image( const GValue *value, int *n )
/**
* vips_value_set_array_image:
* @value: (out): %GValue to get from
* @array: (array length=n): array of images
* @n: the number of elements
*
* Set @value to hold a copy of @array. Pass in the array length in @n.
*
* See also: vips_array_image_get().
*
* Returns: 0 on success, -1 otherwise.
*/
int
vips_value_set_array_image( GValue *value, VipsImage **array, int n )
void
vips_value_set_array_image( GValue *value, int n )
{
VipsImage **array_copy;
VipsArea *area;
g_value_init( value, VIPS_TYPE_ARRAY_IMAGE );
vips_value_set_array( value, n, VIPS_TYPE_ARRAY_IMAGE,
sizeof( VipsImage * ) );
array_copy = vips_value_get_array_image( value, NULL );
memcpy( array_copy, array, n * sizeof( VipsImage * ) );
return( 0 );
area = vips_area_new_array_object( n );
area->type = VIPS_TYPE_IMAGE;
g_value_set_boxed( value, area );
vips_area_unref( area );
}
/**
@ -1502,27 +1492,22 @@ vips_value_get_array_object( const GValue *value, int *n )
}
/**
* vips_array_object_set:
* vips_value_set_array_object:
* @value: (out): %GValue to set
* @n: the number of elements
*
* Set @value to hold an array of %GObject. Pass in the array length in @n.
*
* See also: vips_array_object_get().
*
* Returns: 0 on success, -1 otherwise.
*/
int
void
vips_value_set_array_object( GValue *value, int n )
{
VipsArea *area;
if( !(area = vips_area_new_array_object( n )) )
return( -1 );
area = vips_area_new_array_object( n );
g_value_set_boxed( value, area );
vips_area_unref( area );
return( 0 );
}
/* Make the types we need for basic functioning. Called from vips_init().