add stdout write

this now works:

	$ vips invert k2.jpg .jpg | vips invert stdin x.jpg

"stdin" means read from stdin, ".jpg" means write to stdout in JPG
format
This commit is contained in:
John Cupitt 2019-10-12 14:12:01 +01:00
parent a2d57180b1
commit 4d3f66fe33
6 changed files with 140 additions and 12 deletions

View File

@ -1865,6 +1865,58 @@ vips_foreign_save( VipsImage *in, const char *name, ... )
return( result );
}
/* Can thsi class write this filetype to a stream?
*/
static void *
vips_foreign_find_save_stream_sub( VipsForeignSaveClass *save_class,
const char *suffix )
{
VipsObjectClass *object_class = VIPS_OBJECT_CLASS( save_class );
VipsForeignClass *class = VIPS_FOREIGN_CLASS( save_class );
printf( "testing %s for %s\n", object_class->nickname, suffix );
if( class->suffs &&
vips_ispostfix( object_class->nickname, "_stream" ) &&
vips_filename_suffix_match( suffix, class->suffs ) )
return( save_class );
return( NULL );
}
/**
* vips_foreign_find_save_stream:
* @suffix: format to find a saver for
*
* Searches for an operation you could use to write to a stream in @suffix
* format.
*
* See also: vips_image_write_to_buffer().
*
* Returns: the name of an operation on success, %NULL on error
*/
const char *
vips_foreign_find_save_stream( const char *name )
{
char suffix[VIPS_PATH_MAX];
char option_string[VIPS_PATH_MAX];
VipsForeignSaveClass *save_class;
vips__filename_split8( name, suffix, option_string );
if( !(save_class = (VipsForeignSaveClass *) vips_foreign_map(
"VipsForeignSave",
(VipsSListMap2Fn) vips_foreign_find_save_stream_sub,
(void *) suffix, NULL )) ) {
vips_error( "VipsForeignSave",
_( "\"%s\" is not a known stream format" ), name );
return( NULL );
}
return( G_OBJECT_CLASS_NAME( save_class ) );
}
/* Can we write this buffer with this file type?
*/
static void *
@ -1946,6 +1998,7 @@ vips_foreign_operation_init( void )
extern GType vips_foreign_load_jpeg_stream_get_type( void );
extern GType vips_foreign_save_jpeg_file_get_type( void );
extern GType vips_foreign_save_jpeg_buffer_get_type( void );
extern GType vips_foreign_save_jpeg_stream_get_type( void );
extern GType vips_foreign_save_jpeg_mime_get_type( void );
extern GType vips_foreign_load_tiff_file_get_type( void );
extern GType vips_foreign_load_tiff_buffer_get_type( void );
@ -2058,6 +2111,7 @@ vips_foreign_operation_init( void )
vips_foreign_load_jpeg_stream_get_type();
vips_foreign_save_jpeg_file_get_type();
vips_foreign_save_jpeg_buffer_get_type();
vips_foreign_save_jpeg_stream_get_type();
vips_foreign_save_jpeg_mime_get_type();
#endif /*HAVE_JPEG*/

View File

@ -354,6 +354,7 @@ GType vips_foreign_save_get_type(void);
const char *vips_foreign_find_save( const char *filename );
gchar **vips_foreign_get_suffixes( void );
const char *vips_foreign_find_save_buffer( const char *suffix );
const char *vips_foreign_find_save_stream( const char *suffix );
int vips_vipsload( const char *filename, VipsImage **out, ... )
__attribute__((sentinel));

View File

