/* Insert generate function. */ static int vips_insert_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop ) { VipsRegion **ir = (VipsRegion **) seq; VipsRect *r = &or->valid; VipsInsert *insert = (VipsInsert *) b; VipsRect ovl; /* Does the rect we have been asked for fall entirely inside the * sub-image? */ if( vips_rect_includesrect( &insert->rsub, &or->valid ) ) return( vips_insert_just_one( or, ir[1], insert->rsub.left, insert->rsub.top ) ); /* Does it fall entirely inside the main, and not at all inside the * sub? */ vips_rect_intersectrect( &or->valid, &insert->rsub, &ovl ); if( vips_rect_includesrect( &insert->rmain, &or->valid ) && vips_rect_isempty( &ovl ) ) return( vips_insert_just_one( or, ir[0], insert->rmain.left, insert->rmain.top ) ); /* Output requires both (or neither) input. If it is not entirely * inside both the main and the sub, then there is going to be some * background. */ if( !(vips_rect_includesrect( &insert->rsub, &or->valid ) && vips_rect_includesrect( &insert->rmain, &or->valid )) ) vips_region_paint_pel( or, r, insert->ink ); /* Paste from main. */ if( vips_insert_paste_region( or, ir[0], &insert->rmain ) ) return( -1 ); /* Paste from sub. */ if( vips_insert_paste_region( or, ir[1], &insert->rsub ) ) return( -1 ); return( 0 ); }
static int vips_embed_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop ) { VipsRegion *ir = (VipsRegion *) seq; VipsEmbed *embed = (VipsEmbed *) b; VipsRect *r = &or->valid; Rect ovl; int i; VipsPel *p; int plsk; /* Entirely within the input image? Generate the subimage and copy * pointers. */ if( vips_rect_includesrect( &embed->rsub, r ) ) { VipsRect need; need = *r; need.left -= embed->x; need.top -= embed->y; if( vips_region_prepare( ir, &need ) || vips_region_region( or, ir, r, need.left, need.top ) ) return( -1 ); return( 0 ); } /* Does any of the input image appear in the area we have been asked * to make? Paste it in. */ vips_rect_intersectrect( r, &embed->rsub, &ovl ); if( !vips_rect_isempty( &ovl ) ) { /* Paint the bits coming from the input image. */ ovl.left -= embed->x; ovl.top -= embed->y; if( vips_region_prepare_to( ir, or, &ovl, ovl.left + embed->x, ovl.top + embed->y ) ) return( -1 ); ovl.left += embed->x; ovl.top += embed->y; } switch( embed->extend ) { case VIPS_EXTEND_BLACK: case VIPS_EXTEND_WHITE: VIPS_GATE_START( "vips_embed_gen: work1" ); /* Paint the borders a solid value. */ for( i = 0; i < 8; i++ ) vips_region_paint( or, &embed->border[i], embed->extend == 0 ? 0 : 255 ); VIPS_GATE_STOP( "vips_embed_gen: work1" ); break; case VIPS_EXTEND_BACKGROUND: VIPS_GATE_START( "vips_embed_gen: work2" ); /* Paint the borders a solid value. */ for( i = 0; i < 8; i++ ) vips_region_paint_pel( or, &embed->border[i], embed->ink ); VIPS_GATE_STOP( "vips_embed_gen: work2" ); break; case VIPS_EXTEND_COPY: /* Extend the borders. */ for( i = 0; i < 8; i++ ) { VipsRect todo; VipsRect edge; vips_rect_intersectrect( r, &embed->border[i], &todo ); if( !vips_rect_isempty( &todo ) ) { vips_embed_find_edge( embed, &todo, i, &edge ); /* Did we paint any of the input image? If we * did, we can fetch the edge pixels from * that. */ if( !vips_rect_isempty( &ovl ) ) { p = VIPS_REGION_ADDR( or, edge.left, edge.top ); plsk = VIPS_REGION_LSKIP( or ); } else { /* No pixels painted ... fetch * directly from the input image. */ edge.left -= embed->x; edge.top -= embed->y; if( vips_region_prepare( ir, &edge ) ) return( -1 ); p = VIPS_REGION_ADDR( ir, edge.left, edge.top ); plsk = VIPS_REGION_LSKIP( ir ); } vips_embed_paint_edge( embed, or, i, &todo, p, plsk ); } } break; default: g_assert( 0 ); } return( 0 ); }