Beispiel #1
0
static int
mask_draw_labq( Mask *mask )
{
	float *lab_buffer;
	float ink_buffer[3];
	int y;

	if( !(lab_buffer = IM_ARRAY( NULL, 
		mask->image_clip.width * 3, float )) )
		return( -1 );

	imb_LabQ2Lab( DRAW( mask )->ink, ink_buffer, 1 );

	for( y = 0; y < mask->image_clip.height; y++ ) {
		PEL *to = (PEL *) IM_IMAGE_ADDR( DRAW( mask )->im, 
			mask->image_clip.left, y + mask->image_clip.top );
		PEL *mask_line = (PEL *) IM_IMAGE_ADDR( mask->mask_im, 
			mask->mask_clip.left, y + mask->mask_clip.top );

		imb_LabQ2Lab( to, lab_buffer, mask->image_clip.width );
		DBLEND( float, lab_buffer, ink_buffer );
		imb_Lab2LabQ( lab_buffer, to, mask->image_clip.width );
	}

	im_free( lab_buffer );

	return( 0 );
}
/* Like im_insert, but perform an in-place insertion.
 */
int
im_insertplace( IMAGE *big, IMAGE *small, int x, int y )
{	
	Rect br, sr;
	PEL *p, *q;
	int z;

	/* Check IO.
	 */
	if( im_rwcheck( big ) || im_incheck( small ) )
		return( -1 );

	/* Check compatibility.
	 */
        if( big->BandFmt != small->BandFmt || big->Bands != small->Bands ||
                big->Coding != small->Coding ) {
                im_error( "im_insertplace", _( "inputs differ in format" ) );
                return( -1 );
        }
        if( big->Coding != IM_CODING_NONE && big->Coding != IM_CODING_LABQ ) {
                im_error( "im_insertplace", _( "input should be uncoded "
                        "or IM_CODING_LABQ" ) );
                return( -1 );
        }

	/* Make rects for big and small.
	 */
	br.left = 0;
	br.top = 0;
	br.width = big->Xsize;
	br.height = big->Ysize;
	sr.left = x;
	sr.top = y;
	sr.width = small->Xsize;
	sr.height = small->Ysize;

	/* Small fits inside big?
	 */
	if( !im_rect_includesrect( &br, &sr ) ) {
		im_error( "im_insertplace", _( "small not inside big" ) );
		return( -1 );
	}

	/* Loop, memcpying small to big.
	 */
	p = (PEL *) IM_IMAGE_ADDR( small, 0, 0 );
	q = (PEL *) IM_IMAGE_ADDR( big, x, y );
	for( z = 0; z < small->Ysize; z++ ) {
		memcpy( (char *) q, (char *) p, IM_IMAGE_SIZEOF_LINE( small ) );
		p += IM_IMAGE_SIZEOF_LINE( small );
		q += IM_IMAGE_SIZEOF_LINE( big );
	}

	im_invalidate( big );

	return( 0 );
}
Beispiel #3
0
/* Generate function.
 */
static int
make_vert_gen( REGION *or, void *seq, void *a, void *b )
{
	IMAGE *in = (IMAGE *) a;
	Rect *r = &or->valid;
	int le = r->left;
	int to = r->top;
	int ri = IM_RECT_RIGHT( r );
	int bo = IM_RECT_BOTTOM( r );
	int nb = in->Bands;

	int x, y, z;

	for( y = to; y < bo; y++ ) {
		VipsPel *q = IM_REGION_ADDR( or, le, y );
		VipsPel *p = IM_IMAGE_ADDR( in, 0, y );

		switch( in->BandFmt ) {
		case IM_BANDFMT_UCHAR: 	VERT( unsigned char ); break;
		case IM_BANDFMT_CHAR: 	VERT( signed char ); break; 
		case IM_BANDFMT_USHORT: VERT( unsigned short ); break; 
		case IM_BANDFMT_SHORT: 	VERT( signed short ); break; 
		case IM_BANDFMT_UINT: 	VERT( unsigned int ); break; 
		case IM_BANDFMT_INT: 	VERT( signed int );  break; 
		case IM_BANDFMT_FLOAT: 	VERT( float ); break; 
		case IM_BANDFMT_DOUBLE:	VERT( double ); break; 

		default:
			g_assert( 0 ); 
		}
	}

	return( 0 );
}
Beispiel #4
0
/* Fill a scanline between points x1 and x2 inclusive. x1 < x2.
 */
