static gboolean get_bounds( openslide_t *osr, VipsRect *rect ) { static const char *openslide_names[] = { "openslide.bounds-x", "openslide.bounds-y", "openslide.bounds-width", "openslide.bounds-height" }; static int vips_offsets[] = { G_STRUCT_OFFSET( VipsRect, left ), G_STRUCT_OFFSET( VipsRect, top ), G_STRUCT_OFFSET( VipsRect, width ), G_STRUCT_OFFSET( VipsRect, height ) }; const char *value; int i; for( i = 0; i < 4; i++ ) { if( !(value = openslide_get_property_value( osr, openslide_names[i] )) ) return( FALSE ); G_STRUCT_MEMBER( int, rect, vips_offsets[i] ) = atoi( value ); } return( TRUE ); }
int vips__openslide_isslide( const char *filename ) { openslide_t *osr; const char *vendor; int ok; ok = 0; if( (osr = openslide_open( filename )) ) { /* Generic tiled tiff images can be opened by openslide as * well. Only offer to load this file if it's not a generic * tiff since we want vips_tiffload() to handle these. */ vendor = openslide_get_property_value( osr, OPENSLIDE_PROPERTY_NAME_VENDOR ); if( vendor && strcmp( vendor, "generic-tiff" ) != 0 ) ok = 1; openslide_close( osr ); } VIPS_DEBUG_MSG( "vips__openslide_isslide: %s - %d\n", filename, ok ); return( ok ); }
int vips__openslide_isslide( const char *filename ) { #ifdef HAVE_OPENSLIDE_3_4 const char *vendor; int ok; vendor = openslide_detect_vendor( filename ); /* Generic tiled tiff images can be opened by openslide as well. * Only offer to load this file if it's not a generic tiff since * we want vips_tiffload() to handle these. */ ok = ( vendor && strcmp( vendor, "generic-tiff" ) != 0 ); VIPS_DEBUG_MSG( "vips__openslide_isslide: %s - %d\n", filename, ok ); return( ok ); #else openslide_t *osr; int ok; ok = 0; osr = openslide_open( filename ); if( osr ) { const char *vendor; /* Generic tiled tiff images can be opened by openslide as * well. Only offer to load this file if it's not a generic * tiff since we want vips_tiffload() to handle these. */ vendor = openslide_get_property_value( osr, OPENSLIDE_PROPERTY_NAME_VENDOR ); /* vendor will be NULL if osr is in error state. */ if( vendor && strcmp( vendor, "generic-tiff" ) != 0 ) ok = 1; openslide_close( osr ); } VIPS_DEBUG_MSG( "vips__openslide_isslide: %s - %d\n", filename, ok ); return( ok ); #endif }
int main(int argc, char **argv) { if (argc!=6) { fprintf(stderr,"Usage: %s <image file> <cancer type> <subject id> <case id> <output file>\n",argv[0]); exit(1); } char *inp_file = argv[1]; char *c_type = argv[2]; char *s_id = argv[3]; char *c_id = argv[4]; char *h_name = "localhost"; FILE *fpo = fopen(argv[5],"w"); int check_ok = 1; struct stat attrib; stat(inp_file,&attrib); char file_date[20]; strftime(file_date, 20, "%m-%d-%y:%H.%M.%S", localtime(&(attrib.st_ctime))); openslide_t *osr = openslide_open(inp_file); if (osr==NULL) { fprintf(stderr,"Error: openslide cannot read file: %s\n",inp_file); exit(1); } int64_t w,h; openslide_get_level0_dimensions(osr,&w,&h); if (w<=0 || h<=0) { fprintf(stderr,"Error: openslide cannot get width (%ld) and height (%ld) from the image file: %s\n.",w,h,inp_file); exit(1); } fprintf(fpo,"hostname,filename,last_modified,cancer_type,case_id,subject_id,identifier,width,height,mpp_x,mpp_y,objective,vendor,status,level_count,imageid\n"); fprintf(fpo,"%s,",h_name); fprintf(fpo,"%s,",inp_file); fprintf(fpo,"%s,",file_date); fprintf(fpo,"%s,",c_type); fprintf(fpo,"%s,",c_id); fprintf(fpo,"%s,",s_id); fprintf(fpo,"%s,",c_id); fprintf(fpo,"%f,",(float)w); fprintf(fpo,"%f,",(float)h); /* get objective value */ char *o_val = (char*)openslide_get_property_value(osr,"openslide.objective-power"); if (o_val==NULL) o_val = (char*)openslide_get_property_value(osr,"aperio.AppMag"); char *mpp_x = (char*)openslide_get_property_value(osr,"openslide.mpp-x"); if (mpp_x!=NULL) fprintf(fpo,"%.8f,",atof(mpp_x)); else { if (o_val!=NULL) fprintf(fpo,"%f,",0.25*40.0/atof(o_val)); else { check_ok = 0; fprintf(fpo,"%f,",-1.0); } } char *mpp_y = (char*)openslide_get_property_value(osr,"openslide.mpp-y"); if (mpp_y!=NULL) fprintf(fpo,"%.8f,",atof(mpp_y)); else { if (o_val!=NULL) fprintf(fpo,"%f,",0.25*40.0/atof(o_val)); else { check_ok = 0; fprintf(fpo,"%f,",-1.0); } } /* print objective value */ if (o_val!=NULL) fprintf(fpo,"%f,",(float)atof(o_val)); else { fprintf(fpo,"%f,",-1.0); check_ok = 0; } char *vendor = (char*)openslide_get_property_value(osr,"openslide.vendor"); if (vendor!=NULL) fprintf(fpo,"%s,",vendor); else fprintf(fpo,"no_vendor,"); if (check_ok==0) { fprintf(fpo,"some_errors,"); fprintf(stderr,"SOME_ERRORS: %s\n",inp_file); } else { fprintf(fpo,"status_ok,"); fprintf(stdout,"OK: %s\n",inp_file); } char *level_count = (char*)openslide_get_property_value(osr,"openslide.level-count"); if (level_count!=NULL) fprintf(fpo,"%s,",level_count); else fprintf(fpo,"1,"); char *image_id = (char*)openslide_get_property_value(osr,"aperio.ImageID"); if (image_id!=NULL) fprintf(fpo,"%d\n",atoi(image_id)); else fprintf(fpo,"-1\n"); fflush(fpo); openslide_close(osr); fclose(fpo); exit(0); }
static ReadSlide * readslide_new( const char *filename, VipsImage *out, int level, gboolean autocrop, const char *associated ) { ReadSlide *rslide; int64_t w, h; const char *error; const char *background; const char * const *properties; char *associated_names; if( level && associated ) { vips_error( "openslide2vips", "%s", _( "specify only one of level or associated " "image" ) ); return( NULL ); } rslide = VIPS_NEW( out, ReadSlide ); memset( rslide, 0, sizeof( *rslide ) ); g_signal_connect( out, "close", G_CALLBACK( readslide_destroy_cb ), rslide ); rslide->level = level; rslide->autocrop = autocrop; rslide->associated = g_strdup( associated ); /* Non-crazy defaults, override below if we can. */ rslide->tile_width = 256; rslide->tile_height = 256; rslide->osr = openslide_open( filename ); if( rslide->osr == NULL ) { vips_error( "openslide2vips", "%s", _( "unsupported slide format" ) ); return( NULL ); } error = openslide_get_error( rslide->osr ); if( error ) { vips_error( "openslide2vips", _( "opening slide: %s" ), error ); return( NULL ); } if( level < 0 || level >= openslide_get_level_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_image_pipelinev( out, VIPS_DEMAND_STYLE_THINSTRIP, NULL ); } else { char buf[256]; const char *value; openslide_get_level_dimensions( rslide->osr, level, &w, &h ); rslide->downsample = openslide_get_level_downsample( rslide->osr, level ); vips_image_set_int( out, "slide-level", level ); vips_image_pipelinev( out, VIPS_DEMAND_STYLE_SMALLTILE, NULL ); /* Try to get tile width/height. An undocumented, experimental * feature. */ vips_snprintf( buf, 256, "openslide.level[%d].tile-width", level ); if( (value = openslide_get_property_value( rslide->osr, buf )) ) rslide->tile_width = atoi( value ); vips_snprintf( buf, 256, "openslide.level[%d].tile-height", level ); if( (value = openslide_get_property_value( rslide->osr, buf )) ) rslide->tile_height = atoi( value ); if( value ) VIPS_DEBUG_MSG( "readslide_new: found tile-size\n" ); /* Some images have a bounds in the header. Crop to * that if autocrop is set. */ if( rslide->autocrop ) if( !get_bounds( rslide->osr, &rslide->bounds ) ) rslide->autocrop = FALSE; if( rslide->autocrop ) { VipsRect image; rslide->bounds.left /= rslide->downsample; rslide->bounds.top /= rslide->downsample; rslide->bounds.width /= rslide->downsample; rslide->bounds.height /= rslide->downsample; /* Clip against image size. */ image.left = 0; image.top = 0; image.width = w; image.height = h; vips_rect_intersectrect( &rslide->bounds, &image, &rslide->bounds ); /* If we've clipped to nothing, ignore bounds. */ if( vips_rect_isempty( &rslide->bounds ) ) rslide->autocrop = FALSE; } if( rslide->autocrop ) { w = rslide->bounds.width; h = rslide->bounds.height; } } rslide->bg = 0xffffff; if( (background = openslide_get_property_value( rslide->osr, OPENSLIDE_PROPERTY_NAME_BACKGROUND_COLOR )) ) rslide->bg = strtoul( background, NULL, 16 ); 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 ); } if( !rslide->autocrop ) { rslide->bounds.left = 0; rslide->bounds.top = 0; rslide->bounds.width = w; rslide->bounds.height = h; } 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_names = g_strjoinv( ", ", (char **) openslide_get_associated_image_names( rslide->osr ) ); vips_image_set_string( out, "slide-associated-images", associated_names ); VIPS_FREE( associated_names ); return( rslide ); }
int main(int argc, char **argv) { if (!g_thread_supported()) { g_thread_init(NULL); } if (argc != 2) { fail("No file specified"); } const char *path = argv[1]; if (g_str_equal(path, "--leak-check--")) { child_check_open_fds(); return 0; } openslide_get_version(); if (!openslide_detect_vendor(path)) { fail("No vendor for %s", path); } openslide_t *osr = openslide_open(path); if (!osr) { fail("Couldn't open %s", path); } const char *err = openslide_get_error(osr); if (err) { fail("Open failed: %s", err); } openslide_close(osr); osr = openslide_open(path); if (!osr || openslide_get_error(osr)) { fail("Reopen failed"); } int64_t w, h; openslide_get_level0_dimensions(osr, &w, &h); int32_t levels = openslide_get_level_count(osr); for (int32_t i = -1; i < levels + 1; i++) { int64_t ww, hh; openslide_get_level_dimensions(osr, i, &ww, &hh); openslide_get_level_downsample(osr, i); } openslide_get_best_level_for_downsample(osr, 0.8); openslide_get_best_level_for_downsample(osr, 1.0); openslide_get_best_level_for_downsample(osr, 1.5); openslide_get_best_level_for_downsample(osr, 2.0); openslide_get_best_level_for_downsample(osr, 3.0); openslide_get_best_level_for_downsample(osr, 3.1); openslide_get_best_level_for_downsample(osr, 10); openslide_get_best_level_for_downsample(osr, 20); openslide_get_best_level_for_downsample(osr, 25); openslide_get_best_level_for_downsample(osr, 100); openslide_get_best_level_for_downsample(osr, 1000); openslide_get_best_level_for_downsample(osr, 10000); // NULL buffer openslide_read_region(osr, NULL, 0, 0, 0, 1000, 1000); // empty region openslide_read_region(osr, NULL, 0, 0, 0, 0, 0); // read properties const char * const *property_names = openslide_get_property_names(osr); while (*property_names) { const char *name = *property_names; openslide_get_property_value(osr, name); property_names++; } // read associated images const char * const *associated_image_names = openslide_get_associated_image_names(osr); while (*associated_image_names) { int64_t w, h; const char *name = *associated_image_names; openslide_get_associated_image_dimensions(osr, name, &w, &h); uint32_t *buf = g_new(uint32_t, w * h); openslide_read_associated_image(osr, name, buf); g_free(buf); associated_image_names++; } test_image_fetch(osr, -10, -10, 200, 200); test_image_fetch(osr, w/2, h/2, 500, 500); test_image_fetch(osr, w - 200, h - 100, 500, 400); test_image_fetch(osr, w*2, h*2, 400, 400); test_image_fetch(osr, w - 20, 0, 40, 100); test_image_fetch(osr, 0, h - 20, 100, 40); // active region const char *bounds_x = openslide_get_property_value(osr, OPENSLIDE_PROPERTY_NAME_BOUNDS_X); const char *bounds_y = openslide_get_property_value(osr, OPENSLIDE_PROPERTY_NAME_BOUNDS_Y); int64_t bounds_xx = 0; int64_t bounds_yy = 0; if (bounds_x && bounds_y) { bounds_xx = g_ascii_strtoll(bounds_x, NULL, 10); bounds_yy = g_ascii_strtoll(bounds_y, NULL, 10); test_image_fetch(osr, bounds_xx, bounds_yy, 200, 200); } openslide_close(osr); check_cloexec_leaks(path, argv[0], bounds_xx, bounds_yy); return 0; }
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); }