Esempio n. 1
0
static int
ifthenelse( IMAGE *c, IMAGE *a, IMAGE *b, IMAGE *out )
{
	IMAGE **in;

	/* Check args.
	 */
	if( im_check_uncoded( "im_ifthenelse", c ) ||
		im_check_coding_known( "im_ifthenelse", a ) ||
		im_check_coding_known( "im_ifthenelse", b ) ||
		im_check_format( "ifthenelse", c, IM_BANDFMT_UCHAR ) || 
		im_check_format_same( "ifthenelse", a, b ) ||
		im_check_bands_same( "ifthenelse", a, b ) ||
		im_check_bands_1orn( "im_ifthenelse", c, a ) || 
		im_piocheck( c, out ) || 
		im_pincheck( a ) || 
		im_pincheck( b ) )
                return( -1 );

	/* Make output image.
	 */
	if( im_demand_hint( out, IM_THINSTRIP, c, a, b, NULL ) ||
		im_cp_descv( out, a, b, c, NULL ) || 
		!(in = im_allocate_input_array( out, c, a, b, NULL )) ||
		im_generate( out, 
			im_start_many, ifthenelse_gen, im_stop_many, 
				in, NULL ) )
		return( -1 );

	return( 0 );
}
Esempio n. 2
0
/**
 * im_shrink:
 * @in: input image
 * @out: output image
 * @xshrink: horizontal shrink
 * @yshrink: vertical shrink
 *
 * Shrink @in by a pair of factors with a simple box filter.
 *
 * You will get aliasing for non-integer shrinks. In this case, shrink with
 * this function to the nearest integer size above the target shrink, then
 * downsample to the exact size with im_affinei() and your choice of
 * interpolator.
 *
 * im_rightshift_size() is faster for factors which are integer powers of two.
 *
 * See also: im_rightshift_size(), im_affinei().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_shrink( IMAGE *in, IMAGE *out, double xshrink, double yshrink )
{
    if( im_check_noncomplex( "im_shrink", in ) ||
            im_check_coding_known( "im_shrink", in ) ||
            im_piocheck( in, out ) )
        return( -1 );
    if( xshrink < 1.0 || yshrink < 1.0 ) {
        im_error( "im_shrink",
                  "%s", _( "shrink factors should be >= 1" ) );
        return( -1 );
    }

    if( xshrink == 1 && yshrink == 1 ) {
        return( im_copy( in, out ) );
    }
    else if( in->Coding == IM_CODING_LABQ ) {
        IMAGE *t[2];

        if( im_open_local_array( out, t, 2, "im_shrink:1", "p" ) ||
                im_LabQ2LabS( in, t[0] ) ||
                shrink( t[0], t[1], xshrink, yshrink ) ||
                im_LabS2LabQ( t[1], out ) )
            return( -1 );
    }
    else if( shrink( in, out, xshrink, yshrink ) )
        return( -1 );

    return( 0 );
}
Esempio n. 3
0
/**
 * im_read_point:
 * @image: image to read from
 * @x: position to read
 * @y: position to read
 * @ink: read value here
 *
 * Reads a single point on an image. 
 *
 * @ink is an array of bytes to contain a valid pixel for the image's format.
 * It must have at least IM_IMAGE_SIZEOF_PEL( @im ) bytes.
 *
 * See also: im_draw_point().
 *
 * Returns: 0 on success, or -1 on error.
 */
int
im_read_point( VipsImage *image, int x, int y, VipsPel *ink )
{
	REGION *reg;
	Rect area;

	if( im_check_coding_known( "im_draw_point", image ) ||
		!(reg = im_region_create( image )) )
		return( -1 );

	area.left = x;
	area.top = y;
	area.width = 1;
	area.height = 1;
	if( im_prepare( reg, &area ) ) {
		im_region_free( reg );
		return( -1 );
	}

	memcpy( ink, IM_REGION_ADDR( reg, x, y ), 
		IM_IMAGE_SIZEOF_PEL( image ) );

	im_region_free( reg );

	return( 0 );
}
Esempio n. 4
0
/* Copy image, changing header fields.
 */
