Exemplo n.º 1
0
/**
 * im_copy_file:
 * @in: input image
 * @out: output image
 *
 * Copy an image to a disc file, then copy again to output. If the image is
 * already a disc file, just copy straight through.
 *
 * The disc file is allocated in the same way as im_system_image(). 
 * The file is automatically deleted when @out is closed.
 *
 * See also: im_copy(), im_system_image().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_copy_file( IMAGE *in, IMAGE *out )
{
	if( !im_isfile( in ) ) {
		IMAGE *disc;

		if( !(disc = im__open_temp( "%s.v" )) )
			return( -1 );
		if( im_add_close_callback( out, 
			(im_callback_fn) im_close, disc, NULL ) ) {
			im_close( disc );
			return( -1 );
		}

		if( im_copy( in, disc ) ||
			im_copy( disc, out ) )
			return( -1 );
	}
	else {
		if( im_copy( in, out ) )
			return( -1 );
	}

	return( 0 );
}
Exemplo n.º 2
0
int
im_flood_blob_copy( IMAGE *in, IMAGE *out, int x, int y, PEL *ink )
{
	IMAGE *t;

	if( !(t = im_open_local( out, "im_flood_blob_copy", "t" )) ||
		im_copy( in, t ) ||
		im_flood_blob( t, x, y, ink, NULL ) ||
		im_copy( t, out ) ) 
		return( -1 );

	return( 0 );
}
Exemplo n.º 3
0
int
im_flood_other_copy( IMAGE *test, IMAGE *mark, IMAGE *out, 
	int x, int y, int serial )
{
	IMAGE *t;

	if( !(t = im_open_local( out, "im_flood_other_copy", "t" )) ||
		im_copy( mark, t ) ||
		im_flood_other( test, t, x, y, serial, NULL ) ||
		im_copy( t, out ) ) 
		return( -1 );

	return( 0 );
}
Exemplo n.º 4
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 );
}
Exemplo n.º 5
0
static int
system_image_vec( im_object *argv )
{
	IMAGE *in = argv[0];
	IMAGE *out = argv[1];
	char *in_format = argv[2];
	char *out_format = argv[3];
	char *cmd = argv[4];
	char **log = (char **) &argv[5];

	IMAGE *out_image;

	if( !(out_image = im_system_image( in, 
		in_format, out_format, cmd, log )) ) {
		im_error( "im_system_image", "%s", *log );
		return( -1 );
	}

	if( im_copy( out_image, out ) ||
		im_add_close_callback( out, 
			(im_callback_fn) im_close, out_image, NULL ) ) {
		im_close( out_image );
		return( -1 );
	}

	return( 0 );
}
Exemplo n.º 6
0
int
im_rotquad( IMAGE *in, IMAGE *out )
{
	IMAGE *t[6];
	int xd = in->Xsize / 2;
	int yd = in->Ysize / 2;

	if( in->Xsize < 2 || in->Ysize < 2 )
		return( im_copy( in, out ) );

	if( im_open_local_array( out, t, 6, "im_rotquad-1", "p" ) ||
		/* Extract 4 areas.
		 */
		im_extract_area( in, t[0], 0, 0, xd, yd ) ||
		im_extract_area( in, t[1], xd, 0, in->Xsize - xd, yd ) ||
		im_extract_area( in, t[2], 0, yd, xd, in->Ysize - yd ) ||
		im_extract_area( in, t[3], xd, yd, 
			in->Xsize - xd, in->Ysize - yd ) ||
	
		/* Reassemble, rotated.
		 */
		im_insert( t[3], t[2], t[4], in->Xsize - xd, 0 ) ||
		im_insert( t[1], t[0], t[5], in->Xsize - xd, 0 ) ||
		im_insert( t[4], t[5], out, 0, in->Ysize - yd ) )
		return( -1 );

	out->Xoffset = xd;
	out->Yoffset = yd;

	return( 0 );
}
Exemplo n.º 7
0
/**
 * im_system:
 * @im: image to run command on
 * @cmd: command to run
 * @out: stdout of command is returned here
 *
 * im_system() runs a command on an image, returning the command's output as a
 * string. The command is executed with popen(), the first '%%s' in the 
 * command being substituted for a filename.
 *
 * If the IMAGE is a file on disc, then the filename will be the name of the 
 * real file. If the image is in memory, or the result of a computation, 
 * then a new file is created in the temporary area called something like 
 * "vips_XXXXXX.v", and that filename given to the command. The file is 
 * deleted when the command finishes.
 *
 * The environment variable TMPDIR can be used to set the temporary 
 * directory. If it is not set, it defaults to "/tmp".
 *
 * In all cases, @log must be freed with im_free().
 *
 * See also: im_system_image().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_system( IMAGE *im, const char *cmd, char **out )
{
	FILE *fp;

	if( !im_isfile( im ) ) {
		IMAGE *disc;

		if( !(disc = im__open_temp( "%s.v" )) )
			return( -1 );
		if( im_copy( im, disc ) ||
			im_system( disc, cmd, out ) ) {
			im_close( disc );
			return( -1 );
		}
		im_close( disc );
	}
	else if( (fp = im_popenf( cmd, "r", im->filename )) ) {
		char line[IM_MAX_STRSIZE];
		char txt[IM_MAX_STRSIZE];
		VipsBuf buf = VIPS_BUF_STATIC( txt );

		while( fgets( line, IM_MAX_STRSIZE, fp ) ) 
			if( !vips_buf_appends( &buf, line ) )
				break; 
		pclose( fp );

		if( out )
			*out = im_strdup( NULL, vips_buf_all( &buf ) );
	}

	return( 0 );
}
Exemplo n.º 8
0
/**
 * im_copy_native:
 * @in: input image
 * @out: output image
 * @is_msb_first: %TRUE if @in is in most-significant first form
 *
 * Copy an image to native order, that is, the order for the executing
 * program.
 *
 * See also: im_copy_swap(), im_amiMSBfirst().
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_copy_native( IMAGE *in, IMAGE *out, gboolean is_msb_first )
{
	if( is_msb_first != im_amiMSBfirst() )
		return( im_copy_swap( in, out ) );
	else
		return( im_copy( in, out ) );
}
Exemplo n.º 9
0
/**
 * im_copy_set_meta:
 * @in: input image
 * @out: output image
 * @field: metadata field to set
 * @value: value to set for the field
 *
 * Copy an image, changing a metadata field. You can use this to, for example,
 * update the ICC profile attached to an image.
 *
 * See also: im_copy().
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_copy_set_meta( IMAGE *in, IMAGE *out, const char *field, GValue *value )
{
	if( im_copy( in, out ) ||
		im_meta_set( out, field, value ) )
		return( 1 );

	return( 0 );
}
Exemplo n.º 10
0
/**
 * im_tone_map:
 * @in: input image
 * @out: output image
 * @lut: look-up table
 *
 * Map the first channel of @in through @lut. If @in is IM_CODING_LABQ, unpack
 * to LABS, map L and then repack.
 *
 * @in should be a LABS or LABQ image for this to work
 * sensibly.
 *
 * See also: im_maplut().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_tone_map( IMAGE *in, IMAGE *out, IMAGE *lut )
{
    IMAGE *t[8];

    if( im_check_hist( "im_tone_map", lut ) ||
            im_open_local_array( out, t, 8, "im_tone_map", "p" ) )
        return( -1 );

    /* If in is IM_CODING_LABQ, unpack.
     */
    if( in->Coding == IM_CODING_LABQ ) {
        if( im_LabQ2LabS( in, t[0] ) )
            return( -1 );
    }
    else
        t[0] = in;

    /* Split into bands.
     */
    if( im_extract_band( t[0], t[1], 0 ) )
        return( -1 );
    if( t[0]->Bands > 1 ) {
        if( im_extract_bands( t[0], t[2], 1, t[0]->Bands - 1 ) )
            return( -1 );
    }

    /* Map L.
     */
    if( im_maplut( t[1], t[3], lut ) )
        return( -1 );

    /* Recombine bands.
     */
    if( t[0]->Bands > 1 ) {
        if( im_bandjoin( t[3], t[2], t[4] ) )
            return( -1 );
    }
    else
        t[4] = t[3];

    /* If input was LabQ, repack.
     */
    if( in->Coding == IM_CODING_LABQ ) {
        if( im_LabS2LabQ( t[4], t[5] ) )
            return( -1 );
    }
    else
        t[5] = t[4];

    return( im_copy( t[4], out ) );
}
Exemplo n.º 11
0
static VALUE
writer_write_internal(VALUE obj, VALUE path)
{
    VipsImage *out;
    GetImg(obj, data, im);

    if (!(out = im_open(StringValuePtr(path), "w")) || im_copy(im, out))
        vips_lib_error();

    im_close(out);

    return obj;
}
Exemplo n.º 12
0
/**
 * im_label_regions:
 * @test: image to test
 * @mask: write labelled regions here
 * @segments: return number of regions here
 *
 * im_label_regions() repeatedly scans @test for regions of 4-connected pixels
 * with the same pixel value. Every time a region is discovered, those
 * pixels are marked in @mask with a unique serial number. Once all pixels
 * have been labelled, the operation returns, setting @segments to the number
 * of discrete regions which were detected.
 *
 * @mask is always a 1-band %IM_BANDFMT_UINT image of the same dimensions as
 * @test.
 *
 * This operation is useful for, for example, blob counting. You can use the
 * morphological operators to detect and isolate a series of objects, then use
 * im_label_regions() to number them all.
 *
 * Use im_histindexed() to (for example) find blob coordinates.
 *
 * See also: im_histindexed()
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_label_regions( IMAGE *test, IMAGE *mask, int *segments )
{
	IMAGE *t[2];
	int serial;
	int *m;
	int x, y;

	/* Create the zero mask image.
	 */
	if( im_open_local_array( mask, t, 2, "im_label_regions", "p" ) ||
		im_black( t[0], test->Xsize, test->Ysize, 1 ) ||
		im_clip2fmt( t[0], t[1], IM_BANDFMT_INT ) ) 
		return( -1 );

	/* Search the mask image, flooding as we find zero pixels.
	 */
	if( im_rwcheck( t[1] ) )
		return( -1 );
	serial = 0;
	m = (int *) t[1]->data;
	for( y = 0; y < test->Ysize; y++ ) {
		for( x = 0; x < test->Xsize; x++ ) {
			if( !m[x] ) {
				/*
				if( im_flood_other_old( t[1], test, 
					x, y, serial ) )
				 */
				if( im_flood_other( test, t[1], 
					x, y, serial, NULL ) )
//				if( im_flood_other_old( t[1], test,
//					x, y, serial ) )
					return( -1 );

				serial += 1;
			}
		}

		m += test->Xsize;
	}

	/* Copy result to mask.
	 */
	if( im_copy( t[1], mask ) )
		return( -1 );
	if( segments )
		*segments = serial;

	return( 0 );
}
Exemplo n.º 13
0
/* Normalise an image using the rules noted above.
 */
