rewritten radiance load is much faster
the old rad code, from radiance.c, was using getc in a loop
This commit is contained in:
parent
b0f262091f
commit
ae71229cf5
@ -13,6 +13,7 @@
|
|||||||
- im_contrast_surface() deprecated: it was slower than calling conv a few
|
- im_contrast_surface() deprecated: it was slower than calling conv a few
|
||||||
times
|
times
|
||||||
- radiance load supports sequential read
|
- radiance load supports sequential read
|
||||||
|
- rewritten radiance decode is much faster
|
||||||
|
|
||||||
18/10/13 started 7.36.3
|
18/10/13 started 7.36.3
|
||||||
- fix compiler warnings in ubuntu 13.10
|
- fix compiler warnings in ubuntu 13.10
|
||||||
|
1
TODO
1
TODO
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
- do conv and morph quickly as simple wrappers over the vips7 operations
|
- do conv and morph quickly as simple wrappers over the vips7 operations
|
||||||
|
|
||||||
- add vips_gaussian_blur() with approx / int / float precision, maybe
|
- add vips_gaussian_blur() with approx / int / float precision, maybe
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
* - tag RGB rad images as scRGB
|
* - tag RGB rad images as scRGB
|
||||||
* 4/11/13
|
* 4/11/13
|
||||||
* - support sequential read
|
* - support sequential read
|
||||||
|
* 5/11/13
|
||||||
|
* - rewritten read, now much faster
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -582,97 +584,161 @@ char *buf;
|
|||||||
#define MAXELEN 0x7fff /* maximum scanline length for encoding */
|
#define MAXELEN 0x7fff /* maximum scanline length for encoding */
|
||||||
#define MINRUN 4 /* minimum run length */
|
#define MINRUN 4 /* minimum run length */
|
||||||
|
|
||||||
|
#define BUFFER_SIZE (4096)
|
||||||
|
#define BUFFER_MARGIN (256)
|
||||||
|
|
||||||
|
static unsigned char buffer[BUFFER_SIZE + BUFFER_MARGIN];
|
||||||
|
static int buffer_length = 0;
|
||||||
|
static int buffer_position = 0;
|
||||||
|
static FILE *buffer_fp = NULL;
|
||||||
|
|
||||||
|
static void
|
||||||
|
buffer_init( FILE *fp )
|
||||||
|
{
|
||||||
|
buffer_length = 0;
|
||||||
|
buffer_position = 0;
|
||||||
|
buffer_fp = fp;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
oldreadcolrs(scanline, len, fp) /* read in an old colr scanline */
|
buffer_need( int require )
|
||||||
register COLR *scanline;
|
|
||||||
int len;
|
|
||||||
register FILE *fp;
|
|
||||||
{
|
{
|
||||||
int rshift;
|
int remaining;
|
||||||
register int i;
|
|
||||||
|
g_assert( require < BUFFER_MARGIN );
|
||||||
|
|
||||||
|
remaining = buffer_length - buffer_position;
|
||||||
|
if( remaining < require ) {
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
memcpy( buffer, buffer + buffer_position, remaining );
|
||||||
|
buffer_position = 0;
|
||||||
|
buffer_length = remaining;
|
||||||
|
|
||||||
|
len = fread( buffer + buffer_length, 1, BUFFER_SIZE,
|
||||||
|
buffer_fp );
|
||||||
|
buffer_length += len;
|
||||||
|
remaining = buffer_length - buffer_position;
|
||||||
|
|
||||||
|
if( remaining < require ) {
|
||||||
|
vips_error( "rad2vips", "%s", _( "end of file" ) );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BUFFER_FETCH (buffer[buffer_position++])
|
||||||
|
#define BUFFER_PEEK (buffer[buffer_position])
|
||||||
|
|
||||||
|
/* Read a single scanlne, encoded in the old style.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
scanline_read_old( COLR *scanline, int width )
|
||||||
|
{
|
||||||
|
int rshift;
|
||||||
|
|
||||||
rshift = 0;
|
rshift = 0;
|
||||||
|
|
||||||
while (len > 0) {
|
while( width > 0 ) {
|
||||||
scanline[0][RED] = getc(fp);
|
if( buffer_need( 4 ) )
|
||||||
scanline[0][GRN] = getc(fp);
|
return( -1 );
|
||||||
scanline[0][BLU] = getc(fp);
|
|
||||||
scanline[0][EXP] = getc(fp);
|
scanline[0][RED] = BUFFER_FETCH;
|
||||||
if (feof(fp) || ferror(fp))
|
scanline[0][GRN] = BUFFER_FETCH;
|
||||||
return(-1);
|
scanline[0][BLU] = BUFFER_FETCH;
|
||||||
if (scanline[0][RED] == 1 &&
|
scanline[0][EXP] = BUFFER_FETCH;
|
||||||
scanline[0][GRN] == 1 &&
|
|
||||||
scanline[0][BLU] == 1) {
|
if( scanline[0][RED] == 1 &&
|
||||||
for (i = scanline[0][EXP] << rshift; i > 0; i--) {
|
scanline[0][GRN] == 1 &&
|
||||||
copycolr(scanline[0], scanline[-1]);
|
scanline[0][BLU] == 1 ) {
|
||||||
scanline++;
|
int i;
|
||||||
len--;
|
|
||||||
|
for( i = scanline[0][EXP] << rshift; i > 0; i-- ) {
|
||||||
|
copycolr( scanline[0], scanline[-1] );
|
||||||
|
scanline += 1;
|
||||||
|
width -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rshift += 8;
|
rshift += 8;
|
||||||
} else {
|
}
|
||||||
scanline++;
|
else {
|
||||||
len--;
|
scanline += 1;
|
||||||
|
width -= 1;
|
||||||
rshift = 0;
|
rshift = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(0);
|
|
||||||
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read a single encoded scanline.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
freadcolrs(scanline, len, fp) /* read in an encoded colr scanline */
|
scanline_read( COLR *scanline, int width )
|
||||||
register COLR *scanline;
|
|
||||||
int len;
|
|
||||||
register FILE *fp;
|
|
||||||
{
|
{
|
||||||
register int i, j;
|
int i, j;
|
||||||
int code, val;
|
|
||||||
/* determine scanline type */
|
/* Detect old-style scanlines.
|
||||||
if ((len < MINELEN) | (len > MAXELEN))
|
*/
|
||||||
return(oldreadcolrs(scanline, len, fp));
|
if( width < MINELEN ||
|
||||||
if ((i = getc(fp)) == EOF)
|
width > MAXELEN )
|
||||||
return(-1);
|
return( scanline_read_old( scanline, width ) );
|
||||||
if (i != 2) {
|
|
||||||
ungetc(i, fp);
|
if( buffer_need( 4 ) )
|
||||||
return(oldreadcolrs(scanline, len, fp));
|
return( -1 );
|
||||||
|
|
||||||
|
if( BUFFER_PEEK != 2 )
|
||||||
|
return( scanline_read_old( scanline, width ) );
|
||||||
|
|
||||||
|
scanline[0][RED] = BUFFER_FETCH;
|
||||||
|
scanline[0][GRN] = BUFFER_FETCH;
|
||||||
|
scanline[0][BLU] = BUFFER_FETCH;
|
||||||
|
scanline[0][EXP] = BUFFER_FETCH;
|
||||||
|
if( scanline[0][GRN] != 2 ||
|
||||||
|
scanline[0][BLU] & 128 )
|
||||||
|
return( scanline_read_old( scanline + 1, width - 1 ) );
|
||||||
|
|
||||||
|
if( ((scanline[0][BLU] << 8) | scanline[0][EXP]) != width ) {
|
||||||
|
vips_error( "rad2vips", "%s", _( "scanline length mismatch" ) );
|
||||||
|
return( -1 );
|
||||||
}
|
}
|
||||||
scanline[0][GRN] = getc(fp);
|
|
||||||
scanline[0][BLU] = getc(fp);
|
for( i = 0; i < 4; i++ ) {
|
||||||
if ((i = getc(fp)) == EOF)
|
for( j = 0; j < width; ) {
|
||||||
return(-1);
|
int code, len;
|
||||||
if (scanline[0][GRN] != 2 || scanline[0][BLU] & 128) {
|
gboolean run;
|
||||||
scanline[0][RED] = 2;
|
|
||||||
scanline[0][EXP] = i;
|
if( buffer_need( 2 ) )
|
||||||
return(oldreadcolrs(scanline+1, len-1, fp));
|
return( -1 );
|
||||||
}
|
|
||||||
if ((scanline[0][BLU]<<8 | i) != len)
|
code = BUFFER_FETCH;
|
||||||
return(-1); /* length mismatch! */
|
run = code > 128;
|
||||||
/* read each component */
|
len = run ? code & 127 : code;
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
for (j = 0; j < len; ) {
|
if( j + len > width ) {
|
||||||
if ((code = getc(fp)) == EOF)
|
vips_error( "rad2vips", "%s", _( "overrun" ) );
|
||||||
return(-1);
|
return( -1 );
|
||||||
if (code > 128) { /* run */
|
}
|
||||||
code &= 127;
|
|
||||||
if ((val = getc(fp)) == EOF)
|
if( run ) {
|
||||||
return -1;
|
int val;
|
||||||
if (j + code > len)
|
|
||||||
return -1; /* overrun */
|
val = BUFFER_FETCH;
|
||||||
while (code--)
|
while( len-- )
|
||||||
scanline[j++][i] = val;
|
scanline[j++][i] = val;
|
||||||
} else { /* non-run */
|
}
|
||||||
if (j + code > len)
|
else {
|
||||||
return -1; /* overrun */
|
if( buffer_need( len ) )
|
||||||
while (code--) {
|
return( -1 );
|
||||||
if ((val = getc(fp)) == EOF)
|
while( len-- )
|
||||||
return -1;
|
scanline[j++][i] = BUFFER_FETCH;
|
||||||
scanline[j++][i] = val;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(0);
|
|
||||||
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -834,6 +900,7 @@ read_new( const char *filename, VipsImage *out )
|
|||||||
|
|
||||||
if( !(read->fin = vips__file_open_read( filename, NULL, FALSE )) )
|
if( !(read->fin = vips__file_open_read( filename, NULL, FALSE )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
buffer_init( read->fin );
|
||||||
|
|
||||||
return( read );
|
return( read );
|
||||||
}
|
}
|
||||||
@ -960,8 +1027,9 @@ rad2vips_generate( VipsRegion *or,
|
|||||||
COLR *buf = (COLR *)
|
COLR *buf = (COLR *)
|
||||||
VIPS_REGION_ADDR( or, 0, r->top + y );
|
VIPS_REGION_ADDR( or, 0, r->top + y );
|
||||||
|
|
||||||
if( freadcolrs( buf, or->im->Xsize, read->fin ) ) {
|
if( scanline_read( buf, or->im->Xsize ) ) {
|
||||||
vips_error( "rad2vips", "%s", _( "read error" ) );
|
vips_error( "rad2vips",
|
||||||
|
_( "read error line %d" ), r->top + y );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user