Beispiel #1
0
static int
vips2csv( VipsImage *in, FILE *fp, const char *sep )
{
    int w = VIPS_IMAGE_N_ELEMENTS( in );
    int es = VIPS_IMAGE_SIZEOF_ELEMENT( in );

    int x, y;
    VipsPel *p;

    p = in->data;
    for( y = 0; y < in->Ysize; y++ ) {
        for( x = 0; x < w; x++ ) {
            if( x > 0 )
                fprintf( fp, "%s", sep );

            switch( in->BandFmt ) {
            case VIPS_FORMAT_UCHAR:
                PRINT_INT( unsigned char );
                break;
            case VIPS_FORMAT_CHAR:
                PRINT_INT( char );
                break;
            case VIPS_FORMAT_USHORT:
                PRINT_INT( unsigned short );
                break;
            case VIPS_FORMAT_SHORT:
                PRINT_INT( short );
                break;
            case VIPS_FORMAT_UINT:
                PRINT_INT( unsigned int );
                break;
            case VIPS_FORMAT_INT:
                PRINT_INT( int );
                break;
            case VIPS_FORMAT_FLOAT:
                PRINT_FLOAT( float );
                break;
            case VIPS_FORMAT_DOUBLE:
                PRINT_FLOAT( double );
                break;
            case VIPS_FORMAT_COMPLEX:
                PRINT_COMPLEX( float );
                break;
            case VIPS_FORMAT_DPCOMPLEX:
                PRINT_COMPLEX( double );
                break;

            default:
                g_assert( 0 );
            }

            p += es;
        }

        fprintf( fp, "\n" );
    }

    return( 0 );
}
Beispiel #2
0
static int
vips_fits_write( VipsRegion *region, VipsRect *area, void *a )
{
	VipsFits *fits = (VipsFits *) a;
	VipsImage *image = fits->image;
	int es = VIPS_IMAGE_SIZEOF_ELEMENT( image );
	int ps = VIPS_IMAGE_SIZEOF_PEL( image );

	int status;
	int y, b, x, k;

	status = 0;

	VIPS_DEBUG_MSG( "vips_fits_write: "
		"writing left = %d, top = %d, width = %d, height = %d\n", 
		area->left, area->top, area->width, area->height );

	/* We need to write a band at a time. We can't bandsplit in vips,
	 * since vips_sink_disc() can't loop over many images at once, sadly.
	 */

	for( y = 0; y < area->height; y++ ) {
		VipsPel *p = VIPS_REGION_ADDR( region, 
			area->left, area->top + y );

		for( b = 0; b < image->Bands; b++ ) {
			VipsPel *p1, *q;
			long fpixel[3];

			p1 = p + b * es;
			q = fits->buffer;

			for( x = 0; x < area->width; x++ ) {
				for( k = 0; k < es; k++ ) 
					q[k] = p1[k];
				
				q += es;
				p1 += ps;
			}

			fpixel[0] = area->left + 1;
			fpixel[1] = area->top + y + 1;
			fpixel[2] = b + 1;

			/* No need to lock, write functions are single-threaded.
			 */

			if( fits_write_pix( fits->fptr, fits->datatype, 
				fpixel, area->width, fits->buffer, 
				&status ) ) {
				vips_fits_error( status );
				return( -1 );
			}
		}
	}

	return( 0 );
}
Beispiel #3
0
/* Generate an area of @or. @ir is large enough.
 */