static int 
im_copy_set_all( IMAGE *in, IMAGE *out, 
	VipsType type, float xres, float yres, int xoffset, int yoffset,
	int bands, VipsBandFmt bandfmt, VipsCoding coding )
{
	/* Check args.
	 */
        if( im_check_coding_known( "im_copy", in ) ||
		im_piocheck( in, out ) )
		return( -1 );
	if( coding != IM_CODING_NONE && 
		coding != IM_CODING_LABQ &&
		coding != IM_CODING_RAD ) {
		im_error( "im_copy", "%s", 
			_( "coding must be NONE, LABQ or RAD" ) );
		return( -1 );
	}
	if( bandfmt < 0 || bandfmt > IM_BANDFMT_DPCOMPLEX ) {
		im_error( "im_copy", _( "bandfmt must be in range [0,%d]" ),
			IM_BANDFMT_DPCOMPLEX );
		return( -1 );
	}

	if( im_cp_desc( out, in ) )
		return( -1 );
	out->Type = type;
	out->Xres = xres;
	out->Yres = yres;
	out->Xoffset = xoffset;
	out->Yoffset = yoffset;
	out->Bands = bands;
	out->BandFmt = bandfmt;
	out->Coding = coding;

	/* Sanity check: we (may) have changed bytes-per-pixel since we've
	 * changed Bands and BandFmt ... bad!
	 */
	if( IM_IMAGE_SIZEOF_PEL( in ) != IM_IMAGE_SIZEOF_PEL( out ) ) {
		im_error( "im_copy", "%s", _( "sizeof( pixel ) has changed" ) );
		return( -1 );
	}

	/* Generate!
	 */
	if( im_demand_hint( out, IM_THINSTRIP, in, NULL ) ||
		im_generate( out, 
			im_start_one, copy_gen, im_stop_one, in, NULL ) )
		return( -1 );

	return( 0 );
}
Esempio n. 5
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 );
}
Esempio n. 6
0
/**
 * im_rot180:
 * @in: input image
 * @out: output image
 *
 * Rotate an image 180 degrees.
 *
 * See also: im_rot90(), im_rot270(), im_affinei_all().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_rot180( IMAGE *in, IMAGE *out )
{
	if( im_piocheck( in, out ) || 
		im_check_coding_known( "im_rot180", in ) )
		return( -1 );

	if( im_cp_desc( out, in ) || 
		im_demand_hint( out, IM_THINSTRIP, in, NULL ) )
		return( -1 );

	if( im_generate( out, 
		im_start_one, rot180_gen, im_stop_one, in, NULL ) )
		return( -1 );

	out->Xoffset = in->Xsize;
	out->Yoffset = in->Ysize;

	return( 0 );
}
Esempio n. 7
0
/* The common part of most binary inplace operators.
 *
 * Unlike im__formatalike() and friends, we can only change one of the images,
 * since the other is being updated.
 */
VipsImage *
im__inplace_base( const char *domain,
                  VipsImage *main, VipsImage *sub, VipsImage *out )
{
    VipsImage *t[2];

    if( im_rwcheck( main ) ||
            im_pincheck( sub ) ||
            im_check_coding_known( domain, main ) ||
            im_check_coding_same( domain, main, sub ) ||
            im_check_bands_1orn_unary( domain, sub, main->Bands ) )
        return( NULL );

    /* Cast sub to match main in bands and format.
     */
    if( im_open_local_array( out, t, 2, domain, "p" ) ||
            im__bandup( domain, sub, t[0], main->Bands ) ||
            im_clip2fmt( t[0], t[1], main->BandFmt ) )
        return( NULL );

    return( t[1] );
}
Esempio n. 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 );
}
Esempio n. 9
0
/**
 * im_subsample:
 * @in: input image
 * @out: output image
 * @xshrink: horizontal shrink factor
 * @yshrink: vertical shrink factor
 *
 * Subsample an image by an integer fraction. This is fast nearest-neighbour
 * shrink.
 *
 * See also: im_shrink(), im_affinei(), im_zoom().
 * 
 * Returns: 0 on success, -1 on error.
 */
int 
im_subsample( IMAGE *in, IMAGE *out, int xshrink, int yshrink )
{
	SubsampleInfo *st;

	/* Check parameters.
	 */
	if( xshrink < 1 || yshrink < 1 ) {
		im_error( "im_subsample", 
			"%s", _( "factors should both be >= 1" ) );
		return( -1 );
	}
	if( xshrink == 1 && yshrink == 1 ) 
		return( im_copy( in, out ) );
	if( im_piocheck( in, out ) ||
		im_check_coding_known( "im_subsample", in ) )
		return( -1 );

	/* Prepare output. Note: we round the output width down!
	 */
	if( im_cp_desc( out, in ) )
		return( -1 );
	out->Xsize = in->Xsize / xshrink;
	out->Ysize = in->Ysize / yshrink;
	out->Xres = in->Xres / xshrink;
	out->Yres = in->Yres / yshrink;
	if( out->Xsize <= 0 || out->Ysize <= 0 ) {
		im_error( "im_subsample", 
			"%s", _( "image has shrunk to nothing" ) );
		return( -1 );
	}

	/* Build and attach state struct.
	 */
	if( !(st = IM_NEW( out, SubsampleInfo )) )
		return( -1 );
	st->xshrink = xshrink;
	st->yshrink = yshrink;

	/* Set demand hints. We want THINSTRIP, as we will be demanding a
	 * large area of input for each output line.
	 */
	if( im_demand_hint( out, IM_THINSTRIP, in, NULL ) )
		return( -1 );

	/* Generate! If this is a very large shrink, then it's
	 * probably faster to do it a pixel at a time. 
	 */
	if( xshrink > 10 ) {
		if( im_generate( out, 
			im_start_one, point_shrink_gen, im_stop_one, in, st ) )
			return( -1 );
	}
	else {
		if( im_generate( out, 
			im_start_one, line_shrink_gen, im_stop_one, in, st ) )
			return( -1 );
	}

	return( 0 );
}