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 ); }
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 ); }
/* 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; } } }
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 ); }
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(); } }
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 ); }
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 ); }
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 ); }
/* * 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 );
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 ); }
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 ); }