region done
VipsRegion now exists, up to semaphore.c
This commit is contained in:
parent
3d55a7876c
commit
6fa48b0e7d
6
TODO
6
TODO
@ -5,8 +5,10 @@
|
||||
|
||||
- im_sanity() should become a method on VipsObject, see debug.c
|
||||
|
||||
- REGION needs moving at the same time, since regions have to ref their image,
|
||||
argh
|
||||
- rename Rect to VipsRect
|
||||
|
||||
- remove im__handle_eval etc. from headers
|
||||
|
||||
|
||||
|
||||
- pre/post/close should be on VipsObject, not VipsImage
|
||||
|
@ -36,11 +36,6 @@
|
||||
extern "C" {
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
/* IMAGE functions which use regions.
|
||||
*/
|
||||
int im_prepare( VipsRegion *reg, Rect *r );
|
||||
int im_prepare_to( VipsRegion *reg, VipsRegion *dest, Rect *r, int x, int y );
|
||||
|
||||
typedef void *(*im_start_fn)( IMAGE *out, void *a, void *b );
|
||||
typedef int (*im_generate_fn)( VipsRegion *out, void *seq, void *a, void *b );
|
||||
typedef int (*im_stop_fn)( void *seq, void *a, void *b );
|
||||
@ -90,10 +85,7 @@ int im_render_priority( IMAGE *in, IMAGE *out, IMAGE *mask,
|
||||
void (*notify)( IMAGE *, Rect *, void * ), void *client );
|
||||
int im_cache( IMAGE *in, IMAGE *out, int width, int height, int max );
|
||||
|
||||
/* WIO.
|
||||
*/
|
||||
int im_setupout( IMAGE *im );
|
||||
int im_writeline( int ypos, IMAGE *im, PEL *linebuffer );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -296,6 +296,8 @@ typedef struct _VipsImageClass {
|
||||
|
||||
} VipsImageClass;
|
||||
|
||||
GType vips_image_get_type( void );
|
||||
|
||||
extern const size_t vips__sizeof_bandfmt[];
|
||||
|
||||
/* Pixel address calculation macros.
|
||||
|
@ -79,7 +79,7 @@ typedef enum {
|
||||
|
||||
/* Useful flag combinations. User-visible ones are:
|
||||
|
||||
VIPS_ARGUMENT_REQURED_INPUT Eg. the "left" argument for an add operation
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT Eg. the "left" argument for an add operation
|
||||
|
||||
VIPS_ARGUMENT_OPTIONAL_INPUT Eg. the "caption" for an object
|
||||
|
||||
|
@ -146,19 +146,19 @@ typedef enum region_type {
|
||||
/* Functions on regions.
|
||||
*/
|
||||
struct _VipsRegion;
|
||||
void im__region_take_ownership( struct _VipsRegion *reg );
|
||||
void im__region_check_ownership( struct _VipsRegion *reg );
|
||||
void im__region_no_ownership( struct _VipsRegion *reg );
|
||||
void vips__region_take_ownership( struct _VipsRegion *reg );
|
||||
void vips__region_check_ownership( struct _VipsRegion *reg );
|
||||
void vips__region_no_ownership( struct _VipsRegion *reg );
|
||||
|
||||
void im__copy_region( struct _VipsRegion *reg, struct _VipsRegion *dest, Rect *r, int x, int y );
|
||||
void im__find_demand_size( struct _VipsImage *im, int *pw, int *ph );
|
||||
|
||||
int im__call_start( struct _VipsRegion *reg );
|
||||
void im__call_stop( struct _VipsRegion *reg );
|
||||
int vips__region_start( struct _VipsRegion *reg );
|
||||
void vips__region_stop( struct _VipsRegion *reg );
|
||||
|
||||
typedef int (*im_region_fill_fn)( struct _VipsRegion *, void * );
|
||||
int im_region_fill( struct _VipsRegion *reg, Rect *r, im_region_fill_fn fn, void *a );
|
||||
void im_region_print( struct _VipsRegion *region );
|
||||
typedef int (*VipsRegionFillFn)( struct _VipsRegion *, void * );
|
||||
int vips_region_fill( struct _VipsRegion *reg,
|
||||
Rect *r, VipsRegionFillFn fn, void *a );
|
||||
|
||||
int im_prepare_many( struct _VipsRegion **reg, Rect *r );
|
||||
|
||||
|
@ -97,6 +97,8 @@ typedef struct _VipsRegionClass {
|
||||
|
||||
} VipsRegionClass;
|
||||
|
||||
GType vips_region_get_type( void );
|
||||
|
||||
VipsRegion *vips_region_new( VipsImage *im );
|
||||
|
||||
int vips_region_buffer( VipsRegion *reg, Rect *r );
|
||||
@ -111,6 +113,11 @@ void vips_region_black( VipsRegion *reg );
|
||||
void vips_region_copy( VipsRegion *reg, VipsRegion *dest,
|
||||
Rect *r, int x, int y );
|
||||
|
||||
int vips_region_prepare( VipsRegion *reg, Rect *r );
|
||||
int vips_region_prepare_to( VipsRegion *reg,
|
||||
VipsRegion *dest, Rect *r, int x, int y );
|
||||
int vips_region_prepare_many( VipsRegion **reg, Rect *r );
|
||||
|
||||
/* Macros on REGIONs.
|
||||
* VIPS_REGION_LSKIP() add to move down line
|
||||
* VIPS_REGION_N_ELEMENTS() number of elements across region
|
||||
|
@ -15,7 +15,6 @@ libiofuncs_la_SOURCES = \
|
||||
im_generate.c \
|
||||
im_histlin.c \
|
||||
im_mapfile.c \
|
||||
im_prepare.c \
|
||||
im_setupout.c \
|
||||
im_guess_prefix.c \
|
||||
sinkmemory.c \
|
||||
|
@ -131,7 +131,7 @@ im_start_one( IMAGE *out, void *a, void *b )
|
||||
{
|
||||
IMAGE *in = (IMAGE *) a;
|
||||
|
||||
return( im_region_create( in ) );
|
||||
return( vips_region_new( in ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -147,9 +147,9 @@ im_start_one( IMAGE *out, void *a, void *b )
|
||||
int
|
||||
im_stop_one( void *seq, void *a, void *b )
|
||||
{
|
||||
REGION *reg = (REGION *) seq;
|
||||
VipsRegion *reg = (VipsRegion *) seq;
|
||||
|
||||
im_region_free( reg );
|
||||
g_object_unref( reg );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -168,13 +168,13 @@ im_stop_one( void *seq, void *a, void *b )
|
||||
int
|
||||
im_stop_many( void *seq, void *a, void *b )
|
||||
{
|
||||
REGION **ar = (REGION **) seq;
|
||||
VipsRegion **ar = (VipsRegion **) seq;
|
||||
|
||||
if( ar ) {
|
||||
int i;
|
||||
|
||||
for( i = 0; ar[i]; i++ )
|
||||
im_region_free( ar[i] );
|
||||
g_object_unref( ar[i] );
|
||||
im_free( (char *) ar );
|
||||
}
|
||||
|
||||
@ -198,7 +198,7 @@ im_start_many( IMAGE *out, void *a, void *b )
|
||||
IMAGE **in = (IMAGE **) a;
|
||||
|
||||
int i, n;
|
||||
REGION **ar;
|
||||
VipsRegion **ar;
|
||||
|
||||
/* How many images?
|
||||
*/
|
||||
@ -207,13 +207,13 @@ im_start_many( IMAGE *out, void *a, void *b )
|
||||
|
||||
/* Alocate space for region array.
|
||||
*/
|
||||
if( !(ar = VIPS_ARRAY( NULL, n + 1, REGION * )) )
|
||||
if( !(ar = VIPS_ARRAY( NULL, n + 1, VipsRegion * )) )
|
||||
return( NULL );
|
||||
|
||||
/* Create a set of regions.
|
||||
*/
|
||||
for( i = 0; i < n; i++ )
|
||||
if( !(ar[i] = im_region_create( in[i] )) ) {
|
||||
if( !(ar[i] = vips_region_new( in[i] )) ) {
|
||||
im_stop_many( ar, NULL, NULL );
|
||||
return( NULL );
|
||||
}
|
||||
@ -281,7 +281,7 @@ im_allocate_input_array( IMAGE *out, ... )
|
||||
|
||||
/**
|
||||
* im_generate_fn:
|
||||
* @out: #REGION to fill
|
||||
* @out: #VipsRegion to fill
|
||||
* @seq: sequence value
|
||||
* @a: user data
|
||||
* @b: user data
|
||||
@ -311,13 +311,13 @@ im_allocate_input_array( IMAGE *out, ... )
|
||||
/* A write function for VIPS images. Just write() the pixel data.
|
||||
*/
|
||||
static int
|
||||
write_vips( REGION *region, Rect *area, void *a, void *b )
|
||||
write_vips( VipsRegion *region, Rect *area, void *a, void *b )
|
||||
{
|
||||
size_t nwritten, count;
|
||||
void *buf;
|
||||
|
||||
count = region->bpl * area->height;
|
||||
buf = IM_REGION_ADDR( region, 0, area->top );
|
||||
buf = VIPS_REGION_ADDR( region, 0, area->top );
|
||||
do {
|
||||
nwritten = write( region->im->fd, buf, count );
|
||||
if( nwritten == (size_t) -1 )
|
||||
|
@ -1,378 +0,0 @@
|
||||
/* Request an area of an image for input.
|
||||
*
|
||||
* J.Cupitt, 17/4/93.
|
||||
*
|
||||
* Modified:
|
||||
* 22/11/94 JC
|
||||
* - check for start and stop functions removed, as can now be NULL
|
||||
* 22/2/95 JC
|
||||
* - im_fill_copy() added
|
||||
* 18/4/95 JC
|
||||
* - kill flag added for compute cases
|
||||
* 27/10/95 JC
|
||||
* - im_fill_copy() now only uses im_generate() mechanism if it has to
|
||||
* - im_fill_copy() renamed as im_prepare_inplace()
|
||||
* 18/8/99 JC
|
||||
* - oops ... cache stuff removed, interacted badly with inplace ops
|
||||
* 26/3/02 JC
|
||||
* - better error message for im_prepare()
|
||||
* 9/8/02 JC
|
||||
* - im_prepare_inplace() broke with mmap() windows ... im_prepare_to()
|
||||
* replaces it and is nicer
|
||||
* 30/9/05
|
||||
* - hmm, did not stop if a start function failed
|
||||
* 7/10/09
|
||||
* - gtkdoc comments
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This file is part of VIPS.
|
||||
|
||||
VIPS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
#define DEBUG
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /*HAVE_CONFIG_H*/
|
||||
#include <vips/intl.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vips/vips.h>
|
||||
#include <vips/thread.h>
|
||||
#include <vips/debug.h>
|
||||
#include <vips/internal.h>
|
||||
|
||||
#ifdef WITH_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif /*WITH_DMALLOC*/
|
||||
|
||||
/* Generate into a region.
|
||||
*/
|
||||
static int
|
||||
fill_region( REGION *reg )
|
||||
{
|
||||
IMAGE *im = reg->im;
|
||||
|
||||
/* Start new sequence, if necessary.
|
||||
*/
|
||||
if( im__call_start( reg ) )
|
||||
return( -1 );
|
||||
|
||||
/* Ask for evaluation.
|
||||
*/
|
||||
if( im->generate( reg, reg->seq, im->client1, im->client2 ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_prepare:
|
||||
* @reg: region to prepare
|
||||
* @r: #Rect of pixels you need to be able to address
|
||||
*
|
||||
* im_prepare() fills @reg with pixels. After calling, you can address at
|
||||
* least the area @r with IM_REGION_ADDR() and get valid pixels.
|
||||
*
|
||||
* im_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 im_prepare_thread() to calculate an area of pixels with many
|
||||
* threads. Use im_render_priority() to calculate an area of pixels in the
|
||||
* background.
|
||||
*
|
||||
* See also: im_prepare_thread(), im_render_priority(), im_prepare_to().
|
||||
*
|
||||
* Returns: 0 on success, or -1 on error.
|
||||
*/
|
||||
int
|
||||
im_prepare( REGION *reg, Rect *r )
|
||||
{
|
||||
IMAGE *im = reg->im;
|
||||
|
||||
Rect save = *r;
|
||||
|
||||
im__region_check_ownership( reg );
|
||||
|
||||
if( im__test_kill( im ) )
|
||||
return( -1 );
|
||||
|
||||
/* We use save for sanity checking valid: we test at the end that the
|
||||
* pixels we have generated are indeed all the ones that were asked
|
||||
* for.
|
||||
*
|
||||
* However, r may be clipped by the image size, so we need to clip
|
||||
* save as well to make sure we don't fail the assert due to that.
|
||||
*/
|
||||
{
|
||||
Rect image;
|
||||
|
||||
image.left = 0;
|
||||
image.top = 0;
|
||||
image.width = reg->im->Xsize;
|
||||
image.height = reg->im->Ysize;
|
||||
im_rect_intersectrect( &save, &image, &save );
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "im_prepare: left = %d, top = %d, width = %d, height = %d\n",
|
||||
r->left, r->top, r->width, r->height );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
switch( im->dtype ) {
|
||||
case VIPS_IMAGE_PARTIAL:
|
||||
if( im_region_fill( reg, r,
|
||||
(im_region_fill_fn) fill_region, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
break;
|
||||
|
||||
case VIPS_IMAGE_SETBUF:
|
||||
case VIPS_IMAGE_SETBUF_FOREIGN:
|
||||
case VIPS_IMAGE_MMAPIN:
|
||||
case VIPS_IMAGE_MMAPINRW:
|
||||
case VIPS_IMAGE_OPENIN:
|
||||
/* Attach to existing buffer.
|
||||
*/
|
||||
if( im_region_image( reg, r ) )
|
||||
return( -1 );
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
vips_error( "im_prepare", _( "unable to input from a %s image" ),
|
||||
im_dtype2char( im->dtype ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* valid should now include all the pixels that were asked for.
|
||||
*/
|
||||
g_assert( im_rect_includesrect( ®->valid, &save ) );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* We need to make pixels using reg's generate function, and write the result
|
||||
* to dest.
|
||||
*/
|
||||
static int
|
||||
im_prepare_to_generate( REGION *reg, REGION *dest, Rect *r, int x, int y )
|
||||
{
|
||||
IMAGE *im = reg->im;
|
||||
char *p;
|
||||
|
||||
if( !im->generate ) {
|
||||
vips_error( "im_prepare_to", "%s", _( "incomplete header" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( im_region_region( reg, dest, r, x, y ) )
|
||||
return( -1 );
|
||||
|
||||
/* Remember where reg is pointing now.
|
||||
*/
|
||||
p = IM_REGION_ADDR( reg, reg->valid.left, reg->valid.top );
|
||||
|
||||
/* Run sequence into reg.
|
||||
*/
|
||||
if( fill_region( reg ) )
|
||||
return( -1 );
|
||||
|
||||
/* The generate function may not have actually made any pixels ... it
|
||||
* might just have redirected reg to point somewhere else. If it has,
|
||||
* we need an extra copy operation.
|
||||
*/
|
||||
if( IM_REGION_ADDR( reg, reg->valid.left, reg->valid.top ) != p )
|
||||
im_region_copy( reg, dest, r, x, y );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* im_prepare_to:
|
||||
* @reg: region to prepare
|
||||
* @dest: region to write to
|
||||
* @r: #Rect of pixels you need to be able to address
|
||||
* @x: postion of @r in @dest
|
||||
* @y: postion of @r in @dest
|
||||
*
|
||||
* Like im_prepare(): fill @reg with data, ready to be read from by our caller.
|
||||
* Unlike im_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 im_prepare(), @dest is not set up for writing for you with
|
||||
* im_region_buffer(). You can
|
||||
* point @dest at anything, and pixels really will be written there.
|
||||
* This makes im_prepare_to() useful for making the ends of pipelines, since
|
||||
* it (effectively) makes a break in the pipe.
|
||||
*
|
||||
* See also: im_prepare(), vips_sink_disc().
|
||||
*
|
||||
* Returns: 0 on success, or -1 on error
|
||||
*/
|
||||
int
|
||||
im_prepare_to( REGION *reg, REGION *dest, Rect *r, int x, int y )
|
||||
{
|
||||
IMAGE *im = reg->im;
|
||||
Rect image;
|
||||
Rect wanted;
|
||||
Rect clipped;
|
||||
Rect clipped2;
|
||||
Rect final;
|
||||
|
||||
if( im__test_kill( im ) )
|
||||
return( -1 );
|
||||
|
||||
/* Sanity check.
|
||||
*/
|
||||
if( !dest->data ||
|
||||
dest->im->BandFmt != reg->im->BandFmt ||
|
||||
dest->im->Bands != reg->im->Bands ) {
|
||||
vips_error( "im_prepare_to",
|
||||
"%s", _( "inappropriate region type" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* clip r first against the size of reg->im, then again against the
|
||||
* memory we have available to write to on dest. Just like
|
||||
* im_region_region()
|
||||
*/
|
||||
image.top = 0;
|
||||
image.left = 0;
|
||||
image.width = reg->im->Xsize;
|
||||
image.height = reg->im->Ysize;
|
||||
im_rect_intersectrect( r, &image, &clipped );
|
||||
|
||||
g_assert( clipped.left == r->left );
|
||||
g_assert( clipped.top == r->top );
|
||||
|
||||
wanted.left = x + (clipped.left - r->left);
|
||||
wanted.top = y + (clipped.top - r->top);
|
||||
wanted.width = clipped.width;
|
||||
wanted.height = clipped.height;
|
||||
|
||||
/* Test that dest->valid is large enough.
|
||||
*/
|
||||
if( !im_rect_includesrect( &dest->valid, &wanted ) ) {
|
||||
vips_error( "im_prepare_to", "%s", _( "dest too small" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
im_rect_intersectrect( &wanted, &dest->valid, &clipped2 );
|
||||
|
||||
/* Translate back to reg's coordinate space and set as valid.
|
||||
*/
|
||||
final.left = r->left + (clipped2.left - wanted.left);
|
||||
final.top = r->top + (clipped2.top - wanted.top);
|
||||
final.width = clipped2.width;
|
||||
final.height = clipped2.height;
|
||||
|
||||
x = clipped2.left;
|
||||
y = clipped2.top;
|
||||
|
||||
if( im_rect_isempty( &final ) ) {
|
||||
vips_error( "im_prepare_to",
|
||||
"%s", _( "valid clipped to nothing" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf( "im_prepare_to: left = %d, top = %d, width = %d, height = %d\n",
|
||||
final.left, final.top, final.width, final.height );
|
||||
#endif /*DEBUG*/
|
||||
|
||||
/* Input or output image type?
|
||||
*/
|
||||
switch( im->dtype ) {
|
||||
case VIPS_IMAGE_OPENOUT:
|
||||
case VIPS_IMAGE_PARTIAL:
|
||||
/* We are generating with a sequence.
|
||||
*/
|
||||
if( im_prepare_to_generate( reg, dest, &final, x, y ) )
|
||||
return( -1 );
|
||||
|
||||
break;
|
||||
|
||||
case VIPS_IMAGE_MMAPIN:
|
||||
case VIPS_IMAGE_MMAPINRW:
|
||||
case VIPS_IMAGE_OPENIN:
|
||||
/* Attach to existing buffer and copy to dest.
|
||||
*/
|
||||
if( im_region_image( reg, &final ) )
|
||||
return( -1 );
|
||||
im_region_copy( reg, dest, &final, x, y );
|
||||
|
||||
break;
|
||||
|
||||
case VIPS_IMAGE_SETBUF:
|
||||
case VIPS_IMAGE_SETBUF_FOREIGN:
|
||||
/* Could be either input or output. If there is a generate
|
||||
* function, we are outputting.
|
||||
*/
|
||||
if( im->generate ) {
|
||||
if( im_prepare_to_generate( reg, dest, &final, x, y ) )
|
||||
return( -1 );
|
||||
}
|
||||
else {
|
||||
if( im_region_image( reg, &final ) )
|
||||
return( -1 );
|
||||
im_region_copy( reg, dest, &final, x, y );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
vips_error( "im_prepare_to", _( "unable to input from a "
|
||||
"%s image" ), im_dtype2char( im->dtype ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
/* We've written fresh pixels to dest, it's no longer invalid (if it
|
||||
* was).
|
||||
*
|
||||
* We need this extra thing here because, unlike im_prepare(), we
|
||||
* don't im_region_buffer() dest before writing it.
|
||||
*/
|
||||
dest->invalid = FALSE;
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int
|
||||
im_prepare_many( REGION **reg, Rect *r )
|
||||
{
|
||||
for( ; *reg; ++reg )
|
||||
if( im_prepare( *reg, r ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
}
|
@ -62,12 +62,12 @@ typedef struct {
|
||||
*/
|
||||
#define MAX_INPUT_IMAGES (64)
|
||||
|
||||
/* Convert a REGION.
|
||||
/* Convert a VipsRegion.
|
||||
*/
|
||||
static int
|
||||
process_region( REGION *or, void *seq, void *a, void *b )
|
||||
process_region( VipsRegion *or, void *seq, void *a, void *b )
|
||||
{
|
||||
REGION **ir = (REGION **) seq;
|
||||
VipsRegion **ir = (VipsRegion **) seq;
|
||||
Bundle *bun = (Bundle *) b;
|
||||
|
||||
PEL *p[MAX_INPUT_IMAGES], *q;
|
||||
@ -76,13 +76,13 @@ process_region( REGION *or, void *seq, void *a, void *b )
|
||||
/* Prepare all input regions and make buffer pointers.
|
||||
*/
|
||||
for( i = 0; ir[i]; i++ ) {
|
||||
if( im_prepare( ir[i], &or->valid ) )
|
||||
if( vips_region_prepare( ir[i], &or->valid ) )
|
||||
return( -1 );
|
||||
p[i] = (PEL *) IM_REGION_ADDR( ir[i],
|
||||
p[i] = (PEL *) VIPS_REGION_ADDR( ir[i],
|
||||
or->valid.left, or->valid.top );
|
||||
}
|
||||
p[i] = NULL;
|
||||
q = (PEL *) IM_REGION_ADDR( or, or->valid.left, or->valid.top );
|
||||
q = (PEL *) VIPS_REGION_ADDR( or, or->valid.left, or->valid.top );
|
||||
|
||||
/* Convert linewise.
|
||||
*/
|
||||
@ -103,8 +103,8 @@ process_region( REGION *or, void *seq, void *a, void *b )
|
||||
/* Move pointers on.
|
||||
*/
|
||||
for( i = 0; ir[i]; i++ )
|
||||
p[i] += IM_REGION_LSKIP( ir[i] );
|
||||
q += IM_REGION_LSKIP( or );
|
||||
p[i] += VIPS_REGION_LSKIP( ir[i] );
|
||||
q += VIPS_REGION_LSKIP( or );
|
||||
}
|
||||
|
||||
return( 0 );
|
||||
|
@ -448,6 +448,8 @@ vips_image_print( VipsObject *object, VipsBuf *buf )
|
||||
vips_image_get_bands( image ),
|
||||
VIPS_ENUM_NICK( VIPS_TYPE_INTERPRETATION,
|
||||
vips_image_get_interpretation( image ) ) );
|
||||
|
||||
VIPS_OBJECT_CLASS( vips_image_parent_class )->print( object, buf );
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -623,26 +625,26 @@ open_lazy_start( VipsImage *out, void *a, void *dummy )
|
||||
}
|
||||
}
|
||||
|
||||
return( im_region_create( lazy->real ) );
|
||||
return( vips_region_new( lazy->real ) );
|
||||
}
|
||||
|
||||
/* Just copy.
|
||||
*/
|
||||
static int
|
||||
open_lazy_generate( REGION *or, void *seq, void *a, void *b )
|
||||
open_lazy_generate( VipsRegion *or, void *seq, void *a, void *b )
|
||||
{
|
||||
REGION *ir = (REGION *) seq;
|
||||
VipsRegion *ir = (VipsRegion *) seq;
|
||||
|
||||
Rect *r = &or->valid;
|
||||
|
||||
/* Ask for input we need.
|
||||
*/
|
||||
if( im_prepare( ir, r ) )
|
||||
if( vips_region_prepare( ir, r ) )
|
||||
return( -1 );
|
||||
|
||||
/* Attach output region to that.
|
||||
*/
|
||||
if( im_region_region( or, ir, r, r->left, r->top ) )
|
||||
if( vips_region_region( or, ir, r, r->left, r->top ) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
||||
@ -948,7 +950,7 @@ vips_image_build( VipsObject *object )
|
||||
}
|
||||
|
||||
static void *
|
||||
vips_region_invalidate( REGION *reg )
|
||||
vips_region_invalidate( VipsRegion *reg )
|
||||
{
|
||||
reg->invalid = TRUE;
|
||||
|
||||
|
@ -977,9 +977,9 @@ build_args( im_function *fn, im_object *vargv, int argc, char **argv )
|
||||
/* Free a region, but return 0 so we can be used as a close callback.
|
||||
*/
|
||||
static void
|
||||
region_local_image_cb( VipsImage *main, REGION *reg )
|
||||
region_local_image_cb( VipsImage *main, VipsRegion *reg )
|
||||
{
|
||||
im_region_free( reg );
|
||||
g_object_unref( reg );
|
||||
}
|
||||
|
||||
/* Make a region on sub, closed by callback on main.
|
||||
@ -987,9 +987,9 @@ region_local_image_cb( VipsImage *main, REGION *reg )
|
||||
static int
|
||||
region_local_image( IMAGE *main, IMAGE *sub )
|
||||
{
|
||||
REGION *reg;
|
||||
VipsRegion *reg;
|
||||
|
||||
if( !(reg = im_region_create( sub )) )
|
||||
if( !(reg = vips_region_new( sub )) )
|
||||
return( -1 );
|
||||
g_signal_connect( main, "close",
|
||||
G_CALLBACK( region_local_image_cb ), reg );
|
||||
|
@ -91,12 +91,12 @@ im_rect_includesrect( Rect *r1, Rect *r2 )
|
||||
void
|
||||
im_rect_intersectrect( Rect *r1, Rect *r2, Rect *r3 )
|
||||
{
|
||||
int left = IM_MAX( r1->left, r2->left );
|
||||
int top = IM_MAX( r1->top, r2->top );
|
||||
int right = IM_MIN( IM_RECT_RIGHT( r1 ), IM_RECT_RIGHT( r2 ) );
|
||||
int bottom = IM_MIN( IM_RECT_BOTTOM( r1 ), IM_RECT_BOTTOM( r2 ) );
|
||||
int width = IM_MAX( 0, right - left );
|
||||
int height = IM_MAX( 0, bottom - top );
|
||||
int left = VIPS_MAX( r1->left, r2->left );
|
||||
int top = VIPS_MAX( r1->top, r2->top );
|
||||
int right = VIPS_MIN( IM_RECT_RIGHT( r1 ), IM_RECT_RIGHT( r2 ) );
|
||||
int bottom = VIPS_MIN( IM_RECT_BOTTOM( r1 ), IM_RECT_BOTTOM( r2 ) );
|
||||
int width = VIPS_MAX( 0, right - left );
|
||||
int height = VIPS_MAX( 0, bottom - top );
|
||||
|
||||
r3->left = left;
|
||||
r3->top = top;
|
||||
@ -124,11 +124,11 @@ im_rect_unionrect( Rect *r1, Rect *r2, Rect *r3 )
|
||||
else if( im_rect_isempty( r2 ) )
|
||||
*r3 = *r1;
|
||||
else {
|
||||
int left = IM_MIN( r1->left, r2->left );
|
||||
int top = IM_MIN( r1->top, r2->top );
|
||||
int width = IM_MAX( IM_RECT_RIGHT( r1 ),
|
||||
int left = VIPS_MIN( r1->left, r2->left );
|
||||
int top = VIPS_MIN( r1->top, r2->top );
|
||||
int width = VIPS_MAX( IM_RECT_RIGHT( r1 ),
|
||||
IM_RECT_RIGHT( r2 ) ) - left;
|
||||
int height = IM_MAX( IM_RECT_BOTTOM( r1 ),
|
||||
int height = VIPS_MAX( IM_RECT_BOTTOM( r1 ),
|
||||
IM_RECT_BOTTOM( r2 ) )- top;
|
||||
|
||||
r3->left = left;
|
||||
@ -152,7 +152,7 @@ im_rect_equalsrect( Rect *r1, Rect *r2 )
|
||||
Rect *
|
||||
im_rect_dup( Rect *r )
|
||||
{
|
||||
Rect *out = IM_NEW( NULL, Rect );
|
||||
Rect *out = VIPS_NEW( NULL, Rect );
|
||||
|
||||
if( !out )
|
||||
return( NULL );
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -93,7 +93,7 @@ typedef struct _SinkThreadState {
|
||||
/* The region we walk over sink.t copy. We can't use
|
||||
* parent_object.reg, it's defined on the outer image.
|
||||
*/
|
||||
REGION *reg;
|
||||
VipsRegion *reg;
|
||||
} SinkThreadState;
|
||||
|
||||
typedef struct _SinkThreadStateClass {
|
||||
@ -131,7 +131,7 @@ sink_thread_state_dispose( GObject *gobject )
|
||||
Sink *sink = (Sink *) ((VipsThreadState *) state)->a;
|
||||
|
||||
sink_call_stop( sink, state );
|
||||
VIPS_FREEF( im_region_free, state->reg );
|
||||
VIPS_FREEF( g_object_unref, state->reg );
|
||||
|
||||
G_OBJECT_CLASS( sink_thread_state_parent_class )->dispose( gobject );
|
||||
}
|
||||
@ -163,7 +163,7 @@ sink_thread_state_build( VipsObject *object )
|
||||
SinkThreadState *state = (SinkThreadState *) object;
|
||||
Sink *sink = (Sink *) ((VipsThreadState *) state)->a;
|
||||
|
||||
if( !(state->reg = im_region_create( sink->t )) ||
|
||||
if( !(state->reg = vips_region_new( sink->t )) ||
|
||||
sink_call_start( sink, state ) )
|
||||
return( -1 );
|
||||
|
||||
@ -278,7 +278,7 @@ sink_work( VipsThreadState *state, void *a )
|
||||
SinkThreadState *sstate = (SinkThreadState *) state;
|
||||
Sink *sink = (Sink *) a;
|
||||
|
||||
if( im_prepare( sstate->reg, &state->pos ) ||
|
||||
if( vips_region_prepare( sstate->reg, &state->pos ) ||
|
||||
sink->generate( sstate->reg, sstate->seq, sink->a, sink->b ) )
|
||||
return( -1 );
|
||||
|
||||
|
@ -70,7 +70,7 @@
|
||||
typedef struct _WriteBuffer {
|
||||
struct _Write *write;
|
||||
|
||||
REGION *region; /* Pixels */
|
||||
VipsRegion *region; /* Pixels */
|
||||
Rect area; /* Part of image this region covers */
|
||||
im_semaphore_t go; /* Start bg thread loop */
|
||||
im_semaphore_t nwrite; /* Number of threads writing to region */
|
||||
@ -168,7 +168,7 @@ wbuffer_free( WriteBuffer *wbuffer )
|
||||
wbuffer->thread = NULL;
|
||||
}
|
||||
|
||||
VIPS_FREEF( im_region_free, wbuffer->region );
|
||||
VIPS_FREEF( g_object_unref, wbuffer->region );
|
||||
im_semaphore_destroy( &wbuffer->go );
|
||||
im_semaphore_destroy( &wbuffer->nwrite );
|
||||
im_semaphore_destroy( &wbuffer->done );
|
||||
@ -234,14 +234,14 @@ wbuffer_new( Write *write )
|
||||
wbuffer->thread = NULL;
|
||||
wbuffer->kill = FALSE;
|
||||
|
||||
if( !(wbuffer->region = im_region_create( write->im )) ) {
|
||||
if( !(wbuffer->region = vips_region_new( write->im )) ) {
|
||||
wbuffer_free( wbuffer );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
/* The worker threads need to be able to move the buffers around.
|
||||
*/
|
||||
im__region_no_ownership( wbuffer->region );
|
||||
vips__region_no_ownership( wbuffer->region );
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
/* Make this last (picks up parts of wbuffer on startup).
|
||||
@ -315,11 +315,11 @@ wbuffer_position( WriteBuffer *wbuffer, int top, int height )
|
||||
|
||||
/* The workers take turns to move the buffers.
|
||||
*/
|
||||
im__region_take_ownership( wbuffer->region );
|
||||
vips__region_take_ownership( wbuffer->region );
|
||||
|
||||
result = im_region_buffer( wbuffer->region, &wbuffer->area );
|
||||
result = vips_region_buffer( wbuffer->region, &wbuffer->area );
|
||||
|
||||
im__region_no_ownership( wbuffer->region );
|
||||
vips__region_no_ownership( wbuffer->region );
|
||||
|
||||
/* This should be an exclusive buffer, hopefully.
|
||||
*/
|
||||
|
@ -58,7 +58,7 @@ typedef struct _Sink {
|
||||
|
||||
/* A big region for the image memory. All the threads write to this.
|
||||
*/
|
||||
REGION *all;
|
||||
VipsRegion *all;
|
||||
|
||||
/* The position we're at in the image.
|
||||
*/
|
||||
@ -75,7 +75,7 @@ typedef struct _Sink {
|
||||
static void
|
||||
sink_free( Sink *sink )
|
||||
{
|
||||
VIPS_FREEF( im_region_free, sink->all );
|
||||
VIPS_FREEF( g_object_unref, sink->all );
|
||||
}
|
||||
|
||||
static int
|
||||
@ -92,8 +92,8 @@ sink_init( Sink *sink, VipsImage *im )
|
||||
all.width = im->Xsize;
|
||||
all.height = im->Ysize;
|
||||
|
||||
if( !(sink->all = im_region_create( im )) ||
|
||||
im_region_image( sink->all, &all ) ) {
|
||||
if( !(sink->all = vips_region_new( im )) ||
|
||||
vips_region_image( sink->all, &all ) ) {
|
||||
sink_free( sink );
|
||||
return( -1 );
|
||||
}
|
||||
@ -148,7 +148,7 @@ sink_work( VipsThreadState *state, void *a )
|
||||
{
|
||||
Sink *sink = (Sink *) a;
|
||||
|
||||
if( im_prepare_to( state->reg, sink->all,
|
||||
if( vips_region_prepare_to( state->reg, sink->all,
|
||||
&state->pos, state->pos.left, state->pos.top ) )
|
||||
return( -1 );
|
||||
|
||||
|
@ -88,7 +88,7 @@ typedef struct {
|
||||
struct _Render *render;
|
||||
|
||||
Rect area; /* Place here (unclipped) */
|
||||
REGION *region; /* REGION with the pixels */
|
||||
VipsRegion *region; /* VipsRegion with the pixels */
|
||||
|
||||
/* The tile contains calculated pixels. Though the region may have been
|
||||
* invalidated behind our backs: we have to check that too.
|
||||
@ -208,7 +208,7 @@ tile_free( Tile *tile )
|
||||
{
|
||||
VIPS_DEBUG_MSG_AMBER( "tile_free\n" );
|
||||
|
||||
VIPS_FREEF( im_region_free, tile->region );
|
||||
VIPS_FREEF( g_object_unref, tile->region );
|
||||
im_free( tile );
|
||||
|
||||
return( NULL );
|
||||
@ -426,9 +426,10 @@ render_work( VipsThreadState *state, void *a )
|
||||
VIPS_DEBUG_MSG( "calculating tile %p %dx%d\n",
|
||||
tile, tile->area.left, tile->area.top );
|
||||
|
||||
if( im_prepare_to( state->reg, tile->region,
|
||||
if( vips_region_prepare_to( state->reg, tile->region,
|
||||
&tile->area, tile->area.left, tile->area.top ) ) {
|
||||
VIPS_DEBUG_MSG_RED( "render_work: im_prepare_to() failed\n" );
|
||||
VIPS_DEBUG_MSG_RED( "render_work: "
|
||||
"vips_region_prepare_to() failed\n" );
|
||||
return( -1 );
|
||||
}
|
||||
tile->painted = TRUE;
|
||||
@ -665,7 +666,7 @@ tile_new( Render *render )
|
||||
tile->dirty = FALSE;
|
||||
tile->ticks = render->ticks;
|
||||
|
||||
if( !(tile->region = im_region_create( render->in )) ) {
|
||||
if( !(tile->region = vips_region_new( render->in )) ) {
|
||||
(void) tile_free( tile );
|
||||
return( NULL );
|
||||
}
|
||||
@ -699,7 +700,7 @@ render_tile_add( Tile *tile, Rect *area )
|
||||
/* Ignore buffer allocate errors, there's not much we could do with
|
||||
* them.
|
||||
*/
|
||||
if( im_region_buffer( tile->region, &tile->area ) )
|
||||
if( vips_region_buffer( tile->region, &tile->area ) )
|
||||
VIPS_DEBUG_MSG_RED( "render_tile_add: "
|
||||
"buffer allocate failed\n" );
|
||||
|
||||
@ -739,7 +740,7 @@ tile_touch( Tile *tile )
|
||||
/* Queue a tile for calculation.
|
||||
*/
|
||||
static void
|
||||
tile_queue( Tile *tile, REGION *reg )
|
||||
tile_queue( Tile *tile, VipsRegion *reg )
|
||||
{
|
||||
Render *render = tile->render;
|
||||
|
||||
@ -772,7 +773,7 @@ tile_queue( Tile *tile, REGION *reg )
|
||||
*/
|
||||
g_mutex_unlock( render->lock );
|
||||
|
||||
if( im_prepare_to( reg, tile->region,
|
||||
if( vips_region_prepare_to( reg, tile->region,
|
||||
&tile->area, tile->area.left, tile->area.top ) )
|
||||
VIPS_DEBUG_MSG_RED( "tile_queue: prepare failed\n" );
|
||||
|
||||
@ -813,7 +814,7 @@ render_tile_get_painted( Render *render )
|
||||
* or if we've no threads or no notify, calculate immediately.
|
||||
*/
|
||||
static Tile *
|
||||
render_tile_request( Render *render, REGION *reg, Rect *area )
|
||||
render_tile_request( Render *render, VipsRegion *reg, Rect *area )
|
||||
{
|
||||
Tile *tile;
|
||||
|
||||
@ -863,7 +864,7 @@ render_tile_request( Render *render, REGION *reg, Rect *area )
|
||||
/* Copy what we can from the tile into the region.
|
||||
*/
|
||||
static void
|
||||
tile_copy( Tile *tile, REGION *to )
|
||||
tile_copy( Tile *tile, VipsRegion *to )
|
||||
{
|
||||
Rect ovlap;
|
||||
int y;
|
||||
@ -884,9 +885,9 @@ tile_copy( Tile *tile, REGION *to )
|
||||
tile, tile->area.left, tile->area.top );
|
||||
|
||||
for( y = ovlap.top; y < IM_RECT_BOTTOM( &ovlap ); y++ ) {
|
||||
PEL *p = (PEL *) IM_REGION_ADDR( tile->region,
|
||||
PEL *p = (PEL *) VIPS_REGION_ADDR( tile->region,
|
||||
ovlap.left, y );
|
||||
PEL *q = (PEL *) IM_REGION_ADDR( to, ovlap.left, y );
|
||||
PEL *q = (PEL *) VIPS_REGION_ADDR( to, ovlap.left, y );
|
||||
|
||||
memcpy( q, p, len );
|
||||
}
|
||||
@ -894,7 +895,7 @@ tile_copy( Tile *tile, REGION *to )
|
||||
else {
|
||||
VIPS_DEBUG_MSG( "tile_copy: zero filling for %p %dx%d\n",
|
||||
tile, tile->area.left, tile->area.top );
|
||||
im_region_paint( to, &ovlap, 0 );
|
||||
vips_region_paint( to, &ovlap, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -903,16 +904,16 @@ image_start( IMAGE *out, void *a, void *b )
|
||||
{
|
||||
Render *render = (Render *) a;
|
||||
|
||||
return( im_region_create( render->in ) );
|
||||
return( vips_region_new( render->in ) );
|
||||
}
|
||||
|
||||
/* Loop over the output region, filling with data from cache.
|
||||
*/
|
||||
static int
|
||||
image_fill( REGION *out, void *seq, void *a, void *b )
|
||||
image_fill( VipsRegion *out, void *seq, void *a, void *b )
|
||||
{
|
||||
Render *render = (Render *) a;
|
||||
REGION *reg = (REGION *) seq;
|
||||
VipsRegion *reg = (VipsRegion *) seq;
|
||||
Rect *r = &out->valid;
|
||||
int x, y;
|
||||
|
||||
@ -959,9 +960,9 @@ image_fill( REGION *out, void *seq, void *a, void *b )
|
||||
static int
|
||||
image_stop( void *seq, void *a, void *b )
|
||||
{
|
||||
REGION *reg = (REGION *) seq;
|
||||
VipsRegion *reg = (VipsRegion *) seq;
|
||||
|
||||
im_region_free( reg );
|
||||
g_object_unref( reg );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
@ -969,7 +970,7 @@ image_stop( void *seq, void *a, void *b )
|
||||
/* The mask image is 255 / 0 for the state of painted for each tile.
|
||||
*/
|
||||
static int
|
||||
mask_fill( REGION *out, void *seq, void *a, void *b )
|
||||
mask_fill( VipsRegion *out, void *seq, void *a, void *b )
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
Render *render = (Render *) a;
|
||||
@ -1005,12 +1006,12 @@ mask_fill( REGION *out, void *seq, void *a, void *b )
|
||||
|
||||
/* Only mark painted tiles containing valid pixels.
|
||||
*/
|
||||
im_region_paint( out, &area, value );
|
||||
vips_region_paint( out, &area, value );
|
||||
}
|
||||
|
||||
g_mutex_unlock( render->lock );
|
||||
#else /*!HAVE_THREADS*/
|
||||
im_region_paint( out, &out->valid, 255 );
|
||||
vips_region_paint( out, &out->valid, 255 );
|
||||
#endif /*HAVE_THREADS*/
|
||||
|
||||
return( 0 );
|
||||
@ -1044,7 +1045,8 @@ mask_fill( REGION *out, void *seq, void *a, void *b )
|
||||
* priority, negative numbers are low priority, positive numbers high
|
||||
* priority.
|
||||
*
|
||||
* Calls to im_prepare() on @out return immediately and hold whatever is
|
||||
* Calls to vips_region_prepare() on @out return immediately and hold
|
||||
* whatever is
|
||||
* currently in cache for that #Rect (check @mask to see which parts of the
|
||||
* #Rect are valid). Any pixels in the #Rect which are not in cache are added
|
||||
* to a queue, and the @notify callback will trigger when those pixels are
|
||||
@ -1056,10 +1058,11 @@ mask_fill( REGION *out, void *seq, void *a, void *b )
|
||||
* ready. In a glib-based application, this is easily done with g_idle_add().
|
||||
*
|
||||
* If @notify is %NULL then im_render_priority() runs synchronously.
|
||||
* im_prepare() on @out will always block until the pixels have been
|
||||
* vips_region_prepare() on @out will always block until the pixels have been
|
||||
* calculated.
|
||||
*
|
||||
* See also: im_cache(), im_tile_cache(), im_prepare(), vips_sink_disc(),
|
||||
* See also: im_cache(), im_tile_cache(), vips_region_prepare(),
|
||||
* vips_sink_disc(),
|
||||
* vips_sink().
|
||||
*
|
||||
* Returns: 0 on sucess, -1 on error.
|
||||
|
Loading…
Reference in New Issue
Block a user