gmic uses an imagevec for input images
This commit is contained in:
parent
ae7d81d748
commit
3788c85e54
@ -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
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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 ) );
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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().
|
||||
|
Loading…
Reference in New Issue
Block a user