Merge remote-tracking branch 'origin/7.38'
Conflicts: ChangeLog configure.ac libvips/conversion/falsecolour.c libvips/resample/affine.c
This commit is contained in:
commit
13a6ed1457
@ -1,4 +1,12 @@
|
|||||||
21/1/14 started 7.39.0
|
21/1/14 started 7.39.0
|
||||||
|
- fancy auto-decode for all operations
|
||||||
|
|
||||||
|
22/1/14 started 7.38.2
|
||||||
|
- auto RAD decode for affine
|
||||||
|
- falsecolour was not working for some image types
|
||||||
|
- foreign memory buffer images did not have the right dhint, broke
|
||||||
|
command-line falsecolour on sequential images
|
||||||
|
- support many Radiance readers active at once
|
||||||
|
|
||||||
19/1/14 started 7.38.1
|
19/1/14 started 7.38.1
|
||||||
- bump soname, thanks benjamin
|
- bump soname, thanks benjamin
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
* - force input to mono 8-bit for the user
|
* - force input to mono 8-bit for the user
|
||||||
* 1/8/13
|
* 1/8/13
|
||||||
* - redone as a class
|
* - redone as a class
|
||||||
|
* 23/1/14
|
||||||
|
* - oops, was not auto-getting and casting the first band
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -342,11 +344,14 @@ vips_falsecolour_build( VipsObject *object )
|
|||||||
VIPS_FORMAT_UCHAR )) )
|
VIPS_FORMAT_UCHAR )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
/* Force to mono 8-bit.
|
/* Force to mono 8-bit. Don't use vips_colourspace() to go to B_W, we
|
||||||
|
* want to work for images which aren't in a recognised space, like
|
||||||
|
* MULTIBAND.
|
||||||
*/
|
*/
|
||||||
if( vips_colourspace( falsecolour->in, &t[1],
|
if( vips_check_uncoded( class->nickname, falsecolour->in ) ||
|
||||||
VIPS_INTERPRETATION_B_W, NULL ) ||
|
vips_extract_band( falsecolour->in, &t[1], 0, NULL ) ||
|
||||||
vips_maplut( t[1], &t[3], t[0], NULL ) ||
|
vips_cast( t[1], &t[2], VIPS_FORMAT_UCHAR, NULL ) ||
|
||||||
|
vips_maplut( t[2], &t[3], t[0], NULL ) ||
|
||||||
vips_image_write( t[3], conversion->out ) )
|
vips_image_write( t[3], conversion->out ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
|
@ -150,6 +150,10 @@ typedef struct _ReadJpeg {
|
|||||||
/* Set if we need to finish the decompress.
|
/* Set if we need to finish the decompress.
|
||||||
*/
|
*/
|
||||||
gboolean decompressing;
|
gboolean decompressing;
|
||||||
|
|
||||||
|
/* Track the y pos during a read with this.
|
||||||
|
*/
|
||||||
|
int y_pos;
|
||||||
} ReadJpeg;
|
} ReadJpeg;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -222,6 +226,8 @@ readjpeg_new( VipsImage *out, int shrink, gboolean fail, gboolean readbehind )
|
|||||||
jpeg->eman.pub.output_message = vips__new_output_message;
|
jpeg->eman.pub.output_message = vips__new_output_message;
|
||||||
jpeg->eman.fp = NULL;
|
jpeg->eman.fp = NULL;
|
||||||
|
|
||||||
|
jpeg->y_pos = 0;
|
||||||
|
|
||||||
/* jpeg_create_decompress() can fail on some sanity checks. Don't
|
/* jpeg_create_decompress() can fail on some sanity checks. Don't
|
||||||
* readjpeg_free() since we don't want to jpeg_destroy_decompress().
|
* readjpeg_free() since we don't want to jpeg_destroy_decompress().
|
||||||
*/
|
*/
|
||||||
@ -888,7 +894,7 @@ read_jpeg_generate( VipsRegion *or,
|
|||||||
printf( "read_jpeg_generate: line %d, %d rows\n",
|
printf( "read_jpeg_generate: line %d, %d rows\n",
|
||||||
r->top, r->height );
|
r->top, r->height );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
VIPS_GATE_START( "read_jpeg_generate: work" );
|
VIPS_GATE_START( "read_jpeg_generate: work" );
|
||||||
|
|
||||||
/* We're inside a tilecache where tiles are the full image width, so
|
/* We're inside a tilecache where tiles are the full image width, so
|
||||||
@ -907,6 +913,11 @@ read_jpeg_generate( VipsRegion *or,
|
|||||||
*/
|
*/
|
||||||
g_assert( r->height == VIPS_MIN( 8, or->im->Ysize - r->top ) );
|
g_assert( r->height == VIPS_MIN( 8, or->im->Ysize - r->top ) );
|
||||||
|
|
||||||
|
/* And check that y_pos is correct. It should be, since we are inside
|
||||||
|
* a vips_sequential().
|
||||||
|
*/
|
||||||
|
g_assert( r->top == jpeg->y_pos );
|
||||||
|
|
||||||
/* Here for longjmp() from vips__new_error_exit().
|
/* Here for longjmp() from vips__new_error_exit().
|
||||||
*/
|
*/
|
||||||
if( setjmp( jpeg->eman.jmp ) )
|
if( setjmp( jpeg->eman.jmp ) )
|
||||||
@ -926,6 +937,8 @@ read_jpeg_generate( VipsRegion *or,
|
|||||||
for( x = 0; x < sz; x++ )
|
for( x = 0; x < sz; x++ )
|
||||||
row_pointer[0][x] = 255 - row_pointer[0][x];
|
row_pointer[0][x] = 255 - row_pointer[0][x];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jpeg->y_pos += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
VIPS_GATE_STOP( "read_jpeg_generate: work" );
|
VIPS_GATE_STOP( "read_jpeg_generate: work" );
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
* - support sequential read
|
* - support sequential read
|
||||||
* 5/11/13
|
* 5/11/13
|
||||||
* - rewritten scanline encode and decode, now much faster
|
* - rewritten scanline encode and decode, now much faster
|
||||||
|
* 23/1/14
|
||||||
|
* - put the reader globals into a struct so we can have many active
|
||||||
|
* readers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -617,38 +620,57 @@ register RESOLU *rp;
|
|||||||
#define BUFFER_SIZE (4096)
|
#define BUFFER_SIZE (4096)
|
||||||
#define BUFFER_MARGIN (256)
|
#define BUFFER_MARGIN (256)
|
||||||
|
|
||||||
static unsigned char buffer[BUFFER_SIZE + BUFFER_MARGIN];
|
/* Read from a FILE with a rolling memory buffer ... this lets us reduce the
|
||||||
static int buffer_length = 0;
|
* number of fgetc() and gives us some very quick readahead.
|
||||||
static int buffer_position = 0;
|
*/
|
||||||
static FILE *buffer_fp = NULL;
|
|
||||||
|
|
||||||
static void
|
typedef struct _Buffer {
|
||||||
buffer_init( FILE *fp )
|
unsigned char text[BUFFER_SIZE + BUFFER_MARGIN];
|
||||||
|
int length;
|
||||||
|
int position;
|
||||||
|
FILE *fp;
|
||||||
|
} Buffer;
|
||||||
|
|
||||||
|
static Buffer *
|
||||||
|
buffer_new( FILE *fp )
|
||||||
{
|
{
|
||||||
buffer_length = 0;
|
Buffer *buffer = g_new0( Buffer, 1 );
|
||||||
buffer_position = 0;
|
|
||||||
buffer_fp = fp;
|
buffer->length = 0;
|
||||||
|
buffer->position = 0;
|
||||||
|
buffer->fp = fp;
|
||||||
|
|
||||||
|
return( buffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
buffer_free( Buffer *buffer )
|
||||||
|
{
|
||||||
|
g_free( buffer );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure there are at least @require bytes of readahead available.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
buffer_need( int require )
|
buffer_need( Buffer *buffer, int require )
|
||||||
{
|
{
|
||||||
int remaining;
|
int remaining;
|
||||||
|
|
||||||
g_assert( require < BUFFER_MARGIN );
|
g_assert( require < BUFFER_MARGIN );
|
||||||
|
|
||||||
remaining = buffer_length - buffer_position;
|
remaining = buffer->length - buffer->position;
|
||||||
if( remaining < require ) {
|
if( remaining < require ) {
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
memcpy( buffer, buffer + buffer_position, remaining );
|
memcpy( buffer->text,
|
||||||
buffer_position = 0;
|
buffer->text + buffer->position, remaining );
|
||||||
buffer_length = remaining;
|
buffer->position = 0;
|
||||||
|
buffer->length = remaining;
|
||||||
|
|
||||||
len = fread( buffer + buffer_length, 1, BUFFER_SIZE,
|
len = fread( buffer->text + buffer->length,
|
||||||
buffer_fp );
|
1, BUFFER_SIZE, buffer->fp );
|
||||||
buffer_length += len;
|
buffer->length += len;
|
||||||
remaining = buffer_length - buffer_position;
|
remaining = buffer->length - buffer->position;
|
||||||
|
|
||||||
if( remaining < require ) {
|
if( remaining < require ) {
|
||||||
vips_error( "rad2vips", "%s", _( "end of file" ) );
|
vips_error( "rad2vips", "%s", _( "end of file" ) );
|
||||||
@ -659,26 +681,26 @@ buffer_need( int require )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BUFFER_FETCH (buffer[buffer_position++])
|
#define BUFFER_FETCH(B) ((B)->text[(B)->position++])
|
||||||
#define BUFFER_PEEK (buffer[buffer_position])
|
#define BUFFER_PEEK(B) ((B)->text[(B)->position])
|
||||||
|
|
||||||
/* Read a single scanlne, encoded in the old style.
|
/* Read a single scanlne, encoded in the old style.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
scanline_read_old( COLR *scanline, int width )
|
scanline_read_old( Buffer *buffer, COLR *scanline, int width )
|
||||||
{
|
{
|
||||||
int rshift;
|
int rshift;
|
||||||
|
|
||||||
rshift = 0;
|
rshift = 0;
|
||||||
|
|
||||||
while( width > 0 ) {
|
while( width > 0 ) {
|
||||||
if( buffer_need( 4 ) )
|
if( buffer_need( buffer, 4 ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
scanline[0][RED] = BUFFER_FETCH;
|
scanline[0][RED] = BUFFER_FETCH( buffer );
|
||||||
scanline[0][GRN] = BUFFER_FETCH;
|
scanline[0][GRN] = BUFFER_FETCH( buffer );
|
||||||
scanline[0][BLU] = BUFFER_FETCH;
|
scanline[0][BLU] = BUFFER_FETCH( buffer );
|
||||||
scanline[0][EXP] = BUFFER_FETCH;
|
scanline[0][EXP] = BUFFER_FETCH( buffer );
|
||||||
|
|
||||||
if( scanline[0][RED] == 1 &&
|
if( scanline[0][RED] == 1 &&
|
||||||
scanline[0][GRN] == 1 &&
|
scanline[0][GRN] == 1 &&
|
||||||
@ -706,7 +728,7 @@ scanline_read_old( COLR *scanline, int width )
|
|||||||
/* Read a single encoded scanline.
|
/* Read a single encoded scanline.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
scanline_read( COLR *scanline, int width )
|
scanline_read( Buffer *buffer, COLR *scanline, int width )
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
@ -714,21 +736,21 @@ scanline_read( COLR *scanline, int width )
|
|||||||
*/
|
*/
|
||||||
if( width < MINELEN ||
|
if( width < MINELEN ||
|
||||||
width > MAXELEN )
|
width > MAXELEN )
|
||||||
return( scanline_read_old( scanline, width ) );
|
return( scanline_read_old( buffer, scanline, width ) );
|
||||||
|
|
||||||
if( buffer_need( 4 ) )
|
if( buffer_need( buffer, 4 ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( BUFFER_PEEK != 2 )
|
if( BUFFER_PEEK( buffer ) != 2 )
|
||||||
return( scanline_read_old( scanline, width ) );
|
return( scanline_read_old( buffer, scanline, width ) );
|
||||||
|
|
||||||
scanline[0][RED] = BUFFER_FETCH;
|
scanline[0][RED] = BUFFER_FETCH( buffer );
|
||||||
scanline[0][GRN] = BUFFER_FETCH;
|
scanline[0][GRN] = BUFFER_FETCH( buffer );
|
||||||
scanline[0][BLU] = BUFFER_FETCH;
|
scanline[0][BLU] = BUFFER_FETCH( buffer );
|
||||||
scanline[0][EXP] = BUFFER_FETCH;
|
scanline[0][EXP] = BUFFER_FETCH( buffer );
|
||||||
if( scanline[0][GRN] != 2 ||
|
if( scanline[0][GRN] != 2 ||
|
||||||
scanline[0][BLU] & 128 )
|
scanline[0][BLU] & 128 )
|
||||||
return( scanline_read_old( scanline + 1, width - 1 ) );
|
return( scanline_read_old( buffer, scanline + 1, width - 1 ) );
|
||||||
|
|
||||||
if( ((scanline[0][BLU] << 8) | scanline[0][EXP]) != width ) {
|
if( ((scanline[0][BLU] << 8) | scanline[0][EXP]) != width ) {
|
||||||
vips_error( "rad2vips", "%s", _( "scanline length mismatch" ) );
|
vips_error( "rad2vips", "%s", _( "scanline length mismatch" ) );
|
||||||
@ -740,10 +762,10 @@ scanline_read( COLR *scanline, int width )
|
|||||||
int code, len;
|
int code, len;
|
||||||
gboolean run;
|
gboolean run;
|
||||||
|
|
||||||
if( buffer_need( 2 ) )
|
if( buffer_need( buffer, 2 ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
code = BUFFER_FETCH;
|
code = BUFFER_FETCH( buffer );
|
||||||
run = code > 128;
|
run = code > 128;
|
||||||
len = run ? code & 127 : code;
|
len = run ? code & 127 : code;
|
||||||
|
|
||||||
@ -755,15 +777,16 @@ scanline_read( COLR *scanline, int width )
|
|||||||
if( run ) {
|
if( run ) {
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
val = BUFFER_FETCH;
|
val = BUFFER_FETCH( buffer );
|
||||||
while( len-- )
|
while( len-- )
|
||||||
scanline[j++][i] = val;
|
scanline[j++][i] = val;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if( buffer_need( len ) )
|
if( buffer_need( buffer, len ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
while( len-- )
|
while( len-- )
|
||||||
scanline[j++][i] = BUFFER_FETCH;
|
scanline[j++][i] =
|
||||||
|
BUFFER_FETCH( buffer );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,6 +884,7 @@ typedef struct {
|
|||||||
double aspect;
|
double aspect;
|
||||||
RGBPRIMS prims;
|
RGBPRIMS prims;
|
||||||
RESOLU rs;
|
RESOLU rs;
|
||||||
|
Buffer *buffer;
|
||||||
} Read;
|
} Read;
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -888,7 +912,7 @@ read_destroy( VipsObject *object, Read *read )
|
|||||||
{
|
{
|
||||||
VIPS_FREE( read->filename );
|
VIPS_FREE( read->filename );
|
||||||
VIPS_FREEF( fclose, read->fin );
|
VIPS_FREEF( fclose, read->fin );
|
||||||
buffer_init( NULL );
|
VIPS_FREEF( buffer_free, read->buffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
static Read *
|
static Read *
|
||||||
@ -920,9 +944,9 @@ read_new( const char *filename, VipsImage *out )
|
|||||||
g_signal_connect( out, "close",
|
g_signal_connect( out, "close",
|
||||||
G_CALLBACK( read_destroy ), read );
|
G_CALLBACK( read_destroy ), read );
|
||||||
|
|
||||||
if( !(read->fin = vips__file_open_read( filename, NULL, FALSE )) )
|
if( !(read->fin = vips__file_open_read( filename, NULL, FALSE )) ||
|
||||||
|
!(read->buffer = buffer_new( read->fin )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
buffer_init( read->fin );
|
|
||||||
|
|
||||||
return( read );
|
return( read );
|
||||||
}
|
}
|
||||||
@ -1037,24 +1061,30 @@ rad2vips_generate( VipsRegion *or,
|
|||||||
void *seq, void *a, void *b, gboolean *stop )
|
void *seq, void *a, void *b, gboolean *stop )
|
||||||
{
|
{
|
||||||
VipsRect *r = &or->valid;
|
VipsRect *r = &or->valid;
|
||||||
|
Read *read = (Read *) a;
|
||||||
|
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "rad2vips_get_data\n" );
|
printf( "rad2vips_generate: line %d, %d rows\n",
|
||||||
|
r->top, r->height );
|
||||||
#endif /*DEBUG*/
|
#endif /*DEBUG*/
|
||||||
|
|
||||||
|
VIPS_GATE_START( "rad2vips_generate: work" );
|
||||||
|
|
||||||
for( y = 0; y < r->height; y++ ) {
|
for( y = 0; y < r->height; y++ ) {
|
||||||
COLR *buf = (COLR *)
|
COLR *buf = (COLR *)
|
||||||
VIPS_REGION_ADDR( or, 0, r->top + y );
|
VIPS_REGION_ADDR( or, 0, r->top + y );
|
||||||
|
|
||||||
if( scanline_read( buf, or->im->Xsize ) ) {
|
if( scanline_read( read->buffer, buf, or->im->Xsize ) ) {
|
||||||
vips_error( "rad2vips",
|
vips_error( "rad2vips",
|
||||||
_( "read error line %d" ), r->top + y );
|
_( "read error line %d" ), r->top + y );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VIPS_GATE_STOP( "rad2vips_generate: work" );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -937,6 +937,7 @@ vips_image_build( VipsObject *object )
|
|||||||
image->Type = VIPS_INTERPRETATION_MULTIBAND;
|
image->Type = VIPS_INTERPRETATION_MULTIBAND;
|
||||||
|
|
||||||
image->dtype = VIPS_IMAGE_SETBUF_FOREIGN;
|
image->dtype = VIPS_IMAGE_SETBUF_FOREIGN;
|
||||||
|
image->dhint = VIPS_DEMAND_STYLE_ANY;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -79,6 +79,8 @@
|
|||||||
* 14/12/12
|
* 14/12/12
|
||||||
* - redone as a class
|
* - redone as a class
|
||||||
* - added input space translation
|
* - added input space translation
|
||||||
|
* 22/1/14
|
||||||
|
* - auto RAD decode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -412,7 +414,7 @@ vips_affine_build( VipsObject *object )
|
|||||||
if( VIPS_OBJECT_CLASS( vips_affine_parent_class )->build( object ) )
|
if( VIPS_OBJECT_CLASS( vips_affine_parent_class )->build( object ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( vips_check_coding_noneorlabq( class->nickname, resample->in ) )
|
if( vips_check_coding_known( class->nickname, resample->in ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
if( vips_check_vector_length( class->nickname,
|
if( vips_check_vector_length( class->nickname,
|
||||||
affine->matrix->n, 4 ) )
|
affine->matrix->n, 4 ) )
|
||||||
@ -483,21 +485,19 @@ vips_affine_build( VipsObject *object )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unpack labq for processing.
|
|
||||||
*/
|
|
||||||
if( vips__image_decode( in, &t[0] ) )
|
if( vips__image_decode( in, &t[0] ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
in = t[0];
|
in = t[0];
|
||||||
|
|
||||||
/* Add new pixels around the input so we can interpolate at the edges.
|
/* Add new pixels around the input so we can interpolate at the edges.
|
||||||
*/
|
*/
|
||||||
if( vips_embed( in, &t[1],
|
if( vips_embed( in, &t[2],
|
||||||
window_offset, window_offset,
|
window_offset, window_offset,
|
||||||
in->Xsize + window_size, in->Ysize + window_size,
|
in->Xsize + window_size, in->Ysize + window_size,
|
||||||
"extend", VIPS_EXTEND_COPY,
|
"extend", VIPS_EXTEND_COPY,
|
||||||
NULL ) )
|
NULL ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
in = t[1];
|
in = t[2];
|
||||||
|
|
||||||
/* Normally SMALLTILE ... except if this is a size up/down affine.
|
/* Normally SMALLTILE ... except if this is a size up/down affine.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user