From cfcf8619cd41c304224aba9a870cbe4b10d51d36 Mon Sep 17 00:00:00 2001 From: David Date: Wed, 5 Oct 2016 15:12:17 -0500 Subject: [PATCH] changes to filename and image to allow native loading and saving of Netpbm files --- stim/image/image.h | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- stim/parser/filename.h | 9 +++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/stim/image/image.h b/stim/image/image.h index 394551c..9a85584 100644 --- a/stim/image/image.h +++ b/stim/image/image.h @@ -7,6 +7,7 @@ #include #include #include +#include namespace stim{ /// This static class provides the STIM interface for loading, saving, and storing 2D images. @@ -18,7 +19,7 @@ template class image{ //cimg_library::CImg img; - T* img; //pointer to the image data (assumes RGB for loading/saving) + T* img; //pointer to the image data (interleaved RGB for color) size_t R[3]; size_t X() const { return R[1]; } @@ -151,6 +152,57 @@ public: return *this; } + //save a Netpbm file + void load_netpbm(std::string filename) { + std::ifstream infile(filename, std::ios::in | std::ios::binary); //open an output file + if (!infile) { + std::cout << "Error opening input file in image::load_netpbm()" << std::endl; + exit(1); + } + if (sizeof(T) != 1) { + std::cout << "Error in image::load_netpbm() - data type must be 8-bit integer." << std::endl; + exit(1); + } + + size_t c; //allocate space for the number of channels + unsigned char format[2]; //allocate space to hold the image format tag + infile.read(format, 2); //read the image format tag + infile.seekg(1); //skip the newline character + + if (format[0] != 'P') { + std::cout << "Error in image::load_netpbm() - file format tag is invalid: " << format[0] << format[1] << std::endl; + exit(1); + } + if (format[1] == '5') c = 1; //get the number of channels from the format flag + else if (format[1] == '6') c = 3; + else { + std::cout << "Error in image::load_netpbm() - file format tag is invalid: " << format[0] << format[1] << std::endl; + exit(1); + } + std::string sw; //create a string to store the width of the image + unsigned char c; + while(true){ + c = infile.get(); //get a single character + if (c == ' ') break; //exit if we've encountered a space + sw.push_back(c); //push the character on to the string + } + size_t w = atoi(sw.c_str()); //convert the string into an integer + + std::string sh; + while (true) { + c = infile.get(); + if (c == 0x0A) break; + sh.push_back(c); + } + size_t h = atoi(ah.c_str()); //convert the string into an integer + + allocate(w, h, c); //allocate space for the image + infile.read(img, size()); //copy the binary data from the file to the image + infile.close(); + } + + + /// Load an image from a file void load(std::string filename){ @@ -185,6 +237,30 @@ public: } } + //save a Netpbm file + void save_netpbm(std::string filename) { + std::ofstream outfile(filename, std::ios::out | std::ios::binary); //open an output file + if(!outfile) { + std::cout << "Error generating output file in image::save_netpbm()" << std::endl; + exit(1); + } + if (sizeof(T) != 1) { + std::cout << "Error in image::save_netpbm() - data type must be 8-bit integer." << std::endl; + exit(1); + } + std::string format; + if (channels() == 1) outfile << "P5" << (char)0x0A; //output P5 if the file is grayscale + else if (channels() == 3) outfile << "P6" << (char)0x0A; //output P6 if the file is color + else { + std::cout << "Error in image::save_netpbm() - data must be grayscale or RGB." << std::endl; + exit(1); + } + outfile << width() << " " << height() << (char)0x0A; //save the width and height + outfile << "255" << (char)0x0A; //output the maximum value + outfile.write((const char*)img, size()); //write the binary data + outfile.close(); + } + //save a file void save(std::string filename){ //OpenCV uses an interleaved format, so convert first and then output diff --git a/stim/parser/filename.h b/stim/parser/filename.h index 0f9bfd5..9987c22 100644 --- a/stim/parser/filename.h +++ b/stim/parser/filename.h @@ -302,6 +302,15 @@ public: return insert(ss.str()); } + ///This method returns true if any characters in the filename contain '*' or '?' + bool wildcards() { + if (_prefix.find('*') != std::string::npos) return true; + if (_prefix.find('?') != std::string::npos) return true; + if (_extension.find('*') != std::string::npos) return true; + if (_extension.find('?') != std::string::npos) return true; + return false; + } + /// Returns a list of files using the current filename as a template. /// For example: -- libgit2 0.21.4