@ -473,6 +473,9 @@ int vips_image_write_to_file( VipsImage *image, const char *name, ... )
int vips_image_write_to_buffer( VipsImage *in,
const char *suffix, void **buf, size_t *size, ... )
__attribute__((sentinel));
int vips_image_write_to_stream( VipsImage *in,
const char *suffix, VipsStreamOutput *output, ... )
__attribute__((sentinel));
void *vips_image_write_to_memory( VipsImage *in, size_t *size );
int vips_image_decode_predict( VipsImage *in,

View File

@ -2704,6 +2704,51 @@ vips_image_write_to_buffer( VipsImage *in,
return( 0 );
}
/**
* vips_image_write_to_stream: (method)
* @in: image to write
* @suffix: format to write
* @output: stream to write to
* @...: %NULL-terminated list of optional named arguments
*
* Writes @in to @output in format @suffix.
*
* Save options may be appended to @suffix as "[name=value,...]" or given as
* a NULL-terminated list of name-value pairs at the end of the arguments.
* Options given in the function call override options given in the filename.
*
* You can call the various save operations directly if you wish, see
* vips_jpegsave_stream(), for example.
*
* See also: vips_image_write_to_file().
*
* Returns: 0 on success, -1 on error
*/
int
vips_image_write_to_stream( VipsImage *in,
const char *suffix, VipsStreamOutput *output, ... )
{
char filename[VIPS_PATH_MAX];
char option_string[VIPS_PATH_MAX];
const char *operation_name;
va_list ap;
int result;
vips__filename_split8( suffix, filename, option_string );
if( !(operation_name = vips_foreign_find_save_stream( filename )) )
return( -1 );
va_start( ap, output );
result = vips_call_split_option_string( operation_name, option_string,
ap, in, output );
va_end( ap );
if( result )
return( -1 );
return( 0 );
}
/**
* vips_image_write_to_memory: (method)
* @in: image to write

View File

@ -1886,6 +1886,8 @@ vips_object_set_argument_from_string( VipsObject *object,
VipsImage *out;
VipsOperationFlags flags;
VipsAccess access;
char filename[VIPS_PATH_MAX];
char option_string[VIPS_PATH_MAX];
if( !value ) {
vips_object_no_value( object, name );
@ -1906,15 +1908,16 @@ vips_object_set_argument_from_string( VipsObject *object,
else
access = VIPS_ACCESS_RANDOM;
/* The special filename "-" means stdin.
*/
if( strcmp( value, "-" ) == 0 ) {
vips__filename_split8( value, filename, option_string );
if( strcmp( "stdin", filename ) == 0 ) {
VipsStreamInput *input;
if( !(input =
vips_stream_input_new_from_descriptor( 0 )) )
return( -1 );
if( !(out = vips_image_new_from_stream( input, "",
if( !(out = vips_image_new_from_stream( input,
option_string,
"access", access,
NULL )) ) {
VIPS_UNREF( input );
@ -2185,14 +2188,37 @@ vips_object_get_argument_to_string( VipsObject *object,
if( g_type_is_a( otype, VIPS_TYPE_IMAGE ) ) {
VipsImage *in;
/* Pull out the image and write it.
*/
g_object_get( object, name, &in, NULL );
if( vips_image_write_to_file( in, arg, NULL ) ) {
g_object_unref( in );
return( -1 );
char filename[VIPS_PATH_MAX];
char option_string[VIPS_PATH_MAX];
vips__filename_split8( arg, filename, option_string );
if( vips_isprefix( ".", filename ) ) {
VipsStreamOutput *output;
if( !(output =
vips_stream_output_new_from_descriptor( 1 )) )
return( -1 );
g_object_get( object, name, &in, NULL );
if( vips_image_write_to_stream( in,
arg, output, NULL ) ) {
VIPS_UNREF( in );
VIPS_UNREF( output );
return( -1 );
}
VIPS_UNREF( in );
VIPS_UNREF( output );
}
else {
/* Pull out the image and write it.
*/
g_object_get( object, name, &in, NULL );
if( vips_image_write_to_file( in, arg, NULL ) ) {
VIPS_UNREF( in );
return( -1 );
}
VIPS_UNREF( in );
}
g_object_unref( in );
}
else if( g_type_is_a( otype, VIPS_TYPE_OBJECT ) &&
(oclass = g_type_class_ref( otype )) &&

View File

@ -744,7 +744,6 @@ vips_stream_output_new_from_descriptor( int descriptor )
stream = VIPS_STREAM_OUTPUT(
g_object_new( VIPS_TYPE_STREAM_OUTPUT,
"descriptor", descriptor,
"filename", "descriptor",
NULL ) );
if( vips_object_build( VIPS_OBJECT( stream ) ) ) {