From 5f024984084d055dede1a3b7017630b51a3c2960 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Wed, 7 Oct 2009 13:03:46 +0000 Subject: [PATCH] docs for REGION --- ChangeLog | 5 +- TODO | 6 +- libvips/include/vips/image.h | 43 --------- libvips/include/vips/private.h | 42 +++++++++ libvips/include/vips/region.h | 54 ++--------- libvips/iofuncs/buffer.c | 9 +- libvips/iofuncs/im_open_vips.c | 59 ++++++++++-- libvips/iofuncs/region.c | 164 ++++++++++++++++++++++++++++++--- 8 files changed, 263 insertions(+), 119 deletions(-) diff --git a/ChangeLog b/ChangeLog index 74b68fab..48349f98 100644 --- a/ChangeLog +++ b/ChangeLog @@ -50,11 +50,8 @@ - better im_check() functions - added im_flood_other() as start of simple segmentation operator - added im_segment() -- gtk-doc comments for meta -- gtk-doc comments for header - im_printlines(), im_debugim() deprecated (use im_vips2csv() instead) -- callback gtkdocs -- error gtkdocs +- meta, header, callback, error, REGION gtkdocs - removed printlines tool, vips2csv is much better - removed other useless tools as well: debugim, binfile diff --git a/TODO b/TODO index 68f062f3..a441c55d 100644 --- a/TODO +++ b/TODO @@ -1,12 +1,10 @@ -- image.h/im_invalidate() needs docs - -- started region.h +- reached im_prepare() in region.h - more stuff from util.c? too much to do it all now -- im_prepare(), im_render()? +- im_render()? - memory.c diff --git a/libvips/include/vips/image.h b/libvips/include/vips/image.h index 9b3ed612..fb28395f 100644 --- a/libvips/include/vips/image.h +++ b/libvips/include/vips/image.h @@ -272,57 +272,14 @@ const char *im_guess_libdir( const char *, const char * ); VipsImage *im_open( const char *filename, const char *mode ); -/** - * im_open_local: - * @IM: image to open local to - * @NAME: filename to open - * @MODE: mode to open with - * - * Just like im_open(), but the #IMAGE will be closed for you automatically - * when @IM is closed. - * - * Returns: a new #IMAGE, or NULL on error - * - * See also: im_open(), im_close(), im_local(). - */ #define im_open_local( IM, NAME, MODE ) \ ((IMAGE *) im_local( (IM), \ (im_construct_fn) im_open, (im_callback_fn) im_close, \ (void *) (NAME), (void *) (MODE), NULL )) -/** - * im_open_local_array: - * @IM: image to open local to - * @OUT: array to fill with #IMAGE - * @N: array size - * @NAME: filename to open - * @MODE: mode to open with - * - * Just like im_open(), but opens an array of images. Handy for creating a set - * of temporary images for a function. - * - * Example: - * - * |[ - * IMAGE *t[5]; - * - * if( im_open_local_array( out, t, 5, "some-temps", "p" ) || - * im_add( a, b, t[0] ) || - * im_invert( t[0], t[1] ) || - * im_add( t[1], t[0], t[2] ) || - * im_costra( t[2], out ) ) - * return( -1 ); - * ]| - * - * Returns: 0 on sucess, or -1 on error - * - * See also: im_open(), im_open_local(), im_local_array(). - */ - /* Strange double cast stops bogus warnings from gcc 4.1 */ - #define im_open_local_array( IM, OUT, N, NAME, MODE ) \ (im_local_array( (IM), (void **)((void*)(OUT)), (N),\ (im_construct_fn) im_open, (im_callback_fn) im_close, \ diff --git a/libvips/include/vips/private.h b/libvips/include/vips/private.h index 1e39a5cf..cf76b2a5 100644 --- a/libvips/include/vips/private.h +++ b/libvips/include/vips/private.h @@ -129,6 +129,48 @@ im_buffer_t *im_buffer_unref_ref( im_buffer_t *buffer, struct _VipsImage *im, Rect *area ); void im_buffer_print( im_buffer_t *buffer ); +/* Sections of region.h that are private to VIPS. + */ + +/* Region types. + */ +typedef enum region_type { + IM_REGION_NONE, + IM_REGION_BUFFER, /* a pixel buffer */ + IM_REGION_OTHER_REGION, /* memory on another region */ + IM_REGION_OTHER_IMAGE, /* memory on another image */ + IM_REGION_WINDOW /* mmap() buffer on fd on another image */ +} RegionType; + +/* Private to iofuncs: the size of the `tiles' requested by im_generate() + * when acting as a data sink. + */ +#define IM__TILE_WIDTH (64) +#define IM__TILE_HEIGHT (64) + +/* The height of the strips for the other two request styles. + */ +#define IM__THINSTRIP_HEIGHT (1) +#define IM__FATSTRIP_HEIGHT (16) + +/* Functions on regions. + */ +struct _REGION; +void im__region_take_ownership( struct _REGION *reg ); +void im__region_check_ownership( struct _REGION *reg ); +void im__region_no_ownership( struct _REGION *reg ); + +void im__copy_region( struct _REGION *reg, struct _REGION *dest, Rect *r, int x, int y ); +void im__find_demand_size( struct _VipsImage *im, int *pw, int *ph ); + +int im__call_start( struct _REGION *reg ); +void im__call_stop( struct _REGION *reg ); + +typedef int (*im_region_fill_fn)( struct _REGION *, void * ); +int im_region_fill( struct _REGION *reg, Rect *r, im_region_fill_fn fn, void *a ); +void im_region_print( struct _REGION *region ); + +void im_region_print( struct _REGION *region ); #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/include/vips/region.h b/libvips/include/vips/region.h index 7c98703d..8a8036c2 100644 --- a/libvips/include/vips/region.h +++ b/libvips/include/vips/region.h @@ -36,19 +36,10 @@ extern "C" { #endif /*__cplusplus*/ -/* Region types. - */ -typedef enum region_type { - IM_REGION_NONE, - IM_REGION_BUFFER, /* a pixel buffer */ - IM_REGION_OTHER_REGION, /* memory on another region */ - IM_REGION_OTHER_IMAGE, /* memory on another image */ - IM_REGION_WINDOW /* mmap() buffer on fd on another image */ -} RegionType; - /* Sub-area of image. */ -typedef struct region_struct { +typedef struct _REGION { + /*< public >*/ /* Users may read these two fields. */ IMAGE *im; /* Link back to parent image */ @@ -56,6 +47,7 @@ typedef struct region_struct { /* The rest of REGION is private. */ + /*< private >*/ RegionType type; /* What kind of attachment */ char *data; /* Off here to get data */ int bpl; /* Bytes-per-line for data */ @@ -75,34 +67,14 @@ typedef struct region_struct { im_buffer_t *buffer; } REGION; -/* Private to iofuncs: the size of the `tiles' requested by im_generate() - * when acting as a data sink. - */ -#define IM__TILE_WIDTH (64) -#define IM__TILE_HEIGHT (64) - -/* The height of the strips for the other two request styles. - */ -#define IM__THINSTRIP_HEIGHT (1) -#define IM__FATSTRIP_HEIGHT (16) - -/* Functions on regions. - */ -void im__region_take_ownership( REGION *reg ); -void im__region_check_ownership( REGION *reg ); -void im__region_no_ownership( REGION *reg ); - REGION *im_region_create( IMAGE *im ); void im_region_free( REGION *reg ); + int im_region_buffer( REGION *reg, Rect *r ); int im_region_image( REGION *reg, Rect *r ); int im_region_region( REGION *reg, REGION *to, Rect *r, int x, int y ); int im_region_equalsregion( REGION *reg1, REGION *reg2 ); int im_region_position( REGION *reg1, int x, int y ); -typedef int (*im_region_fill_fn)( REGION *, void * ); -int im_region_fill( REGION *reg, Rect *r, im_region_fill_fn fn, void *a ); - -void im_region_print( REGION *region ); /* IMAGE functions which use regions. */ @@ -120,7 +92,6 @@ int im_iterate( IMAGE *im, im_start_fn start, im_generate_fn generate, im_stop_fn stop, void *a, void *b ); -void im__copy_region( REGION *reg, REGION *dest, Rect *r, int x, int y ); /* Convenience functions for im_generate()/im_iterate(). */ @@ -134,29 +105,24 @@ int im_demand_hint( IMAGE *im, im_demand_type hint, ... ) int im_demand_hint_array( IMAGE *im, im_demand_type hint, IMAGE **in ); void im_free_region_array( REGION **regs ); REGION **im_allocate_region_array( IMAGE *im, int count ); -void im__find_demand_size( IMAGE *im, int *pw, int *ph ); /* Buffer processing. */ typedef void (*im_wrapone_fn)( void *in, void *out, int width, void *a, void *b ); -typedef void (*im_wraptwo_fn)( void *in1, void *in2, void *out, - int width, void *a, void *b ); -typedef void (*im_wrapmany_fn)( void **in, void *out, int width, - void *a, void *b ); - int im_wrapone( IMAGE *in, IMAGE *out, im_wrapone_fn fn, void *a, void *b ); + +typedef void (*im_wraptwo_fn)( void *in1, void *in2, void *out, + int width, void *a, void *b ); int im_wraptwo( IMAGE *in1, IMAGE *in2, IMAGE *out, im_wraptwo_fn fn, void *a, void *b ); + +typedef void (*im_wrapmany_fn)( void **in, void *out, int width, + void *a, void *b ); int im_wrapmany( IMAGE **in, IMAGE *out, im_wrapmany_fn fn, void *a, void *b ); -/* Internal VIPS functions shared by partials. - */ -int im__call_start( REGION *reg ); -void im__call_stop( REGION *reg ); - /* Macros on REGIONs. * IM_REGION_LSKIP() add to move down line * IM_REGION_N_ELEMENTS() number of elements across region diff --git a/libvips/iofuncs/buffer.c b/libvips/iofuncs/buffer.c index c2b292bc..d41451a9 100644 --- a/libvips/iofuncs/buffer.c +++ b/libvips/iofuncs/buffer.c @@ -569,7 +569,14 @@ im_invalidate_image( IMAGE *im ) return( NULL ); } -/* Invalidate all pixel caches on an IMAGE and any parents. +/** + * im_invalidate: + * @im: #IMAGE to invalidate + * + * Invalidate all pixel caches on an #IMAGE and any derived images. The + * "invalidate" callback is triggered for all invalidated images. + * + * See also: im_add_invalidate_callback(). */ void im_invalidate( IMAGE *im ) diff --git a/libvips/iofuncs/im_open_vips.c b/libvips/iofuncs/im_open_vips.c index e86262e3..623ca25b 100644 --- a/libvips/iofuncs/im_open_vips.c +++ b/libvips/iofuncs/im_open_vips.c @@ -84,7 +84,7 @@ * SECTION: image * @short_description: the VIPS image class * @stability: Stable - * @see_also: vips + * @see_also: region * @include: vips/vips.h * * The VIPS image class and associated types and macros. @@ -134,7 +134,7 @@ * These values are set by operations as hints to user-interfaces built on top * of VIPS to help them show images to the user in a meaningful way. * Operations do not use these values to decide their action. - **/ + */ /** * VipsBandFmt: @@ -153,7 +153,7 @@ * * Each corresponnds to a native C type for the current machine. For example, * %IM_BANDFMT_USHORT is unsigned short. - **/ + */ /** * VipsCoding: @@ -208,28 +208,28 @@ * @I: a #VipsImage * * Returns: sizeof() a band element. - **/ + */ /** * IM_IMAGE_SIZEOF_PEL: * @I: a #VipsImage * * Returns: sizeof() a pixel. - **/ + */ /** * IM_IMAGE_SIZEOF_LINE: * @I: a #VipsImage * * Returns: sizeof() a scanline of pixels. - **/ + */ /** * IM_IMAGE_N_ELEMENTS: * @I: a #VipsImage * * Returns: the number of band elements in a scanline. - **/ + */ /** * IM_IMAGE_ADDR: @@ -244,7 +244,50 @@ * If DEBUG is defined, you get a version that checks bounds for you. * * Returns: the address of pixel (x,y) in the image. - **/ + */ + +/** + * im_open_local_array: + * @IM: image to open local to + * @OUT: array to fill with #IMAGE + * @N: array size + * @NAME: filename to open + * @MODE: mode to open with + * + * Just like im_open(), but opens an array of images. Handy for creating a set + * of temporary images for a function. + * + * Example: + * + * |[ + * IMAGE *t[5]; + * + * if( im_open_local_array( out, t, 5, "some-temps", "p" ) || + * im_add( a, b, t[0] ) || + * im_invert( t[0], t[1] ) || + * im_add( t[1], t[0], t[2] ) || + * im_costra( t[2], out ) ) + * return( -1 ); + * ]| + * + * Returns: 0 on sucess, or -1 on error + * + * See also: im_open(), im_open_local(), im_local_array(). + */ + +/** + * im_open_local: + * @IM: image to open local to + * @NAME: filename to open + * @MODE: mode to open with + * + * Just like im_open(), but the #IMAGE will be closed for you automatically + * when @IM is closed. + * + * Returns: a new #IMAGE, or NULL on error + * + * See also: im_open(), im_close(), im_local(). + */ /* Try to make an O_BINARY ... sometimes need the leading '_'. */ diff --git a/libvips/iofuncs/region.c b/libvips/iofuncs/region.c index 967bc564..d2084bdb 100644 --- a/libvips/iofuncs/region.c +++ b/libvips/iofuncs/region.c @@ -35,6 +35,8 @@ * - gah, im_region_image() could still break (thanks Mikkel) * 23/7/08 * - added im_region_print() + * 7/10/09 + * - gtkdoc comments */ /* @@ -100,6 +102,77 @@ #include #endif /*WITH_DMALLOC*/ +/** + * SECTION: region + * @short_description: small, rectangular parts of images + * @stability: Stable + * @see_also: image + * @include: vips/vips.h + * + * A #REGION is a small part of an image and some pixels. You use regions to + * read pixels out of images without having to have the whole image in memory + * at once. + * + * A region can be a memory buffer, part of a memory-mapped file, part of some + * other image, or part of some other region. + */ + +/** + * REGION: + * @im: the #IMAGE that this region is defined on + * @valid: the #Rect of pixels that this region represents + * + * A small part of an #IMAGE. @valid holds the left/top/width/height of the + * area of pixels that are available from the region. + * + * See also: IM_REGION_ADDR(), im_region_create(), im_prepare(). + */ + +/** + * IM_REGION_LSKIP: + * @R: a #REGION + * + * Returns: the number of bytes to add to move down a scanline. + */ + +/** + * IM_REGION_N_ELEMENTS: + * @R: a #REGION + * + * Returns: the number of band elements across a region. + */ + +/** + * IM_REGION_SIZEOF_LINE: + * @R: a #REGION + * + * Returns: the number of bytes across a region. + */ + +/** + * IM_REGION_ADDR: + * @R: a #REGION + * @X: x coordinate + * @Y: y coordinate + * + * This macro returns a pointer to a pixel in a region. The (x, y) coordinates + * need to be within the #Rect (@R->valid). + * + * If DEBUG is defined, you get a version that checks bounds for you. + * + * Returns: the address of pixel (x,y) in the region. + */ + +/** + * IM_REGION_ADDR_TOPLEFT: + * @R: a #REGION + * + * This macro returns a pointer to the top-left pixel in the #REGION, that is, + * the pixel at (@R->valid.left, @R->valid.top). + * + * Returns: the address of the top-left pixel in the region. + */ + #ifdef DEBUG /* Track all regions here for debugging. */ @@ -208,9 +281,14 @@ im__region_no_ownership( REGION *reg ) g_mutex_unlock( reg->im->sslock ); } -/* Create a region. Set no attachments. Either im_prepare() or im_generate() - * are responsible for getting regions ready for user functions to read - * from/write to. +/** + * im_region_create: + * @im: image to create this region on + * + * Create a region. #REGION s start out empty, you need to call im_prepare() to + * fill them with pixels. + * + * See also: im_prepare(), im_region_free(). */ REGION * im_region_create( IMAGE *im ) @@ -262,6 +340,15 @@ im_region_reset( REGION *reg ) IM_FREEF( im_buffer_unref, reg->buffer ); } +/** + * im_region_free: + * @reg: #REGION to free + * + * Free a region and any resources it holds. + * + * If @im has previously been closed, then freeing the last #REGION on @in can + * cause @im to finally be freed as well. + */ void im_region_free( REGION *reg ) { @@ -315,6 +402,17 @@ im_region_free( REGION *reg ) * reg->buffer->done to see if there are pixels there already. Otherwise, you * need to calculate. */ + +/** + * im_region_buffer: + * @reg: region to operate upon + * @r: #Rect of pixels you need to be able to address + * + * The region is transformed so that at least @r pixels are available as a + * memory buffer. + * + * Returns: 0 on success, or -1 for error. + */ int im_region_buffer( REGION *reg, Rect *r ) { @@ -366,9 +464,16 @@ im_region_buffer( REGION *reg, Rect *r ) return( 0 ); } -/* Attach a region to a small section of the image on which it is defined. - * The IMAGE we are attached to should be im_mmapin(), im_mmapinrw() or - * im_setbuf(). The Rect is clipped against the image size. +/** + * im_region_image: + * @reg: region to operate upon + * @r: #Rect of pixels you need to be able to address + * + * The region is transformed so that at least @r pixels are available directly + * from the image. The image needs to be a memory buffer or represent a file + * on disc that has been mapped or can be mapped. + * + * Returns: 0 on success, or -1 for error. */ int im_region_image( REGION *reg, Rect *r ) @@ -445,18 +550,29 @@ im_region_image( REGION *reg, Rect *r ) return( 0 ); } -/* Make IM_REGION_ADDR() stuff to reg go to dest instead. +/** + * im_region_region: + * @reg: region to operate upon + * @dest: region to connect to + * @r: #Rect of pixels you need to be able to address + * @x: postion of @r in @dest + * @y: postion of @r in @dest * - * r is the part of the reg image which you want to be able to write to (this - * effectively becomes the valid field), (x,y) is the top LH corner of the - * corresponding area in dest. + * Make IM_REGION_ADDR() on @reg go to @dest instead. * - * Performs all clippings necessary to ensure that ®->valid is indeed + * @r is the part of @reg which you want to be able to address (this + * effectively becomes the valid field), (@x, @y) is the top LH corner of the + * corresponding area in @dest. + * + * Performs all clipping necessary to ensure that @reg->valid is indeed * valid. * - * If the region we attach to is modified, we are left with dangling pointers! - * If the region we attach to is on another image, the two images must have + * If the region we attach to is modified, we can be left with dangling + * pointers! If the region we attach to is on another image, the two images + * must have * the same sizeof( pel ). + * + * Returns: 0 on success, or -1 for error. */ int im_region_region( REGION *reg, REGION *dest, Rect *r, int x, int y ) @@ -540,10 +656,20 @@ im_region_region( REGION *reg, REGION *dest, Rect *r, int x, int y ) return( 0 ); } -/* Do two regions point to the same piece of image? ie. +/** + * im_region_equalsregion: + * @reg1: region to test + * @reg2: region to test + * + * Do two regions point to the same piece of image? ie. + * + * |[ * IM_REGION_ADDR( reg1, x, y ) == IM_REGION_ADDR( reg2, x, y ) && * *IM_REGION_ADDR( reg1, x, y ) == * *IM_REGION_ADDR( reg2, x, y ) for all x, y, reg1, reg2. + * ]| + * + * Returns: non-zero on equality. */ int im_region_equalsregion( REGION *reg1, REGION *reg2 ) @@ -553,10 +679,18 @@ im_region_equalsregion( REGION *reg1, REGION *reg2 ) reg1->data == reg2->data ); } -/* Set the position of a region. This only affects reg->valid, ie. the way +/** + * im_region_position: + * @reg: region to operate upon + * @x: position to move to + * @y: position to move to + * + * Set the position of a region. This only affects reg->valid, ie. the way * pixels are addressed, not reg->data, the pixels which are addressed. Clip * against the size of the image. Do not allow negative positions, or * positions outside the image. + * + * Returns: 0 on success, or -1 for error. */ int im_region_position( REGION *reg, int x, int y )