static void
vips_shrink2_gen2( VipsShrink2 *shrink, VipsShrink2Sequence *seq,
                   VipsRegion *or, VipsRegion *ir,
                   int left, int top, int width, int height )
{
    VipsResample *resample = VIPS_RESAMPLE( shrink );
    const int bands = resample->in->Bands;
    const int sizeof_pixel = VIPS_IMAGE_SIZEOF_PEL( resample->in );
    const int ls = VIPS_REGION_LSKIP( ir ) /
                   VIPS_IMAGE_SIZEOF_ELEMENT( resample->in );

    int x, y, i;
    int x1, y1, b;

    for( y = 0; y < height; y++ ) {
        VipsPel *out = VIPS_REGION_ADDR( or, left, top + y );

        for( x = 0; x < width; x++ ) {
            int ix = (left + x) * shrink->xshrink;
            int iy = (top + y) * shrink->yshrink;
            VipsPel *in = VIPS_REGION_ADDR( ir, ix, iy );

            switch( resample->in->BandFmt ) {
            case VIPS_FORMAT_UCHAR:
                ISHRINK( unsigned char );
                break;
            case VIPS_FORMAT_CHAR:
                ISHRINK( char );
                break;
            case VIPS_FORMAT_USHORT:
                ISHRINK( unsigned short );
                break;
            case VIPS_FORMAT_SHORT:
                ISHRINK( short );
                break;
            case VIPS_FORMAT_UINT:
                ISHRINK( unsigned int );
                break;
            case VIPS_FORMAT_INT:
                ISHRINK( int );
                break;
            case VIPS_FORMAT_FLOAT:
                FSHRINK( float );
                break;
            case VIPS_FORMAT_DOUBLE:
                FSHRINK( double );
                break;

            default:
                g_assert( 0 );
            }

            out += sizeof_pixel;
        }
    }
}
Beispiel #4
0
static int
mat2vips_get_data( mat_t *mat, matvar_t *var, VipsImage *im )
{
	int y;
	VipsPel *buffer;
	const int es = VIPS_IMAGE_SIZEOF_ELEMENT( im );

	/* Matlab images are plane-separate, so we have to assemble bands in
	 * image-size chunks.
	 */
	const guint64 is = es * VIPS_IMAGE_N_PELS( im );

	if( Mat_VarReadDataAll( mat, var ) ) {
		vips_error( "mat2vips", "%s", 
			_( "Mat_VarReadDataAll failed" ) );
		return( -1 );
	}

	/* Matlab images are in columns, so we have to transpose into
	 * scanlines with this buffer.
	 */
	if( !(buffer = VIPS_ARRAY( im, 
		VIPS_IMAGE_SIZEOF_LINE( im ), VipsPel )) )
		return( -1 );

	for( y = 0; y < im->Ysize; y++ ) {
		const VipsPel *p = var->data + y * es;
		int x;
		VipsPel *q;

		q = buffer;
		for( x = 0; x < im->Xsize; x++ ) {
			int b;

			for( b = 0; b < im->Bands; b++ ) {
				const VipsPel *p2 = p + b * is;
				int z;

				for( z = 0; z < es; z++ )
					q[z] = p2[z];

				q += es;
			}

			p += es * im->Ysize;
		}

		if( vips_image_write_line( im, y, buffer ) )
			return( -1 );
	}

	return( 0 );
}
Beispiel #5
0
static void
vips_fastcor_correlation( VipsCorrelation *correlation,
	VipsRegion *in, VipsRegion *out )
{
	VipsRect *r = &out->valid;
	VipsImage *ref = correlation->ref_ready;
	int bands = vips_band_format_iscomplex( ref->BandFmt ) ? 
		ref->Bands * 2 : ref->Bands; 
	int sz = ref->Xsize * bands; 
	int lsk = VIPS_REGION_LSKIP( in ) / VIPS_IMAGE_SIZEOF_ELEMENT( in->im );

	int x, y, i, j, b;

        switch( vips_image_get_format( ref ) ) {
        case VIPS_FORMAT_CHAR: 	
		CORR_INT( signed char ); 
		break; 

        case VIPS_FORMAT_UCHAR:	
		CORR_INT( unsigned char ); 
		break; 

        case VIPS_FORMAT_SHORT:	
		CORR_INT( signed short ); 
		break; 

        case VIPS_FORMAT_USHORT:
		CORR_INT( unsigned short ); 
		break; 

        case VIPS_FORMAT_INT: 	
		CORR_INT( signed int ); 
		break; 

        case VIPS_FORMAT_UINT: 	
		CORR_INT( unsigned int ); 
		break; 

        case VIPS_FORMAT_FLOAT:	
        case VIPS_FORMAT_COMPLEX: 
		CORR_FLOAT( float ); 
		break; 

        case VIPS_FORMAT_DOUBLE: 
        case VIPS_FORMAT_DPCOMPLEX: 
		CORR_FLOAT( double ); 
		break;

        default:
		g_assert_not_reached();
        }
}
Beispiel #6
0
static VipsFits *
vips_fits_new_write( VipsImage *in, const char *filename )
{
	VipsFits *fits;
	int status;

	status = 0;

	if( !(fits = VIPS_NEW( in, VipsFits )) )
		return( NULL );
	fits->filename = vips_strdup( VIPS_OBJECT( in ), filename );
	fits->image = in;
	fits->fptr = NULL;
	fits->lock = NULL;
	fits->band_select = -1;
	fits->buffer = NULL;
	g_signal_connect( in, "close", 
		G_CALLBACK( vips_fits_close_cb ), fits );

	if( !(fits->filename = vips_strdup( NULL, filename )) )
		return( NULL );

	/* We need to be able to hold one scanline of one band.
	 */
	if( !(fits->buffer = VIPS_ARRAY( NULL, 
		VIPS_IMAGE_SIZEOF_ELEMENT( in ) * in->Xsize, VipsPel )) )
		return( NULL );

	/* fits_create_file() will fail if there's a file of thet name, unless
	 * we put a "!" in front ofthe filename. This breaks conventions with
	 * the rest of vips, so just unlink explicitly.
	 */
	g_unlink( filename );

	if( fits_create_file( &fits->fptr, filename, &status ) ) {
		vips_error( "fits", 
			_( "unable to write to \"%s\"" ), filename );
		vips_fits_error( status );
		return( NULL );
	}

	fits->lock = vips_g_mutex_new();

	return( fits );
}
Beispiel #7
0
static void *
vips_rank_start( IMAGE *out, void *a, void *b )
{
	VipsImage *in = (VipsImage *) a;
	VipsRank *rank = (VipsRank *) b;
	VipsRankSequence *seq;

	if( !(seq = VIPS_NEW( out, VipsRankSequence )) )
		return( NULL );
	seq->ir = NULL;
	seq->sort = NULL;

	seq->ir = vips_region_new( in );
	if( !(seq->sort = VIPS_ARRAY( out, 
		VIPS_IMAGE_SIZEOF_ELEMENT( in ) * rank->n, VipsPel )) ) { 
		vips_rank_stop( seq, in, rank );
		return( NULL );
	}

	return( (void *) seq );
}
Beispiel #8
0
static int
vips_bandunfold_gen( VipsRegion *or, 
	void *seq, void *a, void *b, gboolean *stop )
{
	VipsBandunfold *bandunfold = (VipsBandunfold *) b;
	VipsRegion *ir = (VipsRegion *) seq;
	VipsImage *in = ir->im;
	VipsImage *out = or->im;
	VipsRect *r = &or->valid;
	int esize = VIPS_IMAGE_SIZEOF_ELEMENT( in );
	int psize = VIPS_IMAGE_SIZEOF_PEL( out );

	VipsRect need;
	int y;

	need.left = r->left / bandunfold->factor;
	need.top = r->top;
	need.width = (1 + r->width) / bandunfold->factor;
	need.height = r->height;
	if( vips_region_prepare( ir, &need ) )
		return( -1 );

	for( y = 0; y < r->height; y++ ) {
		VipsPel *p = VIPS_REGION_ADDR( ir, 
			r->left / bandunfold->factor, r->top + y ) + 
			(r->left % bandunfold->factor) * esize;
		VipsPel *q = VIPS_REGION_ADDR( or, r->left, r->top + y );

		/* We can't use vips_region_region() since we change pixel
		 * coordinates.
		 */
		memcpy( q, p, r->width * psize );
	}

	return( 0 );
}
Beispiel #9
0
  /*
   * Move the pointer to (the first band of) the top/left pixel of the
   * 2x2 group of pixel centers which contains the sampling location
   * in its convex hull:
   */
  const VipsPel* restrict p = VIPS_REGION_ADDR( in, ix, iy );

  const double relative_x = absolute_x - ix;
  const double relative_y = absolute_y - iy;

  /*
   * VIPS versions of Nicolas's pixel addressing values.
   */
  const int lskip = VIPS_REGION_LSKIP( in ) / 
	  VIPS_IMAGE_SIZEOF_ELEMENT( in->im );

  /*
   * Double the bands for complex images to account for the real and
   * imaginary parts being computed independently:
   */
  const int actual_bands = in->im->Bands;
  const int bands =
    vips_band_format_iscomplex( in->im->BandFmt ) ? 
      2 * actual_bands : actual_bands;

  /* Confirm that absolute_x and absolute_y are >= 1, see above. 
   */
  g_assert( absolute_x >= 1.0 );
  g_assert( absolute_y >= 1.0 );
