From 4ee19edd46e9f166b10330cd16ad1bcb255b808c Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Fri, 18 Jun 2021 11:39:00 +0100 Subject: [PATCH] add another C example see https://github.com/libvips/libvips/issues/1167 --- ChangeLog | 3 ++ configure.ac | 4 +- doc/using-C.xml | 123 +++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 116 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index d728fb96..62f6bc66 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +14/8/20 started 8.11.1 +- add more example code to C docs + 14/8/20 started 8.11 - add vips_jpegload_source() and vips_svgload_source() to public C API - integrate doxygen in build system to generate C++ API docs diff --git a/configure.ac b/configure.ac index aa53f7ba..b009bde1 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # also update the version number in the m4 macros below -AC_INIT([vips], [8.11.0], [vipsip@jiscmail.ac.uk]) +AC_INIT([vips], [8.11.1], [vipsip@jiscmail.ac.uk]) # required for gobject-introspection AC_PREREQ(2.62) @@ -18,7 +18,7 @@ AC_CONFIG_MACRO_DIR([m4]) # user-visible library versioning m4_define([vips_major_version], [8]) m4_define([vips_minor_version], [11]) -m4_define([vips_micro_version], [0]) +m4_define([vips_micro_version], [1]) m4_define([vips_version], [vips_major_version.vips_minor_version.vips_micro_version]) diff --git a/doc/using-C.xml b/doc/using-C.xml index ab43f2a6..2ad7083d 100644 --- a/doc/using-C.xml +++ b/doc/using-C.xml @@ -76,9 +76,12 @@ - See #VipsOperation for more detail on VIPS - reference counting conventions. + See #VipsOperation for more detail on VIPS + reference counting conventions. See the Reference pools + section below for a way to automate reference counting in C. + @@ -133,21 +136,21 @@ where: in - Input image, input VipsImage out - Output image, output VipsImage x - Left edge of input in output, input gint - default: 0 - min: -1000000000, max: 1000000000 + default: 0 + min: -1000000000, max: 1000000000 y - Top edge of input in output, input gint - default: 0 - min: -1000000000, max: 1000000000 + default: 0 + min: -1000000000, max: 1000000000 width - Image width in pixels, input gint - default: 1 - min: 1, max: 1000000000 + default: 1 + min: 1, max: 1000000000 height - Image height in pixels, input gint - default: 1 - min: 1, max: 1000000000 + default: 1 + min: 1, max: 1000000000 optional arguments: extend - How to generate the extra pixels, input VipsExtend - default: black - allowed: black, copy, repeat, mirror, white, background + default: black + allowed: black, copy, repeat, mirror, white, background background - Colour for background pixels, input VipsArrayDouble operation flags: sequential-unbuffered @@ -260,6 +263,102 @@ main( int argc, char **argv ) return( 0 ); } + + + + + + Reference pools + + libvips has a simple system to automate at least some reference counting + issues. Reference pools are arrays of object pointers which will be + released automatically when some other object is finalized. + + + + The code below crops a many-page image (perhaps a GIF or PDF). It + splits the image into separate pages, crops each page, reassembles the + cropped areas, and saves again. It creates a context + object representing the state of processing, and + crop_animation allocates two reference pools off that using + vips_object_local_array, one to hold the cropped frames, + and one to assemble and copy the result. + + + + All unreffing is handled by main, and it doesn't need to + know anything about crop_animation. + + + +Reference pool example + +#include <vips/vips.h> + +static int +crop_animation( VipsObject *context, VipsImage *image, VipsImage **out, + int left, int top, int width, int height ) +{ + int page_height = vips_image_get_page_height( image ); + int n_pages = image->Ysize / page_height; + VipsImage **page = (VipsImage **) vips_object_local_array( context, n_pages ); + VipsImage **copy = (VipsImage **) vips_object_local_array( context, 1 ); + + int i; + + /* Split the image into cropped frames. + */ + for( i = 0; i < n_pages; i++ ) + if( vips_crop( image, &page[i], + left, page_height * i + top, width, height, NULL ) ) + return( -1 ); + + /* Reassemble the frames and set the page height. You must copy before + * modifying metadata. + */ + if( vips_arrayjoin( page, &copy[0], n_pages, "across", 1, NULL ) || + vips_copy( copy[0], out, NULL ) ) + return( -1 ); + vips_image_set_int( *out, "page-height", height ); + + return( 0 ); +} + +int +main( int argc, char **argv ) +{ + VipsImage *image; + VipsObject *context; + VipsImage *x; + + if( VIPS_INIT( NULL ) ) + vips_error_exit( NULL ); + + if( !(image = vips_image_new_from_file( argv[1], + "access", VIPS_ACCESS_SEQUENTIAL, + NULL )) ) + vips_error_exit( NULL ); + + context = VIPS_OBJECT( vips_image_new() ); + if( crop_animation( context, image, &x, 10, 10, 500, 500 ) ) { + g_object_unref( image ); + g_object_unref( context ); + vips_error_exit( NULL ); + } + g_object_unref( image ); + g_object_unref( context ); + image = x; + + if( vips_image_write_to_file( image, argv[2], NULL ) ) { + g_object_unref( image ); + vips_error_exit( NULL ); + } + + g_object_unref( image ); + + return( 0 ); +} +