Commit 2dec3dbb10bd77994f033023d5790a616e417efa

Authored by Tianshu Cheng
2 parents 6d30a707 3033b886

Merge branch 'master' of git.stim.ee.uh.edu:codebase/stimlib

@@ -1005,29 +1005,55 @@ public: @@ -1005,29 +1005,55 @@ public:
1005 /// @param y0 is the lower-left y pixel coordinate to be included in the cropped image 1005 /// @param y0 is the lower-left y pixel coordinate to be included in the cropped image
1006 /// @param x1 is the upper-right x pixel coordinate to be included in the cropped image 1006 /// @param x1 is the upper-right x pixel coordinate to be included in the cropped image
1007 /// @param y1 is the upper-right y pixel coordinate to be included in the cropped image 1007 /// @param y1 is the upper-right y pixel coordinate to be included in the cropped image
1008 - bool crop(std::string outfile, unsigned x0, unsigned y0, unsigned x1, unsigned y1){  
1009 -  
1010 - //calculate the new number of samples and lines  
1011 - unsigned long long sam = x1 - x0; //samples  
1012 - unsigned long long lin = y1 - y0; //lines  
1013 - unsigned long long L = sam * Z() * sizeof(T);  
1014 - //get specified band and save  
1015 - T* temp = (T*)malloc(L); 1008 + bool crop(std::string outfile, unsigned long long x0,
  1009 + unsigned long long y0,
  1010 + unsigned long long x1,
  1011 + unsigned long long y1,
  1012 + unsigned long long b0,
  1013 + unsigned long long b1){
  1014 +
  1015 + //calculate the new image parameters
  1016 + unsigned long long samples = x1 - x0;
  1017 + unsigned long long lines = y1 - y0;
  1018 + unsigned long long bands = b1 - b0;
  1019 +
  1020 + //calculate the size of a line
  1021 + unsigned long long L = samples * sizeof(T);
  1022 +
  1023 +
  1024 + //allocate space for a line
  1025 + T* temp = (T*)malloc(bands * L);
  1026 +
  1027 + //create an output stream to store the cropped file
1016 std::ofstream out(outfile.c_str(), std::ios::binary); 1028 std::ofstream out(outfile.c_str(), std::ios::binary);
1017 - unsigned long long jumpb = (X() - sam) * sizeof(T); //jump pointer to the next band  
1018 - //get start  
1019 - file.seekg((y0 * X() * Z() + x0) * sizeof(T), std::ios::beg);  
1020 - for (unsigned i = 0; i < lin; i++) 1029 +
  1030 + //calculate the distance between bands
  1031 + unsigned long long jumpb = (X() - samples) * sizeof(T);
  1032 +
  1033 + //distance needed to jump from the previous line of the last band to the next line of the first band
  1034 + unsigned long long longjump = ((Z() - b1) * X() + b0 * X()) * sizeof(T);
  1035 +
  1036 + //set the start position for the cropped region
  1037 + file.seekg((y0 * X() * Z() + b0 * X() + x0) * sizeof(T), std::ios::beg);
  1038 +
  1039 + for (unsigned x = 0; x < lines; x++)
1021 { 1040 {
1022 - for (unsigned j = 0; j < Z(); j++) 1041 + for (unsigned z = b0; z < b1; z++)
1023 { 1042 {
1024 - file.read((char *)(temp + j * sam), sizeof(T) * sam); 1043 + file.read((char *)(temp + z * samples), sizeof(T) * samples);
1025 file.seekg(jumpb, std::ios::cur); //go to the next band 1044 file.seekg(jumpb, std::ios::cur); //go to the next band
1026 1045
1027 - thread_data = (double)(i * Z() + j) / (lin * Z()) * 100; 1046 + thread_data = (double)(x * Z() + z) / (lines * Z()) * 100;
1028 } 1047 }
1029 - out.write(reinterpret_cast<const char*>(temp), L); //write slice data into target file 1048 +
  1049 + //write slice data into target file
  1050 + out.write(reinterpret_cast<const char*>(temp), bands * L);
  1051 +
  1052 + //seek to the beginning of the next X-Z slice
  1053 + file.seekg(longjump, std::ios::cur);
1030 } 1054 }
  1055 +
  1056 + //free the temporary frame
1031 free(temp); 1057 free(temp);
1032 1058
1033 thread_data = 100; 1059 thread_data = 100;
@@ -1061,26 +1061,57 @@ public: @@ -1061,26 +1061,57 @@ public:
1061 /// @param y0 is the lower-left y pixel coordinate to be included in the cropped image 1061 /// @param y0 is the lower-left y pixel coordinate to be included in the cropped image
1062 /// @param x1 is the upper-right x pixel coordinate to be included in the cropped image 1062 /// @param x1 is the upper-right x pixel coordinate to be included in the cropped image
1063 /// @param y1 is the upper-right y pixel coordinate to be included in the cropped image 1063 /// @param y1 is the upper-right y pixel coordinate to be included in the cropped image
1064 - bool crop(std::string outfile, unsigned x0, unsigned y0, unsigned x1, unsigned y1){ 1064 + bool crop(std::string outfile, unsigned long long x0,
  1065 + unsigned long long y0,
  1066 + unsigned long long x1,
  1067 + unsigned long long y1,
  1068 + unsigned long long b0,
  1069 + unsigned long long b1){
1065 1070
1066 - //calculate the new number of samples and lines  
1067 - unsigned long long sam = x1 - x0; //samples  
1068 - unsigned long long lin = y1 - y0; //lines  
1069 - unsigned long long L = Z() * sizeof(T);  
1070 - //get specified band and save 1071 + //calculate the new number of samples, lines, and bands
  1072 + unsigned long long samples = x1 - x0;
  1073 + unsigned long long lines = y1 - y0;
  1074 + unsigned long long bands = b1 - b0;
  1075 +
  1076 + //calculate the length of one cropped spectrum
  1077 + unsigned long long L = bands * sizeof(T);
  1078 +
  1079 + //unsigned long long L = Z() * sizeof(T);
  1080 +
  1081 + //allocate space for the spectrum
1071 T* temp = (T*)malloc(L); 1082 T* temp = (T*)malloc(L);
  1083 +
  1084 + //open an output file for binary writing
1072 std::ofstream out(outfile.c_str(), std::ios::binary); 1085 std::ofstream out(outfile.c_str(), std::ios::binary);
1073 - //get start  
1074 - unsigned long long sp = y0 * X() + x0; //start pixel  
1075 - for (unsigned i = 0; i < lin; i++) 1086 +
  1087 + //seek to the first pixel in the cropped image
  1088 + file.seekg( (y0 * X() * Z() + x0 * Z() + b0) * sizeof(T), std::ios::beg);
  1089 +
  1090 + //distance between sample spectra in the same line
  1091 + unsigned long long jump_sample = ( (Z() - b1) + b0 ) * sizeof(T);
  1092 +
  1093 + //distance between sample spectra in adjacent lines
  1094 + unsigned long long jump_line = (X() - x1) * Z() * sizeof(T);
  1095 +
  1096 +
  1097 + //unsigned long long sp = y0 * X() + x0; //start pixel
  1098 +
  1099 + //for each pixel in the image
  1100 + for (unsigned y = 0; y < lines; y++)
1076 { 1101 {
1077 - for (unsigned j = 0; j < sam; j++) 1102 + for (unsigned x = 0; x < samples; x++)
1078 { 1103 {
1079 - pixel(temp, sp + j + i * X()); 1104 + //read the cropped spectral region
  1105 + file.read( (char*) temp, L );
  1106 + //pixel(temp, sp + x + y * X());
1080 out.write(reinterpret_cast<const char*>(temp), L); //write slice data into target file 1107 out.write(reinterpret_cast<const char*>(temp), L); //write slice data into target file
1081 1108
1082 - thread_data = (double)(i * sam + j) / (lin * sam) * 100; 1109 + file.seekg(jump_sample, std::ios::cur);
  1110 +
  1111 + thread_data = (double)(y * samples + x) / (lines * samples) * 100;
1083 } 1112 }
  1113 +
  1114 + file.seekg(jump_line, std::ios::cur);
1084 } 1115 }
1085 free(temp); 1116 free(temp);
1086 1117
@@ -968,27 +968,45 @@ public: @@ -968,27 +968,45 @@ public:
968 /// @param y0 is the lower-left y pixel coordinate to be included in the cropped image 968 /// @param y0 is the lower-left y pixel coordinate to be included in the cropped image
969 /// @param x1 is the upper-right x pixel coordinate to be included in the cropped image 969 /// @param x1 is the upper-right x pixel coordinate to be included in the cropped image
970 /// @param y1 is the upper-right y pixel coordinate to be included in the cropped image 970 /// @param y1 is the upper-right y pixel coordinate to be included in the cropped image
971 - bool crop(std::string outfile, unsigned x0, unsigned y0, unsigned x1, unsigned y1){  
972 -  
973 - //calculate the new number of samples and lines  
974 - unsigned long long sam = x1 - x0; //samples  
975 - unsigned long long lin = y1 - y0; //lines  
976 - unsigned long long L = sam * lin * sizeof(T);  
977 - //get specified band and save 971 + bool crop(std::string outfile, unsigned long long x0,
  972 + unsigned long long y0,
  973 + unsigned long long x1,
  974 + unsigned long long y1,
  975 + unsigned long long b0,
  976 + unsigned long long b1){
  977 +
  978 + //calculate the new number of samples, lines, and bands
  979 + unsigned long long samples = x1 - x0;
  980 + unsigned long long lines = y1 - y0;
  981 + unsigned long long bands = b1 - b0;
  982 +
  983 + //calculate the size of a single band
  984 + unsigned long long L = samples * lines * sizeof(T);
  985 +
  986 + //allocate space for a single band
978 T* temp = (T*)malloc(L); 987 T* temp = (T*)malloc(L);
  988 +
  989 + //create an output stream to store the output file
979 std::ofstream out(outfile.c_str(), std::ios::binary); 990 std::ofstream out(outfile.c_str(), std::ios::binary);
980 - unsigned long long jumpb = X() * (Y() - lin) * sizeof(T); //jump pointer to the next band  
981 - unsigned long long jumpl = (X() - sam) * sizeof(T); //jump pointer to the next line  
982 - //get start  
983 - file.seekg((y0 * X() + x0) * sizeof(T), std::ios::beg);  
984 - for (unsigned z = 0; z < Z(); z++) 991 +
  992 + //calculate the distance required to jump from the end of one band to the beginning of another
  993 + unsigned long long jumpb = X() * (Y() - lines) * sizeof(T);
  994 +
  995 + //calculate the distance required to jump from the end of one line to the beginning of another
  996 + unsigned long long jumpl = (X() - samples) * sizeof(T);
  997 +
  998 + //seek to the start of the cropped region in the input file
  999 + file.seekg( (b0 * X() * Y() + y0 * X() + x0) * sizeof(T), std::ios::beg);
  1000 +
  1001 + //for each band
  1002 + for (unsigned long long z = b0; z < b1; z++)
985 { 1003 {
986 - for (unsigned j = 0; j < lin; j++) 1004 + for (unsigned y = 0; y < lines; y++)
987 { 1005 {
988 - file.read((char *)(temp + j * sam), sizeof(T) * sam); 1006 + file.read((char *)(temp + y * samples), sizeof(T) * samples);
989 file.seekg(jumpl, std::ios::cur); //go to the next band 1007 file.seekg(jumpl, std::ios::cur); //go to the next band
990 1008
991 - thread_data = (double)(z * lin + j) / (Z() * lin) * 100; 1009 + thread_data = (double)(z * lines + y) / (Z() * lines) * 100;
992 } 1010 }
993 out.write(reinterpret_cast<const char*>(temp), L); //write slice data into target file 1011 out.write(reinterpret_cast<const char*>(temp), L); //write slice data into target file
994 file.seekg(jumpb, std::ios::cur); 1012 file.seekg(jumpb, std::ios::cur);
@@ -1022,13 +1022,23 @@ public: @@ -1022,13 +1022,23 @@ public:
1022 /// @param y0 is the lower-left y pixel coordinate to be included in the cropped image 1022 /// @param y0 is the lower-left y pixel coordinate to be included in the cropped image
1023 /// @param x1 is the upper-right x pixel coordinate to be included in the cropped image 1023 /// @param x1 is the upper-right x pixel coordinate to be included in the cropped image
1024 /// @param y1 is the upper-right y pixel coordinate to be included in the cropped image 1024 /// @param y1 is the upper-right y pixel coordinate to be included in the cropped image
1025 - bool crop(std::string outfile,unsigned x0, unsigned y0, unsigned x1, unsigned y1){ 1025 + bool crop(std::string outfile,unsigned x0, unsigned y0, unsigned x1, unsigned y1, unsigned b0, unsigned b1){
  1026 +
  1027 + //save the header for the cropped file
  1028 + stim::envi_header new_header = header;
  1029 + new_header.samples = x1 - x0;
  1030 + new_header.lines = y1 - y0;
  1031 + new_header.bands = b1 - b0;
  1032 + std::vector<double>::const_iterator first = new_header.wavelength.begin() + b0;
  1033 + std::vector<double>::const_iterator last = new_header.wavelength.begin() + b1;
  1034 + new_header.wavelength = std::vector<double>(first, last);
  1035 + new_header.save(outfile + ".hdr");
1026 1036
1027 if (header.interleave == envi_header::BSQ){ 1037 if (header.interleave == envi_header::BSQ){
1028 if (header.data_type == envi_header::float32) 1038 if (header.data_type == envi_header::float32)
1029 - return ((bsq<float>*)file)->crop(outfile, x0, y0, x1, y1); 1039 + return ((bsq<float>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1);
1030 else if (header.data_type == envi_header::float64) 1040 else if (header.data_type == envi_header::float64)
1031 - return ((bsq<double>*)file)->crop(outfile, x0, y0, x1, y1); 1041 + return ((bsq<double>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1);
1032 else{ 1042 else{
1033 std::cout << "ERROR: unidentified data type" << std::endl; 1043 std::cout << "ERROR: unidentified data type" << std::endl;
1034 exit(1); 1044 exit(1);
@@ -1036,9 +1046,9 @@ public: @@ -1036,9 +1046,9 @@ public:
1036 } 1046 }
1037 else if (header.interleave == envi_header::BIL){ 1047 else if (header.interleave == envi_header::BIL){
1038 if (header.data_type == envi_header::float32) 1048 if (header.data_type == envi_header::float32)
1039 - return ((bil<float>*)file)->crop(outfile, x0, y0, x1, y1); 1049 + return ((bil<float>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1);
1040 else if (header.data_type == envi_header::float64) 1050 else if (header.data_type == envi_header::float64)
1041 - return ((bil<double>*)file)->crop(outfile, x0, y0, x1, y1); 1051 + return ((bil<double>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1);
1042 else{ 1052 else{
1043 std::cout << "ERROR: unidentified data type" << std::endl; 1053 std::cout << "ERROR: unidentified data type" << std::endl;
1044 exit(1); 1054 exit(1);
@@ -1046,9 +1056,9 @@ public: @@ -1046,9 +1056,9 @@ public:
1046 } 1056 }
1047 else if (header.interleave == envi_header::BIP){ 1057 else if (header.interleave == envi_header::BIP){
1048 if (header.data_type == envi_header::float32) 1058 if (header.data_type == envi_header::float32)
1049 - return ((bip<float>*)file)->crop(outfile, x0, y0, x1, y1); 1059 + return ((bip<float>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1);
1050 else if (header.data_type == envi_header::float64) 1060 else if (header.data_type == envi_header::float64)
1051 - return ((bip<double>*)file)->crop(outfile, x0, y0, x1, y1); 1061 + return ((bip<double>*)file)->crop(outfile, x0, y0, x1, y1, b0, b1);
1052 else{ 1062 else{
1053 std::cout << "ERROR: unidentified data type" << std::endl; 1063 std::cout << "ERROR: unidentified data type" << std::endl;
1054 exit(1); 1064 exit(1);
stim/parser/arguments.h
@@ -479,6 +479,14 @@ namespace stim{ @@ -479,6 +479,14 @@ namespace stim{
479 return args.size(); 479 return args.size();
480 } 480 }
481 481
  482 + /// Returns the number of options that are set
  483 + unsigned int nopts(){
  484 + unsigned int n = 0; //initialize the counter for the number of options
  485 + for(unsigned int i = 0; i < opts.size(); i++) //go through each option
  486 + if(opts[i].is_set()) n++; //if a value is specified, increment the counter
  487 + return n;
  488 + }
  489 +
482 ///Returns the name of an argument, given its index 490 ///Returns the name of an argument, given its index
483 491
484 /// @param a is the index of the requested argument 492 /// @param a is the index of the requested argument