Skip to content

Instantly share code, notes, and snippets.

@jcupitt
Created March 22, 2020 17:12
Show Gist options
  • Save jcupitt/7ee49c3910e417bd1c0abffaae8d8667 to your computer and use it in GitHub Desktop.
Save jcupitt/7ee49c3910e417bd1c0abffaae8d8667 to your computer and use it in GitHub Desktop.
custom libvips source and target in C
/* Compile with:
*
* gcc -g -Wall custom.c `pkg-config vips --cflags --libs`
*
* Run with:
*
* ./a.out ~/pics/k2.jpg x.jpg
*
*/
#include <vips/vips.h>
static gint64
my_read( VipsSourceCustom *source, void *buffer, gint64 length, void *user )
{
FILE *in = (FILE *) user;
size_t items;
printf( "my_read: length = %zd\n", length );
items = fread( buffer, sizeof( char ), length, in );
printf( " items = %zd\n", items );
return( items );
}
static gint64
my_seek( VipsSourceCustom *source, gint64 pos, int whence, void *user )
{
FILE *in = (FILE *) user;
long new_pos;
printf( "my_seek: pos = %zd, whence = %d\n", pos, whence );
if( fseek( in, pos, whence ) )
return( -1 );
new_pos = ftell( in );
printf( " new_pos = %zd\n", new_pos );
return( new_pos );
}
static gint64
my_write( VipsTargetCustom *target, const void *buffer, gint64 length,
void *user )
{
FILE *out = (FILE *) user;
size_t items;
printf( "my_write: length = %zd\n", length );
items = fwrite( buffer, sizeof( char ), length, out );
printf( " items = %zd\n", items );
return( items );
}
static void
my_finish( VipsTargetCustom *target, void *user )
{
FILE *out = (FILE *) user;
printf( "my_finish:\n" );
fclose( out );
}
int
main( int argc, char **argv )
{
FILE *in;
FILE *out;
VipsSourceCustom *source;
VipsTargetCustom *target;
VipsImage *image;
source = vips_source_custom_new();
if( !(in = fopen( argv[1], "rb" )) )
vips_error_exit( "unable to read %s", argv[1] );
g_signal_connect( source, "read", G_CALLBACK( my_read ), in );
g_signal_connect( source, "seek", G_CALLBACK( my_seek ), in );
if( !(image = vips_image_new_from_source( VIPS_SOURCE( source ), "",
"access", VIPS_ACCESS_SEQUENTIAL,
NULL )) )
vips_error_exit( "unable to read from %s as image", argv[1] );
target = vips_target_custom_new();
if( !(out = fopen( argv[2], "wb" )) )
vips_error_exit( "unable to write %s", argv[2] );
g_signal_connect( target, "write", G_CALLBACK( my_write ), out );
g_signal_connect( target, "finish", G_CALLBACK( my_finish ), out );
if( vips_image_write_to_target( image, ".jpg", VIPS_TARGET( target ),
"Q", 90,
NULL ) )
vips_error_exit( "unable to write to %s as image", argv[2] );
g_object_unref( image );
g_object_unref( source );
g_object_unref( target );
fclose( in );
/* out is fclose()ed in finish.
*/
return( 0 );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment