fix up new-style analyze load
This commit is contained in:
parent
03069261bb
commit
25e42d1625
@ -14,7 +14,7 @@
|
||||
im_pow*(), im_exp*(), im_ifthenelse(), im_blend(), im_c2amph(), im_c2rect(),
|
||||
im_bandmean(), im_c2real(), im_c2imag(), im_ri2c(), im_jpeg*2vips(),
|
||||
im_vips2jpeg*(), im_tiff2vips(), im_vips2tiff(), im_exr2vips(),
|
||||
im_fits2vips(), im_vips2fits()
|
||||
im_fits2vips(), im_vips2fits(), im_analyze2vips()
|
||||
redone as classes
|
||||
- added argument priorites to help control arg ordering
|
||||
- generate has a 'stop' param to signal successful early termination
|
||||
|
2
TODO
2
TODO
@ -1,5 +1,7 @@
|
||||
- suppression for the strspn() thing?
|
||||
|
||||
- test analyze load
|
||||
|
||||
|
||||
|
||||
- "header fred.png" does not work, since header uses im_open() which uses
|
||||
|
@ -186,7 +186,6 @@ vips_join_build( VipsObject *object )
|
||||
t = t2;
|
||||
}
|
||||
|
||||
|
||||
if( vips_image_write( t, conversion->out ) ) {
|
||||
g_object_unref( t );
|
||||
return( -1 );
|
||||
|
@ -3,6 +3,9 @@ noinst_LTLIBRARIES = libforeign.la
|
||||
libforeign_la_SOURCES = \
|
||||
vipssave.c \
|
||||
vipsload.c \
|
||||
analyzeload.c \
|
||||
analyze2vips.c \
|
||||
analyze2vips.h \
|
||||
foreign.c
|
||||
|
||||
EXTRA_DIST =
|
||||
|
@ -41,8 +41,8 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
#define DEBUG
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
@ -58,6 +58,7 @@
|
||||
#include <vips/internal.h>
|
||||
|
||||
#include "dbh.h"
|
||||
#include "analyze2vips.h"
|
||||
|
||||
/* The things we can have in header fields. Can't use GType, since we want a
|
||||
* static value we can use in a declaration.
|
||||
@ -219,13 +220,10 @@ static Field dsr_header[] = {
|
||||
static void
|
||||
generate_filenames( const char *path, char *header, char *image )
|
||||
{
|
||||
char name[FILENAME_MAX];
|
||||
char mode[FILENAME_MAX];
|
||||
|
||||
const char *olds[] = { ".img", ".hdr" };
|
||||
|
||||
vips__change_suffix( name, header, FILENAME_MAX, ".hdr", olds, 2 );
|
||||
vips__change_suffix( name, image, FILENAME_MAX, ".img", olds, 2 );
|
||||
vips__change_suffix( path, header, FILENAME_MAX, ".hdr", olds, 2 );
|
||||
vips__change_suffix( path, image, FILENAME_MAX, ".img", olds, 2 );
|
||||
}
|
||||
|
||||
/* str is a str which may not be NULL-terminated. Return a pointer to a static
|
||||
@ -318,7 +316,7 @@ read_header( const char *header )
|
||||
/* dsr headers are always SPARC byte order (MSB first). Do we need to
|
||||
* swap?
|
||||
*/
|
||||
if( !im_amiMSBfirst() ) {
|
||||
if( !vips_amiMSBfirst() ) {
|
||||
int i;
|
||||
|
||||
for( i = 0; i < VIPS_NUMBER( dsr_header ); i++ ) {
|
||||
@ -350,7 +348,7 @@ read_header( const char *header )
|
||||
}
|
||||
|
||||
if( (int) len != d->hk.sizeof_hdr ) {
|
||||
im_free( d );
|
||||
vips_free( d );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
@ -361,7 +359,7 @@ read_header( const char *header )
|
||||
*/
|
||||
static int
|
||||
get_vips_properties( struct dsr *d,
|
||||
int *width, int *height, int *bands, int *fmt )
|
||||
int *width, int *height, int *bands, VipsBandFormat *fmt )
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -385,37 +383,37 @@ get_vips_properties( struct dsr *d,
|
||||
switch( d->dime.datatype ) {
|
||||
case DT_UNSIGNED_CHAR:
|
||||
*bands = 1;
|
||||
*fmt = IM_BANDFMT_UCHAR;
|
||||
*fmt = VIPS_FORMAT_UCHAR;
|
||||
break;
|
||||
|
||||
case DT_SIGNED_SHORT:
|
||||
*bands = 1;
|
||||
*fmt = IM_BANDFMT_SHORT;
|
||||
*fmt = VIPS_FORMAT_SHORT;
|
||||
break;
|
||||
|
||||
case DT_SIGNED_INT:
|
||||
*bands = 1;
|
||||
*fmt = IM_BANDFMT_INT;
|
||||
*fmt = VIPS_FORMAT_INT;
|
||||
break;
|
||||
|
||||
case DT_FLOAT:
|
||||
*bands = 1;
|
||||
*fmt = IM_BANDFMT_FLOAT;
|
||||
*fmt = VIPS_FORMAT_FLOAT;
|
||||
break;
|
||||
|
||||
case DT_COMPLEX:
|
||||
*bands = 1;
|
||||
*fmt = IM_BANDFMT_COMPLEX;
|
||||
*fmt = VIPS_FORMAT_COMPLEX;
|
||||
break;
|
||||
|
||||
case DT_DOUBLE:
|
||||
*bands = 1;
|
||||
*fmt = IM_BANDFMT_DOUBLE;
|
||||
*fmt = VIPS_FORMAT_DOUBLE;
|
||||
break;
|
||||
|
||||
case DT_RGB:
|
||||
*bands = 3;
|
||||
*fmt = IM_BANDFMT_UCHAR;
|
||||
*fmt = VIPS_FORMAT_UCHAR;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -489,7 +487,7 @@ vips__isanalyze( const char *filename )
|
||||
struct dsr *d;
|
||||
int width, height;
|
||||
int bands;
|
||||
int fmt;
|
||||
VipsBandFormat fmt;
|
||||
|
||||
generate_filenames( filename, header, image );
|
||||
if( !vips_existsf( "%s", header ) )
|
||||
@ -518,7 +516,7 @@ vips__analyze_read_header( const char *filename, VipsImage *out )
|
||||
struct dsr *d;
|
||||
int width, height;
|
||||
int bands;
|
||||
int fmt;
|
||||
VipsBandFormat fmt;
|
||||
|
||||
generate_filenames( filename, header, image );
|
||||
if( !(d = read_header( header )) )
|
||||
@ -529,7 +527,7 @@ vips__analyze_read_header( const char *filename, VipsImage *out )
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( get_vips_properties( d, &width, &height, &bands, &fmt ) ) {
|
||||
im_free( d );
|
||||
vips_free( d );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
@ -551,10 +549,10 @@ vips__analyze_read( const char *filename, VipsImage *out )
|
||||
char header[FILENAME_MAX];
|
||||
char image[FILENAME_MAX];
|
||||
struct dsr *d;
|
||||
IMAGE *t[2];
|
||||
VipsImage *t;
|
||||
int width, height;
|
||||
int bands;
|
||||
int fmt;
|
||||
VipsBandFormat fmt;
|
||||
|
||||
generate_filenames( filename, header, image );
|
||||
if( !(d = read_header( header )) )
|
||||
@ -565,14 +563,19 @@ vips__analyze_read( const char *filename, VipsImage *out )
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( get_vips_properties( d, &width, &height, &bands, &fmt ) ||
|
||||
im_open_local_array( out, t, 2, "analyze2vips", "p" ) ||
|
||||
im_raw2vips( image, t[0], width, height,
|
||||
bands * im_bits_of_fmt( fmt ) / 8, 0 ) ||
|
||||
im_copy_morph( t[0], t[1], bands, fmt, IM_CODING_NONE ) ||
|
||||
im_copy_native( t[1], out, TRUE ) ) {
|
||||
!(t = vips_image_new_from_file_raw( image, width, height,
|
||||
bands * vips_format_sizeof( fmt ), 0 )) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_copy( t, &t,
|
||||
"bands", bands, "format", fmt, "swap", vips_amiMSBfirst(),
|
||||
NULL ) ||
|
||||
vips_image_write( t, out ) ) {
|
||||
g_object_unref( t );
|
||||
vips_free( d );
|
||||
return( -1 );
|
||||
}
|
||||
g_object_unref( t );
|
||||
|
||||
attach_meta( out, d );
|
||||
|
@ -36,7 +36,7 @@ extern "C" {
|
||||
|
||||
int vips__isanalyze( const char *filename );
|
||||
int vips__analyze_read_header( const char *filename, VipsImage *out );
|
||||
int vips__analyze_read( const char *filename, VipsImage *out )
|
||||
int vips__analyze_read( const char *filename, VipsImage *out );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
167
libvips/foreign/analyzeload.c
Normal file
167
libvips/foreign/analyzeload.c
Normal file
@ -0,0 +1,167 @@
|
||||
/* load analyze from a file
|
||||
*
|
||||
* 5/12/11
|
||||
* - from openslideload.c
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
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 DEBUG
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/buf.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#include "analyze2vips.h"
|
||||
|
||||
typedef struct _VipsForeignLoadAnalyze {
|
||||
VipsForeignLoad parent_object;
|
||||
|
||||
/* Filename for load.
|
||||
*/
|
||||
char *filename;
|
||||
|
||||
} VipsForeignLoadAnalyze;
|
||||
|
||||
typedef VipsForeignLoadClass VipsForeignLoadAnalyzeClass;
|
||||
|
||||
G_DEFINE_TYPE( VipsForeignLoadAnalyze, vips_foreign_load_analyze,
|
||||
VIPS_TYPE_FOREIGN_LOAD );
|
||||
|
||||
static VipsForeignFlags
|
||||
vips_foreign_load_analyze_get_flags_filename( const char *filename )
|
||||
{
|
||||
return( VIPS_FOREIGN_PARTIAL );
|
||||
}
|
||||
|
||||
static VipsForeignFlags
|
||||
vips_foreign_load_analyze_get_flags( VipsForeignLoad *load )
|
||||
{
|
||||
return( VIPS_FOREIGN_PARTIAL );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_foreign_load_analyze_header( VipsForeignLoad *load )
|
||||
{
|
||||
VipsForeignLoadAnalyze *analyze = (VipsForeignLoadAnalyze *) load;
|
||||
|
||||
if( vips__analyze_read_header( analyze->filename, load->out ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_foreign_load_analyze_load( VipsForeignLoad *load )
|
||||
{
|
||||
VipsForeignLoadAnalyze *analyze = (VipsForeignLoadAnalyze *) load;
|
||||
|
||||
if( vips__analyze_read( analyze->filename, load->real ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static const char *vips_foreign_analyze_suffs[] = { ".img", ".hdr", NULL };
|
||||
|
||||
static void
|
||||
vips_foreign_load_analyze_class_init( VipsForeignLoadAnalyzeClass *class )
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
VipsObjectClass *object_class = (VipsObjectClass *) class;
|
||||
VipsForeignClass *foreign_class = (VipsForeignClass *) 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 = "analyzeload";
|
||||
object_class->description = _( "load an Analyze6 image" );
|
||||
|
||||
foreign_class->suffs = vips_foreign_analyze_suffs;
|
||||
|
||||
load_class->is_a = vips__isanalyze;
|
||||
load_class->get_flags_filename =
|
||||
vips_foreign_load_analyze_get_flags_filename;
|
||||
load_class->get_flags = vips_foreign_load_analyze_get_flags;
|
||||
load_class->header = vips_foreign_load_analyze_header;
|
||||
load_class->load = vips_foreign_load_analyze_load;
|
||||
|
||||
VIPS_ARG_STRING( class, "filename", 1,
|
||||
_( "Filename" ),
|
||||
_( "Filename to load from" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsForeignLoadAnalyze, filename ),
|
||||
NULL );
|
||||
}
|
||||
|
||||
static void
|
||||
vips_foreign_load_analyze_init( VipsForeignLoadAnalyze *analyze )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_analyzeload:
|
||||
* @filename: file to load
|
||||
* @out: decompressed image
|
||||
* @...: %NULL-terminated list of optional named arguments
|
||||
*
|
||||
* Load an Analyze 6.0 file. If @filename is "fred.img", this will look for
|
||||
* an image header called "fred.hdr" and pixel data in "fred.img". You can
|
||||
* also load "fred" or "fred.hdr".
|
||||
*
|
||||
* Images are
|
||||
* loaded lazilly and byte-swapped, if necessary. The Analyze metadata is read
|
||||
* and attached.
|
||||
*
|
||||
* See also: vips_image_new_from_file().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_analyzeload( const char *filename, VipsImage **out, ... )
|
||||
{
|
||||
va_list ap;
|
||||
int result;
|
||||
|
||||
va_start( ap, out );
|
||||
result = vips_call_split( "analyzeload", ap, filename, out );
|
||||
va_end( ap );
|
||||
|
||||
return( result );
|
||||
}
|
@ -1156,6 +1156,7 @@ vips_foreign_operation_init( void )
|
||||
{
|
||||
extern GType vips_foreign_load_fits_get_type( void );
|
||||
extern GType vips_foreign_save_fits_get_type( void );
|
||||
extern GType vips_foreign_load_analyze_get_type( void );
|
||||
extern GType vips_foreign_load_openexr_get_type( void );
|
||||
extern GType vips_foreign_load_openslide_get_type( void );
|
||||
extern GType vips_foreign_load_jpeg_file_get_type( void );
|
||||
@ -1194,6 +1195,7 @@ vips_foreign_operation_init( void )
|
||||
vips_foreign_load_openexr_get_type();
|
||||
#endif /*HAVE_OPENEXR*/
|
||||
|
||||
vips_foreign_load_analyze_get_type();
|
||||
vips_foreign_load_vips_get_type();
|
||||
vips_foreign_save_vips_get_type();
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
noinst_LTLIBRARIES = libformat.la
|
||||
|
||||
libformat_la_SOURCES = \
|
||||
dbh.h \
|
||||
format.c \
|
||||
format_dispatch.c \
|
||||
im_analyze2vips.c \
|
||||
|
@ -1,98 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright, 1986-1991
|
||||
* Biodynamics Research Unit
|
||||
* Mayo Foundation
|
||||
*
|
||||
* dbh.h
|
||||
*
|
||||
*
|
||||
* database sub-definitions
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* The previous-generation header for Analyze images. Although (c) Mayo
|
||||
* Foundation, it has been in the public domain for many years.
|
||||
*
|
||||
* Analyze images have a 348 byte header stored in a file with a .hdr suffix,
|
||||
* and a corresponding .img file containing just the pixel data.
|
||||
*
|
||||
*/
|
||||
|
||||
struct header_key /* header_key */
|
||||
{ /* off + size*/
|
||||
int sizeof_hdr; /* 0 + 4 */
|
||||
char data_type[10]; /* 4 + 10 */
|
||||
char db_name[18]; /* 14 + 18 */
|
||||
int extents; /* 32 + 4 */
|
||||
short int session_error; /* 36 + 2 */
|
||||
char regular; /* 38 + 1 */
|
||||
char hkey_un0; /* 39 + 1 */
|
||||
}; /* total=40 */
|
||||
|
||||
struct image_dimension /* image_dimension */
|
||||
{ /* off + size*/
|
||||
short int dim[8]; /* 0 + 16 */
|
||||
char vox_units[4]; /* 16 + 4 */
|
||||
char cal_units[8]; /* 20 + 4 */
|
||||
short int unused1; /* 24 + 2 */
|
||||
short int datatype; /* 30 + 2 */
|
||||
short int bitpix; /* 32 + 2 */
|
||||
short int dim_un0; /* 34 + 2 */
|
||||
float pixdim[8]; /* 36 + 32 */
|
||||
|
||||
/* pixdim[] specifies the voxel dimensions:
|
||||
pixdim[1] - voxel width
|
||||
pixdim[2] - voxel height
|
||||
pixdim[3] - interslice distance
|
||||
..etc
|
||||
*/
|
||||
float vox_offset; /* 68 + 4 */
|
||||
float funused1; /* 72 + 4 */
|
||||
float funused2; /* 76 + 4 */
|
||||
float funused3; /* 80 + 4 */
|
||||
float cal_max; /* 84 + 4 */
|
||||
float cal_min; /* 88 + 4 */
|
||||
int compressed; /* 92 + 4 */
|
||||
int verified; /* 96 + 4 */
|
||||
int glmax, glmin; /* 100 + 8 */
|
||||
};
|
||||
|
||||
struct data_history /* data_history */
|
||||
{ /* off + size*/
|
||||
char descrip[80]; /* 0 + 80 */
|
||||
char aux_file[24]; /* 80 + 24 */
|
||||
char orient; /* 104 + 1 */
|
||||
char originator[10]; /* 105 + 10 */
|
||||
char generated[10]; /* 115 + 10 */
|
||||
char scannum[10]; /* 125 + 10 */
|
||||
char patient_id[10]; /* 135 + 10 */
|
||||
char exp_date[10]; /* 145 + 10 */
|
||||
char exp_time[10]; /* 155 + 10 */
|
||||
char hist_un0[3]; /* 165 + 3 */
|
||||
int views; /* 168 + 4 */
|
||||
int vols_added; /* 172 + 4 */
|
||||
int start_field; /* 176 + 4 */
|
||||
int field_skip; /* 180 + 4 */
|
||||
int omax,omin; /* 184 + 8 */
|
||||
int smax,smin; /* 192 + 8 */
|
||||
}; /* total=200 */
|
||||
|
||||
struct dsr /* dsr */
|
||||
{ /* off + size*/
|
||||
struct header_key hk; /* 0 + 40 */
|
||||
struct image_dimension dime; /* 40 + 108 */
|
||||
struct data_history hist; /* 148 + 200 */
|
||||
}; /* total=348 */
|
||||
|
||||
/* Acceptable values for hdr.dime.datatype */
|
||||
#define DT_UNKNOWN 0
|
||||
#define DT_BINARY 1
|
||||
#define DT_UNSIGNED_CHAR 2
|
||||
#define DT_SIGNED_SHORT 4
|
||||
#define DT_SIGNED_INT 8
|
||||
#define DT_FLOAT 16
|
||||
#define DT_COMPLEX 32
|
||||
#define DT_DOUBLE 64
|
||||
#define DT_RGB 128
|
@ -1,15 +1,7 @@
|
||||
/* Read a Analyze file. Old-style header (so called 7.5 format).
|
||||
*
|
||||
* 3/8/05
|
||||
* - dbh.h header from Ralph Myers
|
||||
* 22/8/05
|
||||
* - better byteswapper
|
||||
* 12/5/09
|
||||
* - fix signed/unsigned warning
|
||||
* 13/1/09
|
||||
* - try harder not to generate error messages in "isanalyze"
|
||||
* 4/2/10
|
||||
* - gtkdoc
|
||||
* 14/12/11
|
||||
* - just a compat stub now
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -39,575 +31,46 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
#define DEBUG
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#include "dbh.h"
|
||||
|
||||
/* The things we can have in header fields. Can't use GType, since we want a
|
||||
* static value we can use in a declaration.
|
||||
*/
|
||||
typedef enum {
|
||||
BYTE,
|
||||
SHORT,
|
||||
INT,
|
||||
FLOAT,
|
||||
STRING
|
||||
} Type;
|
||||
|
||||
/* A field in the dsr header.
|
||||
*/
|
||||
typedef struct {
|
||||
const char *name; /* Eg. "header_key.sizeof_hdr" */
|
||||
Type type;
|
||||
glong offset; /* Offset in struct */
|
||||
int len; /* Sizeof ... useful for string types */
|
||||
} Field;
|
||||
|
||||
static Field dsr_header[] = {
|
||||
{ "dsr-header_key.sizeof_hdr", INT,
|
||||
G_STRUCT_OFFSET( struct dsr, hk.sizeof_hdr ), 4 },
|
||||
{ "dsr-header_key.data_type", STRING,
|
||||
G_STRUCT_OFFSET( struct dsr, hk.data_type ), 10 },
|
||||
{ "dsr-header_key.db_name", STRING,
|
||||
G_STRUCT_OFFSET( struct dsr, hk.db_name ), 18 },
|
||||
{ "dsr-header_key.extents", INT,
|
||||
G_STRUCT_OFFSET( struct dsr, hk.extents ), 4 },
|
||||
{ "dsr-header_key.session_error", SHORT,
|
||||
G_STRUCT_OFFSET( struct dsr, hk.session_error ), 2 },
|
||||
{ "dsr-header_key.regular", BYTE,
|
||||
G_STRUCT_OFFSET( struct dsr, hk.regular ), 1 },
|
||||
{ "dsr-header_key.hkey_un0", BYTE,
|
||||
G_STRUCT_OFFSET( struct dsr, hk.hkey_un0 ), 1 },
|
||||
|
||||
{ "dsr-image_dimension.dim[0]", SHORT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.dim[0] ), 2 },
|
||||
{ "dsr-image_dimension.dim[1]", SHORT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.dim[1] ), 2 },
|
||||
{ "dsr-image_dimension.dim[2]", SHORT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.dim[2] ), 2 },
|
||||
{ "dsr-image_dimension.dim[3]", SHORT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.dim[3] ), 2 },
|
||||
{ "dsr-image_dimension.dim[4]", SHORT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.dim[4] ), 2 },
|
||||
{ "dsr-image_dimension.dim[5]", SHORT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.dim[5] ), 2 },
|
||||
{ "dsr-image_dimension.dim[6]", SHORT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.dim[6] ), 2 },
|
||||
{ "dsr-image_dimension.dim[7]", SHORT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.dim[7] ), 2 },
|
||||
{ "dsr-image_dimension.vox_units[0]", BYTE,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.vox_units[0] ), 1 },
|
||||
{ "dsr-image_dimension.vox_units[1]", BYTE,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.vox_units[1] ), 1 },
|
||||
{ "dsr-image_dimension.vox_units[2]", BYTE,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.vox_units[2] ), 1 },
|
||||
{ "dsr-image_dimension.vox_units[3]", BYTE,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.vox_units[3] ), 1 },
|
||||
{ "dsr-image_dimension.cal_units[0]", BYTE,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.cal_units[0] ), 1 },
|
||||
{ "dsr-image_dimension.cal_units[1]", BYTE,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.cal_units[1] ), 1 },
|
||||
{ "dsr-image_dimension.cal_units[2]", BYTE,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.cal_units[2] ), 1 },
|
||||
{ "dsr-image_dimension.cal_units[3]", BYTE,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.cal_units[3] ), 1 },
|
||||
{ "dsr-image_dimension.cal_units[4]", BYTE,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.cal_units[4] ), 1 },
|
||||
{ "dsr-image_dimension.cal_units[5]", BYTE,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.cal_units[5] ), 1 },
|
||||
{ "dsr-image_dimension.cal_units[6]", BYTE,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.cal_units[6] ), 1 },
|
||||
{ "dsr-image_dimension.cal_units[7]", BYTE,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.cal_units[7] ), 1 },
|
||||
{ "dsr-image_dimension.data_type", SHORT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.datatype ), 2 },
|
||||
{ "dsr-image_dimension.bitpix", SHORT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.bitpix ), 2 },
|
||||
{ "dsr-image_dimension.dim_un0", SHORT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.dim_un0 ), 2 },
|
||||
{ "dsr-image_dimension.pixdim[0]", FLOAT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.pixdim[0] ), 4 },
|
||||
{ "dsr-image_dimension.pixdim[1]", FLOAT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.pixdim[1] ), 4 },
|
||||
{ "dsr-image_dimension.pixdim[2]", FLOAT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.pixdim[2] ), 4 },
|
||||
{ "dsr-image_dimension.pixdim[3]", FLOAT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.pixdim[3] ), 4 },
|
||||
{ "dsr-image_dimension.pixdim[4]", FLOAT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.pixdim[4] ), 4 },
|
||||
{ "dsr-image_dimension.pixdim[5]", FLOAT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.pixdim[5] ), 4 },
|
||||
{ "dsr-image_dimension.pixdim[6]", FLOAT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.pixdim[6] ), 4 },
|
||||
{ "dsr-image_dimension.pixdim[7]", FLOAT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.pixdim[7] ), 4 },
|
||||
{ "dsr-image_dimension.vox_offset", FLOAT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.vox_offset ), 4 },
|
||||
{ "dsr-image_dimension.cal_max", FLOAT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.cal_max ), 4 },
|
||||
{ "dsr-image_dimension.cal_min", FLOAT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.cal_min ), 4 },
|
||||
{ "dsr-image_dimension.compressed", INT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.compressed ), 4 },
|
||||
{ "dsr-image_dimension.verified", INT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.verified ), 4 },
|
||||
{ "dsr-image_dimension.glmax", INT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.glmax ), 4 },
|
||||
{ "dsr-image_dimension.glmin", INT,
|
||||
G_STRUCT_OFFSET( struct dsr, dime.glmin ), 4 },
|
||||
|
||||
{ "dsr-data_history.descrip", STRING,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.descrip ), 80 },
|
||||
{ "dsr-data_history.aux_file", STRING,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.aux_file ), 24 },
|
||||
{ "dsr-data_history.orient", BYTE,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.orient ), 1 },
|
||||
{ "dsr-data_history.originator", STRING,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.originator ), 10 },
|
||||
{ "dsr-data_history.generated", STRING,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.generated ), 10 },
|
||||
{ "dsr-data_history.scannum", STRING,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.scannum ), 10 },
|
||||
{ "dsr-data_history.patient_id", STRING,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.patient_id ), 10 },
|
||||
{ "dsr-data_history.exp_date", STRING,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.exp_date ), 10 },
|
||||
{ "dsr-data_history.exp_time", STRING,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.exp_time ), 10 },
|
||||
{ "dsr-data_history.hist_un0", STRING,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.hist_un0 ), 3 },
|
||||
{ "dsr-data_history.views", INT,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.views ), 4 },
|
||||
{ "dsr-data_history.vols_added", INT,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.vols_added ), 4 },
|
||||
{ "dsr-data_history.start_field", INT,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.start_field ), 4 },
|
||||
{ "dsr-data_history.field_skip", INT,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.field_skip ), 4 },
|
||||
{ "dsr-data_history.omax", INT,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.omax ), 4 },
|
||||
{ "dsr-data_history.omin", INT,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.omin ), 4 },
|
||||
{ "dsr-data_history.smax", INT,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.smax ), 4 },
|
||||
{ "dsr-data_history.smin", INT,
|
||||
G_STRUCT_OFFSET( struct dsr, hist.smin ), 4 }
|
||||
};
|
||||
|
||||
/* Given a filename, generate the names for the header and the image data.
|
||||
*
|
||||
* Eg.
|
||||
* "fred" -> "fred.hdr", "fred.img"
|
||||
* "fred.img" -> "fred.hdr", "fred.img"
|
||||
*/
|
||||
static void
|
||||
generate_filenames( const char *path, char *header, char *image )
|
||||
static VipsFormatFlags
|
||||
analyze_flags( const char *filename )
|
||||
{
|
||||
char name[FILENAME_MAX];
|
||||
char mode[FILENAME_MAX];
|
||||
|
||||
const char *olds[] = { ".img", ".hdr" };
|
||||
|
||||
/* Take off any modifiers.
|
||||
*/
|
||||
im_filename_split( path, name, mode );
|
||||
|
||||
im__change_suffix( name, header, FILENAME_MAX, ".hdr", olds, 2 );
|
||||
im__change_suffix( name, image, FILENAME_MAX, ".img", olds, 2 );
|
||||
}
|
||||
|
||||
/* str is a str which may not be NULL-terminated. Return a pointer to a static
|
||||
* buffer with a NULL-terminated version so we can safely printf() the string.
|
||||
* Also, make sure the string is plain ascii.
|
||||
*/
|
||||
static char *
|
||||
getstr( int mx, const char *str )
|
||||
{
|
||||
static char buf[256];
|
||||
int i;
|
||||
|
||||
assert( mx < 256 );
|
||||
|
||||
strncpy( buf, str, mx );
|
||||
buf[mx]= '\0';
|
||||
|
||||
/* How annoying, patient_id has some funny ctrlchars in that mess up
|
||||
* xml encode later.
|
||||
*/
|
||||
for( i = 0; i < mx && buf[i]; i++ )
|
||||
if( !isascii( buf[i] ) || buf[i] < 32 )
|
||||
buf[i] = '@';
|
||||
|
||||
return( buf );
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
print_dsr( struct dsr *d )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < IM_NUMBER( dsr_header ); i++ ) {
|
||||
printf( "%s = ", dsr_header[i].name );
|
||||
|
||||
switch( dsr_header[i].type ) {
|
||||
case BYTE:
|
||||
printf( "%d\n", G_STRUCT_MEMBER( char, d,
|
||||
dsr_header[i].offset ) );
|
||||
break;
|
||||
|
||||
case SHORT:
|
||||
printf( "%d\n", G_STRUCT_MEMBER( short, d,
|
||||
dsr_header[i].offset ) );
|
||||
break;
|
||||
|
||||
case INT:
|
||||
printf( "%d\n", G_STRUCT_MEMBER( int, d,
|
||||
dsr_header[i].offset ) );
|
||||
break;
|
||||
|
||||
case FLOAT:
|
||||
printf( "%g\n", G_STRUCT_MEMBER( float, d,
|
||||
dsr_header[i].offset ) );
|
||||
break;
|
||||
|
||||
case STRING:
|
||||
printf( "\"%s\"\n", getstr( dsr_header[i].len,
|
||||
&G_STRUCT_MEMBER( char, d,
|
||||
dsr_header[i].offset ) ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /*DEBUG*/
|
||||
|
||||
static struct dsr *
|
||||
read_header( const char *header )
|
||||
{
|
||||
struct dsr *d;
|
||||
unsigned int len;
|
||||
|
||||
if( !(d = (struct dsr *) im__file_read_name( header, NULL, &len )) )
|
||||
return( NULL );
|
||||
if( len != sizeof( struct dsr ) ) {
|
||||
im_free( d );
|
||||
im_error( "im_analyze2vips",
|
||||
"%s", _( "header file size incorrect" ) );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
/* Ouch! Should check at configure time I guess.
|
||||
*/
|
||||
g_assert( sizeof( struct dsr ) == 348 );
|
||||
|
||||
/* dsr headers are always SPARC byte order (MSB first). Do we need to
|
||||
* swap?
|
||||
*/
|
||||
if( !im_amiMSBfirst() ) {
|
||||
int i;
|
||||
|
||||
for( i = 0; i < IM_NUMBER( dsr_header ); i++ ) {
|
||||
unsigned char *p;
|
||||
|
||||
|
||||
switch( dsr_header[i].type ) {
|
||||
case SHORT:
|
||||
p = &G_STRUCT_MEMBER( unsigned char, d,
|
||||
dsr_header[i].offset );
|
||||
vips__copy_2byte( TRUE, p, p );
|
||||
break;
|
||||
|
||||
case INT:
|
||||
case FLOAT:
|
||||
p = &G_STRUCT_MEMBER( unsigned char, d,
|
||||
dsr_header[i].offset );
|
||||
vips__copy_4byte( TRUE, p, p );
|
||||
break;
|
||||
|
||||
case BYTE:
|
||||
case STRING:
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( (int) len != d->hk.sizeof_hdr ) {
|
||||
im_free( d );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
return( d );
|
||||
}
|
||||
|
||||
/* Try to get VIPS header properties from a dsr.
|
||||
*/
|
||||
static int
|
||||
get_vips_properties( struct dsr *d,
|
||||
int *width, int *height, int *bands, int *fmt )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( d->dime.dim[0] < 2 || d->dime.dim[0] > 7 ) {
|
||||
im_error( "im_analyze2vips",
|
||||
_( "%d-dimensional images not supported" ),
|
||||
d->dime.dim[0] );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* Size of base 2d images.
|
||||
*/
|
||||
*width = d->dime.dim[1];
|
||||
*height = d->dime.dim[2];
|
||||
|
||||
for( i = 3; i <= d->dime.dim[0]; i++ )
|
||||
*height *= d->dime.dim[i];
|
||||
|
||||
/* Check it's a datatype we can handle.
|
||||
*/
|
||||
switch( d->dime.datatype ) {
|
||||
case DT_UNSIGNED_CHAR:
|
||||
*bands = 1;
|
||||
*fmt = IM_BANDFMT_UCHAR;
|
||||
break;
|
||||
|
||||
case DT_SIGNED_SHORT:
|
||||
*bands = 1;
|
||||
*fmt = IM_BANDFMT_SHORT;
|
||||
break;
|
||||
|
||||
case DT_SIGNED_INT:
|
||||
*bands = 1;
|
||||
*fmt = IM_BANDFMT_INT;
|
||||
break;
|
||||
|
||||
case DT_FLOAT:
|
||||
*bands = 1;
|
||||
*fmt = IM_BANDFMT_FLOAT;
|
||||
break;
|
||||
|
||||
case DT_COMPLEX:
|
||||
*bands = 1;
|
||||
*fmt = IM_BANDFMT_COMPLEX;
|
||||
break;
|
||||
|
||||
case DT_DOUBLE:
|
||||
*bands = 1;
|
||||
*fmt = IM_BANDFMT_DOUBLE;
|
||||
break;
|
||||
|
||||
case DT_RGB:
|
||||
*bands = 3;
|
||||
*fmt = IM_BANDFMT_UCHAR;
|
||||
break;
|
||||
|
||||
default:
|
||||
im_error( "im_analyze2vips",
|
||||
_( "datatype %d not supported" ), d->dime.datatype );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "get_vips_properties: width = %d\n", *width );
|
||||
printf( "get_vips_properties: height = %d\n", *height );
|
||||
printf( "get_vips_properties: bands = %d\n", *bands );
|
||||
printf( "get_vips_properties: fmt = %d\n", *fmt );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void
|
||||
attach_meta( IMAGE *out, struct dsr *d )
|
||||
{
|
||||
int i;
|
||||
|
||||
im_meta_set_blob( out, "dsr",
|
||||
(im_callback_fn) im_free, d, d->hk.sizeof_hdr );
|
||||
|
||||
for( i = 0; i < IM_NUMBER( dsr_header ); i++ ) {
|
||||
switch( dsr_header[i].type ) {
|
||||
case BYTE:
|
||||
im_meta_set_int( out, dsr_header[i].name,
|
||||
G_STRUCT_MEMBER( char, d,
|
||||
dsr_header[i].offset ) );
|
||||
break;
|
||||
|
||||
case SHORT:
|
||||
im_meta_set_int( out, dsr_header[i].name,
|
||||
G_STRUCT_MEMBER( short, d,
|
||||
dsr_header[i].offset ) );
|
||||
break;
|
||||
|
||||
case INT:
|
||||
im_meta_set_int( out, dsr_header[i].name,
|
||||
G_STRUCT_MEMBER( int, d,
|
||||
dsr_header[i].offset ) );
|
||||
break;
|
||||
|
||||
case FLOAT:
|
||||
im_meta_set_double( out, dsr_header[i].name,
|
||||
G_STRUCT_MEMBER( float, d,
|
||||
dsr_header[i].offset ) );
|
||||
break;
|
||||
|
||||
case STRING:
|
||||
im_meta_set_string( out, dsr_header[i].name,
|
||||
getstr( dsr_header[i].len,
|
||||
&G_STRUCT_MEMBER( char, d,
|
||||
dsr_header[i].offset ) ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( 0 );
|
||||
}
|
||||
}
|
||||
return( vips_foreign_flags( "analyzeload", filename ) );
|
||||
}
|
||||
|
||||
static int
|
||||
isanalyze( const char *filename )
|
||||
{
|
||||
char header[FILENAME_MAX];
|
||||
char image[FILENAME_MAX];
|
||||
struct dsr *d;
|
||||
int width, height;
|
||||
int bands;
|
||||
int fmt;
|
||||
|
||||
generate_filenames( filename, header, image );
|
||||
if( !im_existsf( "%s", header ) )
|
||||
return( 0 );
|
||||
if( !(d = read_header( header )) )
|
||||
return( 0 );
|
||||
|
||||
#ifdef DEBUG
|
||||
print_dsr( d );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( get_vips_properties( d, &width, &height, &bands, &fmt ) ) {
|
||||
im_free( d );
|
||||
return( 0 );
|
||||
}
|
||||
im_free( d );
|
||||
|
||||
return( 1 );
|
||||
return( vips_foreign_is_a( "analyzeload", filename ) );
|
||||
}
|
||||
|
||||
static int
|
||||
analyze2vips_header( const char *filename, IMAGE *out )
|
||||
{
|
||||
char header[FILENAME_MAX];
|
||||
char image[FILENAME_MAX];
|
||||
struct dsr *d;
|
||||
int width, height;
|
||||
int bands;
|
||||
int fmt;
|
||||
|
||||
generate_filenames( filename, header, image );
|
||||
if( !(d = read_header( header )) )
|
||||
return( -1 );
|
||||
|
||||
#ifdef DEBUG
|
||||
print_dsr( d );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( get_vips_properties( d, &width, &height, &bands, &fmt ) ) {
|
||||
im_free( d );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
im_initdesc( out, width, height, bands, im_bits_of_fmt( fmt ), fmt,
|
||||
IM_CODING_NONE,
|
||||
bands == 1 ? IM_TYPE_B_W : IM_TYPE_sRGB,
|
||||
1.0, 1.0,
|
||||
0, 0 );
|
||||
|
||||
attach_meta( out, d );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_analyze2vips:
|
||||
* @filename: file to load
|
||||
* @out: image to write to
|
||||
*
|
||||
* Load an Analyze 6.0 file. If @filename is "fred.img", this will look for
|
||||
* an image header called "fred.hdr" and pixel data in "fred.img". You can
|
||||
* also load "fred" or "fred.hdr".
|
||||
*
|
||||
* Images are
|
||||
* loaded lazilly and byte-swapped, if necessary. The Analyze metadata is read
|
||||
* and attached.
|
||||
*
|
||||
* See also: #VipsFormat, im_meta_get(), im_grid().
|
||||
*
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
im_analyze2vips( const char *filename, IMAGE *out )
|
||||
{
|
||||
char header[FILENAME_MAX];
|
||||
char image[FILENAME_MAX];
|
||||
struct dsr *d;
|
||||
IMAGE *t[2];
|
||||
int width, height;
|
||||
int bands;
|
||||
int fmt;
|
||||
VipsImage *t;
|
||||
|
||||
generate_filenames( filename, header, image );
|
||||
if( !(d = read_header( header )) )
|
||||
if( vips_analyzeload( filename, &t, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
#ifdef DEBUG
|
||||
print_dsr( d );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
if( get_vips_properties( d, &width, &height, &bands, &fmt ) ||
|
||||
im_open_local_array( out, t, 2, "im_analyze2vips", "p" ) ||
|
||||
im_raw2vips( image, t[0], width, height,
|
||||
bands * im_bits_of_fmt( fmt ) / 8, 0 ) ||
|
||||
im_copy_morph( t[0], t[1], bands, fmt, IM_CODING_NONE ) ||
|
||||
im_copy_native( t[1], out, TRUE ) ) {
|
||||
im_free( d );
|
||||
if( vips_image_write( t, out ) ) {
|
||||
g_object_unref( t );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
attach_meta( out, d );
|
||||
g_object_unref( t );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static const char *analyze_suffs[] = { ".img", ".hdr", NULL };
|
||||
|
||||
static VipsFormatFlags
|
||||
analyze_flags( const char *filename )
|
||||
{
|
||||
return( VIPS_FORMAT_PARTIAL );
|
||||
}
|
||||
|
||||
/* analyze format adds no new members.
|
||||
*/
|
||||
typedef VipsFormat VipsFormatAnalyze;
|
||||
typedef VipsFormatClass VipsFormatAnalyzeClass;
|
||||
|
||||
@ -621,7 +84,7 @@ vips_format_analyze_class_init( VipsFormatAnalyzeClass *class )
|
||||
object_class->description = _( "Analyze 6.0" );
|
||||
|
||||
format_class->is_a = isanalyze;
|
||||
format_class->header = analyze2vips_header;
|
||||
format_class->header = im_analyze2vips;
|
||||
format_class->load = im_analyze2vips;
|
||||
format_class->get_flags = analyze_flags;
|
||||
format_class->suffs = analyze_suffs;
|
||||
|
@ -328,6 +328,9 @@ int vips_fitsload( const char *filename, VipsImage **out, ... )
|
||||
int vips_fitssave( VipsImage *in, const char *filename, ... )
|
||||
__attribute__((sentinel));
|
||||
|
||||
int vips_analyzeload( const char *filename, VipsImage **out, ... )
|
||||
__attribute__((sentinel));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
|
Loading…
Reference in New Issue
Block a user