static int
normalise( IMAGE *in, IMAGE *out )
{
	if( im_check_uncoded( "im_histplot", in ) ||
		im_check_noncomplex( "im_histplot", in ) )
		return( -1 );

	if( vips_bandfmt_isuint( in->BandFmt ) ) {
		if( im_copy( in, out ) )
			return( -1 );
	}
	else if( vips_bandfmt_isint( in->BandFmt ) ) {
		IMAGE *t1;
		double min;

		/* Move min up to 0. 
		 */
		if( !(t1 = im_open_local( out, "im_histplot", "p" )) ||
			im_min( in, &min ) ||
			im_lintra( 1.0, in, -min, t1 ) )
			return( -1 );
	}
	else {
		/* Float image: scale min--max to 0--any. Output square
		 * graph.
		 */
		IMAGE *t1;
		DOUBLEMASK *stats;
		double min, max;
		int any;

		if( in->Xsize == 1 )
			any = in->Ysize;
		else
			any = in->Xsize;

		if( !(stats = im_stats( in )) )
			return( -1 );
		min = VIPS_MASK( stats, 0, 0 );
		max = VIPS_MASK( stats, 1, 0 );
		im_free_dmask( stats );

		if( !(t1 = im_open_local( out, "im_histplot", "p" )) ||
			im_lintra( any / (max - min), in, 
				-min * any / (max - min), out ) )
			return( -1 );
	}

	return( 0 );
}
Exemplo n.º 14
0
static VALUE
writer_initialize(int argc, VALUE *argv, VALUE obj)
{
    VALUE image, opts;
	rb_scan_args(argc, argv, "11", &image, &opts);
    GetImg(image, data, im);
    GetImg(obj, data_new, im_new);

    img_add_dep(data_new, image);
    if (im_copy(im, im_new))
        vips_lib_error();

    return obj;
}
Exemplo n.º 15
0
int 
im_freqflt( IMAGE *in, IMAGE *mask, IMAGE *out )
{
	IMAGE *dummy;

	/* Placeholder for memory free.
	 */
	if( !(dummy = im_open( "memory-1", "p" )) )
		return( -1 );

	if( im_iscomplex( in ) ) {
		/* Easy case! Assume it has already been transformed.
		 */
		IMAGE *t1 = im_open_local( dummy, "im_freqflt-1", "p" );

		if( !t1 ||
			im_multiply( in, mask, t1 ) ||
			im_invfftr( t1, out ) ) {
			im_close( dummy );
			return( -1 );
		}
	}
	else {
		/* Harder - fft first, then mult, then force back to start
		 * type.
		 * 
		 * Optimisation: output of im_invfft() is float buffer, we 
		 * will usually chagetype to char, so rather than keeping a
		 * large float buffer and partial to char from that, do
		 * changetype to a memory buffer, and copy to out from that.
		 */
		IMAGE *t[3];
		IMAGE *t3;

		if( im_open_local_array( dummy, t, 3, "im_freqflt-1", "p" ) ||
			!(t3 = im_open_local( out, "im_freqflt-3", "t" )) ||
			im_fwfft( in, t[0] ) ||
			im_multiply( t[0], mask, t[1] ) ||
			im_invfftr( t[1], t[2] ) ||
			im_clip2fmt( t[2], t3, in->BandFmt ) ||
			im_copy( t3, out ) ) {
			im_close( dummy );
			return( -1 );
		}	
	}

	im_close( dummy );

	return( 0 );
}
Exemplo n.º 16
0
/**
 * im_abs:
 * @in: input #IMAGE
 * @out: output #IMAGE
 *
 * This operation finds the absolute value of an image. It does a copy for
 * unsigned integer types, negate for negative values in
 * signed integer types, <function>fabs(3)</function> for
 * float types, and calculate modulus for complex
 * types.
 *
 * See also: im_exp10tra(), im_sign().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_abs( IMAGE *in, IMAGE *out )
{
    if( im_piocheck( in, out ) ||
            im_check_uncoded( "im_abs", in ) )
        return( -1 );

    /* Is this one of the unsigned types? Degenerate to im_copy() if it
     * is.
     */
    if( vips_bandfmt_isuint( in->BandFmt ) )
        return( im_copy( in, out ) );

    /* Prepare output header. Output type == input type, except for
     * complex.
     */
    if( im_cp_desc( out, in ) )
        return( -1 );
    switch( in->BandFmt ) {
    case IM_BANDFMT_CHAR:
    case IM_BANDFMT_SHORT:
    case IM_BANDFMT_INT:
    case IM_BANDFMT_FLOAT:
    case IM_BANDFMT_DOUBLE:
        /* No action.
         */
        break;

    case IM_BANDFMT_COMPLEX:
        out->BandFmt = IM_BANDFMT_FLOAT;
        break;

    case IM_BANDFMT_DPCOMPLEX:
        out->BandFmt = IM_BANDFMT_DOUBLE;
        break;

    default:
        im_error( "im_abs", "%s", _( "unknown input type" ) );
        return( -1 );
    }

    /* Generate!
     */
    if( im_wrapone( in, out,
                    (im_wrapone_fn) abs_gen, in, NULL ) )
        return( -1 );

    return( 0 );
}
Exemplo n.º 17
0
int
im_copy_from( IMAGE *in, IMAGE *out, im_arch_type architecture )
{
	switch( architecture ) {
	case IM_ARCH_NATIVE:
		return( im_copy( in, out ) );

	case IM_ARCH_BYTE_SWAPPED:
		return( im_copy_swap( in, out ) );

	case IM_ARCH_LSB_FIRST:
		return( im_amiMSBfirst() ? 
			im_copy_swap( in, out ) : im_copy( in, out ) );

	case IM_ARCH_MSB_FIRST:
		return( im_amiMSBfirst() ? 
			im_copy( in, out ) : im_copy_swap( in, out ) );

	default:
		im_error( "im_copy_from", 
			_( "bad architecture: %d" ), architecture );
		return( -1 );
	}
}
Exemplo n.º 18
0
static VALUE
vips_write_internal(VALUE obj, VALUE path)
{
    VipsImage *im_new;
    GetImg(obj, data, im);

    if (!(im_new = (VipsImage *)im_openout(RSTRING_PTR(path))))
        vips_lib_error();

    if (im_copy(im, im_new))
        vips_lib_error();

    im_close(im_new);

    return obj;
}
Exemplo n.º 19
0
/* Draw a set of lines with an ink and a mask. A non-inplace operation, handy
 * for nip2.
 */
