libvips/test/test_connections.c

160 lines
3.4 KiB
C

/* Test stream*u.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <vips/vips.h>
typedef struct _MyInput {
const char *filename;
unsigned char *contents;
size_t length;
size_t read_position;
} MyInput;
typedef struct _MyOutput {
const char *filename;
int fd;
} MyOutput;
static gint64
read_cb( VipsSourceCustom *source_custom,
void *buffer, gint64 length, MyInput *my_input )
{
gint64 bytes_read = VIPS_MIN( length,
my_input->length - my_input->read_position );
/*
printf( "read_cb: buffer = 0x%p, length = %zd\n", buffer, length );
*/
memcpy( buffer,
my_input->contents + my_input->read_position, bytes_read );
my_input->read_position += bytes_read;
return( bytes_read );
}
static gint64
seek_cb( VipsSourceCustom *source_custom,
gint64 offset, int whence, MyInput *my_input )
{
gint64 new_pos;
/*
printf( "seek_cb: offset = %zd, whence = %d\n", offset, whence );
*/
switch( whence ) {
case SEEK_SET:
new_pos = offset;
break;
case SEEK_CUR:
new_pos = my_input->read_position + offset;
break;
case SEEK_END:
new_pos = my_input->length + offset;
break;
default:
vips_error( "demo", "%s", "bad 'whence'" );
return( -1 );
}
my_input->read_position = VIPS_CLIP( 0, new_pos, my_input->length );
return( my_input->read_position );
}
static gint64
write_cb( VipsTargetCustom *target_custom,
const void *data, gint64 length, MyOutput *my_output )
{
gint64 bytes_written;
/*
printf( "write_cb: data = 0x%p, length = %zd\n", data, length );
*/
bytes_written = write( my_output->fd, data, length );
return( bytes_written );
}
static void
finish_cb( VipsTargetCustom *target_custom, MyOutput *my_output )
{
/*
printf( "finish_cb:\n" );
*/
close( my_output->fd );
my_output->fd = -1;
}
int
main( int argc, char **argv )
{
MyInput my_input;
MyOutput my_output;
VipsSourceCustom *source_custom;
VipsTargetCustom *target_custom;
VipsImage *image;
if( VIPS_INIT( argv[0] ) )
return( -1 );
if( argc != 3 )
vips_error_exit( "usage: %s in-file out-file.png", argv[0] );
my_input.filename = argv[1];
my_input.contents = NULL;
my_input.length = 0;
my_input.read_position = 0;
if( !g_file_get_contents( my_input.filename,
(char **) &my_input.contents, &my_input.length, NULL ) )
vips_error_exit( "unable to load from %s", my_input.filename );
source_custom = vips_source_custom_new();
g_signal_connect( source_custom, "seek",
G_CALLBACK( seek_cb ), &my_input );
g_signal_connect( source_custom, "read",
G_CALLBACK( read_cb ), &my_input );
if( !(image = vips_image_new_from_source(
VIPS_SOURCE( source_custom ), "",
"access", VIPS_ACCESS_SEQUENTIAL,
NULL )) )
vips_error_exit( NULL );
my_output.filename = argv[2];
my_output.fd = -1;
if( (my_output.fd = vips__open( my_output.filename,
O_WRONLY | O_CREAT | O_TRUNC, 0644 )) == -1 )
vips_error_exit( "unable to save to %s", my_output.filename );
target_custom = vips_target_custom_new();
g_signal_connect( target_custom, "write",
G_CALLBACK( write_cb ), &my_output );
g_signal_connect( target_custom, "finish",
G_CALLBACK( finish_cb ), &my_output );
if( vips_image_write_to_target( image, ".png",
VIPS_TARGET( target_custom ), NULL ) )
vips_error_exit( NULL );
VIPS_UNREF( image );
VIPS_UNREF( source_custom );
VIPS_UNREF( target_custom );
g_free( my_input.contents );
return( 0 );
}