static ReadSlide * readslide_new( const char *filename, VipsImage *out, int layer, const char *associated ) { ReadSlide *rslide; int64_t w, h; const char *background; const char * const *properties; rslide = VIPS_NEW( out, ReadSlide ); memset( rslide, 0, sizeof( *rslide ) ); g_signal_connect( out, "close", G_CALLBACK( readslide_destroy_cb ), rslide ); rslide->layer = layer; rslide->associated = g_strdup( associated ); rslide->osr = openslide_open( filename ); if( rslide->osr == NULL ) { vips_error( "openslide2vips", "%s", _( "failure opening slide" ) ); return( NULL ); } if( layer < 0 || layer >= openslide_get_layer_count( rslide->osr ) ) { vips_error( "openslide2vips", "%s", _( "invalid slide level" ) ); return( NULL ); } if( associated && check_associated_image( rslide->osr, associated ) ) return( NULL ); if( associated ) { openslide_get_associated_image_dimensions( rslide->osr, associated, &w, &h ); vips_image_set_string( out, "slide-associated-image", associated ); vips_demand_hint( out, VIPS_DEMAND_STYLE_THINSTRIP, NULL ); } else { openslide_get_layer_dimensions( rslide->osr, layer, &w, &h ); rslide->downsample = openslide_get_layer_downsample( rslide->osr, layer ); vips_image_set_int( out, "slide-level", layer ); vips_demand_hint( out, VIPS_DEMAND_STYLE_SMALLTILE, NULL ); } /* This tag is used by argb2rgba() to paint fully-transparent pixels. */ background = openslide_get_property_value( rslide->osr, OPENSLIDE_PROPERTY_NAME_BACKGROUND_COLOR ); if( background != NULL ) vips_image_set_int( out, VIPS_META_BACKGROUND_RGB, strtoul( background, NULL, 16 ) ); else vips_image_set_int( out, VIPS_META_BACKGROUND_RGB, 0xffffff ); if( w < 0 || h < 0 || rslide->downsample < 0 ) { vips_error( "openslide2vips", _( "getting dimensions: %s" ), openslide_get_error( rslide->osr ) ); return( NULL ); } if( w > INT_MAX || h > INT_MAX ) { vips_error( "openslide2vips", "%s", _( "image dimensions overflow int" ) ); return( NULL ); } vips_image_init_fields( out, w, h, 4, VIPS_FORMAT_UCHAR, VIPS_CODING_NONE, VIPS_INTERPRETATION_RGB, 1.0, 1.0 ); for( properties = openslide_get_property_names( rslide->osr ); *properties != NULL; properties++ ) vips_image_set_string( out, *properties, openslide_get_property_value( rslide->osr, *properties ) ); associated = g_strjoinv( ", ", (char **) openslide_get_associated_image_names( rslide->osr ) ); vips_image_set_string( out, "slide-associated-images", associated ); return( rslide ); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /*variables*/ char *buffer; /*array for input string*/ int32_t levels; /*number of levels*/ int64_t w, h; /*width, height of each level*/ double *dims, *ds; /*pointers to outputs - for convenience*/ const char *objective, *mppx, *mppy; openslide_t *slide; /*openslide struct*/ int i; /*loop iterator*/ /*check input arguments*/ if(nrhs != 1) { mexErrMsgTxt("'openslide_check_levels.m' requires one input argument."); } if(nlhs > 5) { mexErrMsgTxt("'openslide_check_levels.m' produces two outputs."); } /*check input type*/ if(!mxIsChar(prhs[0]) || (mxGetM(prhs[0]) != 1)) { mexErrMsgTxt("Input must be character array."); } /*copy*/ buffer = mxArrayToString(prhs[0]); /*copy input*/ if(openslide_can_open(buffer) == 1) { /*open*/ slide = openslide_open(buffer); /*check for error*/ if(openslide_get_error(slide) != NULL) { mexErrMsgTxt("'openslide_check_levels.m' cannot open slide."); } else { /*get # of levels*/ levels = openslide_get_layer_count(slide); /*allocate arrays*/ plhs[0] = mxCreateDoubleMatrix((mwSize)levels, 2, mxREAL); plhs[1] = mxCreateDoubleMatrix((mwSize)levels, 1, mxREAL); /*get output addresses*/ dims = mxGetPr(plhs[0]); ds = mxGetPr(plhs[1]); /*loop through levels, get dimensions/downsample factor of each*/ for(i = 0; i < levels; i++) { /*get level info*/ openslide_get_layer_dimensions(slide, (int32_t)i, &w, &h); *ds = openslide_get_layer_downsample(slide, (int32_t)i); ds = ds + 1; /*copy dimensions to outputs*/ *dims = (double)h; *(dims+levels) = (double)w; dims = dims + 1; } /*get properties*/ objective = openslide_get_property_value(slide, OPENSLIDE_PROPERTY_NAME_OBJECTIVE_POWER); mppx = openslide_get_property_value(slide, OPENSLIDE_PROPERTY_NAME_MPP_X); mppy = openslide_get_property_value(slide, OPENSLIDE_PROPERTY_NAME_MPP_Y); /*assign properties to outputs*/ plhs[2] = mxCreateString(objective); plhs[3] = mxCreateString(mppx); plhs[4] = mxCreateString(mppy); } } else{ /*can't open slide*/ mexErrMsgTxt("'openslide_check_levels.m' cannot open slide."); } /*free input buffer copy*/ mxFree(buffer); }