int
im_lineset( IMAGE *in, IMAGE *out, IMAGE *mask, IMAGE *ink,
	int n, int *x1v, int *y1v, int *x2v, int *y2v )
{
	Rect mask_rect;
	int i;

	if( mask->Bands != 1 || mask->BandFmt != IM_BANDFMT_UCHAR ||
		mask->Coding != IM_CODING_NONE ) {
		im_error( "im_lineset", 
			"%s", _( "mask image not 1 band 8 bit uncoded" ) );
		return( -1 );
	}
	if( ink->Bands != in->Bands || ink->BandFmt != in->BandFmt ||
		ink->Coding != in->Coding ) {
		im_error( "im_lineset", 
			"%s", _( "ink image does not match in image" ) );
		return( -1 );
	}
	if( ink->Xsize != 1 || ink->Ysize != 1 ) {
		im_error( "im_lineset", "%s", _( "ink image not 1x1 pixels" ) );
		return( -1 );
	}

	/* Copy the image then fastline to it ... this will render to a "t"
	 * usually.
	 */
	if( im_copy( in, out ) )
		return( -1 );

	mask_rect.left = mask->Xsize / 2;
	mask_rect.top = mask->Ysize / 2;
	mask_rect.width = mask->Xsize;
	mask_rect.height = mask->Ysize;

	if( im_incheck( ink ) ||
		im_incheck( mask ) )
		return( -1 );

	for( i = 0; i < n; i++ ) {
		if( im_fastlineuser( out, x1v[i], y1v[i], x2v[i], y2v[i], 
			im_plotmask, ink->data, mask->data, &mask_rect ) )
			return( -1 );
	}

	return( 0 );
}
Exemplo n.º 20
0
/**
 * im_copy_swap:
 * @in: input image
 * @out: output image
 *
 * Copy an image, swapping byte order between little and big endian. This
 * really does change image pixels and does not just alter the header.
 *
 * See also: im_copy(), im_amiMSBfirst(), im_isMSBfirst().
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_copy_swap( IMAGE *in, IMAGE *out )
{
        if( im_piocheck( in, out ) ||
		im_check_uncoded( "im_copy_swap", in ) ||
		im_cp_desc( out, in ) )
                return( -1 );

	switch( in->BandFmt ) {
        case IM_BANDFMT_CHAR:
        case IM_BANDFMT_UCHAR:
		if( im_copy( in, out ) ) 
			return( -1 );
		break;

        case IM_BANDFMT_SHORT:
        case IM_BANDFMT_USHORT:
		if( im_wrapone( in, out, 
			(im_wrapone_fn) im_copy_swap2_gen, in, NULL ) )
			return( -1 );
		break;

	case IM_BANDFMT_INT:
	case IM_BANDFMT_UINT:
	case IM_BANDFMT_FLOAT:
	case IM_BANDFMT_COMPLEX:
		if( im_wrapone( in, out, 
			(im_wrapone_fn) im_copy_swap4_gen, in, NULL ) )
			return( -1 );
		break;

        case IM_BANDFMT_DOUBLE:
        case IM_BANDFMT_DPCOMPLEX:
		if( im_wrapone( in, out, 
			(im_wrapone_fn) im_copy_swap8_gen, in, NULL ) )
			return( -1 );
		break;

	default:
		im_error( "im_copy_swap", "%s", _( "unsupported image type" ) );
		return( -1 );
	}

	return( 0 );
}
Exemplo n.º 21
0
/* Transform an n-band image with a 1-band processing function.
 */
