Commit cfcf8619cd41c304224aba9a870cbe4b10d51d36
1 parent
a60b7829
changes to filename and image to allow native loading and saving of Netpbm files
Showing
2 changed files
with
86 additions
and
1 deletions
Show diff stats
stim/image/image.h
... | ... | @@ -7,6 +7,7 @@ |
7 | 7 | #include <iostream> |
8 | 8 | #include <limits> |
9 | 9 | #include <typeinfo> |
10 | +#include <fstream> | |
10 | 11 | |
11 | 12 | namespace stim{ |
12 | 13 | /// This static class provides the STIM interface for loading, saving, and storing 2D images. |
... | ... | @@ -18,7 +19,7 @@ template <class T> |
18 | 19 | class image{ |
19 | 20 | |
20 | 21 | //cimg_library::CImg<T> img; |
21 | - T* img; //pointer to the image data (assumes RGB for loading/saving) | |
22 | + T* img; //pointer to the image data (interleaved RGB for color) | |
22 | 23 | size_t R[3]; |
23 | 24 | |
24 | 25 | size_t X() const { return R[1]; } |
... | ... | @@ -151,6 +152,57 @@ public: |
151 | 152 | return *this; |
152 | 153 | } |
153 | 154 | |
155 | + //save a Netpbm file | |
156 | + void load_netpbm(std::string filename) { | |
157 | + std::ifstream infile(filename, std::ios::in | std::ios::binary); //open an output file | |
158 | + if (!infile) { | |
159 | + std::cout << "Error opening input file in image::load_netpbm()" << std::endl; | |
160 | + exit(1); | |
161 | + } | |
162 | + if (sizeof(T) != 1) { | |
163 | + std::cout << "Error in image::load_netpbm() - data type must be 8-bit integer." << std::endl; | |
164 | + exit(1); | |
165 | + } | |
166 | + | |
167 | + size_t c; //allocate space for the number of channels | |
168 | + unsigned char format[2]; //allocate space to hold the image format tag | |
169 | + infile.read(format, 2); //read the image format tag | |
170 | + infile.seekg(1); //skip the newline character | |
171 | + | |
172 | + if (format[0] != 'P') { | |
173 | + std::cout << "Error in image::load_netpbm() - file format tag is invalid: " << format[0] << format[1] << std::endl; | |
174 | + exit(1); | |
175 | + } | |
176 | + if (format[1] == '5') c = 1; //get the number of channels from the format flag | |
177 | + else if (format[1] == '6') c = 3; | |
178 | + else { | |
179 | + std::cout << "Error in image::load_netpbm() - file format tag is invalid: " << format[0] << format[1] << std::endl; | |
180 | + exit(1); | |
181 | + } | |
182 | + std::string sw; //create a string to store the width of the image | |
183 | + unsigned char c; | |
184 | + while(true){ | |
185 | + c = infile.get(); //get a single character | |
186 | + if (c == ' ') break; //exit if we've encountered a space | |
187 | + sw.push_back(c); //push the character on to the string | |
188 | + } | |
189 | + size_t w = atoi(sw.c_str()); //convert the string into an integer | |
190 | + | |
191 | + std::string sh; | |
192 | + while (true) { | |
193 | + c = infile.get(); | |
194 | + if (c == 0x0A) break; | |
195 | + sh.push_back(c); | |
196 | + } | |
197 | + size_t h = atoi(ah.c_str()); //convert the string into an integer | |
198 | + | |
199 | + allocate(w, h, c); //allocate space for the image | |
200 | + infile.read(img, size()); //copy the binary data from the file to the image | |
201 | + infile.close(); | |
202 | + } | |
203 | + | |
204 | + | |
205 | + | |
154 | 206 | /// Load an image from a file |
155 | 207 | void load(std::string filename){ |
156 | 208 | |
... | ... | @@ -185,6 +237,30 @@ public: |
185 | 237 | } |
186 | 238 | } |
187 | 239 | |
240 | + //save a Netpbm file | |
241 | + void save_netpbm(std::string filename) { | |
242 | + std::ofstream outfile(filename, std::ios::out | std::ios::binary); //open an output file | |
243 | + if(!outfile) { | |
244 | + std::cout << "Error generating output file in image::save_netpbm()" << std::endl; | |
245 | + exit(1); | |
246 | + } | |
247 | + if (sizeof(T) != 1) { | |
248 | + std::cout << "Error in image::save_netpbm() - data type must be 8-bit integer." << std::endl; | |
249 | + exit(1); | |
250 | + } | |
251 | + std::string format; | |
252 | + if (channels() == 1) outfile << "P5" << (char)0x0A; //output P5 if the file is grayscale | |
253 | + else if (channels() == 3) outfile << "P6" << (char)0x0A; //output P6 if the file is color | |
254 | + else { | |
255 | + std::cout << "Error in image::save_netpbm() - data must be grayscale or RGB." << std::endl; | |
256 | + exit(1); | |
257 | + } | |
258 | + outfile << width() << " " << height() << (char)0x0A; //save the width and height | |
259 | + outfile << "255" << (char)0x0A; //output the maximum value | |
260 | + outfile.write((const char*)img, size()); //write the binary data | |
261 | + outfile.close(); | |
262 | + } | |
263 | + | |
188 | 264 | //save a file |
189 | 265 | void save(std::string filename){ |
190 | 266 | //OpenCV uses an interleaved format, so convert first and then output | ... | ... |
stim/parser/filename.h
... | ... | @@ -302,6 +302,15 @@ public: |
302 | 302 | return insert(ss.str()); |
303 | 303 | } |
304 | 304 | |
305 | + ///This method returns true if any characters in the filename contain '*' or '?' | |
306 | + bool wildcards() { | |
307 | + if (_prefix.find('*') != std::string::npos) return true; | |
308 | + if (_prefix.find('?') != std::string::npos) return true; | |
309 | + if (_extension.find('*') != std::string::npos) return true; | |
310 | + if (_extension.find('?') != std::string::npos) return true; | |
311 | + return false; | |
312 | + } | |
313 | + | |
305 | 314 | |
306 | 315 | /// Returns a list of files using the current filename as a template. |
307 | 316 | /// For example: | ... | ... |