fits reader is now lazy
The fits format reader now uses fits_read_subset() to erad pixels lazilly. There are a few unresolved issues though: - getting some streaking, try putting a lock around the read subarea call, perhaps it can't thread? - add a tile cache, cf. tiff - test colour read with valgrind - ask Doug for a test colour image - read whole tiles, if the alignment is right, again see tiff reader - test performance - remove the old scanline reader?
This commit is contained in:
parent
1aea6a1347
commit
5e366bcaf3
@ -36,8 +36,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define DEBUG
|
|
||||||
*/
|
*/
|
||||||
|
#define DEBUG
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
@ -60,6 +60,27 @@
|
|||||||
#include <dmalloc.h>
|
#include <dmalloc.h>
|
||||||
#endif /*WITH_DMALLOC*/
|
#endif /*WITH_DMALLOC*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
- getting some streaking, try putting a lock around the read
|
||||||
|
subarea call
|
||||||
|
|
||||||
|
- add a tile cache, cf. tiff
|
||||||
|
|
||||||
|
- test colour read with valgrind
|
||||||
|
|
||||||
|
- ask Doug for a test colour image
|
||||||
|
|
||||||
|
- read whole tiles, if the alignment is right
|
||||||
|
|
||||||
|
- test performance
|
||||||
|
|
||||||
|
- remove the old scanline reader?
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
/* vips only supports 3 dimensions, but we allow up to MAX_DIMENSIONS as long
|
/* vips only supports 3 dimensions, but we allow up to MAX_DIMENSIONS as long
|
||||||
* as the higher dimensions are all empty. If you change this value, change
|
* as the higher dimensions are all empty. If you change this value, change
|
||||||
* fits2vips_get_header() as well.
|
* fits2vips_get_header() as well.
|
||||||
@ -118,12 +139,17 @@ read_new( const char *filename, IMAGE *out )
|
|||||||
read->out = out;
|
read->out = out;
|
||||||
read->fptr = NULL;
|
read->fptr = NULL;
|
||||||
|
|
||||||
|
if( im_add_close_callback( out,
|
||||||
|
(im_callback_fn) read_destroy, read, NULL ) ) {
|
||||||
|
read_destroy( read );
|
||||||
|
return( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
status = 0;
|
status = 0;
|
||||||
|
|
||||||
if( fits_open_file( &read->fptr, filename, READONLY, &status ) ) {
|
if( fits_open_file( &read->fptr, filename, READONLY, &status ) ) {
|
||||||
im_error( "fits", _( "unable to open \"%s\"" ), filename );
|
im_error( "fits", _( "unable to open \"%s\"" ), filename );
|
||||||
read_error( status );
|
read_error( status );
|
||||||
read_destroy( read );
|
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,13 +308,9 @@ fits2vips_header( const char *filename, IMAGE *out )
|
|||||||
printf( "fits2vips_header: reading \"%s\"\n", filename );
|
printf( "fits2vips_header: reading \"%s\"\n", filename );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
if( !(read = read_new( filename, out )) )
|
if( !(read = read_new( filename, out )) ||
|
||||||
|
fits2vips_get_header( read ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
if( fits2vips_get_header( read ) ) {
|
|
||||||
read_destroy( read );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
read_destroy( read );
|
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
@ -362,12 +384,9 @@ fits2vips_generate( REGION *out, void *seq, void *a, void *b )
|
|||||||
Rect *r = &out->valid;
|
Rect *r = &out->valid;
|
||||||
|
|
||||||
IMAGE *im = read->out;
|
IMAGE *im = read->out;
|
||||||
const int es = IM_IMAGE_SIZEOF_ELEMENT( im );
|
|
||||||
|
|
||||||
PEL *line_buffer;
|
PEL *q;
|
||||||
PEL *band_buffer;
|
int y, z;
|
||||||
PEL *p, *q;
|
|
||||||
int x, y, z, k;
|
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
status = 0;
|
status = 0;
|
||||||
@ -376,59 +395,35 @@ fits2vips_generate( REGION *out, void *seq, void *a, void *b )
|
|||||||
long lpixel[MAX_DIMENSIONS];
|
long lpixel[MAX_DIMENSIONS];
|
||||||
long inc[MAX_DIMENSIONS];
|
long inc[MAX_DIMENSIONS];
|
||||||
|
|
||||||
if( !(line_buffer = IM_ARRAY( im, IM_IMAGE_SIZEOF_LINE( im ), PEL )) ||
|
/* We read the area a scanline at a time. If the REGION we are reading
|
||||||
!(band_buffer = IM_ARRAY( im, es * im->Xsize, PEL )) ||
|
* to has bpl set right we should be able to read all scanlines in one
|
||||||
im_outcheck( im ) ||
|
* go, experiment.
|
||||||
im_setupout( im ) )
|
|
||||||
return( -1 );
|
|
||||||
|
|
||||||
/* Read out the entire
|
|
||||||
for( b = 0; b < MAX_DIMENSIONS; b++ )
|
|
||||||
fpixel[b] = 1;
|
|
||||||
fpixel[1] = im->Ysize - y;
|
|
||||||
|
|
||||||
if( fits_read_subset( read->fptr, read->datatype,
|
|
||||||
long *fpixel,
|
|
||||||
long *lpixel, long *inc, void *nulval, void *array,
|
|
||||||
int *anynul, int *status)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
for( y = r->top; y < IM_RECT_BOTTOM( r ); y ++ ) {
|
||||||
for( y = 0; y < im->Ysize; y++ ) {
|
|
||||||
long int fpixel[MAX_DIMENSIONS];
|
|
||||||
|
|
||||||
/* Start of scanline. We have to read top-to-bottom.
|
|
||||||
*/
|
|
||||||
for( z = 0; z < MAX_DIMENSIONS; z++ )
|
for( z = 0; z < MAX_DIMENSIONS; z++ )
|
||||||
fpixel[z] = 1;
|
fpixel[z] = 1;
|
||||||
|
fpixel[0] = r->left + 1;
|
||||||
fpixel[1] = im->Ysize - y;
|
fpixel[1] = im->Ysize - y;
|
||||||
|
|
||||||
for( z = 0; z < im->Bands; z++ ) {
|
for( z = 0; z < MAX_DIMENSIONS; z++ )
|
||||||
fpixel[2] = z + 1;
|
lpixel[z] = 1;
|
||||||
|
lpixel[0] = IM_RECT_RIGHT( r );
|
||||||
|
lpixel[1] = im->Ysize - y;
|
||||||
|
lpixel[2] = im->Bands;
|
||||||
|
|
||||||
/* Read one band of one scanline, then scatter-write
|
for( z = 0; z < MAX_DIMENSIONS; z++ )
|
||||||
* into the line buffer.
|
inc[z] = 1;
|
||||||
*/
|
|
||||||
if( fits_read_pix( read->fptr,
|
|
||||||
read->datatype, fpixel, im->Xsize,
|
|
||||||
NULL, band_buffer, NULL, &status ) ) {
|
|
||||||
read_error( status );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
p = band_buffer;
|
q = (PEL *) IM_REGION_ADDR( out, r->left, y );
|
||||||
q = line_buffer + z * es;
|
|
||||||
for( x = 0; x < im->Xsize; x++ ) {
|
|
||||||
for( k = 0; k < es; k++ )
|
|
||||||
q[k] = p[k];
|
|
||||||
|
|
||||||
p += es;
|
/* Break on ffgsv() for this call.
|
||||||
q += im->Bands * es;
|
*/
|
||||||
}
|
if( fits_read_subset( read->fptr, read->datatype,
|
||||||
}
|
fpixel, lpixel, inc, NULL, q, NULL, &status ) ) {
|
||||||
|
read_error( status );
|
||||||
if( im_writeline( y, im, line_buffer ) )
|
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
@ -439,8 +434,12 @@ fits2vips_generate( REGION *out, void *seq, void *a, void *b )
|
|||||||
static int
|
static int
|
||||||
fits2vips_get_data_lazy( Read *read )
|
fits2vips_get_data_lazy( Read *read )
|
||||||
{
|
{
|
||||||
return( im_generate( read->out,
|
if( im_demand_hint( read->out, IM_SMALLTILE, NULL ) ||
|
||||||
NULL, fits2vips_generate, NULL, read, NULL ) );
|
im_generate( read->out,
|
||||||
|
NULL, fits2vips_generate, NULL, read, NULL ) )
|
||||||
|
return( -1 );
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -467,12 +466,9 @@ im_fits2vips( const char *filename, IMAGE *out )
|
|||||||
if( !(read = read_new( filename, out )) )
|
if( !(read = read_new( filename, out )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
if( fits2vips_get_header( read ) ||
|
if( fits2vips_get_header( read ) ||
|
||||||
fits2vips_get_data_scanlinewise( read ) ) {
|
fits2vips_get_data_lazy( read ) )
|
||||||
read_destroy( read );
|
// fits2vips_get_data_scanlinewise( read ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
|
||||||
|
|
||||||
read_destroy( read );
|
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user