Blame view

main.cpp 3.46 KB
f043d1fa   David Mayerich   first commit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  #include <iostream>
  #include <string>
  #include <openslide/openslide.h>
  #include <opencv2/opencv.hpp>
  #include <stim/parser/arguments.h>
  
  stim::arglist args;
  int32_t level = 0;
  int64_t x = 0;
  int64_t y = 0;
  int64_t sx, sy;
  openslide_t* slide = NULL;
  
  std::string infile;
  std::string outfile;
  
  void openSlide() {
  	slide = openslide_open(infile.c_str());						//open the slide file
  	if (slide == NULL) {											//if the slide wasn't opened
  		throw std::runtime_error("ERROR: unable to open file");
  	}
  }
  void closeSlide() {
  	openslide_close(slide);											//close the slide file
  }
  //this function displays details about the specified image
  void dispDetails() {
  	std::cout << "OpenSlide version: " << openslide_get_version() << std::endl;
  	openSlide();
  	std::cout << "Details for slide file: " << infile << std::endl;
  	int32_t levels = openslide_get_level_count(slide);
  	int64_t w, h;
  	std::cout << "level sizes (in pixels):" << std::endl;
  	std::cout << "-------------------------------------" << std::endl;
  	for (int32_t l = 0; l < levels; l++) {
  		std::cout << "level " << l;
  		openslide_get_level_dimensions(slide, l, &w, &h);
  		std::cout << " [" << w << " x " << h << "]" << std::endl;
  	}
  	closeSlide();
  }
  
  void addArguments() {
  	args.add("help", "prints this help");
  	args.add("level", "specify the level to output", "", "integer value between 0 and max");
  	args.add("region", "region to save", "", "x-pos y-pos x-size y-size");
  }
  
  void readArguments() {
  
  	if (args.nargs() > 0) infile = args.arg(0);						//store the file name
  
  	if (args.nargs() > 1) outfile = args.arg(1);					//store the output file name
  
  	if (args["level"]) {
  		level = args["level"].as_int();								//store the desired level to extract
  	}
  	else {															//if the desired level isn't set, default to the smallest resolution image
  		openSlide();
  		int32_t levels = openslide_get_level_count(slide);
  		level = levels - 1;
  		closeSlide();
  	}
  	if (args["region"]) {
  		if (args["region"].nargs() == 4) {
  			x = args["region"].as_int(0);
  			y = args["region"].as_int(1);
  			sx = args["region"].as_int(2);
  			sy = args["region"].as_int(3);
  		}
  		else {
  			throw std::runtime_error("ERROR: --region requires 4 parameters");
  		}
  	}
  	else {
  		openSlide();
  		openslide_get_level_dimensions(slide, level, &sx, &sy);
  		closeSlide();
  	}
  }
  
  int main(int argc, char** argv) {
  	addArguments();
  	args.parse(argc, argv);
  	readArguments();
  	if (args.nargs() == 0 || args["help"]) {	//if the user requests help or doesn't do anything, show usage
  		std::cout << "OpenSlide version: " << openslide_get_version() << std::endl;
  		std::cout << "Usage----------------" << std::endl;
  		std::cout << "save the full image at the lowest resolution:  slideconvert slidefile.ndpi output.bmp" << std::endl;
  		std::cout << "save the level-3 (3x downsampling) image:      slideconvert slidefile.ndpi output.bmp --level 3" << std::endl;
  		std::cout << "save a 1024x1024 region at full-resolution:    slideconvert slidefile.ndpi output.bmp --level 0 --region 10000 15000 1024 1024" << std::endl;
  		std::cout << args.str();				//if no arguments are provided, show usage
  		return 0;
  	}
  	else if (args.nargs() == 1) {				//if one argument is provided, display file information
  		dispDetails();
  		return 0;
  	}
  	else if (args.nargs() == 2) {				//if two arguments are provided, save the specified region
  		openSlide();
  		cv::Mat I(sy, sx, CV_8UC4);				//allocate an OpenCV image array
  		openslide_read_region(slide, (uint32_t*)I.data, x, y, level, sx, sy);
  		cv::imwrite(outfile, I);
  		closeSlide();
  	}
  }