Ejemplo n.º 1
0
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 );
}
Ejemplo n.º 2
0
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 );
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 5
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 );
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
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);
	
}