int 
im__fftproc( IMAGE *dummy, IMAGE *in, IMAGE *out, im__fftproc_fn fn )
{
	if( im_pincheck( in ) || im_outcheck( out ) )
                return( -1 );
	
	if( in->Bands == 1 ) {
		if( fn( dummy, in, out ) )
			return( -1 );
	}
	else {
		IMAGE *acc;
		int b;

		for( acc = NULL, b = 0; b < in->Bands; b++ ) {
			IMAGE *t1 = im_open_local( dummy, 
				"fwfftn:1", "p" );
			IMAGE *t2 = im_open_local( dummy, 
				"fwfftn:2", "p" );

			if( !t1 || !t2 || 
				im_extract_band( in, t1, b ) ||
				fn( dummy, t1, t2 ) )
				return( -1 );
			
			if( !acc )
				acc = t2;
			else {
				IMAGE *t3 = im_open_local( dummy, 
					"fwfftn:3", "p" );

				if( !t3 || im_bandjoin( acc, t2, t3 ) )
					return( -1 );

				acc = t3;
			}
		}

		if( im_copy( acc, out ) )
			return( -1 );
	}

	return( 0 );
}
Exemplo n.º 22
0
/**
 * im_msb:
 * @in: input image
 * @out: output image
 *
 * Turn any integer image to 8-bit unsigned char by discarding all but the most
 * significant byte.
 * Signed values are converted to unsigned by adding 128.
 *
 * This operator also works for LABQ coding.
 *
 * See also: im_msb_band().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_msb( IMAGE *in, IMAGE *out )
{
	Msb *msb;
	im_wrapone_fn func;

	if( in->Coding == IM_CODING_NONE &&
		in->BandFmt == IM_BANDFMT_UCHAR )
		return( im_copy( in, out ) );

	if( im_piocheck( in, out ) ||
		!(msb = IM_NEW( out, Msb )) )
		return( -1 );

	if( in->Coding == IM_CODING_NONE ) {
		if( im_check_int( "im_msb", in ) ) 
			return( -1 );

		msb->width = IM_IMAGE_SIZEOF_ELEMENT( in );
		msb->index = im_amiMSBfirst() ? 0 : msb->width - 1;
		msb->repeat = in->Bands;

		if( vips_bandfmt_isuint( in->BandFmt ) )
			func = (im_wrapone_fn) byte_select;
		else
			func = (im_wrapone_fn) byte_select_flip;
	}
	else if( IM_CODING_LABQ == in->Coding )
		func = (im_wrapone_fn) msb_labq;
	else {
		im_error( "im_msb", "%s", _( "unknown coding" ) );
		return( -1 );
	}

	if( im_cp_desc( out, in ) )
		return( -1 );
	out->BandFmt = IM_BANDFMT_UCHAR;
	out->Coding = IM_CODING_NONE;

	return( im_wrapone( in, out, func, msb, NULL ) );
}
Exemplo n.º 23
0
int
im_msb (IMAGE * in, IMAGE * out)
{
#define FUNCTION_NAME "im_msb"

  size_t *params;
  im_wrapone_fn func;

#define index   (params[0])
#define width   (params[1])
#define repeat  (params[2])

  if (im_piocheck (in, out))
    return -1;

  /* Stops a used-before-set warning.
   */
  params = NULL;

  if (IM_UNCODED (in))
    {

      if (!IM_ANY_INT (in))
	{
	  im_error (FUNCTION_NAME, _("char, short or int only"));
	  return -1;
	}

      params = IM_ARRAY (out, 3, size_t);

      if (!params)
	return -1;

      width = SIZEOF_BAND (in->BandFmt);

#if G_BYTE_ORDER == G_BIG_ENDIAN
      index = 0;
#else
      index = width - 1;
#endif

      repeat = in->Bands;

      if (IM_UNSIGNED (in))
	func = (im_wrapone_fn) byte_select;
      else
	func = (im_wrapone_fn) byte_select_flip;

      if (1 == width && (im_wrapone_fn) byte_select == func)
	{
	  return im_copy (in, out);
	}
    }

  else if (IM_CODING_LABQ == in->Coding)

    func = (im_wrapone_fn) msb_labq;

  else
    {
      im_error (FUNCTION_NAME, _("unknown coding"));
      return -1;
    }

  if (im_cp_desc (out, in))
    return -1;

  out->Bbits = sizeof (unsigned char) << 3;
  out->BandFmt = IM_BANDFMT_UCHAR;
  out->Coding = IM_CODING_NONE;

  return im_wrapone (in, out, func, (void *) params, NULL);