void 
im__draw_scanline( Draw *draw, int y, int x1, int x2 )
{
	PEL *mp;
	int i;
	int len;

	g_assert( x1 <= x2 );

	if( y < 0 || y >= draw->im->Ysize )
		return;
	if( x1 < 0 && x2 < 0 )
		return;
	if( x1 >= draw->im->Xsize && x2 >= draw->im->Xsize )
		return;
	x1 = IM_CLIP( 0, x1, draw->im->Xsize - 1 );
	x2 = IM_CLIP( 0, x2, draw->im->Xsize - 1 );

	mp = (PEL *) IM_IMAGE_ADDR( draw->im, x1, y );
	len = x2 - x1 + 1;

	for( i = 0; i < len; i++ ) {
		im__draw_pel( draw, mp );
		mp += draw->psize;
	}
}
Beispiel #5
0
/* Generate function.
 */
static int
make_horz_gen( REGION *or, void *seq, void *a, void *b )
{
    IMAGE *in = (IMAGE *) a;
    Rect *r = &or->valid;
    int le = r->left;
    int to = r->top;
    int ri = IM_RECT_RIGHT( r );
    int bo = IM_RECT_BOTTOM( r );
    int nb = in->Bands;
    int lsk = IM_REGION_LSKIP( or );
    int ht = or->im->Ysize;

    int x, y, z;

    for( x = le; x < ri; x++ ) {
        VipsPel *q = IM_REGION_ADDR( or, x, to );
        VipsPel *p = IM_IMAGE_ADDR( in, x, 0 );

        switch( in->BandFmt ) {
        case IM_BANDFMT_UCHAR:
            HORZ( unsigned char );
            break;
        case IM_BANDFMT_CHAR:
            HORZ( signed char );
            break;
        case IM_BANDFMT_USHORT:
            HORZ( unsigned short );
            break;
        case IM_BANDFMT_SHORT:
            HORZ( signed short );
            break;
        case IM_BANDFMT_UINT:
            HORZ( unsigned int );
            break;
        case IM_BANDFMT_INT:
            HORZ( signed int );
            break;
        case IM_BANDFMT_FLOAT:
            HORZ( float );
            break;
        case IM_BANDFMT_DOUBLE:
            HORZ( double );
            break;

        default:
            g_assert( 0 );
        }
    }

    return( 0 );
}
Beispiel #6
0
/**
 * im_draw_image:
 * @image: image to draw on
 * @sub: image to draw
 * @x: position to insert
 * @y: position to insert
 *
 * Draw @sub on top of @image at position @x, @y. The two images must have the
 * same
 * Coding. If @sub has 1 band, the bands will be duplicated to match the
 * number of bands in @image. @sub will be converted to @image's format, see
 * im_clip2fmt().
 *
 * See also: im_insert().
 *
 * Returns: 0 on success, or -1 on error.
 */
int
im_draw_image( VipsImage *image, VipsImage *sub, int x, int y )
{
    Rect br, sr, clip;
    PEL *p, *q;
    int z;

    /* Make rects for main and sub and clip.
     */
    br.left = 0;
    br.top = 0;
    br.width = image->Xsize;
    br.height = image->Ysize;
    sr.left = x;
    sr.top = y;
    sr.width = sub->Xsize;
    sr.height = sub->Ysize;
    im_rect_intersectrect( &br, &sr, &clip );
    if( im_rect_isempty( &clip ) )
        return( 0 );

    if( !(sub = im__inplace_base( "im_draw_image", image, sub, image )) ||
            im_rwcheck( image ) ||
            im_incheck( sub ) )
        return( -1 );

    /* Loop, memcpying sub to main.
     */
    p = (PEL *) IM_IMAGE_ADDR( sub, clip.left - x, clip.top - y );
    q = (PEL *) IM_IMAGE_ADDR( image, clip.left, clip.top );
    for( z = 0; z < clip.height; z++ ) {
        memcpy( (char *) q, (char *) p,
                clip.width * IM_IMAGE_SIZEOF_PEL( sub ) );
        p += IM_IMAGE_SIZEOF_LINE( sub );
        q += IM_IMAGE_SIZEOF_LINE( image );
    }

    return( 0 );
}
Beispiel #7
0
/**
 * im_draw_point:
 * @image: image to draw on
 * @x: position to draw
 * @y: position to draw
 * @ink: value to draw
 *
 * Draws a single point on an image. 
 *
 * @ink is an array of bytes containing a valid pixel for the image's format.
 * It must have at least IM_IMAGE_SIZEOF_PEL( @im ) bytes.
 *
 * See also: im_draw_line().
 *
 * Returns: 0 on success, or -1 on error.
 */
