Browse Source

Add .rawls save and comments extraction

Jérôme BUISINE 5 months ago
parent
commit
67d75a1307
4 changed files with 125 additions and 9 deletions
  1. 8 0
      README.md
  2. 16 9
      main/rawls_merge.cpp
  3. 94 0
      rawls/rawls.cpp
  4. 7 0
      rawls/rawls.h

+ 8 - 0
README.md

@@ -25,7 +25,15 @@ cd build && cmake ..
 make 
 ```
 
+### Examples:
+
 Convert the `.rawls` image format into `.ppm` 
 ```
 ./main/rawls_reader --image ../path/to/image.rawls --outfile image.ppm
+```
+
+
+Merge `.rawls` images samples
+```
+./main/rawls_merge --folder ../path/to/images --samples 100 --random 0 --outfile image.png
 ```

+ 16 - 9
main/rawls_merge.cpp

@@ -10,7 +10,7 @@
 
 
 void writeProgress(float progress){
-    int barWidth = 70;
+    int barWidth = 200;
 
     std::cout << "[";
     int pos = barWidth * progress;
@@ -44,8 +44,12 @@ int main(int argc, char *argv[]){
 
     std::vector<std::string> imagesPath;
 
-    for (const auto & entry : std::filesystem::directory_iterator(folderName))
-        imagesPath.push_back(entry.path().string());
+    for (const auto & entry : std::filesystem::directory_iterator(folderName)){
+        std::string imageName = entry.path().string();
+        if (rawls::HasExtension(imageName, ".rawls") || rawls::HasExtension(imageName, ".rawls_20")){
+            imagesPath.push_back(imageName);
+        }
+    }
 
     // sort or shuffle the images path
     if (!random){
@@ -53,7 +57,7 @@ int main(int argc, char *argv[]){
     }else{
         std::random_shuffle(imagesPath.begin(), imagesPath.end());
     }
-    
+
     // check nSamples
     if (nbSamples > imagesPath.size()){
         nbSamples = imagesPath.size();
@@ -110,7 +114,8 @@ int main(int argc, char *argv[]){
 
         delete buffer;
     }
-        
+    
+    writeProgress(1.);
     std::cout << std::endl;
 
     // mean all samples values by number of samples used
@@ -125,10 +130,12 @@ int main(int argc, char *argv[]){
     else if (rawls::HasExtension(outfileName, ".png")){
         rawls::saveAsPNG(width, height, nbChanels, outputBuffer, outfileName);
     } 
-    else if (rawls::HasExtension(outfileName, ".rawls")){
-        // TODO
-        //rawls::saveAsPNG(width, height, nbChanels, outputBuffer, outfileName);
-        std::cout << "Saved as rawls is not yet implemented" << std::endl;
+    else if (rawls::HasExtension(outfileName, ".rawls") || rawls::HasExtension(outfileName, ".rawls_20")){
+        // need to get comments from an image
+        std::string comments = rawls::getCommentsRAWLS(imagesPath.at(0));
+
+        // Here no gamma conversion is done, only mean of samples
+        rawls::saveAsRAWLS(width, height, nbChanels, comments, outputBuffer, outfileName);
     } 
     else{
         std::cout << "Unexpected output extension image" << std::endl;

+ 94 - 0
rawls/rawls.cpp

@@ -120,6 +120,57 @@ bool rawls::saveAsPNG(unsigned width, unsigned height, unsigned nbChanels, float
 }
 
 
+bool rawls::saveAsRAWLS(unsigned width, unsigned height, unsigned nbChanels, std::string comments, float* buffer, std::string outfileName){
+    
+    std::ofstream outfile(outfileName, std::ios::out | std::ios::binary);
+
+    outfile << "IHDR" << std::endl;
+    outfile << ((sizeof(width) + sizeof(height) + sizeof(nbChanels)))  << std::endl;
+    outfile.write((char *) &width, sizeof(width));
+    outfile << " ";
+    outfile.write((char *) &height, sizeof(height));
+    outfile << " ";
+    outfile.write((char *) &nbChanels, sizeof(nbChanels));
+    outfile << std::endl;
+
+    // Part 2
+    // Comments (usefull information about scene and generation data used)
+    outfile << "COMMENTS" << std::endl;
+    outfile << comments;
+    
+    // Part 3
+    // using data information write specific chunck
+    outfile << "DATA" << std::endl;
+    outfile << (sizeof(float) * nbChanels * width * height) << std::endl;
+
+    for (int y = 0; y < height; ++y) {
+        for (int x = 0; x < width; ++x) {
+            float pixel[3];
+
+            pixel[0] = buffer[3 * (y * width + x) + 0];
+            pixel[1] = buffer[3 * (y * width + x) + 1];
+            pixel[2] = buffer[3 * (y * width + x) + 2];
+            
+            outfile.write((char *) &pixel[0], sizeof(pixel[0]));
+            outfile.write((char *) &pixel[1], sizeof(pixel[1]));
+            outfile.write((char *) &pixel[2], sizeof(pixel[2]));
+            outfile << std::endl;
+        }
+    }
+
+    outfile.close();
+    
+    if(!outfile.good()) {
+        std::cout << "Error occurred at writing time!" << std::endl;
+        return false;
+    }
+
+    std::cout << "Image is now saved as .rawls into " << outfileName << std::endl;
+
+    return true;
+}
+
+
 float* rawls::getPixelsRAWLS(std::string filename){
 
     // get dimensions information from image
@@ -294,4 +345,47 @@ std::tuple<unsigned, unsigned, unsigned, float*> rawls::getDataRAWLS(std::string
     }
 
     return std::make_tuple(width, height, nbChanels, buffer);
+}
+
+std::string rawls::getCommentsRAWLS(std::string filename){
+
+    std::string comments;
+
+    // only one read buffer used for the whole function
+    std::ifstream rf(filename, std::ios::out | std::ios::binary);
+
+    if(!rf) {
+      std::cout << "Cannot open file!" << std::endl;
+    }
+
+    std::string line; 
+    unsigned nbChanels, width, height;
+    char c; // to get space of new line char
+
+    // READ IHDR info
+    bool commentsBegin = false;
+
+    while (!commentsBegin && std::getline(rf, line)) { 
+
+        if (line.find(std::string("COMMENTS")) != std::string::npos){
+            commentsBegin = true;
+        }
+    }
+
+    bool dataBegin = false;
+
+    // READ DATA info
+    // case of data chunck begin
+    while (!dataBegin && std::getline(rf, line)) { 
+
+        if (line.find(std::string("DATA")) != std::string::npos){
+            dataBegin = true;
+        }
+        else
+        {
+            comments = comments + line + '\n';
+        }
+    }
+
+    return comments;
 }

+ 7 - 0
rawls/rawls.h

@@ -47,6 +47,8 @@ bool saveAsPPM(unsigned width, unsigned height, unsigned nbChanels, float* buffe
 
 bool saveAsPNG(unsigned width, unsigned height, unsigned nbChanels, float* buffer, std::string outfileName);
 
+bool saveAsRAWLS(unsigned width, unsigned height, unsigned nbChanels, std::string comments, float* buffer, std::string outfileName);
+
 /*
  * Read `.rawls` image and fill buffer pass as parameter
  *
@@ -54,6 +56,11 @@ bool saveAsPNG(unsigned width, unsigned height, unsigned nbChanels, float* buffe
  */
 float* getPixelsRAWLS(std::string filename);
 
+/*
+ * Returns comments from `.rawls` format
+ */
+std::string getCommentsRAWLS(std::string filename);
+
 /*
  * Returns tuple with <width, height, channels> information of image
  */