revise matrixload for source API
This commit is contained in:
parent
d68e02a3c4
commit
ce240b1ca2
@ -5,7 +5,7 @@
|
|||||||
- allow \ as an escape character in vips_break_token() [akemrir]
|
- allow \ as an escape character in vips_break_token() [akemrir]
|
||||||
- tiffsave has a "depth" param to set max pyr depth
|
- tiffsave has a "depth" param to set max pyr depth
|
||||||
- libtiff LOGLUV images load and save as libvips XYZ
|
- libtiff LOGLUV images load and save as libvips XYZ
|
||||||
- add gifload_source, csvload_source, csvsave_target
|
- add gifload_source, csvload_source, csvsave_target, matrixload_source
|
||||||
- revise vipsthumbnail flags
|
- revise vipsthumbnail flags
|
||||||
- add VIPS_LEAK env var
|
- add VIPS_LEAK env var
|
||||||
- add vips_pipe_read_limit_set(), --vips-pipe-read-limit,
|
- add vips_pipe_read_limit_set(), --vips-pipe-read-limit,
|
||||||
|
@ -89,7 +89,7 @@ typedef struct _VipsForeignLoadCsv {
|
|||||||
* a double.
|
* a double.
|
||||||
*/
|
*/
|
||||||
char item[MAX_ITEM_SIZE];
|
char item[MAX_ITEM_SIZE];
|
||||||
|
|
||||||
/* A line of pixels.
|
/* A line of pixels.
|
||||||
*/
|
*/
|
||||||
double *linebuf;
|
double *linebuf;
|
||||||
@ -295,8 +295,8 @@ vips_foreign_load_csv_read_double( VipsForeignLoadCsv *csv, double *out )
|
|||||||
item = vips_foreign_load_csv_fetch_item( csv );
|
item = vips_foreign_load_csv_fetch_item( csv );
|
||||||
if( !item )
|
if( !item )
|
||||||
return( EOF );
|
return( EOF );
|
||||||
*out = g_ascii_strtod( item, NULL );
|
|
||||||
if( errno )
|
if( vips_strtod( item, out ) )
|
||||||
/* Only a warning, since (for example) exported
|
/* Only a warning, since (for example) exported
|
||||||
* spreadsheets will often have text or date fields.
|
* spreadsheets will often have text or date fields.
|
||||||
*/
|
*/
|
||||||
|
@ -2039,7 +2039,8 @@ vips_foreign_operation_init( void )
|
|||||||
extern GType vips_foreign_save_csv_file_get_type( void );
|
extern GType vips_foreign_save_csv_file_get_type( void );
|
||||||
extern GType vips_foreign_save_csv_target_get_type( void );
|
extern GType vips_foreign_save_csv_target_get_type( void );
|
||||||
|
|
||||||
extern GType vips_foreign_load_matrix_get_type( void );
|
extern GType vips_foreign_load_matrix_file_get_type( void );
|
||||||
|
extern GType vips_foreign_load_matrix_source_get_type( void );
|
||||||
extern GType vips_foreign_save_matrix_get_type( void );
|
extern GType vips_foreign_save_matrix_get_type( void );
|
||||||
extern GType vips_foreign_print_matrix_get_type( void );
|
extern GType vips_foreign_print_matrix_get_type( void );
|
||||||
|
|
||||||
@ -2115,7 +2116,8 @@ vips_foreign_operation_init( void )
|
|||||||
vips_foreign_load_csv_source_get_type();
|
vips_foreign_load_csv_source_get_type();
|
||||||
vips_foreign_save_csv_file_get_type();
|
vips_foreign_save_csv_file_get_type();
|
||||||
vips_foreign_save_csv_target_get_type();
|
vips_foreign_save_csv_target_get_type();
|
||||||
vips_foreign_load_matrix_get_type();
|
vips_foreign_load_matrix_file_get_type();
|
||||||
|
vips_foreign_load_matrix_source_get_type();
|
||||||
vips_foreign_save_matrix_get_type();
|
vips_foreign_save_matrix_get_type();
|
||||||
vips_foreign_print_matrix_get_type();
|
vips_foreign_print_matrix_get_type();
|
||||||
vips_foreign_load_raw_get_type();
|
vips_foreign_load_raw_get_type();
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
*
|
*
|
||||||
* 5/12/11
|
* 5/12/11
|
||||||
* - from csvload.c
|
* - from csvload.c
|
||||||
|
* 22/2/20
|
||||||
|
* - rewrite for source API
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -53,9 +55,17 @@
|
|||||||
typedef struct _VipsForeignLoadMatrix {
|
typedef struct _VipsForeignLoadMatrix {
|
||||||
VipsForeignLoad parent_object;
|
VipsForeignLoad parent_object;
|
||||||
|
|
||||||
/* Filename for load.
|
/* Set by subclasses.
|
||||||
*/
|
*/
|
||||||
char *filename;
|
VipsSource *source;
|
||||||
|
|
||||||
|
/* Buffered source.
|
||||||
|
*/
|
||||||
|
VipsSbuf *sbuf;
|
||||||
|
|
||||||
|
/* A line of pixels.
|
||||||
|
*/
|
||||||
|
double *linebuf;
|
||||||
|
|
||||||
} VipsForeignLoadMatrix;
|
} VipsForeignLoadMatrix;
|
||||||
|
|
||||||
@ -64,18 +74,99 @@ typedef VipsForeignLoadClass VipsForeignLoadMatrixClass;
|
|||||||
G_DEFINE_TYPE( VipsForeignLoadMatrix, vips_foreign_load_matrix,
|
G_DEFINE_TYPE( VipsForeignLoadMatrix, vips_foreign_load_matrix,
|
||||||
VIPS_TYPE_FOREIGN_LOAD );
|
VIPS_TYPE_FOREIGN_LOAD );
|
||||||
|
|
||||||
static VipsForeignFlags
|
static void
|
||||||
vips_foreign_load_matrix_get_flags_filename( const char *filename )
|
vips_foreign_load_matrix_dispose( GObject *gobject )
|
||||||
{
|
{
|
||||||
|
VipsForeignLoadMatrix *matrix = (VipsForeignLoadMatrix *) gobject;
|
||||||
|
|
||||||
|
VIPS_UNREF( matrix->source );
|
||||||
|
VIPS_UNREF( matrix->sbuf );
|
||||||
|
VIPS_FREE( matrix->linebuf );
|
||||||
|
|
||||||
|
G_OBJECT_CLASS( vips_foreign_load_matrix_parent_class )->
|
||||||
|
dispose( gobject );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vips_foreign_load_matrix_build( VipsObject *object )
|
||||||
|
{
|
||||||
|
VipsForeignLoadMatrix *matrix = (VipsForeignLoadMatrix *) object;
|
||||||
|
|
||||||
|
if( !(matrix->sbuf = vips_sbuf_new_from_source( matrix->source )) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
if( VIPS_OBJECT_CLASS( vips_foreign_load_matrix_parent_class )->
|
||||||
|
build( object ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static VipsForeignFlags
|
static VipsForeignFlags
|
||||||
vips_foreign_load_matrix_get_flags( VipsForeignLoad *load )
|
vips_foreign_load_matrix_get_flags( VipsForeignLoad *load )
|
||||||
{
|
{
|
||||||
VipsForeignLoadMatrix *matrix = (VipsForeignLoadMatrix *) load;
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
return( vips_foreign_load_matrix_get_flags_filename( matrix->filename ) );
|
/* Parse a header line. Two numbers for width and height, and two optional
|
||||||
|
* numbers for scale and offset.
|
||||||
|
*
|
||||||
|
* We can have scale and no offset, in which case we assume offset = 0.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
parse_matrix_header( char *line,
|
||||||
|
int *width, int *height, double *scale, double *offset )
|
||||||
|
{
|
||||||
|
double header[4];
|
||||||
|
char *p, *q;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for( i = 0, p = line;
|
||||||
|
(q = vips_break_token( p, " \t" )) &&
|
||||||
|
i < 4;
|
||||||
|
i++, p = q )
|
||||||
|
if( vips_strtod( p, &header[i] ) ) {
|
||||||
|
vips_error( "matload",
|
||||||
|
_( "bad number \"%s\"" ), p );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( i < 4 )
|
||||||
|
header[3] = 0.0;
|
||||||
|
if( i < 3 )
|
||||||
|
header[2] = 1.0;
|
||||||
|
if( i < 2 ) {
|
||||||
|
vips_error( "matload", "%s", _( "no width / height" ) );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( VIPS_FLOOR( header[0] ) != header[0] ||
|
||||||
|
VIPS_FLOOR( header[1] ) != header[1] ) {
|
||||||
|
vips_error( "mask2vips", "%s", _( "width / height not int" ) );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Width / height can be 65536 for a 16-bit LUT, for example.
|
||||||
|
*/
|
||||||
|
*width = header[0];
|
||||||
|
*height = header[1];
|
||||||
|
if( *width <= 0 ||
|
||||||
|
*width > 100000 ||
|
||||||
|
*height <= 0 ||
|
||||||
|
*height > 100000 ) {
|
||||||
|
vips_error( "mask2vips",
|
||||||
|
"%s", _( "width / height out of range" ) );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
if( header[2] == 0.0 ) {
|
||||||
|
vips_error( "mask2vips", "%s", _( "zero scale" ) );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
*scale = header[2];
|
||||||
|
*offset = header[3];
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -83,23 +174,39 @@ vips_foreign_load_matrix_header( VipsForeignLoad *load )
|
|||||||
{
|
{
|
||||||
VipsForeignLoadMatrix *matrix = (VipsForeignLoadMatrix *) load;
|
VipsForeignLoadMatrix *matrix = (VipsForeignLoadMatrix *) load;
|
||||||
|
|
||||||
|
char *line;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
double scale;
|
double scale;
|
||||||
double offset;
|
double offset;
|
||||||
|
int result;
|
||||||
|
|
||||||
if( vips__matrix_read_header( matrix->filename,
|
/* Rewind.
|
||||||
&width, &height, &scale, &offset ) )
|
*/
|
||||||
|
vips_sbuf_unbuffer( matrix->sbuf );
|
||||||
|
if( vips_source_rewind( matrix->source ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
|
line = vips_sbuf_get_line_copy( matrix->sbuf );
|
||||||
|
result = parse_matrix_header( line, &width, &height, &scale, &offset );
|
||||||
|
g_free( line );
|
||||||
|
if( result )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
vips_image_pipelinev( load->out, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
|
||||||
vips_image_init_fields( load->out,
|
vips_image_init_fields( load->out,
|
||||||
width, height, 1,
|
width, height, 1,
|
||||||
VIPS_FORMAT_DOUBLE,
|
VIPS_FORMAT_DOUBLE,
|
||||||
VIPS_CODING_NONE, VIPS_INTERPRETATION_B_W, 1.0, 1.0 );
|
VIPS_CODING_NONE, VIPS_INTERPRETATION_B_W, 1.0, 1.0 );
|
||||||
|
|
||||||
vips_image_set_double( load->out, "scale", scale );
|
vips_image_set_double( load->out, "scale", scale );
|
||||||
vips_image_set_double( load->out, "offset", offset );
|
vips_image_set_double( load->out, "offset", offset );
|
||||||
|
|
||||||
VIPS_SETSTR( load->out->filename, matrix->filename );
|
VIPS_SETSTR( load->out->filename,
|
||||||
|
vips_connection_filename( VIPS_CONNECTION( matrix->source ) ) );
|
||||||
|
|
||||||
|
if( !(matrix->linebuf = VIPS_ARRAY( NULL, width, double )) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
@ -108,22 +215,142 @@ static int
|
|||||||
vips_foreign_load_matrix_load( VipsForeignLoad *load )
|
vips_foreign_load_matrix_load( VipsForeignLoad *load )
|
||||||
{
|
{
|
||||||
VipsForeignLoadMatrix *matrix = (VipsForeignLoadMatrix *) load;
|
VipsForeignLoadMatrix *matrix = (VipsForeignLoadMatrix *) load;
|
||||||
|
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( load );
|
||||||
|
|
||||||
VipsImage *out;
|
int x, y;
|
||||||
|
|
||||||
if( !(out = vips__matrix_read( matrix->filename )) )
|
vips_image_pipelinev( load->real, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
|
||||||
return( -1 );
|
vips_image_init_fields( load->real,
|
||||||
if( vips_image_write( out, load->real ) ) {
|
load->out->Xsize, load->out->Ysize, 1,
|
||||||
g_object_unref( out );
|
VIPS_FORMAT_DOUBLE,
|
||||||
return( -1 );
|
VIPS_CODING_NONE, VIPS_INTERPRETATION_B_W, 1.0, 1.0 );
|
||||||
|
|
||||||
|
for( y = 0; y < load->real->Ysize; y++ ) {
|
||||||
|
char *line;
|
||||||
|
char *p, *q;
|
||||||
|
|
||||||
|
line = vips_sbuf_get_line_copy( matrix->sbuf );
|
||||||
|
|
||||||
|
for( x = 0, p = line;
|
||||||
|
(q = vips_break_token( p, " \t" )) &&
|
||||||
|
x < load->out->Xsize;
|
||||||
|
x++, p = q )
|
||||||
|
if( vips_strtod( p, &matrix->linebuf[x] ) ) {
|
||||||
|
g_free( line );
|
||||||
|
vips_error( class->nickname,
|
||||||
|
_( "bad number \"%s\"" ), p );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free( line );
|
||||||
|
|
||||||
|
if( x != load->out->Xsize ) {
|
||||||
|
vips_error( class->nickname,
|
||||||
|
_( "line %d too short" ), y );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( vips_image_write_line( load->real, y,
|
||||||
|
(VipsPel *) matrix->linebuf ) )
|
||||||
|
return( -1 );
|
||||||
}
|
}
|
||||||
g_object_unref( out );
|
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vips_foreign_load_matrix_class_init( VipsForeignLoadMatrixClass *class )
|
vips_foreign_load_matrix_class_init( VipsForeignLoadMatrixClass *class )
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||||
|
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||||
|
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||||
|
|
||||||
|
gobject_class->dispose = vips_foreign_load_matrix_dispose;
|
||||||
|
|
||||||
|
object_class->nickname = "matrixload_base";
|
||||||
|
object_class->description = _( "load matrix" );
|
||||||
|
object_class->build = vips_foreign_load_matrix_build;
|
||||||
|
|
||||||
|
load_class->get_flags = vips_foreign_load_matrix_get_flags;
|
||||||
|
load_class->header = vips_foreign_load_matrix_header;
|
||||||
|
load_class->load = vips_foreign_load_matrix_load;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_foreign_load_matrix_init( VipsForeignLoadMatrix *matrix )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _VipsForeignLoadMatrixFile {
|
||||||
|
VipsForeignLoadMatrix parent_object;
|
||||||
|
|
||||||
|
/* Filename for load.
|
||||||
|
*/
|
||||||
|
char *filename;
|
||||||
|
|
||||||
|
} VipsForeignLoadMatrixFile;
|
||||||
|
|
||||||
|
typedef VipsForeignLoadMatrixClass VipsForeignLoadMatrixFileClass;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE( VipsForeignLoadMatrixFile, vips_foreign_load_matrix_file,
|
||||||
|
vips_foreign_load_matrix_get_type() );
|
||||||
|
|
||||||
|
static VipsForeignFlags
|
||||||
|
vips_foreign_load_matrix_file_get_flags_filename( const char *filename )
|
||||||
|
{
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vips_foreign_load_matrix_file_build( VipsObject *object )
|
||||||
|
{
|
||||||
|
VipsForeignLoadMatrixFile *file = (VipsForeignLoadMatrixFile *) object;
|
||||||
|
VipsForeignLoadMatrix *matrix = (VipsForeignLoadMatrix *) object;
|
||||||
|
|
||||||
|
if( file->filename )
|
||||||
|
if( !(matrix->source =
|
||||||
|
vips_source_new_from_file( file->filename )) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
if( VIPS_OBJECT_CLASS( vips_foreign_load_matrix_file_parent_class )->
|
||||||
|
build( object ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *vips_foreign_load_matrix_suffs[] = {
|
||||||
|
".mat",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
vips_foreign_load_matrix_file_is_a( const char *filename )
|
||||||
|
{
|
||||||
|
unsigned char line[80];
|
||||||
|
guint64 bytes;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
double scale;
|
||||||
|
double offset;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if( (bytes = vips__get_bytes( filename, line, 79 )) <= 0 )
|
||||||
|
return( FALSE );
|
||||||
|
line[bytes] = '\0';
|
||||||
|
|
||||||
|
vips_error_freeze();
|
||||||
|
result = parse_matrix_header( (char *) line,
|
||||||
|
&width, &height, &scale, &offset );
|
||||||
|
vips_error_thaw();
|
||||||
|
|
||||||
|
return( result == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_foreign_load_matrix_file_class_init(
|
||||||
|
VipsForeignLoadMatrixFileClass *class )
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||||
@ -134,31 +361,111 @@ vips_foreign_load_matrix_class_init( VipsForeignLoadMatrixClass *class )
|
|||||||
gobject_class->get_property = vips_object_get_property;
|
gobject_class->get_property = vips_object_get_property;
|
||||||
|
|
||||||
object_class->nickname = "matrixload";
|
object_class->nickname = "matrixload";
|
||||||
object_class->description = _( "load matrix from file" );
|
object_class->build = vips_foreign_load_matrix_file_build;
|
||||||
|
|
||||||
foreign_class->suffs = vips__foreign_matrix_suffs;
|
foreign_class->suffs = vips_foreign_load_matrix_suffs;
|
||||||
|
|
||||||
/* is_a() is not that quick ... lower the priority.
|
load_class->is_a = vips_foreign_load_matrix_file_is_a;
|
||||||
*/
|
|
||||||
foreign_class->priority = -50;
|
|
||||||
|
|
||||||
load_class->is_a = vips__matrix_ismatrix;
|
|
||||||
load_class->get_flags_filename =
|
load_class->get_flags_filename =
|
||||||
vips_foreign_load_matrix_get_flags_filename;
|
vips_foreign_load_matrix_file_get_flags_filename;
|
||||||
load_class->get_flags = vips_foreign_load_matrix_get_flags;
|
|
||||||
load_class->header = vips_foreign_load_matrix_header;
|
|
||||||
load_class->load = vips_foreign_load_matrix_load;
|
|
||||||
|
|
||||||
VIPS_ARG_STRING( class, "filename", 1,
|
VIPS_ARG_STRING( class, "filename", 1,
|
||||||
_( "Filename" ),
|
_( "Filename" ),
|
||||||
_( "Filename to load from" ),
|
_( "Filename to load from" ),
|
||||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
G_STRUCT_OFFSET( VipsForeignLoadMatrix, filename ),
|
G_STRUCT_OFFSET( VipsForeignLoadMatrixFile, filename ),
|
||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vips_foreign_load_matrix_init( VipsForeignLoadMatrix *matrix )
|
vips_foreign_load_matrix_file_init( VipsForeignLoadMatrixFile *file )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _VipsForeignLoadMatrixSource {
|
||||||
|
VipsForeignLoadMatrix parent_object;
|
||||||
|
|
||||||
|
VipsSource *source;
|
||||||
|
|
||||||
|
} VipsForeignLoadMatrixSource;
|
||||||
|
|
||||||
|
typedef VipsForeignLoadMatrixClass VipsForeignLoadMatrixSourceClass;
|
||||||
|
|
||||||
|
G_DEFINE_TYPE( VipsForeignLoadMatrixSource, vips_foreign_load_matrix_source,
|
||||||
|
vips_foreign_load_matrix_get_type() );
|
||||||
|
|
||||||
|
static int
|
||||||
|
vips_foreign_load_matrix_source_build( VipsObject *object )
|
||||||
|
{
|
||||||
|
VipsForeignLoadMatrixSource *source =
|
||||||
|
(VipsForeignLoadMatrixSource *) object;
|
||||||
|
VipsForeignLoadMatrix *matrix = (VipsForeignLoadMatrix *) object;
|
||||||
|
|
||||||
|
if( matrix->source ) {
|
||||||
|
matrix->source = source->source;
|
||||||
|
g_object_ref( matrix->source );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( VIPS_OBJECT_CLASS( vips_foreign_load_matrix_source_parent_class )->
|
||||||
|
build( object ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vips_foreign_load_matrix_source_is_a_source( VipsSource *source )
|
||||||
|
{
|
||||||
|
unsigned char *data;
|
||||||
|
size_t bytes_read;
|
||||||
|
char line[80];
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
double scale;
|
||||||
|
double offset;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if( (bytes_read = vips_source_sniff_at_most( source,
|
||||||
|
&data, 79 )) <= 0 )
|
||||||
|
return( FALSE );
|
||||||
|
vips_strncpy( line, (const char *) data, 80 );
|
||||||
|
|
||||||
|
vips_error_freeze();
|
||||||
|
result = parse_matrix_header( line,
|
||||||
|
&width, &height, &scale, &offset );
|
||||||
|
vips_error_thaw();
|
||||||
|
|
||||||
|
return( result == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_foreign_load_matrix_source_class_init(
|
||||||
|
VipsForeignLoadMatrixFileClass *class )
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||||
|
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||||
|
VipsForeignLoadClass *load_class = (VipsForeignLoadClass *) class;
|
||||||
|
|
||||||
|
gobject_class->set_property = vips_object_set_property;
|
||||||
|
gobject_class->get_property = vips_object_get_property;
|
||||||
|
|
||||||
|
object_class->nickname = "matrixload_source";
|
||||||
|
object_class->build = vips_foreign_load_matrix_source_build;
|
||||||
|
|
||||||
|
load_class->is_a_source = vips_foreign_load_matrix_source_is_a_source;
|
||||||
|
|
||||||
|
VIPS_ARG_OBJECT( class, "source", 1,
|
||||||
|
_( "Source" ),
|
||||||
|
_( "Source to load from" ),
|
||||||
|
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||||
|
G_STRUCT_OFFSET( VipsForeignLoadMatrixSource, source ),
|
||||||
|
VIPS_TYPE_SOURCE );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_foreign_load_matrix_source_init( VipsForeignLoadMatrixSource *source )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +497,7 @@ vips_foreign_load_matrix_init( VipsForeignLoadMatrix *matrix )
|
|||||||
* Extra characters at the ends of lines or at the end of the file are
|
* Extra characters at the ends of lines or at the end of the file are
|
||||||
* ignored.
|
* ignored.
|
||||||
*
|
*
|
||||||
* See also: vips_csvload().
|
* See also: vips_matrixload().
|
||||||
*
|
*
|
||||||
* Returns: 0 on success, -1 on error.
|
* Returns: 0 on success, -1 on error.
|
||||||
*/
|
*/
|
||||||
@ -207,3 +514,28 @@ vips_matrixload( const char *filename, VipsImage **out, ... )
|
|||||||
return( result );
|
return( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vips_matrixload_source:
|
||||||
|
* @source: source to load
|
||||||
|
* @out: (out): output image
|
||||||
|
* @...: %NULL-terminated list of optional named arguments
|
||||||
|
*
|
||||||
|
* Exactly as vips_matrixload(), but read from a source.
|
||||||
|
*
|
||||||
|
* See also: vips_matrixload().
|
||||||
|
*
|
||||||
|
* Returns: 0 on success, -1 on error.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
vips_matrixload_source( VipsSource *source, VipsImage **out, ... )
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
va_start( ap, out );
|
||||||
|
result = vips_call_split( "matrixload_source", ap, source, out );
|
||||||
|
va_end( ap );
|
||||||
|
|
||||||
|
return( result );
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -533,6 +533,8 @@ int vips_csvsave_target( VipsImage *in, VipsTarget *target, ... )
|
|||||||
|
|
||||||
int vips_matrixload( const char *filename, VipsImage **out, ... )
|
int vips_matrixload( const char *filename, VipsImage **out, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
|
int vips_matrixload_source( VipsSource *source, VipsImage **out, ... )
|
||||||
|
__attribute__((sentinel));
|
||||||
int vips_matrixsave( VipsImage *in, const char *filename, ... )
|
int vips_matrixsave( VipsImage *in, const char *filename, ... )
|
||||||
__attribute__((sentinel));
|
__attribute__((sentinel));
|
||||||
int vips_matrixprint( VipsImage *in, ... )
|
int vips_matrixprint( VipsImage *in, ... )
|
||||||
|
@ -346,6 +346,8 @@ const char *vips__windows_prefix( void );
|
|||||||
|
|
||||||
char *vips__get_iso8601( void );
|
char *vips__get_iso8601( void );
|
||||||
|
|
||||||
|
int vips_strtod( const char *str, double *out );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /*__cplusplus*/
|
#endif /*__cplusplus*/
|
||||||
|
@ -2066,3 +2066,33 @@ vips__get_iso8601( void )
|
|||||||
|
|
||||||
return( date );
|
return( date );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convert a string to a double in the ASCII locale (ie. decimal point is
|
||||||
|
* ".").
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
vips_strtod( const char *str, double *out )
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
*out = 0;
|
||||||
|
|
||||||
|
/* The str we fetched must contain at least 1 digit. This
|
||||||
|
* helps stop us trying to convert "MATLAB" (for example) to
|
||||||
|
* a number and getting zero.
|
||||||
|
*/
|
||||||
|
for( p = str; *p; p++ )
|
||||||
|
if( isdigit( *p ) )
|
||||||
|
break;
|
||||||
|
if( !*p )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
/* This will fail for out of range numbers, like 1e343434, but
|
||||||
|
* is quite happy with eg. "banana".
|
||||||
|
*/
|
||||||
|
*out = g_ascii_strtod( str, NULL );
|
||||||
|
if( errno )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user