## VipsRegion

VipsRegion — small, rectangular parts of images

## Stability Level

Stable, unless otherwise indicated

## Synopsis

    #include <vips/vips.h>

                        VipsRegion;
                        VipsRegionClass;
    VipsRegion *        vips_region_new                     (VipsImage *image);
    int                 vips_region_buffer                  (VipsRegion *reg,
                                                             VipsRect *r);
    int                 vips_region_image                   (VipsRegion *reg,
                                                             VipsRect *r);
    int                 vips_region_region                  (VipsRegion *reg,
                                                             VipsRegion *dest,
                                                             VipsRect *r,
                                                             int x,
                                                             int y);
    int                 vips_region_equalsregion            (VipsRegion *reg1,
                                                             VipsRegion *reg2);
    int                 vips_region_position                (VipsRegion *reg,
                                                             int x,
                                                             int y);
    void                vips_region_paint                   (VipsRegion *reg,
                                                             VipsRect *r,
                                                             int value);
    void                vips_region_paint_pel               (VipsRegion *reg,
                                                             VipsRect *r,
                                                             VipsPel *ink);
    void                vips_region_black                   (VipsRegion *reg);
    void                vips_region_copy                    (VipsRegion *reg,
                                                             VipsRegion *dest,
                                                             VipsRect *r,
                                                             int x,
                                                             int y);
    int                 vips_region_prepare                 (VipsRegion *reg,
                                                             VipsRect *r);
    int                 vips_region_prepare_to              (VipsRegion *reg,
                                                             VipsRegion *dest,
                                                             VipsRect *r,
                                                             int x,
                                                             int y);
    int                 vips_region_prepare_many            (VipsRegion **reg,
                                                             VipsRect *r);
    void                vips_region_dump_all                (void);
    #define             VIPS_REGION_LSKIP                   (R)
    #define             VIPS_REGION_N_ELEMENTS              (R)
    #define             VIPS_REGION_SIZEOF_LINE             (R)
    #define             VIPS_REGION_ADDR                    (R,
                                                             X,
                                                             Y)
    #define             VIPS_REGION_ADDR_TOPLEFT            (R)

## Object Hierarchy

      GObject
       +----VipsObject
             +----VipsRegion

## Description

A VipsRegion 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.

Regions must be created, used and freed all within the same thread, since they can reference private per-thread caches. VIPS sanity-checks region ownership in various places, so you are likely to see `g_assert()` errors if you don't follow this rule.

There is API to transfer ownership of regions between threads, but hopefully this is only needed within VIPS, so we don't expose it. Hopefully.

## Details

### VipsRegion

    typedef struct {
    	/* Users may read these two fields.
    	 */
    	VipsImage *im;		/* Link back to parent image */
    	VipsRect valid;		/* Area of parent we can see */

    	/* The rest of VipsRegion is private.
    	 */
    } VipsRegion;

A small part of a VipsImage. `valid` holds the left/top/width/height of the area of pixels that are available from the region.

See also: `VIPS_REGION_ADDR()`, `vips_region_new()`, `vips_region_prepare()`.

VipsImage *`im`; | the VipsImage that this region is defined on
VipsRect `valid`; | the VipsRect of pixels that this region represents

### VipsRegionClass

    typedef struct {
    	VipsObjectClass parent_class;
    } VipsRegionClass;

### vips_region_new ()

    VipsRegion *        vips_region_new                     (VipsImage *image);

Create a region. VipsRegion s start out empty, you need to call `vips_region_prepare()` to fill them with pixels.

See also: `vips_region_prepare()`.

`image` : | image to create this region on

### vips_region_buffer ()

    int                 vips_region_buffer                  (VipsRegion *reg,
                                                             VipsRect *r);

The region is transformed so that at least `r` pixels are available as a memory buffer.

`reg` : | region to operate upon
`r` : | VipsRect of pixels you need to be able to address
Returns : | 0 on success, or -1 for error.

### vips_region_image ()

    int                 vips_region_image                   (VipsRegion *reg,
                                                             VipsRect *r);

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.

`reg` : | region to operate upon
`r` : | VipsRect of pixels you need to be able to address
Returns : | 0 on success, or -1 for error.

### vips_region_region ()

    int                 vips_region_region                  (VipsRegion *reg,
                                                             VipsRegion *dest,
                                                             VipsRect *r,
                                                             int x,
                                                             int y);

Make `VIPS_REGION_ADDR()` on `reg` go to `dest` instead.