Beispiel #10
0
static int
vips_ifthenelse_gen( VipsRegion *or, void *seq, void *client1, void *client2,
	gboolean *stop )
{
	VipsRegion **ir = (VipsRegion **) seq;
	VipsIfthenelse *ifthenelse = (VipsIfthenelse *) client2;
	VipsRect *r = &or->valid;
	int le = r->left;
	int to = r->top;
	int bo = VIPS_RECT_BOTTOM( r );

	VipsImage *c = ir[2]->im;
	VipsImage *a = ir[0]->im;

	int size, width;
	int i, x, y, z;

	int all0, alln0;

	if( c->Bands == 1 ) {
		/* Copying PEL-sized units with a one-band conditional.
		 */
		size = VIPS_IMAGE_SIZEOF_PEL( a );
		width = r->width;
	}
	else {
		/* Copying ELEMENT sized-units with an n-band conditional.
		 */
		size = VIPS_IMAGE_SIZEOF_ELEMENT( a );
		width = r->width * a->Bands;
	}

	if( vips_region_prepare( ir[2], r ) )
		return( -1 );

	/* Is the conditional all zero or all non-zero? We can avoid asking
	 * for one of the inputs to be calculated.
	 */
	all0 = *((PEL *) VIPS_REGION_ADDR( ir[2], le, to )) == 0;
	alln0 = *((PEL *) VIPS_REGION_ADDR( ir[2], le, to )) != 0;
	for( y = to; y < bo; y++ ) {
		PEL *p = (PEL *) VIPS_REGION_ADDR( ir[2], le, y );

		for( x = 0; x < width; x++ ) {
			all0 &= p[x] == 0;
			alln0 &= p[x] != 0;
		}

		if( !all0 && !alln0 )
			break;
	}

	if( alln0 ) {
		/* All non-zero. Point or at the then image.
		 */
		if( vips_region_prepare( ir[0], r ) ||
			vips_region_region( or, ir[0], r, r->left, r->top ) )
			return( -1 );
	}
	else if( all0 ) {
		/* All zero. Point or at the else image.
		 */
		if( vips_region_prepare( ir[1], r ) ||
			vips_region_region( or, ir[1], r, r->left, r->top ) )
			return( -1 );
	}
	else {
		/* Mix of set and clear ... ask for both then and else parts 
		 * and interleave.
		 */
		if( vips_region_prepare( ir[0], r ) || 
			vips_region_prepare( ir[1], r ) ) 
			return( -1 );

		for( y = to; y < bo; y++ ) {
			PEL *ap = (PEL *) VIPS_REGION_ADDR( ir[0], le, y );
			PEL *bp = (PEL *) VIPS_REGION_ADDR( ir[1], le, y );
			PEL *cp = (PEL *) VIPS_REGION_ADDR( ir[2], le, y );
			PEL *q = (PEL *) VIPS_REGION_ADDR( or, le, y );

			if( ifthenelse->blend ) {
				if( c->Bands == 1 ) 
					vips_blend1_buffer( q, 
						cp, ap, bp, r->width, a );
				else
					vips_blendn_buffer( q, 
						cp, ap, bp, r->width, a );
			}
			else {
				for( x = 0, i = 0; i < width; i++, x += size ) 
					if( cp[i] )
						for( z = x; z < x + size; z++ )
							q[z] = ap[z];
					else
						for( z = x; z < x + size; z++ )
							q[z] = bp[z];
			}
		}
	}

	return( 0 );
}
Beispiel #11
0
static VipsFits *
vips_fits_new_write( VipsImage *in, const char *filename )
{
	VipsImage *flip;
	VipsImage *type;
	VipsFits *fits;
	int status;

	status = 0;

	if( im_check_noncomplex( "im_vips2fits", in ) ||
		im_check_uncoded( "im_vips2fits", in ) )
		return( NULL );

	/* Cast to a supported format.
	 */
	if( !(type = vips_image_new()) ||
		vips_object_local( in, type ) ||
		im_clip2fmt( in, type, vips_fits_bandfmt[in->BandFmt] ) )
		return( NULL );
	in = type;

	/* FITS has (0,0) in the bottom left, we need to flip.
	 */
	if( !(flip = vips_image_new()) ||
		vips_object_local( in, flip ) ||
		im_flipver( in, flip ) )
		return( NULL );
	in = flip;

	if( !(fits = VIPS_NEW( in, VipsFits )) )
		return( NULL );
	fits->filename = im_strdup( NULL, filename );
	fits->image = in;
	fits->fptr = NULL;
	fits->lock = NULL;
	fits->band_select = -1;
	fits->buffer = NULL;
	g_signal_connect( in, "close", 
		G_CALLBACK( vips_fits_close_cb ), fits );

	if( !(fits->filename = im_strdup( NULL, filename )) )
		return( NULL );

	/* We need to be able to hold one scanline of one band.
	 */
	if( !(fits->buffer = VIPS_ARRAY( NULL, 
		VIPS_IMAGE_SIZEOF_ELEMENT( in ) * in->Xsize, PEL )) )
		return( NULL );

	/* fits_create_file() will fail if there's a file of thet name, unless
	 * we put a "!" in front ofthe filename. This breaks conventions with
	 * the rest of vips, so just unlink explicitly.
	 */
	g_unlink( filename );

	if( fits_create_file( &fits->fptr, filename, &status ) ) {
		im_error( "fits", _( "unable to write to \"%s\"" ), filename );
		vips_fits_error( status );
		return( NULL );
	}

	fits->lock = g_mutex_new();

	return( fits );
}