Merge branch 'master' into dzsave-gsf
Conflicts: ChangeLog
This commit is contained in:
commit
1384f9d4e0
@ -28,6 +28,8 @@
|
|||||||
- added vips_foreign_load_buffer(), vips_foreign_save_buffer()
|
- added vips_foreign_load_buffer(), vips_foreign_save_buffer()
|
||||||
- added vips_object_set_from_string()
|
- added vips_object_set_from_string()
|
||||||
- added @container option to dzsave
|
- added @container option to dzsave
|
||||||
|
- support 1/2/4 bit palette tiff images with alpha
|
||||||
|
- vips_system() now uses g_spawn_command_line_sync()
|
||||||
|
|
||||||
6/3/14 started 7.38.6
|
6/3/14 started 7.38.6
|
||||||
- grey ramp minimum was wrong
|
- grey ramp minimum was wrong
|
||||||
|
5
TODO
5
TODO
@ -19,11 +19,6 @@
|
|||||||
|
|
||||||
deprecate this thing and stop ':' split
|
deprecate this thing and stop ':' split
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- support 1/2/4 bit palette tiff with alpha
|
|
||||||
|
|
||||||
- can we use postbuild elsewhere? look at use of "preclose" / "written", etc.
|
- can we use postbuild elsewhere? look at use of "preclose" / "written", etc.
|
||||||
|
|
||||||
|
|
||||||
|
@ -146,6 +146,8 @@
|
|||||||
* - palette images can have an alpha
|
* - palette images can have an alpha
|
||||||
* 22/4/14
|
* 22/4/14
|
||||||
* - add read from buffer
|
* - add read from buffer
|
||||||
|
* 30/4/14
|
||||||
|
* - 1/2/4 bit palette images can have alpha
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -707,12 +709,13 @@ typedef struct {
|
|||||||
gboolean mono;
|
gboolean mono;
|
||||||
} PaletteRead;
|
} PaletteRead;
|
||||||
|
|
||||||
/* Per-scanline process function for palette images.
|
/* 1/2/4 bit samples with an 8-bit palette.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
palette_line_bit( ReadTiff *rtiff, VipsPel *q, VipsPel *p, int n, void *client )
|
palette_line_bit( ReadTiff *rtiff, VipsPel *q, VipsPel *p, int n, void *client )
|
||||||
{
|
{
|
||||||
PaletteRead *read = (PaletteRead *) client;
|
PaletteRead *read = (PaletteRead *) client;
|
||||||
|
int samples = rtiff->samples_per_pixel;
|
||||||
|
|
||||||
int bit;
|
int bit;
|
||||||
VipsPel data;
|
VipsPel data;
|
||||||
@ -720,7 +723,7 @@ palette_line_bit( ReadTiff *rtiff, VipsPel *q, VipsPel *p, int n, void *client )
|
|||||||
|
|
||||||
bit = 0;
|
bit = 0;
|
||||||
data = 0;
|
data = 0;
|
||||||
for( x = 0; x < n; x++ ) {
|
for( x = 0; x < n * samples; x++ ) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if( bit <= 0 ) {
|
if( bit <= 0 ) {
|
||||||
@ -732,10 +735,12 @@ palette_line_bit( ReadTiff *rtiff, VipsPel *q, VipsPel *p, int n, void *client )
|
|||||||
data <<= rtiff->bits_per_sample;
|
data <<= rtiff->bits_per_sample;
|
||||||
bit -= rtiff->bits_per_sample;
|
bit -= rtiff->bits_per_sample;
|
||||||
|
|
||||||
if( read->mono ) {
|
/* The first band goes through the LUT, subsequent bands are
|
||||||
q[0] = read->red8[i];
|
* left-justified and copied.
|
||||||
q += 1;
|
*/
|
||||||
}
|
if( x % samples == 0 ) {
|
||||||
|
if( read->mono )
|
||||||
|
*q++ = read->red8[i];
|
||||||
else {
|
else {
|
||||||
q[0] = read->red8[i];
|
q[0] = read->red8[i];
|
||||||
q[1] = read->green8[i];
|
q[1] = read->green8[i];
|
||||||
@ -743,9 +748,12 @@ palette_line_bit( ReadTiff *rtiff, VipsPel *q, VipsPel *p, int n, void *client )
|
|||||||
q += 3;
|
q += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
*q++ = i << (8 - rtiff->bits_per_sample);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The tiff is 8-bit and can have an alpha.
|
/* 8-bit samples with an 8-bit palette.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
palette_line8( ReadTiff *rtiff, VipsPel *q, VipsPel *p, int n,
|
palette_line8( ReadTiff *rtiff, VipsPel *q, VipsPel *p, int n,
|
||||||
@ -777,7 +785,7 @@ palette_line8( ReadTiff *rtiff, VipsPel *q, VipsPel *p, int n,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 16-bit tiff and can have an alpha.
|
/* 16-bit samples with 16-bit data in the palette.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
palette_line16( ReadTiff *rtiff, VipsPel *q, VipsPel *p, int n,
|
palette_line16( ReadTiff *rtiff, VipsPel *q, VipsPel *p, int n,
|
||||||
@ -827,13 +835,6 @@ parse_palette( ReadTiff *rtiff, VipsImage *out )
|
|||||||
return( -1 );
|
return( -1 );
|
||||||
len = 1 << rtiff->bits_per_sample;
|
len = 1 << rtiff->bits_per_sample;
|
||||||
|
|
||||||
if( rtiff->bits_per_sample < 8 &&
|
|
||||||
rtiff->samples_per_pixel > 1 ) {
|
|
||||||
vips_error( "tiff2vips", "%s", _( "can't have an alpha for "
|
|
||||||
"palette images less than 8 bits per sample" ) );
|
|
||||||
return( -1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !(read = VIPS_NEW( out, PaletteRead )) ||
|
if( !(read = VIPS_NEW( out, PaletteRead )) ||
|
||||||
!(read->red8 = VIPS_ARRAY( out, len, VipsPel )) ||
|
!(read->red8 = VIPS_ARRAY( out, len, VipsPel )) ||
|
||||||
!(read->green8 = VIPS_ARRAY( out, len, VipsPel )) ||
|
!(read->green8 = VIPS_ARRAY( out, len, VipsPel )) ||
|
||||||
|
@ -186,6 +186,8 @@ gboolean vips_ispostfix( const char *a, const char *b );
|
|||||||
gboolean vips_isprefix( const char *a, const char *b );
|
gboolean vips_isprefix( const char *a, const char *b );
|
||||||
char *vips_break_token( char *str, const char *brk );
|
char *vips_break_token( char *str, const char *brk );
|
||||||
|
|
||||||
|
void vips__chomp( char *str );
|
||||||
|
|
||||||
int vips_vsnprintf( char *str, size_t size, const char *format, va_list ap );
|
int vips_vsnprintf( char *str, size_t size, const char *format, va_list ap );
|
||||||
int vips_snprintf( char *str, size_t size, const char *format, ... )
|
int vips_snprintf( char *str, size_t size, const char *format, ... )
|
||||||
__attribute__((format(printf, 3, 4)));
|
__attribute__((format(printf, 3, 4)));
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
* 4/6/13
|
* 4/6/13
|
||||||
* - redo as a class
|
* - redo as a class
|
||||||
* - input and output images are now optional
|
* - input and output images are now optional
|
||||||
|
* 3/5/14
|
||||||
|
* - switch to g_spawn_command_line_sync() from popen() ... helps stop
|
||||||
|
* stray command-windows on Windows
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -120,7 +123,10 @@ vips_system_build( VipsObject *object )
|
|||||||
char txt[VIPS_PATH_MAX];
|
char txt[VIPS_PATH_MAX];
|
||||||
VipsBuf buf = VIPS_BUF_STATIC( txt );
|
VipsBuf buf = VIPS_BUF_STATIC( txt );
|
||||||
char *p;
|
char *p;
|
||||||
|
char *std_output;
|
||||||
|
char *std_error;
|
||||||
int result;
|
int result;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
if( VIPS_OBJECT_CLASS( vips_system_parent_class )->build( object ) )
|
if( VIPS_OBJECT_CLASS( vips_system_parent_class )->build( object ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
@ -174,21 +180,48 @@ vips_system_build( VipsObject *object )
|
|||||||
p[1] == '%' )
|
p[1] == '%' )
|
||||||
memmove( p, p + 1, strlen( p ) );
|
memmove( p, p + 1, strlen( p ) );
|
||||||
|
|
||||||
if( !(fp = vips_popenf( "%s", "r", cmd )) )
|
if( !g_spawn_command_line_sync( cmd,
|
||||||
return( -1 );
|
&std_output, &std_error, &result, &error ) ) {
|
||||||
|
if( error ) {
|
||||||
while( fgets( line, VIPS_PATH_MAX, fp ) )
|
vips_error( class->nickname, "%s", error->message );
|
||||||
if( !vips_buf_appends( &buf, line ) )
|
g_error_free( error );
|
||||||
break;
|
}
|
||||||
|
if( std_error ) {
|
||||||
g_object_set( system, "log", vips_buf_all( &buf ), NULL );
|
vips__chomp( std_error );
|
||||||
|
if( strcmp( std_error, "" ) != 0 )
|
||||||
if( (result = pclose( fp )) ) {
|
|
||||||
vips_error( class->nickname,
|
vips_error( class->nickname,
|
||||||
_( "command failed: \"%s\"" ), system->cmd_format );
|
"error output: %s", std_error );
|
||||||
|
VIPS_FREE( std_error );
|
||||||
|
}
|
||||||
|
if( std_output ) {
|
||||||
|
vips__chomp( std_output );
|
||||||
|
if( strcmp( std_output, "" ) != 0 )
|
||||||
|
vips_error( class->nickname,
|
||||||
|
"output: %s", std_output );
|
||||||
|
VIPS_FREE( std_output );
|
||||||
|
}
|
||||||
|
vips_error_system( result, class->nickname,
|
||||||
|
"%s", _( "command failed" ) );
|
||||||
|
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_assert( !result );
|
||||||
|
|
||||||
|
if( std_error ) {
|
||||||
|
vips__chomp( std_error );
|
||||||
|
if( strcmp( std_error, "" ) != 0 )
|
||||||
|
vips_warn( class->nickname,
|
||||||
|
_( "stderr output: %s" ), std_error );
|
||||||
|
}
|
||||||
|
if( std_output ) {
|
||||||
|
vips__chomp( std_output );
|
||||||
|
g_object_set( system, "log", std_output, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
VIPS_FREE( std_output );
|
||||||
|
VIPS_FREE( std_error );
|
||||||
|
|
||||||
if( system->out_name ) {
|
if( system->out_name ) {
|
||||||
VipsImage *out;
|
VipsImage *out;
|
||||||
|
|
||||||
@ -206,6 +239,7 @@ vips_system_class_init( VipsSystemClass *class )
|
|||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||||
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
|
VipsObjectClass *vobject_class = VIPS_OBJECT_CLASS( class );
|
||||||
|
VipsOperationClass *operation_class = VIPS_OPERATION_CLASS( class );
|
||||||
|
|
||||||
gobject_class->dispose = vips_system_dispose;
|
gobject_class->dispose = vips_system_dispose;
|
||||||
gobject_class->set_property = vips_object_set_property;
|
gobject_class->set_property = vips_object_set_property;
|
||||||
@ -215,6 +249,10 @@ vips_system_class_init( VipsSystemClass *class )
|
|||||||
vobject_class->description = _( "run an external command" );
|
vobject_class->description = _( "run an external command" );
|
||||||
vobject_class->build = vips_system_build;
|
vobject_class->build = vips_system_build;
|
||||||
|
|
||||||
|
/* Commands can have side-effects, so don't cache them.
|
||||||
|
*/
|
||||||
|
operation_class->flags = VIPS_OPERATION_NOCACHE;
|
||||||
|
|
||||||
VIPS_ARG_BOXED( class, "in", 0,
|
VIPS_ARG_BOXED( class, "in", 0,
|
||||||
_( "Input" ),
|
_( "Input" ),
|
||||||
_( "Array of input images" ),
|
_( "Array of input images" ),
|
||||||
|
@ -1206,6 +1206,17 @@ vips_mkdirf( const char *name, ... )
|
|||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Chop off any trailing whitespace.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
vips__chomp( char *str )
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
for( p = str + strlen( str ); p > str && isspace( p[-1] ); p-- )
|
||||||
|
p[-1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
/* Break a command-line argument into tokens separated by whitespace.
|
/* Break a command-line argument into tokens separated by whitespace.
|
||||||
*
|
*
|
||||||
* Strings can't be adjacent, so "hello world" (without quotes) is a single
|
* Strings can't be adjacent, so "hello world" (without quotes) is a single
|
||||||
|
Loading…
x
Reference in New Issue
Block a user