`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 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 ).

`reg` : | region to operate upon
`dest` : | region to connect to
`r` : | VipsRect of pixels you need to be able to address
`x` : | postion of `r` in `dest`
`y` : | postion of `r` in `dest`
Returns : | 0 on success, or -1 for error.

### vips_region_equalsregion ()

    int                 vips_region_equalsregion            (VipsRegion *reg1,
                                                             VipsRegion *reg2);

Do two regions point to the same piece of image? ie.

    	VIPS_REGION_ADDR( reg1, x, y ) == VIPS_REGION_ADDR( reg2, x, y ) &&
    	*VIPS_REGION_ADDR( reg1, x, y ) ==
    		*VIPS_REGION_ADDR( reg2, x, y ) for all x, y, reg1, reg2.

`reg1` : | region to test
`reg2` : | region to test
Returns : | non-zero on equality.

### vips_region_position ()

    int                 vips_region_position                (VipsRegion *reg,
                                                             int x,
                                                             int y);

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.

`reg` : | region to operate upon
`x` : | position to move to
`y` : | position to move to
Returns : | 0 on success, or -1 for error.

### vips_region_paint ()

    void                vips_region_paint                   (VipsRegion *reg,
                                                             VipsRect *r,
                                                             int value);

Paints `value` into `reg` covering rectangle `r`. `value` is passed to `memset()`, so it usually needs to be 0 or 255. `r` is clipped against `reg->valid`.

See also: `vips_region_black()`.

`reg` : | region to operate upon
`r` : | area to paint
`value` : | value to paint

### vips_region_paint_pel ()

    void                vips_region_paint_pel               (VipsRegion *reg,
                                                             VipsRect *r,
                                                             VipsPel *ink);

Paints `ink` into `reg` covering rectangle `r`. `r` is clipped against `reg->valid`.

`ink` should be a byte array of the same size as an image pixel containing the binary value to write into the pixels.

See also: `vips_region_paint()`.

`reg` : | region to operate upon
`r` : | area to paint
`ink` : | value to paint

### vips_region_black ()

    void                vips_region_black                   (VipsRegion *reg);

Paints 0 into the valid part of `reg`.

See also: `vips_region_paint()`.

`reg` : | region to operate upon

### vips_region_copy ()

    void                vips_region_copy                    (VipsRegion *reg,
                                                             VipsRegion *dest,
                                                             VipsRect *r,
                                                             int x,
                                                             int y);

Copy from one region to another. Copy area `r` from inside `reg` to `dest`, positioning the area of pixels at `x`, `y`. The two regions must have pixels which are the same size.

See also: `vips_region_paint()`.

`reg` : | source region
`dest` : | destination region
`r` : | VipsRect of pixels you need to copy
`x` : | postion of `r` in `dest`
`y` : | postion of `r` in `dest`

### vips_region_prepare ()

    int                 vips_region_prepare                 (VipsRegion *reg,
                                                             VipsRect *r);

`vips_region_prepare()` fills `reg` with pixels. After calling, you can address at least the area `r` with `VIPS_REGION_ADDR()` and get valid pixels.

`vips_region_prepare()` runs in-line, that is, computation is done by the calling thread, no new threads are involved, and computation blocks until the pixels are ready.

Use `vips_region_prepare_thread()` to calculate an area of pixels with many threads. Use `vips_sink_screen()` to calculate an area of pixels in the background.

See also: `vips_region_prepare_thread()`, `vips_sink_screen()`, `vips_region_prepare_to()`.

`reg` : | region to prepare
`r` : | VipsRect of pixels you need to be able to address
Returns : | 0 on success, or -1 on error.

### vips_region_prepare_to ()

    int                 vips_region_prepare_to              (VipsRegion *reg,
                                                             VipsRegion *dest,
                                                             VipsRect *r,
                                                             int x,
                                                             int y);

Like `vips_region_prepare()`: fill `reg` with data, ready to be read from by our caller. Unlike `vips_region_prepare()`, rather than allocating memory local to `reg` for the result, we guarantee that we will fill the pixels in `dest` at offset `x`, `y`. In other words, we generate an extra copy operation if necessary.

Also unlike `vips_region_prepare()`, `dest` is not set up for writing for you with `vips_region_buffer()`. You can point `dest` at anything, and pixels really will be written there. This makes `vips_prepare_to()` useful for making the ends of pipelines, since it (effectively) makes a break in the pipe.

See also: `vips_region_prepare()`, `vips_sink_disc()`.

`reg` : | region to prepare
`dest` : | region to write to
`r` : | VipsRect of pixels you need to be able to address
`x` : | postion of `r` in `dest`
`y` : | postion of `r` in `dest`
Returns : | 0 on success, or -1 on error

### vips_region_prepare_many ()

    int                 vips_region_prepare_many            (VipsRegion **reg,
                                                             VipsRect *r);

### vips_region_dump_all ()

    void                vips_region_dump_all                (void);

### VIPS_REGION_LSKIP()

    #define             VIPS_REGION_LSKIP( R )

`R` : | a VipsRegion
Returns : | The number of bytes to add to move down a scanline.

### VIPS_REGION_N_ELEMENTS()

    #define             VIPS_REGION_N_ELEMENTS( R )

`R` : | a VipsRegion
Returns : | The number of band elements across a region.

### VIPS_REGION_SIZEOF_LINE()

    #define             VIPS_REGION_SIZEOF_LINE( R )

`R` : | a VipsRegion
Returns : | The number of bytes across a region.

### VIPS_REGION_ADDR()

    #define             VIPS_REGION_ADDR( R, X, Y )

This macro returns a pointer to a pixel in a region. The (x, y) coordinates need to be within the VipsRect (`R->valid`).

If DEBUG is defined, you get a version that checks bounds for you.

`R` : | a VipsRegion
`X` : | x coordinate
`Y` : | y coordinate
Returns : | The address of pixel (x,y) in the region.

### VIPS_REGION_ADDR_TOPLEFT()

    #define VIPS_REGION_ADDR_TOPLEFT( R ) ((R)->data)

This macro returns a pointer to the top-left pixel in the VipsRegion, that is, the pixel at (`R->valid.left`, `R->valid.top`).

`R` : | a VipsRegion
Returns : | The address of the top-left pixel in the region.

## See Also

image, generate