#undef index
#undef width
#undef repeat

#undef FUNCTION_NAME
}
Exemplo n.º 24
0
/* Use fftw2.
 */
static int 
invfft1( IMAGE *dummy, IMAGE *in, IMAGE *out )
{
	IMAGE *cmplx = im_open_local( dummy, "invfft1-1", "t" );
	IMAGE *real = im_open_local( out, "invfft1-2", "t" );
	const int half_width = in->Xsize / 2 + 1;

	/* Transform to halfcomplex here.
	 */
	double *half_complex = IM_ARRAY( dummy, 
		in->Ysize * half_width * 2, double );

	rfftwnd_plan plan;
	int x, y;
	double *q, *p;

	if( !cmplx || !real || !half_complex || im_pincheck( in ) || 
		im_poutcheck( out ) )
		return( -1 );
	if( in->Coding != IM_CODING_NONE || in->Bands != 1 ) {
                im_error( "im_invfft", _( "one band uncoded only" ) );
                return( -1 );
	}

	/* Make dp complex image for input.
	 */
	if( im_clip2fmt( in, cmplx, IM_BANDFMT_DPCOMPLEX ) )
                return( -1 );

	/* Make mem buffer real image for output.
	 */
        if( im_cp_desc( real, in ) )
                return( -1 );
	real->BandFmt = IM_BANDFMT_DOUBLE;
        if( im_setupout( real ) )
                return( -1 );

	/* Build half-complex image.
	 */
	q = half_complex;
	for( y = 0; y < cmplx->Ysize; y++ ) {
		p = ((double *) cmplx->data) + y * in->Xsize * 2; 

		for( x = 0; x < half_width; x++ ) {
			q[0] = p[0];
			q[1] = p[1];
			p += 2;
			q += 2;
		}
	}

	/* Make the plan for the transform. Yes, they really do use nx for
	 * height and ny for width.
	 */
	if( !(plan = rfftw2d_create_plan( in->Ysize, in->Xsize,
		FFTW_BACKWARD, FFTW_MEASURE | FFTW_USE_WISDOM )) ) {
                im_error( "im_invfft", _( "unable to create transform plan" ) );
		return( -1 );
	}

	rfftwnd_one_complex_to_real( plan, 
		(fftw_complex *) half_complex, (fftw_real *) real->data );

	rfftwnd_destroy_plan( plan );

	/* Copy to out.
	 */
        if( im_copy( real, out ) )
                return( -1 );

	return( 0 );
}
Exemplo n.º 25
0
/* Convert to a saveable format. 
 *
 * im__saveable_t gives the general type of image
 * we make: vanilla 1/3 bands (eg. PPM), with an optional alpha (eg. PNG), or
 * with CMYK as an option (eg. JPEG). 
 *
 * format_table[] says how to convert each input format. 
 *
 * Need to im_close() the result IMAGE.
 */