int
im_draw_point( VipsImage *image, int x, int y, VipsPel *ink )
{	
	Point point;

	if( im_check_coding_known( "im_draw_point", image ) ||
		im__draw_init( DRAW( &point ), image, NULL ) )
		return( -1 );

	/* Check coordinates.
	 */
	if( x >= 0 && x < image->Xsize && y >= 0 && y < image->Ysize ) 
		memcpy( IM_IMAGE_ADDR( image, x, y ), ink, 
			DRAW( image )->psize );

	im__draw_free( DRAW( &point ) );

	return( 0 );
}
Beispiel #8
0
/**
 * im_draw_rect:
 * @image: image to draw on
 * @left: area to paint
 * @top: area to paint
 * @width: area to paint
 * @height: area to paint
 * @fill: fill the rect
 * @ink: paint with this colour
 *
 * Paint pixels within @left, @top, @width, @height in @image with @ink. If
 * @fill is zero, just paint a 1-pixel-wide outline.
 *
 * See also: im_draw_circle().
 *
 * Returns: 0 on success, or -1 on error.
 */
int
im_draw_rect( IMAGE *image, 
	int left, int top, int width, int height, int fill, VipsPel *ink )
{
	Rect im, rect, clipped;
	Draw draw;

	if( !fill ) 
		return( im_draw_rect( image, left, top, width, 1, 1, ink ) ||
			im_draw_rect( image, 
				left + width - 1, top, 1, height, 1, ink ) ||
			im_draw_rect( image, 
				left, top + height - 1, width, 1, 1, ink ) ||
			im_draw_rect( image, left, top, 1, height, 1, ink ) );

	int x, y;
	VipsPel *to;
	VipsPel *q;

	/* Find area we plot.
	 */
	im.left = 0;
	im.top = 0;
	im.width = image->Xsize;
	im.height = image->Ysize;
	rect.left = left;
	rect.top = top;
	rect.width = width;
	rect.height = height;
	im_rect_intersectrect( &rect, &im, &clipped );

	/* Any points left to plot?
	 */
	if( im_rect_isempty( &clipped ) )
		return( 0 );

	if( im_check_coding_known( "im_draw_rect", image ) ||
		!im__draw_init( &draw, image, ink ) )
		return( -1 );

	/* We plot the first line pointwise, then memcpy() it for the
	 * subsequent lines.
	 */
	to = IM_IMAGE_ADDR( image, clipped.left, clipped.top );

	q = to;
	for( x = 0; x < clipped.width; x++ ) {
		im__draw_pel( &draw, q );
		q += draw.psize;
	}

	q = to + draw.lsize;
	for( y = 1; y < clipped.height; y++ ) {
		memcpy( q, to, clipped.width * draw.psize );
		q += draw.lsize;
	}

	im__draw_free( &draw );

	return( 0 );
}
Beispiel #9
0
static int
mask_draw( Mask *mask )
{
	int y;

	for( y = 0; y < mask->image_clip.height; y++ ) {
		PEL *to = (PEL *) IM_IMAGE_ADDR( DRAW( mask )->im, 
			mask->image_clip.left, 
			y + mask->image_clip.top );
		PEL *mask_line = (PEL *) IM_IMAGE_ADDR( mask->mask_im, 
			mask->mask_clip.left, 
			y + mask->mask_clip.top );

		switch( DRAW( mask )->im->BandFmt ) {
		case IM_BANDFMT_UCHAR: 		
			IBLEND( unsigned char, to, DRAW( mask )->ink );
			break;

		case IM_BANDFMT_CHAR:  
			IBLEND( signed char, to, DRAW( mask )->ink );
			break;

		case IM_BANDFMT_USHORT: 
			IBLEND( unsigned short, to, DRAW( mask )->ink );
			break;

		case IM_BANDFMT_SHORT: 
			IBLEND( signed short, to, DRAW( mask )->ink );
			break;

		case IM_BANDFMT_UINT: 
			DBLEND( unsigned int, to, DRAW( mask )->ink );
			break;

		case IM_BANDFMT_INT: 
			DBLEND( signed int, to, DRAW( mask )->ink );
			break;

		case IM_BANDFMT_FLOAT:  
			DBLEND( float, to, DRAW( mask )->ink );
			break;

		case IM_BANDFMT_DOUBLE:
			DBLEND( double, to, DRAW( mask )->ink );
			break;

		case IM_BANDFMT_COMPLEX:
			CBLEND( float, to, DRAW( mask )->ink );
			break;

		case IM_BANDFMT_DPCOMPLEX:
			CBLEND( double, to, DRAW( mask )->ink );
			break;

		default:
			g_assert( 0 ); 
		}
	}

	return( 0 );
}
Beispiel #10
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 );
}