/* Two images overlap in an area ... make a mask the size of the area, which * has 255 for every pixel where both images are non-zero. */ static int make_overlap_mask( IMAGE *ref, IMAGE *sec, IMAGE *mask, Rect *rarea, Rect *sarea ) { IMAGE *t[6]; if( im_open_local_array( mask, t, 6, "mytemps", "p" ) || extract_rect( ref, t[0], rarea ) || extract_rect( sec, t[1], sarea ) || im_extract_band( t[0], t[2], 0 ) || im_extract_band( t[1], t[3], 0 ) || im_notequalconst( t[2], t[4], 0.0 ) || im_notequalconst( t[3], t[5], 0.0 ) || im_andimage( t[4], t[5], mask ) ) return( -1 ); return( 0 ); }
/** * im_ifthenelse: * @c: condition #IMAGE * @a: then #IMAGE * @b: else #IMAGE * @out: output #IMAGE * * This operation scans the condition image @c * and uses it to select pixels from either the then image @a or the else * image @b. Non-zero means @a, 0 means @b. * * Any image can have either 1 band or n bands, where n is the same for all * the non-1-band images. Single band images are then effectively copied to * make n-band images. * * Images @a and @b are cast up to the smallest common format. * * If the images differ in size, the smaller image is enlarged to match the * larger by adding zero pixels along the bottom and right. * * See also: im_blend(), im_equal(). * * Returns: 0 on success, -1 on error */ int im_ifthenelse( IMAGE *c, IMAGE *a, IMAGE *b, IMAGE *out ) { IMAGE *t[9]; if( im_open_local_array( out, t, 9, "im_ifthenelse", "p" ) ) return( -1 ); /* Make a and b match in bands and format. Don't make c match: we * special-case this in code above ^^^ for speed. */ if( im__formatalike( a, b, t[0], t[1] ) || im__bandalike( "im_ifthenelse", t[0], t[1], t[2], t[3] ) ) return( -1 ); /* All 3 must match in size. */ t[4] = c; if( im__sizealike_vec( t + 2, t + 5, 3 ) ) return( -1 ); c = t[7]; /* If c is not uchar, do (!=0) to make a uchar image. */ if( c->BandFmt != IM_BANDFMT_UCHAR ) { if( im_notequalconst( c, t[8], 0 ) ) return( -1 ); c = t[8]; } if( ifthenelse( c, t[5], t[6], out ) ) return( -1 ); return( 0 ); }
/** * im_profile: * @in: input image * @out: output image * @dir: search direction * * im_profile() searches inward from the edge of @in and finds the * first non-zero pixel. It outputs an image containing a list of the offsets * for each row or column. * * If @dir == 0, then im_profile() searches down from the top edge, writing an * image as wide as the input image, but only 1 pixel high, containing the * number of pixels down to the first non-zero pixel for each column of input * pixels. * * If @dir == 1, then im_profile() searches across from the left edge, * writing an image as high as the input image, but only 1 pixel wide, * containing the number of pixels across to the * first non-zero pixel for each row of input pixels. * * See also: im_cntlines(). * * Returns: 0 on success, -1 on error */ int im_profile( IMAGE *in, IMAGE *out, int dir ) { int sz; unsigned short *buf; int x, y, b; /* If in is not uchar, do (!=0) to make a uchar image. */ if( in->BandFmt != IM_BANDFMT_UCHAR ) { IMAGE *t; if( !(t = im_open_local( out, "im_profile", "p" )) || im_notequalconst( in, t, 0 ) ) return( -1 ); in = t; } /* Check im. */ if( im_iocheck( in, out ) || im_check_uncoded( "im_profile", in ) || im_check_format( "im_profile", in, IM_BANDFMT_UCHAR ) ) return( -1 ); if( dir != 0 && dir != 1 ) { im_error( "im_profile", "%s", _( "dir not 0 or 1" ) ); return( -1 ); } if( im_cp_desc( out, in ) ) return( -1 ); out->Type = IM_TYPE_HISTOGRAM; if( dir == 0 ) { out->Xsize = in->Xsize; out->Ysize = 1; } else { out->Xsize = 1; out->Ysize = in->Ysize; } out->BandFmt = IM_BANDFMT_USHORT; if( im_setupout( out ) ) return( -1 ); sz = IM_IMAGE_N_ELEMENTS( out ); if( !(buf = IM_ARRAY( out, sz, unsigned short )) ) return( -1 ); if( dir == 0 ) { /* Find vertical lines. */ for( x = 0; x < sz; x++ ) { PEL *p = (PEL *) IM_IMAGE_ADDR( in, 0, 0 ) + x; int lsk = IM_IMAGE_SIZEOF_LINE( in ); for( y = 0; y < in->Ysize; y++ ) { if( *p ) break; p += lsk; } buf[x] = y; } if( im_writeline( 0, out, (PEL *) buf ) ) return( -1 ); } else { /* Search horizontal lines. */ for( y = 0; y < in->Ysize; y++ ) { PEL *p = (PEL *) IM_IMAGE_ADDR( in, 0, y ); for( b = 0; b < in->Bands; b++ ) { PEL *p1; p1 = p + b; for( x = 0; x < in->Xsize; x++ ) { if( *p1 ) break; p1 += in->Bands; } buf[b] = x; } if( im_writeline( y, out, (PEL *) buf ) ) return( -1 ); } } return( 0 ); }
static Morph * morph_new( IMAGE *in, IMAGE *out, INTMASK *mask, MorphOp op ) { const int n_mask = mask->xsize * mask->ysize; Morph *morph; int i; /* If in is not uchar, do (!=0) to make a uchar image. */ if( in->BandFmt != IM_BANDFMT_UCHAR ) { IMAGE *t; if( !(t = im_open_local( out, "morph_new", "p" )) || im_notequalconst( in, t, 0 ) ) return( NULL ); in = t; } if( im_piocheck( in, out ) || im_check_uncoded( "morph", in ) || im_check_format( "morph", in, IM_BANDFMT_UCHAR ) || im_check_imask( "morph", mask ) ) return( NULL ); for( i = 0; i < n_mask; i++ ) if( mask->coeff[i] != 0 && mask->coeff[i] != 128 && mask->coeff[i] != 255 ) { im_error( "morph", _( "bad mask element (%d " "should be 0, 128 or 255)" ), mask->coeff[i] ); return( NULL ); } if( !(morph = IM_NEW( out, Morph )) ) return( NULL ); morph->in = in; morph->out = out; morph->mask = NULL; morph->op = op; morph->n_pass = 0; for( i = 0; i < MAX_PASS; i++ ) morph->pass[i].vector = NULL; if( im_add_close_callback( out, (im_callback_fn) morph_close, morph, NULL ) || !(morph->mask = im_dup_imask( mask, "morph" )) ) return( NULL ); /* Generate code for this mask / image, if possible. */ if( vips_vector_isenabled() ) { if( pass_compile( morph ) ) pass_free( morph ); } return( morph ); }