move vips__lr|tbmerge to private API

This commit is contained in:
John Cupitt 2020-07-01 17:31:25 +01:00
parent 8dcf3bca57
commit 0803de07e7
12 changed files with 182 additions and 115 deletions

View File

@ -367,7 +367,7 @@ lrmerge_vec( im_object *argv )
int dy = *((int *) argv[4]); int dy = *((int *) argv[4]);
int mwidth = *((int *) argv[5]); int mwidth = *((int *) argv[5]);
return( vips_lrmerge( argv[0], argv[1], argv[2], dx, dy, mwidth ) ); return( im_lrmerge( argv[0], argv[1], argv[2], dx, dy, mwidth ) );
} }
/* Call im_lrmerge1 via arg vector. /* Call im_lrmerge1 via arg vector.
@ -421,7 +421,7 @@ tbmerge_vec( im_object *argv )
int dy = *((int *) argv[4]); int dy = *((int *) argv[4]);
int mwidth = *((int *) argv[5]); int mwidth = *((int *) argv[5]);
return( vips_tbmerge( argv[0], argv[1], argv[2], dx, dy, mwidth ) ); return( im_tbmerge( argv[0], argv[1], argv[2], dx, dy, mwidth ) );
} }
/* Call im_tbmerge1 via arg vector. /* Call im_tbmerge1 via arg vector.

View File

@ -5367,6 +5367,25 @@ im_tbmosaic1( IMAGE *ref, IMAGE *sec, IMAGE *out,
return( 0 ); return( 0 );
} }
int
im_lrmerge( IMAGE *ref, IMAGE *sec, IMAGE *out,
int dx, int dy, int mwidth )
{
VipsImage *x;
if( vips_merge( ref, sec, &x, VIPS_DIRECTION_HORIZONTAL, dx, dy,
"mblend", mwidth,
NULL ) )
return( -1 );
if( vips_image_write( x, out ) ) {
g_object_unref( x );
return( -1 );
}
g_object_unref( x );
return( 0 );
}
int int
im_lrmerge1( IMAGE *ref, IMAGE *sec, IMAGE *out, im_lrmerge1( IMAGE *ref, IMAGE *sec, IMAGE *out,
int xr1, int yr1, int xs1, int ys1, int xr1, int yr1, int xs1, int ys1,
@ -5389,6 +5408,25 @@ im_lrmerge1( IMAGE *ref, IMAGE *sec, IMAGE *out,
return( 0 ); return( 0 );
} }
int
im_tbmerge( IMAGE *ref, IMAGE *sec, IMAGE *out,
int dx, int dy, int mwidth )
{
VipsImage *x;
if( vips_merge( ref, sec, &x, VIPS_DIRECTION_VERTICAL, dx, dy,
"mblend", mwidth,
NULL ) )
return( -1 );
if( vips_image_write( x, out ) ) {
g_object_unref( x );
return( -1 );
}
g_object_unref( x );
return( 0 );
}
int int
im_tbmerge1( IMAGE *ref, IMAGE *sec, IMAGE *out, im_tbmerge1( IMAGE *ref, IMAGE *sec, IMAGE *out,
int xr1, int yr1, int xs1, int ys1, int xr1, int yr1, int xs1, int ys1,

View File

@ -1065,10 +1065,14 @@ int im_global_balancef( VipsImage *in, VipsImage *out, double gamma );
int im_remosaic( VipsImage *in, VipsImage *out, int im_remosaic( VipsImage *in, VipsImage *out,
const char *old_str, const char *new_str ); const char *old_str, const char *new_str );
int im_lrmerge( VipsImage *ref, VipsImage *sec, VipsImage *out,
int dx, int dy, int mwidth );
int im_lrmerge1( VipsImage *ref, VipsImage *sec, VipsImage *out, int im_lrmerge1( VipsImage *ref, VipsImage *sec, VipsImage *out,
int xr1, int yr1, int xs1, int ys1, int xr1, int yr1, int xs1, int ys1,
int xr2, int yr2, int xs2, int ys2, int xr2, int yr2, int xs2, int ys2,
int mwidth ); int mwidth );
int im_tbmerge( VipsImage *ref, VipsImage *sec, VipsImage *out,
int dx, int dy, int mwidth );
int im_tbmerge1( VipsImage *ref, VipsImage *sec, VipsImage *out, int im_tbmerge1( VipsImage *ref, VipsImage *sec, VipsImage *out,
int xr1, int yr1, int xs1, int ys1, int xr1, int yr1, int xs1, int ys1,
int xr2, int yr2, int xs2, int ys2, int xr2, int yr2, int xs2, int ys2,

View File

@ -8,16 +8,16 @@ libmosaicing_la_SOURCES = \
mosaic1.c \ mosaic1.c \
matrixinvert.c \ matrixinvert.c \
global_balance.c \ global_balance.c \
lrmerge.c \
tbmerge.c \
im_avgdxdy.c \ im_avgdxdy.c \
im_chkpair.c \ im_chkpair.c \
im_clinear.c \ im_clinear.c \
im_improve.c \ im_improve.c \
im_initialize.c \ im_initialize.c \
im_lrcalcon.c \ im_lrcalcon.c \
im_lrmerge.c \
im_lrmosaic.c \ im_lrmosaic.c \
im_tbcalcon.c \ im_tbcalcon.c \
im_tbmerge.c \
im_remosaic.c \ im_remosaic.c \
im_tbmosaic.c \ im_tbmosaic.c \
global_balance.h \ global_balance.h \

View File

@ -1340,22 +1340,17 @@ make_mos_image( SymbolTable *st, JoinNode *node, transform_fn tfn, void *a )
!(im2 = make_mos_image( st, node->arg2, tfn, a )) ) !(im2 = make_mos_image( st, node->arg2, tfn, a )) )
return( NULL ); return( NULL );
out = vips_image_new(); if( vips_merge( im1, im2, &out,
node->type == JOIN_LR ?
VIPS_DIRECTION_HORIZONTAL :
VIPS_DIRECTION_VERTICAL,
-node->dx, -node->dy,
"mblend", node->mwidth,
NULL ) )
return( NULL );
vips_object_local( st->im, out ); vips_object_local( st->im, out );
vips_image_set_string( out, "mosaic-name", node->name ); vips_image_set_string( out, "mosaic-name", node->name );
if( node->type == JOIN_LR ) {
if( vips_lrmerge( im1, im2, out,
-node->dx, -node->dy, node->mwidth ) )
return( NULL );
}
else {
if( vips_tbmerge( im1, im2, out,
-node->dx, -node->dy, node->mwidth ) )
return( NULL );
}
break; break;
case JOIN_LRROTSCALE: case JOIN_LRROTSCALE:
@ -1415,6 +1410,7 @@ vips__build_mosaic( SymbolTable *st, VipsImage *out, transform_fn tfn, void *a )
{ {
JoinNode *root = st->root; JoinNode *root = st->root;
VipsImage *im1, *im2; VipsImage *im1, *im2;
VipsImage *x;
switch( root->type ) { switch( root->type ) {
case JOIN_LR: case JOIN_LR:
@ -1423,16 +1419,19 @@ vips__build_mosaic( SymbolTable *st, VipsImage *out, transform_fn tfn, void *a )
!(im2 = make_mos_image( st, root->arg2, tfn, a )) ) !(im2 = make_mos_image( st, root->arg2, tfn, a )) )
return( -1 ); return( -1 );
if( root->type == JOIN_LR ) { if( vips_merge( im1, im2, &x,
if( vips_lrmerge( im1, im2, out, root->type == JOIN_LR ?
-root->dx, -root->dy, root->mwidth ) ) VIPS_DIRECTION_HORIZONTAL :
return( -1 ); VIPS_DIRECTION_VERTICAL,
} -root->dx, -root->dy,
else { "mblend", root->mwidth,
if( vips_tbmerge( im1, im2, out, NULL ) )
-root->dx, -root->dy, root->mwidth ) ) return( -1 );
return( -1 ); if( vips_image_write( x, out ) ) {
g_object_unref( x );
return( -1 );
} }
g_object_unref( x );
break; break;

View File

@ -252,6 +252,7 @@ vips_lrmosaic( VipsImage *ref, VipsImage *sec, VipsImage *out,
int dx0, dy0; int dx0, dy0;
double scale1, angle1, dx1, dy1; double scale1, angle1, dx1, dy1;
VipsImage *dummy; VipsImage *dummy;
VipsImage *x;
/* Correct overlap. dummy is just a placeholder used to ensure that /* Correct overlap. dummy is just a placeholder used to ensure that
* memory used by the analysis phase is freed as soon as possible. * memory used by the analysis phase is freed as soon as possible.
@ -270,8 +271,15 @@ vips_lrmosaic( VipsImage *ref, VipsImage *sec, VipsImage *out,
/* Merge left right. /* Merge left right.
*/ */
if( vips_lrmerge( ref, sec, out, dx0, dy0, mwidth ) ) if( vips_merge( ref, sec, &x, VIPS_DIRECTION_HORIZONTAL, dx0, dy0,
"mblend", mwidth,
NULL ) )
return( -1 ); return( -1 );
if( vips_image_write( x, out ) ) {
g_object_unref( x );
return( -1 );
}
g_object_unref( x );
return( 0 ); return( 0 );
} }