IMAGE *
im__convert_saveable( IMAGE *in, 
	im__saveable_t saveable, int format_table[10] ) 
{
	IMAGE *out;

	if( !(out = im_open( "convert-for-save", "p" )) )
		return( NULL );

	/* If this is an IM_CODING_LABQ, we can go straight to RGB.
	 */
	if( in->Coding == IM_CODING_LABQ ) {
		IMAGE *t = im_open_local( out, "conv:1", "p" );
		static void *table = NULL;

		/* Make sure fast LabQ2disp tables are built. 7 is sRGB.
		 */
		if( !table ) 
			table = im_LabQ2disp_build_table( NULL, 
				im_col_displays( 7 ) );

		if( !t || im_LabQ2disp_table( in, t, table ) ) {
			im_close( out );
			return( NULL );
		}

		in = t;
	}

	/* If this is an IM_CODING_RAD, we go to float RGB or XYZ. We should
	 * probably un-gamma-correct the RGB :(
	 */
	if( in->Coding == IM_CODING_RAD ) {
		IMAGE *t;

		if( !(t = im_open_local( out, "conv:1", "p" )) || 
			im_rad2float( in, t ) ) {
			im_close( out );
			return( NULL );
		}

		in = t;
	}

	/* Get the bands right. 
	 */
	if( in->Coding == IM_CODING_NONE ) {
		if( in->Bands == 2 && saveable != IM__RGBA ) {
			IMAGE *t = im_open_local( out, "conv:1", "p" );

			if( !t || im_extract_band( in, t, 0 ) ) {
				im_close( out );
				return( NULL );
			}

			in = t;
		}
		else if( in->Bands > 3 && saveable == IM__RGB ) {
			IMAGE *t = im_open_local( out, "conv:1", "p" );

			if( !t ||
				im_extract_bands( in, t, 0, 3 ) ) {
				im_close( out );
				return( NULL );
			}

			in = t;
		}
		else if( in->Bands > 4 && 
			(saveable == IM__RGB_CMYK || saveable == IM__RGBA) ) {
			IMAGE *t = im_open_local( out, "conv:1", "p" );

			if( !t ||
				im_extract_bands( in, t, 0, 4 ) ) {
				im_close( out );
				return( NULL );
			}

			in = t;
		}

		/* Else we have saveable IM__ANY and we don't chop bands down.
		 */
	}

	/* Interpret the Type field for colorimetric images.
	 */
	if( in->Bands == 3 && in->BandFmt == IM_BANDFMT_SHORT && 
		in->Type == IM_TYPE_LABS ) {
		IMAGE *t = im_open_local( out, "conv:1", "p" );

		if( !t || im_LabS2LabQ( in, t ) ) {
			im_close( out );
			return( NULL );
		}

		in = t;
	}

	if( in->Coding == IM_CODING_LABQ ) {
		IMAGE *t = im_open_local( out, "conv:1", "p" );

		if( !t || im_LabQ2Lab( in, t ) ) {
			im_close( out );
			return( NULL );
		}

		in = t;
	}

	if( in->Coding != IM_CODING_NONE ) {
		im_close( out );
		return( NULL );
	}

	if( in->Bands == 3 && in->Type == IM_TYPE_LCH ) {
		IMAGE *t[2];

                if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
			im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
			im_LCh2Lab( t[0], t[1] ) ) {
			im_close( out );
			return( NULL );
		}

		in = t[1];
	}

	if( in->Bands == 3 && in->Type == IM_TYPE_YXY ) {
		IMAGE *t[2];

                if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
			im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
			im_Yxy2XYZ( t[0], t[1] ) ) {
			im_close( out );
			return( NULL );
		}

		in = t[1];
	}

	if( in->Bands == 3 && in->Type == IM_TYPE_UCS ) {
		IMAGE *t[2];

                if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
			im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
			im_UCS2XYZ( t[0], t[1] ) ) {
			im_close( out );
			return( NULL );
		}

		in = t[1];
	}

	if( in->Bands == 3 && in->Type == IM_TYPE_LAB ) {
		IMAGE *t[2];

                if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
			im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
			im_Lab2XYZ( t[0], t[1] ) ) {
			im_close( out );
			return( NULL );
		}

		in = t[1];
	}

	if( in->Bands == 3 && in->Type == IM_TYPE_XYZ ) {
		IMAGE *t[2];

                if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
			im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
			im_XYZ2disp( t[0], t[1], im_col_displays( 7 ) ) ) {
			im_close( out );
			return( NULL );
		}

		in = t[1];
	}

	/* Cast to the output format.
	 */
	{
		IMAGE *t = im_open_local( out, "conv:1", "p" );

		if( !t || im_clip2fmt( in, t, format_table[in->BandFmt] ) ) {
			im_close( out );
			return( NULL );
		}

		in = t;
	}

	if( im_copy( in, out ) ) {
		im_close( out );
		return( NULL );
	}

	return( out );
}
Exemplo n.º 26
0
/* Call im_copy via arg vector.
 */
