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
|
||||
- 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
|
||||
- bump soname, thanks benjamin
|
||||
|
@ -14,6 +14,8 @@
|
||||
* - force input to mono 8-bit for the user
|
||||
* 1/8/13
|
||||
* - 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 )) )
|
||||
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],
|
||||
VIPS_INTERPRETATION_B_W, NULL ) ||
|
||||
vips_maplut( t[1], &t[3], t[0], NULL ) ||
|
||||
if( vips_check_uncoded( class->nickname, falsecolour->in ) ||
|
||||
vips_extract_band( falsecolour->in, &t[1], 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 ) )
|
||||
return( -1 );
|
||||
|
||||
|
@ -150,6 +150,10 @@ typedef struct _ReadJpeg {
|
||||
/* Set if we need to finish the decompress.
|
||||
*/
|
||||
gboolean decompressing;
|
||||
|
||||
/* Track the y pos during a read with this.
|
||||
*/
|
||||
int y_pos;
|
||||
} ReadJpeg;
|
||||
|
||||
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.fp = NULL;
|
||||
|
||||
jpeg->y_pos = 0;
|
||||
|
||||
/* jpeg_create_decompress() can fail on some sanity checks. Don't
|
||||
* 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",
|
||||
r->top, r->height );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
|
||||
VIPS_GATE_START( "read_jpeg_generate: work" );
|
||||
|
||||
/* 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 ) );
|
||||
|
||||
/* 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().
|
||||
*/
|
||||
if( setjmp( jpeg->eman.jmp ) )
|
||||
@ -926,6 +937,8 @@ read_jpeg_generate( VipsRegion *or,
|
||||
for( x = 0; x < sz; x++ )
|
||||
row_pointer[0][x] = 255 - row_pointer[0][x];
|
||||
}
|
||||
|
||||
jpeg->y_pos += 1;
|
||||
}
|
||||
|
||||
VIPS_GATE_STOP( "read_jpeg_generate: work" );
|
||||
|
@ -12,6 +12,9 @@
|
||||
* - support sequential read
|
||||
* 5/11/13
|
||||
* - 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_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;
|
||||
/* Read from a FILE with a rolling memory buffer ... this lets us reduce the
|
||||
* number of fgetc() and gives us some very quick readahead.
|
||||
*/
|
||||
|
||||
static void
|
||||
buffer_init( FILE *fp )
|
||||
typedef struct _Buffer {
|
||||
unsigned char text[BUFFER_SIZE + BUFFER_MARGIN];
|
||||
int length;
|
||||
int position;
|
||||
FILE *fp;
|
||||
} Buffer;
|
||||
|
||||
static Buffer *
|
||||
buffer_new( FILE *fp )
|
||||
{
|
||||
buffer_length = 0;
|
||||
buffer_position = 0;
|
||||
buffer_fp = fp;
|
||||
Buffer *buffer = g_new0( Buffer, 1 );
|
||||
|
||||
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
|
||||
buffer_need( int require )
|
||||
buffer_need( Buffer *buffer, int require )
|
||||
{
|
||||
int remaining;
|
||||
|
||||
g_assert( require < BUFFER_MARGIN );
|
||||
|
||||
remaining = buffer_length - buffer_position;
|
||||
remaining = buffer->length - buffer->position;
|
||||
if( remaining < require ) {
|
||||
size_t len;
|
||||
|
||||
memcpy( buffer, buffer + buffer_position, remaining );
|
||||
buffer_position = 0;
|
||||
buffer_length = remaining;
|
||||
memcpy( buffer->text,
|
||||
buffer->text + 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;
|
||||
len = fread( buffer->text + 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" ) );
|
||||
@ -659,26 +681,26 @@ buffer_need( int require )
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#define BUFFER_FETCH (buffer[buffer_position++])
|
||||
#define BUFFER_PEEK (buffer[buffer_position])
|
||||
#define BUFFER_FETCH(B) ((B)->text[(B)->position++])
|
||||
#define BUFFER_PEEK(B) ((B)->text[(B)->position])
|
||||
|
||||
/* Read a single scanlne, encoded in the old style.
|
||||
*/
|
||||
static int
|
||||
scanline_read_old( COLR *scanline, int width )
|
||||
scanline_read_old( Buffer *buffer, COLR *scanline, int width )
|
||||
{
|
||||
int rshift;
|
||||
|
||||
rshift = 0;
|
||||
|
||||
while( width > 0 ) {
|
||||
if( buffer_need( 4 ) )
|
||||
if( buffer_need( buffer, 4 ) )
|
||||
return( -1 );
|
||||
|
||||
scanline[0][RED] = BUFFER_FETCH;
|
||||
scanline[0][GRN] = BUFFER_FETCH;
|
||||
scanline[0][BLU] = BUFFER_FETCH;
|
||||
scanline[0][EXP] = BUFFER_FETCH;
|
||||
scanline[0][RED] = BUFFER_FETCH( buffer );
|
||||
scanline[0][GRN] = BUFFER_FETCH( buffer );
|
||||
scanline[0][BLU] = BUFFER_FETCH( buffer );
|
||||
scanline[0][EXP] = BUFFER_FETCH( buffer );
|
||||
|
||||
if( scanline[0][RED] == 1 &&
|
||||
scanline[0][GRN] == 1 &&
|
||||
@ -706,7 +728,7 @@ scanline_read_old( COLR *scanline, int width )
|
||||
/* Read a single encoded scanline.
|
||||
*/
|
||||
static int
|
||||
scanline_read( COLR *scanline, int width )
|
||||
scanline_read( Buffer *buffer, COLR *scanline, int width )
|
||||
{
|
||||
int i, j;
|
||||
|
||||
@ -714,21 +736,21 @@ scanline_read( COLR *scanline, int width )
|
||||
*/
|
||||
if( width < MINELEN ||
|
||||
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 );
|
||||
|
||||
if( BUFFER_PEEK != 2 )
|
||||
return( scanline_read_old( scanline, width ) );
|
||||
if( BUFFER_PEEK( buffer ) != 2 )
|
||||
return( scanline_read_old( buffer, scanline, width ) );
|
||||
|
||||
scanline[0][RED] = BUFFER_FETCH;
|
||||
scanline[0][GRN] = BUFFER_FETCH;
|
||||
scanline[0][BLU] = BUFFER_FETCH;
|
||||
scanline[0][EXP] = BUFFER_FETCH;
|
||||
scanline[0][RED] = BUFFER_FETCH( buffer );
|
||||
scanline[0][GRN] = BUFFER_FETCH( buffer );
|
||||
scanline[0][BLU] = BUFFER_FETCH( buffer );
|
||||
scanline[0][EXP] = BUFFER_FETCH( buffer );
|
||||
if( scanline[0][GRN] != 2 ||
|
||||
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 ) {
|
||||
vips_error( "rad2vips", "%s", _( "scanline length mismatch" ) );
|
||||
@ -740,10 +762,10 @@ scanline_read( COLR *scanline, int width )
|
||||
int code, len;
|
||||
gboolean run;
|
||||
|
||||
if( buffer_need( 2 ) )
|
||||
if( buffer_need( buffer, 2 ) )
|
||||
return( -1 );
|
||||
|
||||
code = BUFFER_FETCH;
|
||||
code = BUFFER_FETCH( buffer );
|
||||
run = code > 128;
|
||||
len = run ? code & 127 : code;
|
||||
|
||||
@ -755,15 +777,16 @@ scanline_read( COLR *scanline, int width )
|
||||
if( run ) {
|
||||
int val;
|
||||
|
||||
val = BUFFER_FETCH;
|
||||
val = BUFFER_FETCH( buffer );
|
||||
while( len-- )
|
||||
scanline[j++][i] = val;
|
||||
}
|
||||
else {
|
||||
if( buffer_need( len ) )
|
||||
if( buffer_need( buffer, len ) )
|
||||
return( -1 );
|
||||
while( len-- )
|
||||
scanline[j++][i] = BUFFER_FETCH;
|
||||
scanline[j++][i] =
|
||||
BUFFER_FETCH( buffer );
|
||||
}
|
||||
}
|
||||
|
||||
@ -861,6 +884,7 @@ typedef struct {
|
||||
double aspect;
|
||||
RGBPRIMS prims;
|
||||
RESOLU rs;
|
||||
Buffer *buffer;
|
||||
} Read;
|
||||
|
||||
int
|
||||
@ -888,7 +912,7 @@ read_destroy( VipsObject *object, Read *read )
|
||||
{
|
||||
VIPS_FREE( read->filename );
|
||||
VIPS_FREEF( fclose, read->fin );
|
||||
buffer_init( NULL );
|
||||
VIPS_FREEF( buffer_free, read->buffer );
|
||||
}
|
||||
|
||||
static Read *
|
||||
@ -920,9 +944,9 @@ read_new( const char *filename, VipsImage *out )
|
||||
g_signal_connect( out, "close",
|
||||
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 );
|
||||
buffer_init( read->fin );
|
||||
|
||||
return( read );
|
||||
}
|
||||
@ -1037,24 +1061,30 @@ rad2vips_generate( VipsRegion *or,
|
||||
void *seq, void *a, void *b, gboolean *stop )
|
||||
{
|
||||
VipsRect *r = &or->valid;
|
||||
Read *read = (Read *) a;
|
||||
|
||||
int y;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "rad2vips_get_data\n" );
|
||||
printf( "rad2vips_generate: line %d, %d rows\n",
|
||||
r->top, r->height );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
VIPS_GATE_START( "rad2vips_generate: work" );
|
||||
|
||||
for( y = 0; y < r->height; y++ ) {
|
||||
COLR *buf = (COLR *)
|
||||
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",
|
||||
_( "read error line %d" ), r->top + y );
|
||||
return( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
VIPS_GATE_STOP( "rad2vips_generate: work" );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
@ -937,6 +937,7 @@ vips_image_build( VipsObject *object )
|
||||
image->Type = VIPS_INTERPRETATION_MULTIBAND;
|
||||
|
||||
image->dtype = VIPS_IMAGE_SETBUF_FOREIGN;
|
||||
image->dhint = VIPS_DEMAND_STYLE_ANY;
|
||||
|
||||
break;
|
||||
|
||||
|
@ -79,6 +79,8 @@
|
||||
* 14/12/12
|
||||
* - redone as a class
|
||||
* - 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 ) )
|
||||
return( -1 );
|
||||
|
||||
if( vips_check_coding_noneorlabq( class->nickname, resample->in ) )
|
||||
if( vips_check_coding_known( class->nickname, resample->in ) )
|
||||
return( -1 );
|
||||
if( vips_check_vector_length( class->nickname,
|
||||
affine->matrix->n, 4 ) )
|
||||
@ -483,21 +485,19 @@ vips_affine_build( VipsObject *object )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* Unpack labq for processing.
|
||||
*/
|
||||
if( vips__image_decode( in, &t[0] ) )
|
||||
return( -1 );
|
||||
in = t[0];
|
||||
|
||||
/* 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,
|
||||
in->Xsize + window_size, in->Ysize + window_size,
|
||||
"extend", VIPS_EXTEND_COPY,
|
||||
NULL ) )
|
||||
return( -1 );
|
||||
in = t[1];
|
||||
in = t[2];
|
||||
|
||||
/* Normally SMALLTILE ... except if this is a size up/down affine.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user