View File

@ -223,6 +223,7 @@ vips_tbmosaic( VipsImage *ref, VipsImage *sec, VipsImage *out,
int dx0, dy0; int dx0, dy0;
double scale1, angle1, dx1, dy1; double scale1, angle1, dx1, dy1;
VipsImage *dummy; VipsImage *dummy;
VipsImage *x;
/* Correct overlap. dummy is just a placeholder used to ensure that /* Correct overlap. dummy is just a placeholder used to ensure that
* memory used by the analysis phase is freed as soon as possible. * memory used by the analysis phase is freed as soon as possible.
@ -241,8 +242,15 @@ vips_tbmosaic( VipsImage *ref, VipsImage *sec, VipsImage *out,
/* Merge top-bottom. /* Merge top-bottom.
*/ */
if( vips_tbmerge( ref, sec, out, dx0, dy0, mwidth ) ) if( vips_merge( ref, sec, &x, VIPS_DIRECTION_VERTICAL, dx0, dy0,
"mblend", mwidth,
NULL ) )
return( -1 ); return( -1 );
if( vips_image_write( x, out ) ) {
g_object_unref( x );
return( -1 );
}
g_object_unref( x );
return( 0 ); return( 0 );
} }

View File

@ -203,19 +203,19 @@ find_first( VipsRegion *ir, int *pos, int x, int y, int w )
} }
switch( im->BandFmt ) { switch( im->BandFmt ) {
case VIPS_FORMAT_UCHAR: lsearch( unsigned char ); break; case VIPS_FORMAT_UCHAR: lsearch( unsigned char ); break;
case VIPS_FORMAT_CHAR: lsearch( signed char ); break; case VIPS_FORMAT_CHAR: lsearch( signed char ); break;
case VIPS_FORMAT_USHORT: lsearch( unsigned short ); break; case VIPS_FORMAT_USHORT: lsearch( unsigned short ); break;
case VIPS_FORMAT_SHORT: lsearch( signed short ); break; case VIPS_FORMAT_SHORT: lsearch( signed short ); break;
case VIPS_FORMAT_UINT: lsearch( unsigned int ); break; case VIPS_FORMAT_UINT: lsearch( unsigned int ); break;
case VIPS_FORMAT_INT: lsearch( signed int ); break; case VIPS_FORMAT_INT: lsearch( signed int ); break;
case VIPS_FORMAT_FLOAT: lsearch( float ); break; case VIPS_FORMAT_FLOAT: lsearch( float ); break;
case VIPS_FORMAT_DOUBLE: lsearch( double ); break; case VIPS_FORMAT_DOUBLE: lsearch( double ); break;
case VIPS_FORMAT_COMPLEX: lsearch( float ); break; case VIPS_FORMAT_COMPLEX: lsearch( float ); break;
case VIPS_FORMAT_DPCOMPLEX: lsearch( double ); break; case VIPS_FORMAT_DPCOMPLEX: lsearch( double ); break;
default: default:
vips_error( "vips_lrmerge", "%s", _( "internal error" ) ); g_assert_not_reached();
return( -1 ); return( -1 );
} }
@ -252,19 +252,19 @@ find_last( VipsRegion *ir, int *pos, int x, int y, int w )
} }
switch( im->BandFmt ) { switch( im->BandFmt ) {
case VIPS_FORMAT_UCHAR: rsearch( unsigned char ); break; case VIPS_FORMAT_UCHAR: rsearch( unsigned char ); break;
case VIPS_FORMAT_CHAR: rsearch( signed char ); break; case VIPS_FORMAT_CHAR: rsearch( signed char ); break;
case VIPS_FORMAT_USHORT: rsearch( unsigned short ); break; case VIPS_FORMAT_USHORT: rsearch( unsigned short ); break;
case VIPS_FORMAT_SHORT: rsearch( signed short ); break; case VIPS_FORMAT_SHORT: rsearch( signed short ); break;
case VIPS_FORMAT_UINT: rsearch( unsigned int ); break; case VIPS_FORMAT_UINT: rsearch( unsigned int ); break;
case VIPS_FORMAT_INT: rsearch( signed int ); break; case VIPS_FORMAT_INT: rsearch( signed int ); break;
case VIPS_FORMAT_FLOAT: rsearch( float ); break; case VIPS_FORMAT_FLOAT: rsearch( float ); break;
case VIPS_FORMAT_DOUBLE: rsearch( double ); break; case VIPS_FORMAT_DOUBLE: rsearch( double ); break;
case VIPS_FORMAT_COMPLEX: rsearch( float ); break; case VIPS_FORMAT_COMPLEX: rsearch( float ); break;
case VIPS_FORMAT_DPCOMPLEX: rsearch( double ); break; case VIPS_FORMAT_DPCOMPLEX: rsearch( double ); break;
default: default:
vips_error( "vipslrmerge", "%s", _( "internal error" ) ); vips_error( "lrmerge", "%s", _( "internal error" ) );
return( -1 ); return( -1 );
} }
@ -330,7 +330,7 @@ make_firstlast( MergeInfo *inf, Overlapping *ovlap, VipsRect *oreg )
sr.top -= ovlap->sarea.top; sr.top -= ovlap->sarea.top;
#ifdef DEBUG #ifdef DEBUG
printf( "vips__lrmerge: making first/last for areas:\n" ); printf( "lrmerge: making first/last for areas:\n" );
printf( "ref: left = %d, top = %d, width = %d, height = %d\n", printf( "ref: left = %d, top = %d, width = %d, height = %d\n",
rr.left, rr.top, rr.width, rr.height ); rr.left, rr.top, rr.width, rr.height );
printf( "sec: left = %d, top = %d, width = %d, height = %d\n", printf( "sec: left = %d, top = %d, width = %d, height = %d\n",
@ -605,7 +605,7 @@ lr_blend( VipsRegion *or, MergeInfo *inf, Overlapping *ovlap, VipsRect *oreg )
fblend( double, im->Bands * 2, pr, ps, q ); break; fblend( double, im->Bands * 2, pr, ps, q ); break;
default: default:
vips_error( "vips_lrmerge", "%s", _( "internal error" ) ); g_assert_not_reached();
return( -1 ); return( -1 );
} }
} }
@ -616,7 +616,8 @@ lr_blend( VipsRegion *or, MergeInfo *inf, Overlapping *ovlap, VipsRect *oreg )
/* Left-right blend function for VIPS_CODING_LABQ images. /* Left-right blend function for VIPS_CODING_LABQ images.
*/ */
static int static int
lr_blend_labpack( VipsRegion *or, MergeInfo *inf, Overlapping *ovlap, VipsRect *oreg ) lr_blend_labpack( VipsRegion *or, MergeInfo *inf, Overlapping *ovlap,
VipsRect *oreg )
{ {
VipsRegion *rir = inf->rir; VipsRegion *rir = inf->rir;
VipsRegion *sir = inf->sir; VipsRegion *sir = inf->sir;
@ -688,11 +689,12 @@ lock_free( VipsImage *image, GMutex *lock )
} }
/* Build basic per-call state and do some geometry calculations. Shared with /* Build basic per-call state and do some geometry calculations. Shared with
* vips_tbmerge, so not static. * tbmerge, so not static.
*/ */
Overlapping * Overlapping *
vips__build_mergestate( const char *domain, vips__build_mergestate( const char *domain,
VipsImage *ref, VipsImage *sec, VipsImage *out, int dx, int dy, int mwidth ) VipsImage *ref, VipsImage *sec, VipsImage *out,
int dx, int dy, int mwidth )
{ {
VipsImage **t = (VipsImage **) VipsImage **t = (VipsImage **)
vips_object_local_array( VIPS_OBJECT( out ), 4 ); vips_object_local_array( VIPS_OBJECT( out ), 4 );
@ -703,14 +705,13 @@ vips__build_mergestate( const char *domain,
/* TODO(kleisauke): Copied from vips_insert, perhaps we /* TODO(kleisauke): Copied from vips_insert, perhaps we
* need a separate function for this? * need a separate function for this?
* (just like im__insert_base) */ * (just like im__insert_base)
*/
if( vips_image_pio_input( ref ) || if( vips_image_pio_input( ref ) ||
vips_image_pio_input( sec ) || vips_image_pio_input( sec ) ||
vips_check_bands_1orn( domain, vips_check_bands_1orn( domain, ref, sec ) ||
ref, sec ) ||
vips_check_coding_known( domain, ref ) || vips_check_coding_known( domain, ref ) ||
vips_check_coding_same( domain, vips_check_coding_same( domain, ref, sec ) )
ref, sec ) )
return( NULL ); return( NULL );
/* Cast our input images up to a common format and bands. /* Cast our input images up to a common format and bands.
@ -809,11 +810,12 @@ vips__build_mergestate( const char *domain,
/* Build per-call state. /* Build per-call state.
*/ */
static Overlapping * static Overlapping *
build_lrstate( VipsImage *ref, VipsImage *sec, VipsImage *out, int dx, int dy, int mwidth ) build_lrstate( VipsImage *ref, VipsImage *sec, VipsImage *out,
int dx, int dy, int mwidth )
{ {
Overlapping *ovlap; Overlapping *ovlap;
if( !(ovlap = vips__build_mergestate( "vips_lrmerge", if( !(ovlap = vips__build_mergestate( "lrmerge",
ref, sec, out, dx, dy, mwidth )) ) ref, sec, out, dx, dy, mwidth )) )
return( NULL ); return( NULL );
@ -829,7 +831,7 @@ build_lrstate( VipsImage *ref, VipsImage *sec, VipsImage *out, int dx, int dy, i
break; break;
default: default:
vips_error( "vips_lrmerge", "%s", _( "unknown coding type" ) ); vips_error( "lrmerge", "%s", _( "unknown coding type" ) );
return( NULL ); return( NULL );
} }
@ -844,9 +846,10 @@ build_lrstate( VipsImage *ref, VipsImage *sec, VipsImage *out, int dx, int dy, i
/* Is there too much overlap? ie. right edge of ref image is greater /* Is there too much overlap? ie. right edge of ref image is greater
* than right edge of sec image, or left > left. * than right edge of sec image, or left > left.
*/ */
if( VIPS_RECT_RIGHT( &ovlap->rarea ) > VIPS_RECT_RIGHT( &ovlap->sarea ) || if( VIPS_RECT_RIGHT( &ovlap->rarea ) >
VIPS_RECT_RIGHT( &ovlap->sarea ) ||
ovlap->rarea.left > ovlap->sarea.left ) { ovlap->rarea.left > ovlap->sarea.left ) {
vips_error( "vips_lrmerge", "%s", _( "too much overlap" ) ); vips_error( "lrmerge", "%s", _( "too much overlap" ) );
return( NULL ); return( NULL );
} }
@ -861,7 +864,7 @@ build_lrstate( VipsImage *ref, VipsImage *sec, VipsImage *out, int dx, int dy, i
* or the sec images. Attach output to the appropriate part of the input image. * or the sec images. Attach output to the appropriate part of the input image.
* area is the position that ir->im occupies in the output image. * area is the position that ir->im occupies in the output image.
* *
* Shared with vips_tbmerge(), so not static. * Shared with tbmerge, so not static.
*/ */
int int
vips__attach_input( VipsRegion *or, VipsRegion *ir, VipsRect *area ) vips__attach_input( VipsRegion *or, VipsRegion *ir, VipsRect *area )
@ -890,10 +893,11 @@ vips__attach_input( VipsRegion *or, VipsRegion *ir, VipsRect *area )
* above, but just do a sub-area of the output, and make sure we copy rather * above, but just do a sub-area of the output, and make sure we copy rather
* than just pointer-fiddling. reg is the sub-area of or->valid we should do. * than just pointer-fiddling. reg is the sub-area of or->valid we should do.
* *
* Shared with vips_tbmerge(), so not static. * Shared with tbmerge, so not static.
*/ */
int int
vips__copy_input( VipsRegion *or, VipsRegion *ir, VipsRect *area, VipsRect *reg ) vips__copy_input( VipsRegion *or, VipsRegion *ir,
VipsRect *area, VipsRect *reg )
{ {
VipsRect r = *reg; VipsRect r = *reg;
@ -910,8 +914,8 @@ vips__copy_input( VipsRegion *or, VipsRegion *ir, VipsRect *area, VipsRect *reg
return( 0 ); return( 0 );
} }
/* Generate function for merge. This is shared between vips_lrmerge() and /* Generate function for merge. This is shared between lrmerge and
* vips_tbmerge(). * tbmerge.
*/ */
int int
vips__merge_gen( VipsRegion *or, void *seq, void *a, void *b, vips__merge_gen( VipsRegion *or, void *seq, void *a, void *b,
@ -981,7 +985,7 @@ vips__merge_gen( VipsRegion *or, void *seq, void *a, void *b,
return( 0 ); return( 0 );
} }
/* Stop function. Shared with vips_tbmerge(). Free explicitly to reduce mem /* Stop function. Shared with tbmerge. Free explicitly to reduce mem
* requirements quickly for large mosaics. * requirements quickly for large mosaics.
*/ */
int int
@ -999,7 +1003,7 @@ vips__stop_merge( void *seq, void *a, void *b )
return( 0 ); return( 0 );
} }
/* Start function. Shared with vips_tbmerge(). /* Start function. Shared with tbmerge.
*/ */
void * void *
vips__start_merge( VipsImage *out, void *a, void *b ) vips__start_merge( VipsImage *out, void *a, void *b )
@ -1041,12 +1045,13 @@ vips__start_merge( VipsImage *out, void *a, void *b )
} }
int int
vips__lrmerge( VipsImage *ref, VipsImage *sec, VipsImage *out, int dx, int dy, int mwidth ) vips__lrmerge( VipsImage *ref, VipsImage *sec, VipsImage *out,
int dx, int dy, int mwidth )
{ {
Overlapping *ovlap; Overlapping *ovlap;
#ifdef DEBUG #ifdef DEBUG
printf( "vips__lrmerge %s %s %s %d %d %d\n", printf( "lrmerge %s %s %s %d %d %d\n",
ref->filename, sec->filename, out->filename, ref->filename, sec->filename, out->filename,
dx, dy, mwidth ); dx, dy, mwidth );
printf( "ref is %d x %d pixels\n", ref->Xsize, ref->Ysize ); printf( "ref is %d x %d pixels\n", ref->Xsize, ref->Ysize );
@ -1054,16 +1059,24 @@ vips__lrmerge( VipsImage *ref, VipsImage *sec, VipsImage *out, int dx, int dy, i
#endif #endif
if( dx > 0 || dx < 1 - ref->Xsize ) { if( dx > 0 || dx < 1 - ref->Xsize ) {
VipsImage *x;
#ifdef DEBUG #ifdef DEBUG
printf( "vips__lrmerge: no overlap, using insert\n" ); printf( "lrmerge: no overlap, using insert\n" );
#endif #endif
/* No overlap, use insert instead. /* No overlap, use insert instead.
*/ */
if( vips_insert( ref, sec, &out, -dx, -dy, if( vips_insert( ref, sec, &x, -dx, -dy,
"expand", TRUE, "expand", TRUE,
NULL ) ) NULL ) )
return( -1 ); return( -1 );
if( vips_image_write( x, out ) ) {
g_object_unref( x );
return( -1 );
}
g_object_unref( x );
out->Xoffset = -dx; out->Xoffset = -dx;
out->Yoffset = -dy; out->Yoffset = -dy;
@ -1083,7 +1096,8 @@ vips__lrmerge( VipsImage *ref, VipsImage *sec, VipsImage *out, int dx, int dy, i
out->Yoffset = -dy; out->Yoffset = -dy;
if( vips_image_generate( out, if( vips_image_generate( out,
vips__start_merge, vips__merge_gen, vips__stop_merge, ovlap, NULL ) ) vips__start_merge, vips__merge_gen, vips__stop_merge,
ovlap, NULL ) )
return( -1 ); return( -1 );
return ( 0 ); return ( 0 );
@ -1109,8 +1123,9 @@ vips__add_mosaic_name( VipsImage *image )
{ {
static int global_serial = 0; static int global_serial = 0;
/* TODO(kleisauke): Could we call vips_image_temp_name instead? */
/* Old glibs named this differently. /* Old glibs named this differently.
*
* TODO(kleisauke): Could we call vips_image_temp_name instead?
*/ */
int serial = int serial =
#if GLIB_CHECK_VERSION( 2, 30, 0 ) #if GLIB_CHECK_VERSION( 2, 30, 0 )
@ -1128,19 +1143,3 @@ vips__add_mosaic_name( VipsImage *image )
vips_image_set_string( image, "mosaic-name", name ); vips_image_set_string( image, "mosaic-name", name );
} }
int
vips_lrmerge( VipsImage *ref, VipsImage *sec, VipsImage *out, int dx, int dy, int mwidth )
{
if( vips__lrmerge( ref, sec, out, dx, dy, mwidth ) )
return( -1 );
vips__add_mosaic_name( out );
if( vips_image_history_printf( out, "#LRJOIN <%s> <%s> <%s> <%d> <%d> <%d>",
vips__get_mosaic_name( ref ),
vips__get_mosaic_name( sec ),
vips__get_mosaic_name( out ),
-dx, -dy, mwidth ) )
return( -1 );
return( 0 );
}

View File

@ -41,7 +41,7 @@
#include <stdio.h> #include <stdio.h>
#include <vips/vips.h> #include <vips/vips.h>
#include <vips/internal.h> #include "pmosaicing.h"
typedef struct { typedef struct {
VipsOperation parent_instance; VipsOperation parent_instance;
@ -72,13 +72,13 @@ vips_merge_build( VipsObject *object )
switch( merge->direction ) { switch( merge->direction ) {
case VIPS_DIRECTION_HORIZONTAL: case VIPS_DIRECTION_HORIZONTAL:
if( vips_lrmerge( merge->ref, merge->sec, merge->out, if( vips__lrmerge( merge->ref, merge->sec, merge->out,
merge->dx, merge->dy, merge->mblend ) ) merge->dx, merge->dy, merge->mblend ) )
return( -1 ); return( -1 );
break; break;
case VIPS_DIRECTION_VERTICAL: case VIPS_DIRECTION_VERTICAL:
if( vips_tbmerge( merge->ref, merge->sec, merge->out, if( vips__tbmerge( merge->ref, merge->sec, merge->out,
merge->dx, merge->dy, merge->mblend ) ) merge->dx, merge->dy, merge->mblend ) )
return( -1 ); return( -1 );
break; break;
@ -87,6 +87,17 @@ vips_merge_build( VipsObject *object )
g_assert_not_reached(); g_assert_not_reached();
} }
vips__add_mosaic_name( merge->out );
if( vips_image_history_printf( merge->out,
"#%s <%s> <%s> <%s> <%d> <%d> <%d>",
merge->direction == VIPS_DIRECTION_HORIZONTAL ?
"LRJOIN" : "TBJOIN",
vips__get_mosaic_name( merge->ref ),
vips__get_mosaic_name( merge->sec ),
vips__get_mosaic_name( merge->out ),
-merge->dx, -merge->dy, merge->mblend ) )
return( -1 );
return( 0 ); return( 0 );
} }

View File

@ -394,7 +394,7 @@ old_lrmosaic1( VipsImage *ref, VipsImage *sec, VipsImage *out,
/* And join to ref. /* And join to ref.
*/ */
if( vips_lrmerge( ref, t[1], out, if( vips_merge( ref, t[1], out, VIPS_DIRECtION_HORIZONTAL,
-trn2.area.left, -trn2.area.top, mwidth ) ) -trn2.area.left, -trn2.area.top, mwidth ) )
return( -1 ); return( -1 );

View File

@ -663,17 +663,30 @@ build_tbstate( VipsImage *ref, VipsImage *sec, VipsImage *out, int dx, int dy, i
} }
int int
vips__tbmerge( VipsImage *ref, VipsImage *sec, VipsImage *out, int dx, int dy, int mwidth ) vips__tbmerge( VipsImage *ref, VipsImage *sec, VipsImage *out,
int dx, int dy, int mwidth )
{ {
Overlapping *ovlap; Overlapping *ovlap;
if( dy > 0 || dy < 1 - ref->Ysize ) { if( dy > 0 || dy < 1 - ref->Ysize ) {
VipsImage *x;
#ifdef DEBUG
printf( "vips__tbmerge: no overlap, using insert\n" );
#endif
/* No overlap, use insert instead. /* No overlap, use insert instead.
*/ */
if( vips_insert( ref, sec, &out, -dx, -dy, if( vips_insert( ref, sec, &x, -dx, -dy,
"expand", TRUE, "expand", TRUE,
NULL ) ) NULL ) )
return( -1 ); return( -1 );
if( vips_image_write( x, out ) ) {
g_object_unref( x );
return( -1 );
}
g_object_unref( x );
out->Xoffset = -dx; out->Xoffset = -dx;
out->Yoffset = -dy; out->Yoffset = -dy;
@ -699,19 +712,3 @@ vips__tbmerge( VipsImage *ref, VipsImage *sec, VipsImage *out, int dx, int dy, i
return ( 0 ); return ( 0 );
} }
int
vips_tbmerge( VipsImage *ref, VipsImage *sec, VipsImage *out, int dx, int dy, int mwidth )
{
if( vips__tbmerge( ref, sec, out, dx, dy, mwidth ) )
return( -1 );
vips__add_mosaic_name( out );
if( vips_image_history_printf( out, "#TBJOIN <%s> <%s> <%s> <%d> <%d> <%d>",
vips__get_mosaic_name( ref ),
vips__get_mosaic_name( sec ),
vips__get_mosaic_name( out ),
-dx, -dy, mwidth ) )
return( -1 );
return( 0 );
}

View File

@ -16,21 +16,24 @@ class TestMosaicing:
im = pyvips.Image.new_from_file(files[0]) im = pyvips.Image.new_from_file(files[0])
sec_im = pyvips.Image.new_from_file(files[1]) sec_im = pyvips.Image.new_from_file(files[1])
horizontal_part = im.mosaic(sec_im, pyvips.Direction.HORIZONTAL, horizontal_part = im.mosaic(sec_im,
marks[0][0], marks[0][1], marks[1][0], marks[1][1]) pyvips.Direction.HORIZONTAL,
marks[0][0], marks[0][1],
marks[1][0], marks[1][1])
if mosaiced_image is None: if mosaiced_image is None:
mosaiced_image = horizontal_part mosaiced_image = horizontal_part
else: else:
vertical_marks = MOSAIC_VERTICAL_MARKS[i - 2:i] vertical_marks = MOSAIC_VERTICAL_MARKS[i - 2:i]
mosaiced_image = mosaiced_image.mosaic(horizontal_part, pyvips.Direction.VERTICAL, mosaiced_image = mosaiced_image.mosaic(horizontal_part,
vertical_marks[1][0], vertical_marks[1][1], pyvips.Direction.VERTICAL,
vertical_marks[0][0], vertical_marks[0][1]) vertical_marks[1][0], vertical_marks[1][1],
vertical_marks[0][0], vertical_marks[0][1])
mosaiced_image = mosaiced_image.globalbalance() mosaiced_image = mosaiced_image.globalbalance()
# Uncomment to see output file # Uncomment to see output file
# mosaiced_image.write_to_file('1-pt-mosaic.jpg') #mosaiced_image.write_to_file('after.jpg')
# hard to test much more than this # hard to test much more than this
assert mosaiced_image.width == 1005 assert mosaiced_image.width == 1005