static int
copy_vec( im_object *argv )
{
	return( im_copy( argv[0], argv[1] ) );
}
Exemplo n.º 27
0
/* Make a mask image.
 */
static int 
build_freq_mask( IMAGE *out, int xs, int ys, ImMaskType flag, va_list ap )
{
	/* May be fewer than 4 args ... but extract them all anyway. Should be
	 * safe.
	 */
	double p0 = va_arg( ap, double );
	double p1 = va_arg( ap, double );
	double p2 = va_arg( ap, double );
	double p3 = va_arg( ap, double );
	double p4 = va_arg( ap, double );

	VipsImage *t;

	switch( flag ) {
	case IM_MASK_IDEAL_HIGHPASS:
		if( vips_mask_ideal( &t, xs, ys, p0,
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_IDEAL_LOWPASS:
		if( vips_mask_ideal( &t, xs, ys, p0,
			"reject", TRUE, 
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_BUTTERWORTH_HIGHPASS:
		if( vips_mask_butterworth( &t, xs, ys, p0, p1, p2,
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_BUTTERWORTH_LOWPASS:
		if( vips_mask_butterworth( &t, xs, ys, p0, p1, p2,
			"reject", TRUE, 
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_GAUSS_HIGHPASS:
		if( vips_mask_gaussian( &t, xs, ys, p0, p1, 
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_GAUSS_LOWPASS:
		if( vips_mask_gaussian( &t, xs, ys, p0, p1, 
			"reject", TRUE, 
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_IDEAL_RINGPASS:
		if( vips_mask_ideal_ring( &t, xs, ys, p0, p1, 
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_IDEAL_RINGREJECT:
		if( vips_mask_ideal_ring( &t, xs, ys, p0, p1, 
			"reject", TRUE, 
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_BUTTERWORTH_RINGPASS:
		if( vips_mask_butterworth_ring( &t, xs, ys, p0, p1, p2, p3,
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_BUTTERWORTH_RINGREJECT:
		if( vips_mask_butterworth_ring( &t, xs, ys, p0, p1, p2, p3,
			"reject", TRUE, 
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_GAUSS_RINGPASS:
		if( vips_mask_gaussian_ring( &t, xs, ys, p0, p1, p2, 
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_GAUSS_RINGREJECT:
		if( vips_mask_gaussian_ring( &t, xs, ys, p0, p1, p2, 
			"reject", TRUE, 
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_FRACTAL_FLT:
		if( vips_mask_fractal( &t, xs, ys, p0, 
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_IDEAL_BANDPASS:
		if( vips_mask_ideal_band( &t, xs, ys, p0, p1, p2, 
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_IDEAL_BANDREJECT:
		if( vips_mask_ideal_band( &t, xs, ys, p0, p1, p2, 
			"reject", TRUE, 
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_BUTTERWORTH_BANDPASS:
		if( vips_mask_butterworth_band( &t, xs, ys, p0, p1, p2, p3, p4,
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_BUTTERWORTH_BANDREJECT:
		if( vips_mask_butterworth_band( &t, xs, ys, p0, p1, p2, p3, p4,
			"reject", TRUE, 
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_GAUSS_BANDPASS:
		if( vips_mask_gaussian_band( &t, xs, ys, p0, p1, p2, p3, 
			NULL ) )
			return( -1 );
		break;

	case IM_MASK_GAUSS_BANDREJECT:
		if( vips_mask_gaussian_band( &t, xs, ys, p0, p1, p2, p3, 
			"reject", TRUE, 
			NULL ) )
			return( -1 );
		break;

	default:
	       im_error( "im_freq_mask", "%s", _( "unimplemented mask type" ) );
	       return( -1 );
	}

	if( im_copy( t, out ) ) {
		g_object_unref( t );
		return( -1 );
	}
	g_object_unref( t );

	return( 0 );
}
Exemplo n.º 28
0
int
main (int argc, char **argv) {
    const int NTMPS = 3;
	VipsImage *in, *out;
    VipsImage *tmps[NTMPS];
    INTMASK *mask;
    int stat;
    const char *ifile, *ofile;
    int extractTop = 100, extractBtm = 200;

    check(argc == 3, "Syntax: %s <input> <output>", argv[0]);
    ifile = argv[1];
    ofile = argv[2];

    timer_start(ifile, "Setup");

    if (im_init_world (argv[0])) error_exit ("unable to start VIPS");

    in = im_open( ifile, "r" );
    if (!in) vips_error_exit( "unable to read %s", ifile );
    check(in->Ysize > 5 && in->Xsize > 5,
          "Input image must be larger than 5 in both dimensions",
          extractBtm);

    stat = im_open_local_array(in, tmps, NTMPS, "tt", "p");
    check(!stat, "Unable to create temps.");

    mask = mk_convmat();

    timer_done();

    /* Reduce the extraction size if it's bigger than the image. */
    if (extractBtm + extractTop >= in->Ysize ||
        extractBtm + extractTop >= in->Xsize) {
        extractTop = 2;
        extractBtm = 2;
    }/* if */

    timer_start(ifile, "im_extract_area");
    check(
        !im_extract_area(in, tmps[0], extractTop, extractTop, in->Xsize - extractBtm,
                         in->Ysize - extractBtm),
        "extract failed.");
    timer_done();

    timer_start(ifile, "im_affine");
    check(
        !im_affine(tmps[0], tmps[1], 0.9, 0, 0, 0.9, 0, 0,
                   0, 0, in->Xsize * 0.9, in->Ysize * 0.9),
        "im_affine failed.");
    timer_done();

    timer_start(ifile, "im_conv");
    check(
        !im_conv (tmps[1], tmps[2], mask),
        "im_conv failed.");
    timer_done();
        
    timer_start(ofile, "writing output");
    out = im_open(ofile, "w");
    check(!!out, "file output failed.");

    im_copy(tmps[2], out);
    timer_done();
    

    timer_start(ofile, "teardown");
    im_close(out);
    im_close(in);
    timer_done();

    print_times();

    return 0;
}/* main */
Exemplo n.º 29
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 );
}
Exemplo n.º 30
0
static int
shrink_factor( IMAGE *in, IMAGE *out, 
	int shrink, double residual, VipsInterpolate *interp )
{
	IMAGE *t[9];
	VipsImage **s = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( out ), 1 );
	IMAGE *x;
	int tile_width;
	int tile_height;
	int nlines;

	if( im_open_local_array( out, t, 9, "thumbnail", "p" ) )
		return( -1 );
	x = in;

	/* Unpack the two coded formats we support to float for processing.
	 */
	if( x->Coding == IM_CODING_LABQ ) {
		if( verbose ) 
			printf( "unpacking LAB to RGB\n" );

		if( im_LabQ2disp( x, t[1], im_col_displays( 7 ) ) )
			return( -1 );
		x = t[1];
	}
	else if( x->Coding == IM_CODING_RAD ) {
		if( verbose ) 
			printf( "unpacking Rad to float\n" );

		if( im_rad2float( x, t[1] ) )
			return( -1 );
		x = t[1];
	}

	if( im_shrink( x, t[2], shrink, shrink ) )
		return( -1 );

	/* We want to make sure we read the image sequentially.
	 * However, the convolution we may be doing later will force us 
	 * into SMALLTILE or maybe FATSTRIP mode and that will break
	 * sequentiality.
	 *
	 * So ... read into a cache where tiles are scanlines, and make sure
	 * we keep enough scanlines to be able to serve a line of tiles.
	 */
	vips_get_tile_size( t[2], 
		&tile_width, &tile_height, &nlines );
	if( vips_tilecache( t[2], &s[0], 
		"tile_width", t[2]->Xsize,
		"tile_height", 10,
		"max_tiles", (nlines * 2) / 10,
		"strategy", VIPS_CACHE_SEQUENTIAL,
		NULL ) ||
		im_affinei_all( s[0], t[4], 
			interp, residual, 0, 0, residual, 0, 0 ) )
		return( -1 );
	x = t[4];

	/* If we are upsampling, don't sharpen, since nearest looks dumb
	 * sharpened.
	 */
	if( shrink > 1 && residual <= 1.0 && !nosharpen ) {
		if( verbose ) 
			printf( "sharpening thumbnail\n" );

		if( im_conv( x, t[5], sharpen_filter() ) )
			return( -1 );
		x = t[5];
	}

	/* Colour management: we can transform the image if we have an output
	 * profile and an input profile. The input profile can be in the
	 * image, or if there is no profile there, supplied by the user.
	 */
	if( export_profile &&
		(im_header_get_typeof( x, IM_META_ICC_NAME ) || 
		 import_profile) ) {
		if( im_header_get_typeof( x, IM_META_ICC_NAME ) ) {
			if( verbose ) 
				printf( "importing with embedded profile\n" );

			if( im_icc_import_embedded( x, t[6], 
				IM_INTENT_RELATIVE_COLORIMETRIC ) )
				return( -1 );
		}
		else {
			if( verbose ) 
				printf( "importing with profile %s\n",
					import_profile );

			if( im_icc_import( x, t[6], 
				import_profile, 
				IM_INTENT_RELATIVE_COLORIMETRIC ) )
				return( -1 );
		}

		if( verbose ) 
			printf( "exporting with profile %s\n", export_profile );

		if( im_icc_export_depth( t[6], t[7], 
			8, export_profile, 
			IM_INTENT_RELATIVE_COLORIMETRIC ) )
			return( -1 );

		x = t[7];
	}

	if( delete_profile ) {
		if( verbose )
			printf( "deleting profile from output image\n" );

		if( im_meta_get_typeof( x, IM_META_ICC_NAME ) &&
			!im_meta_remove( x, IM_META_ICC_NAME ) )
			return( -1 );
	}

	if( im_copy( x, out ) )
		return( -1 );

	return( 0 );
}