From 6a32ab038a04a46f61d9300497b1d193e749bb0d Mon Sep 17 00:00:00 2001
From: Brandon Rodriguez <brodriguez8774@gmail.com>
Date: Thu, 22 Apr 2021 21:41:05 -0400
Subject: [PATCH] Reorganize class logic into separate files and start logging
 logic

---
 documents/references.md           |   6 +
 part_1/image.cu                   | 260 ++++++++++++++++++---
 part_1/image.h                    | 118 ++++++++--
 part_1/logging.cu                 |  70 ++++++
 part_1/logging.h                  |  56 +++++
 part_1/main.cu                    | 376 ++++--------------------------
 part_1/makefile                   |   2 +-
 part_1/{structs.cu => utility.cu} |  33 ++-
 part_1/{structs.h => utility.h}   |   5 +-
 9 files changed, 552 insertions(+), 374 deletions(-)
 create mode 100644 part_1/logging.cu
 create mode 100644 part_1/logging.h
 rename part_1/{structs.cu => utility.cu} (55%)
 rename part_1/{structs.h => utility.h} (80%)

diff --git a/documents/references.md b/documents/references.md
index 2090fc0..f0f8b86 100644
--- a/documents/references.md
+++ b/documents/references.md
@@ -17,6 +17,7 @@ Various references used in project.
 * Check if path is file or directory - <https://stackoverflow.com/a/43281413>
 * Get file name from path - <https://stackoverflow.com/a/24386991>
 * Path value to string - <https://stackoverflow.com/a/45401869>
+* Get current directory - <https://stackoverflow.com/a/52522000>
 
 #### Folder Management
 * Check if dir exists - <https://stackoverflow.com/a/18101042>
@@ -28,10 +29,15 @@ Various references used in project.
 #### C++ Strings
 * What is a C++ string - <https://stackoverflow.com/a/3535904>
 * String splitting - <https://stackoverflow.com/a/14266139>
+* Getting File/LineNum:
+** <https://stackoverflow.com/a/42135375>
+** <https://stackoverflow.com/a/8884408>
 
 #### C++ Classes
 * General Class Syntax - <https://www.w3schools.com/cpp/cpp_classes.asp>
 * Structs Vs Classes in C++ - <https://stackoverflow.com/a/36917400>
+* Deconstructors - <https://www.geeksforgeeks.org/destructors-c/>
+* Splitting into header files - <https://stackoverflow.com/a/9579974>
 
 #### Type Casting
 <https://en.cppreference.com/w/cpp/language/static_cast>
diff --git a/part_1/image.cu b/part_1/image.cu
index 27d3586..779e780 100644
--- a/part_1/image.cu
+++ b/part_1/image.cu
@@ -1,28 +1,232 @@
-// /**
-//  * File for image handling logic.
-//  */
-
-
-// // User Import Headers.
-// #ifndef user_headers
-//     #define user_headers
-//     #include "image.h"
-// #endif
-
-
-// // Global Variables.
-// class Image {
-
-//     public:
-//         /**
-//          * Base constructor.
-//          */
-//         Image() {
-//             // printf("Constructing Image class.");
-//             std::cout << "Constructing Image class." << std::endl;
-//         }
-
-//         void test_method() {
-//             std::cout << "test_method() aaaa" << std::endl;
-//         }
-// };
+/**
+ * File for image handling logic.
+ */
+
+
+// User Import Headers.
+#ifndef user_headers
+    #define user_headers
+    #include "image.h"
+    #include "utility.h"
+#endif
+
+
+// Global Variables.
+const Image::Rgb Image::pixelBlack = Image::Rgb(0);
+const Image::Rgb Image::pixelWhite = Image::Rgb(1);
+const Image::Rgb Image::pixelRed = Image::Rgb(1,0,0);
+const Image::Rgb Image::pixelGreen = Image::Rgb(0,1,0);
+const Image::Rgb Image::pixelBlue = Image::Rgb(0,0,1);
+const Image::Rgb Image::pixelYellow = Image::Rgb(1,1,0);
+const Image::Rgb Image::pixelPink = Image::Rgb(1,0,1);
+const Image::Rgb Image::pixelLiBlue = Image::Rgb(0,1,1);
+
+
+/**
+ * Calculates class input_path and output_path values.
+ *
+ * :param image_path: Path to an image on the system.
+ */
+void Image::calculate_paths(std::string image_path) {
+    // std::cout << "\n\n\n\n\nCalculating input/output paths..." << std::endl;
+    // std::cout << "image_path: " << image_path << std::endl;
+
+    // // Calculate output path location.
+    output_path = "../output/";
+    std::string base_filename = image_path.substr(image_path.find_last_of("/\\") + 1);
+
+    // Grab directory substrings and generate full output path.
+    size_t pos = 0;
+    std::string token;
+    while ((pos = image_path.find("/")) != std::string::npos) {
+
+        // Pull current substring value from input path.
+        token = image_path.substr(0, image_path.find("/"));
+        // std::cout << "    " << token << std::endl;
+        image_path.erase(0, pos + 1);
+
+        // Check if directory value is value we care about.
+        if ( (token != ".") && (token != "..") && (token != "input") ) {
+            output_path += token + "/";
+        }
+
+        // Check if directory exists.
+        struct stat info;
+        if ( (stat(output_path.c_str(), &info) != 0) || (! info.st_mode & S_IFDIR)) {
+            // Directory does not exist.
+            mkdir(output_path.c_str(), 0777);
+        }
+
+    }
+
+    output_path += base_filename;
+    // std::cout << "output_path: " << output_path << std::endl;
+
+    // std::cout << "Input/output paths calculated.\n\n\n\n\n" << std::endl;
+}
+
+
+/**
+ * Imports image file data, using class variable data.
+ */
+void Image::import_image_file() {
+    // Open input file.
+    std::ifstream input_file;
+    input_file.open(input_path, std::ios::binary | std::ios::in);
+
+    if (! input_file.good()) {
+        // Failed to open file.
+        std::cerr << "Failed to open file \"" + input_path + "\"." << std::endl;
+    } else {
+        // File opened. Grab data.
+        std::string header;
+        input_file >> header;
+        if (strcmp(header.c_str(), "P6") != 0) {
+            throw("Can't read input file");
+        }
+
+        // Save image values to class.
+        input_file >> width >> height >> bit_depth;
+
+        // Create and populate image.
+        // std::cout << "Parsing input image" << std::endl;
+        pixel_arr = new Rgb[width * height];
+
+        // Skip empty lines in necessary until we get to the binary data.
+        input_file.ignore(256, '\n');
+
+        // Read each pixel one by one and convert bytes to floats.
+        unsigned char pix[3];
+        for (int index = 0; index < width * height; ++index) {
+            input_file.read(reinterpret_cast<char *>(pix), 3);
+            pixel_arr[index].r = pix[0] / 255.f;
+            pixel_arr[index].g = pix[1] / 255.f;
+            pixel_arr[index].b = pix[2] / 255.f;
+        }
+    }
+
+    input_file.close();
+}
+
+
+
+//region Constructors.
+
+/**
+ * Base constructor.
+ */
+Image::Image() {
+    // Currently test logic.
+    std::cout << "\nConstructing Image class." << std::endl;
+
+    // Essentially creates a 10x10 pixel test image.
+    input_path = "../input/pbm/400x300/hallway_00.pbm";
+    output_path = "../output/test_00.pbm";
+    width = 10;
+    height = 10;
+    bit_depth = 255;
+    Rgb c = pixelBlack; // Default color. Can select based on below preset colors.
+
+    // Create and populate image.
+    pixel_arr = new Rgb[width * height];
+    for (int index = 0; index < (width * height); index++) {
+        pixel_arr[index] = c;
+    }
+
+    std::cout << "Image class populated." << std::endl;
+}
+
+/**
+ * Constructor that takes input path to image file.
+ * Output path is determined based on parsing input path.
+ */
+Image::Image(std::string user_path) {
+    std::cout << "\nConstructing Image class." << std::endl;
+
+    std::cout << "user_path: " << user_path << std::endl;
+
+    // Re-validate path for saving to class..
+    path_validator_struct* return_struct = validate_path(user_path);
+    int path_type = return_struct->file_type;
+    if (return_struct->err_code) {
+        std::cerr << "Error verifying file type: " << return_struct->err_code.message() << std::endl;
+        return;
+    }
+    free_path_validator_struct(return_struct);
+    if (path_type == TYPE_FILE) {
+        input_path = user_path;
+        calculate_paths(user_path);
+        import_image_file();
+    } else {
+        std::cerr << "Provided path is not to image file. Class initialization failed." << std::endl;
+        return;
+    }
+
+    std::cout << "Image class populated." << std::endl;
+}
+
+//endregion Constructors.
+
+
+//region Public Methods.
+
+/**
+ * Displays general properties of image held in class.
+ */
+void Image::display_properties() {
+    std::cout << std::endl;
+    std::cout << "input file path: " << input_path << std::endl;
+    std::cout << "output file path: " << output_path << std::endl;
+    std::cout << "width: " << width << std::endl;
+    std::cout << "height: " << height << std::endl;
+    std::cout << "bit depth: " << bit_depth << std::endl;
+    std::cout << std::endl;
+}
+
+
+/**
+ * Saves class image data to output file.
+ */
+void Image::save() {
+    std::cout << "Attempting to save image to \"" << output_path << "\"." << std::endl;
+
+    // Open output file stream.
+    std::ofstream output_file;
+
+    // Attempt to save file data.
+    try {
+        // Attempt to open file.
+        output_file.open(output_path, std::ios::binary | std::ios::out);
+
+        // Check if opened successfully.
+        if (output_file.fail()) {
+            // Failed to open.
+            std::cout << "Failed to open file \"" + output_path + "\".\n";
+        } else {
+            // Opened successfully.
+
+            // Write image "header" data.
+            output_file << "P6\n" << width << " " << height << "\n255\n";
+
+            // Write image pixel data.
+            unsigned char r, g, b;
+            for (int index = 0; index < (width * height); index++) {
+                r = static_cast<float>(std::min(1.f, pixel_arr[index].r) * 255);
+                g = static_cast<float>(std::min(1.f, pixel_arr[index].g) * 255);
+                b = static_cast<float>(std::min(1.f, pixel_arr[index].b) * 255);
+                output_file << r << g << b;
+            }
+
+        }
+
+        // Close file stream.
+        output_file.close();
+        std::cout << "Image saved." << std::endl;
+
+    } catch (const char* err) {
+        fprintf(stderr, "%s\n", err);
+        output_file.close();
+    }
+}
+
+//endregion Public Methods.
diff --git a/part_1/image.h b/part_1/image.h
index 6bf20f8..e5ceadc 100644
--- a/part_1/image.h
+++ b/part_1/image.h
@@ -1,21 +1,107 @@
-// /**
-//  * Header file for project image handling logic.
-//  */
+/**
+ * Header file for project image handling logic.
+ */
 
 
-// // System Import Headers.
-// #include <cstdio>
-// #include <cstdlib>
-// #include <cctype>
-// #include <iostream>
-// #include <fstream>
-// #include <string>
+// System Import Headers.
+#include <cstdio>
+#include <cstdlib>
+#include <cctype>
+#include <filesystem>
+#include <fstream>
+#include <iostream>
+#include <iterator>
+#include <string>
+#include <sys/stat.h>
+#include <sys/types.h>
 
 
-// // Global Variables.
-// class Image {
+/**
+ * Class that holds data for a single image.
+ */
+class Image {
 
-//     public:
-//         Image() {}
-//         void test_method() {}
-// };
+    private:
+        /**
+         * Struct to act as a "container" of sorts for each individual rgb pixel.
+         * An array of these creates our entire image.
+         *
+         * According to https://stackoverflow.com/a/36917400, this is basically treated as a sub-class.
+         * This allows creating multiple constructors, which will handle different scenarios of pixel input.
+         */
+        struct Rgb {
+            // Struct variables.
+            float r, g, b;
+
+            /**
+             * Struct constructors.
+             *
+             * First one acts as a "default" that provides black pixels.
+             * When a single float is provided, the second constructor sets all three rgb channels to that value.
+             * Finally, when three floats are provided, the last constructor sets rgb channels accordingly.
+             */
+            Rgb(): r(0), g(0), b(0) {}
+            Rgb(float c): r(c), g(c), b(c) {}
+            Rgb(float _r, float _g, float _b) : r(_r), g(_g), b(_b) {}
+
+        };
+
+        // Private Variables.
+        std::string input_path;
+        std::string output_path;
+        unsigned int width;
+        unsigned int height;
+        int bit_depth;
+        Rgb *pixel_arr;     // Array of pixel data.
+
+        /**
+         * Calculates class input_path and output_path values.
+         *
+         * :param image_path: Path to an image on the system.
+         */
+        void calculate_paths(std::string image_path);
+
+
+        /**
+         * Imports image file data, using class variable data.
+         */
+        void import_image_file();
+
+
+    public:
+        // Public Variables.
+        static const Rgb pixelBlack, pixelWhite, pixelRed, pixelGreen, pixelBlue, pixelYellow, pixelPink, pixelLiBlue;
+
+
+        //region Constructors.
+
+        /**
+         * Base constructor.
+         */
+        Image();
+
+        /**
+         * Constructor that takes input path to image file.
+         * Output path is determined based on parsing input path.
+         */
+        Image(std::string user_path);
+
+        //endregion Constructors.
+
+
+        //region Public Methods.
+
+        /**
+         * Displays general properties of image held in class.
+         */
+        void display_properties();
+
+
+        /**
+         * Saves class image data to output file.
+         */
+        void save();
+
+        //endregion Public Methods.
+
+};
diff --git a/part_1/logging.cu b/part_1/logging.cu
new file mode 100644
index 0000000..74ce6a0
--- /dev/null
+++ b/part_1/logging.cu
@@ -0,0 +1,70 @@
+/**
+ * File for project logging.
+ * Contains actual logic for class defined in logging.h.
+ */
+
+
+// User Import Headers.
+#ifndef user_headers
+    #define user_headers
+    #include "logging.h"
+#endif
+
+
+/**
+ * Class constructor.
+ */
+Logging::Logging() {
+    std::cout << "Initializing logger." << std::endl;
+    std::filesystem::path cwd = std::filesystem::current_path();
+    core_logging_folder = cwd.string() + "/log/";
+    std::cout << "logging_folder: " << core_logging_folder << std::endl;
+
+    // Open file descriptors.
+    error_stream.open(core_logging_folder + "error.log", std::ios::binary | std::ios::out);
+    warn_stream.open(core_logging_folder + "warn.log", std::ios::binary | std::ios::out);
+    info_stream.open(core_logging_folder + "info.log", std::ios::binary | std::ios::out);
+}
+
+/**
+ * Class deconstructor.
+ * Closes file descriptors, if open.
+ */
+Logging::~Logging() {
+    if (info_stream.is_open()) {
+        info_stream.close();
+    }
+    if (warn_stream.is_open()) {
+        warn_stream.close();
+    }
+    if (error_stream.is_open()) {
+        error_stream.close();
+    }
+}
+
+/**
+ * Writes message to info log file.
+ */
+void Logging::info(char const* file, long line_num, std::string msg) {
+    info_stream << msg << std::endl;
+}
+
+/**
+ * Writes message to warning log file.
+ */
+void Logging::warn(char const* file, long line_num, std::string msg) {
+    warn_stream << msg << std::endl;
+
+    // Also write to lower level loggers.
+    info(file, line_num, msg);
+}
+
+/**
+ * Writes message to error log file.
+ */
+void Logging::error(char const* file, long line_num, std::string msg) {
+    error_stream << msg << std::endl;
+
+    // Also write to lower level loggers.
+    warn(file, line_num, msg);
+}
diff --git a/part_1/logging.h b/part_1/logging.h
new file mode 100644
index 0000000..b217519
--- /dev/null
+++ b/part_1/logging.h
@@ -0,0 +1,56 @@
+/**
+ * Header file for project logging.
+ */
+
+
+// System Import Headers.
+#include <cstdio>
+#include <cstdlib>
+#include <cctype>
+#include <iostream>
+#include <filesystem>
+#include <fstream>
+#include <string>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+/**
+ * Logging class definition.
+ */
+class Logging {
+
+    private:
+        std::string core_logging_folder;
+        std::ofstream info_stream;
+        std::ofstream warn_stream;
+        std::ofstream error_stream;
+
+    public:
+        /**
+         * Class constructor.
+         */
+        Logging();
+
+        /**
+         * Class deconstructor.
+         * Closes file descriptors, if open.
+         */
+        ~Logging();
+
+        /**
+         * Writes message to info log file.
+         */
+        void info(char const* file, long line_num, std::string msg);
+
+        /**
+         * Writes message to warning log file.
+         */
+        void warn(char const* file, long line_num, std::string msg);
+
+        /**
+         * Writes message to error log file.
+         */
+        void error(char const* file, long line_num, std::string msg);
+};
+
diff --git a/part_1/main.cu b/part_1/main.cu
index 5889de2..d7950db 100644
--- a/part_1/main.cu
+++ b/part_1/main.cu
@@ -12,20 +12,18 @@
 #include <iostream>
 #include <iterator>
 #include <string>
-#include <sys/stat.h>
-#include <sys/types.h>
 #include <vector>
 
 // User Import Headers.
 #ifndef user_headers
     #define user_headers
-    #include "structs.h"
+    #include "logging.h"
     #include "image.h"
+    #include "utility.h"
 #endif
 
 
 // Method Declaration.
-path_validator_struct* validate_path(std::string path_str);
 void process_dir(std::string path_str);
 void process_file(std::string path_str);
 // void validate_path(char* path_str);
@@ -35,270 +33,6 @@ void process_file(std::string path_str);
 
 // Global Variables.
 
-/**
- * Class that holds data for a single image.
- */
-class Image {
-
-    private:
-        /**
-         * Struct to act as a "container" of sorts for each individual rgb pixel.
-         * An array of these creates our entire image.
-         *
-         * According to https://stackoverflow.com/a/36917400, this is basically treated as a sub-class.
-         * This allows creating multiple constructors, which will handle different scenarios of pixel input.
-         */
-        struct Rgb {
-            // Struct variables.
-            float r, g, b;
-
-            /**
-             * Struct constructors.
-             *
-             * First one acts as a "default" that provides black pixels.
-             * When a single float is provided, the second constructor sets all three rgb channels to that value.
-             * Finally, when three floats are provided, the last constructor sets rgb channels accordingly.
-             */
-            Rgb(): r(0), g(0), b(0) {}
-            Rgb(float c): r(c), g(c), b(c) {}
-            Rgb(float _r, float _g, float _b) : r(_r), g(_g), b(_b) {}
-
-        };
-
-        // Private Variables.
-        std::string input_path;
-        std::string output_path;
-        unsigned int width;
-        unsigned int height;
-        int bit_depth;
-        Rgb *pixel_arr;     // Array of pixel data.
-
-        /**
-         * Calculates class input_path and output_path values.
-         *
-         * :param image_path: Path to an image on the system.
-         */
-        void calculate_paths(std::string image_path) {
-            // std::cout << "\n\n\n\n\nCalculating input/output paths..." << std::endl;
-            // std::cout << "image_path: " << image_path << std::endl;
-
-            // // Calculate output path location.
-            output_path = "../output/";
-            std::string base_filename = image_path.substr(image_path.find_last_of("/\\") + 1);
-
-            // Grab directory substrings and generate full output path.
-            size_t pos = 0;
-            std::string token;
-            while ((pos = image_path.find("/")) != std::string::npos) {
-
-                // Pull current substring value from input path.
-                token = image_path.substr(0, image_path.find("/"));
-                // std::cout << "    " << token << std::endl;
-                image_path.erase(0, pos + 1);
-
-                // Check if directory value is value we care about.
-                if ( (token != ".") && (token != "..") && (token != "input") ) {
-                    output_path += token + "/";
-                }
-
-                // Check if directory exists.
-                struct stat info;
-                if ( (stat(output_path.c_str(), &info) != 0) || (! info.st_mode & S_IFDIR)) {
-                    // Directory does not exist.
-                    mkdir(output_path.c_str(), 0777);
-                }
-
-            }
-
-            output_path += base_filename;
-            // std::cout << "output_path: " << output_path << std::endl;
-
-            // std::cout << "Input/output paths calculated.\n\n\n\n\n" << std::endl;
-        }
-
-
-        /**
-         * Imports image file data, using class variable data.
-         */
-        void import_image_file() {
-            // Open input file.
-            std::ifstream input_file;
-            input_file.open(input_path, std::ios::binary | std::ios::in);
-
-            if (! input_file.good()) {
-                // Failed to open file.
-                std::cerr << "Failed to open file \"" + input_path + "\"." << std::endl;
-            } else {
-                // File opened. Grab data.
-                std::string header;
-                input_file >> header;
-                if (strcmp(header.c_str(), "P6") != 0) {
-                    throw("Can't read input file");
-                }
-
-                // Save image values to class.
-                input_file >> width >> height >> bit_depth;
-
-                // Create and populate image.
-                // std::cout << "Parsing input image" << std::endl;
-                pixel_arr = new Rgb[width * height];
-
-                // Skip empty lines in necessary until we get to the binary data.
-                input_file.ignore(256, '\n');
-
-                // Read each pixel one by one and convert bytes to floats.
-                unsigned char pix[3];
-                for (int index = 0; index < width * height; ++index) {
-                    input_file.read(reinterpret_cast<char *>(pix), 3);
-                    pixel_arr[index].r = pix[0] / 255.f;
-                    pixel_arr[index].g = pix[1] / 255.f;
-                    pixel_arr[index].b = pix[2] / 255.f;
-                }
-            }
-
-            input_file.close();
-        }
-
-
-    public:
-        // Public Variables.
-        static const Rgb pixelBlack, pixelWhite, pixelRed, pixelGreen, pixelBlue, pixelYellow, pixelPink, pixelLiBlue;
-
-
-        //region Constructors.
-
-        /**
-         * Base constructor.
-         */
-        Image() {
-            // Currently test logic.
-            std::cout << "\nConstructing Image class." << std::endl;
-
-            // Essentially creates a 10x10 pixel test image.
-            input_path = "../input/pbm/400x300/hallway_00.pbm";
-            output_path = "../output/test_00.pbm";
-            width = 10;
-            height = 10;
-            bit_depth = 255;
-            Rgb c = pixelBlack; // Default color. Can select based on below preset colors.
-
-            // Create and populate image.
-            pixel_arr = new Rgb[width * height];
-            for (int index = 0; index < (width * height); index++) {
-                pixel_arr[index] = c;
-            }
-
-            std::cout << "Image class populated." << std::endl;
-        }
-
-        /**
-         * Constructor that takes input path to image file.
-         * Output path is determined based on parsing input path.
-         */
-        Image(std::string user_path) {
-            std::cout << "\nConstructing Image class." << std::endl;
-
-            std::cout << "user_path: " << user_path << std::endl;
-
-            // Re-validate path for saving to class..
-            path_validator_struct* return_struct = validate_path(user_path);
-            int path_type = return_struct->file_type;
-            if (return_struct->err_code) {
-                std::cerr << "Error verifying file type: " << return_struct->err_code.message() << std::endl;
-                return;
-            }
-            free_path_validator_struct(return_struct);
-            if (path_type == TYPE_FILE) {
-                input_path = user_path;
-                calculate_paths(user_path);
-                import_image_file();
-            } else {
-                std::cerr << "Provided path is not to image file. Class initialization failed." << std::endl;
-                return;
-            }
-
-            std::cout << "Image class populated." << std::endl;
-        }
-
-        //endregion Constructors.
-
-
-        //region Public Methods.
-
-        /**
-         * Displays general properties of image held in class.
-         */
-        void display_properties() {
-            std::cout << std::endl;
-            std::cout << "input file path: " << input_path << std::endl;
-            std::cout << "output file path: " << output_path << std::endl;
-            std::cout << "width: " << width << std::endl;
-            std::cout << "height: " << height << std::endl;
-            std::cout << "bit depth: " << bit_depth << std::endl;
-            std::cout << std::endl;
-        }
-
-
-        /**
-         * Saves class image data to output file.
-         */
-        void save() {
-            std::cout << "Attempting to save image to \"" << output_path << "\"." << std::endl;
-
-            // Open output file stream.
-            std::ofstream output_file;
-
-            // Attempt to save file data.
-            try {
-                // Attempt to open file.
-                output_file.open(output_path, std::ios::binary | std::ios::out);
-
-                // Check if opened successfully.
-                if (output_file.fail()) {
-                    // Failed to open.
-                    std::cout << "Failed to open file \"" + output_path + "\".\n";
-                } else {
-                    // Opened successfully.
-
-                    // Write image "header" data.
-                    output_file << "P6\n" << width << " " << height << "\n255\n";
-
-                    // Write image pixel data.
-                    unsigned char r, g, b;
-                    for (int index = 0; index < (width * height); index++) {
-                        r = static_cast<float>(std::min(1.f, pixel_arr[index].r) * 255);
-                        g = static_cast<float>(std::min(1.f, pixel_arr[index].g) * 255);
-                        b = static_cast<float>(std::min(1.f, pixel_arr[index].b) * 255);
-                        output_file << r << g << b;
-                    }
-
-                }
-
-                // Close file stream.
-                output_file.close();
-                std::cout << "Image saved." << std::endl;
-
-            } catch (const char* err) {
-                fprintf(stderr, "%s\n", err);
-                output_file.close();
-            }
-        }
-
-        //endregion Public Methods.
-
-};
-
-
-// Preset single colors. Mostly for testing purposes.
-const Image::Rgb Image::pixelBlack = Image::Rgb(0);
-const Image::Rgb Image::pixelWhite = Image::Rgb(1);
-const Image::Rgb Image::pixelRed = Image::Rgb(1,0,0);
-const Image::Rgb Image::pixelGreen = Image::Rgb(0,1,0);
-const Image::Rgb Image::pixelBlue = Image::Rgb(0,0,1);
-const Image::Rgb Image::pixelYellow = Image::Rgb(1,1,0);
-const Image::Rgb Image::pixelPink = Image::Rgb(1,0,1);
-const Image::Rgb Image::pixelLiBlue = Image::Rgb(0,1,1);
-
 
 /*
  * Program's main. Initializes and runs program.
@@ -308,34 +42,36 @@ int main(int argc, char* argv[]) {
     printf("\n");
     printf("\n");
 
-    // Check provided number of args.
-    if (argc < 2) {
-        // No args provided.
-        printf("Provided too few program args. Expected one arg.");
-    } else if (argc > 2) {
-        // More than one arg provided.
-        printf("Provided too many program args. Expected one arg.");
-    } else {
-        // Correct number of args provided. Pass to image class for processing.
-
-        // Check data type.
-        std::string path_str = argv[1];
-        path_validator_struct* return_struct = validate_path(path_str);
-        int path_type = return_struct->file_type;
-        if (return_struct->err_code) {
-            std::cerr << "Error verifying file type: " << return_struct->err_code.message() << std::endl;
-        }
-        free_path_validator_struct(return_struct);
-
-        // Handle based on provided type.
-        if (path_type == TYPE_DIR) {
-            // Process dir.
-            process_dir(path_str);
-        } else if (path_type == TYPE_FILE) {
-            // Process file.
-            process_file(path_str);
-        }
-    }
+    Logging logger;
+
+    // // Check provided number of args.
+    // if (argc < 2) {
+    //     // No args provided.
+    //     printf("Provided too few program args. Expected one arg.");
+    // } else if (argc > 2) {
+    //     // More than one arg provided.
+    //     printf("Provided too many program args. Expected one arg.");
+    // } else {
+    //     // Correct number of args provided. Pass to image class for processing.
+
+    //     // Check data type.
+    //     std::string path_str = argv[1];
+    //     path_validator_struct* return_struct = validate_path(path_str);
+    //     int path_type = return_struct->file_type;
+    //     if (return_struct->err_code) {
+    //         std::cerr << "Error verifying file type: " << return_struct->err_code.message() << std::endl;
+    //     }
+    //     free_path_validator_struct(return_struct);
+
+    //     // Handle based on provided type.
+    //     if (path_type == TYPE_DIR) {
+    //         // Process dir.
+    //         process_dir(path_str);
+    //     } else if (path_type == TYPE_FILE) {
+    //         // Process file.
+    //         process_file(path_str);
+    //     }
+    // }
 
     printf("\n");
     printf("\n");
@@ -344,40 +80,12 @@ int main(int argc, char* argv[]) {
 }
 
 
-/**
- * Validates provided path and if valid, determines path type.
- * Returns struct of data.
- */
-path_validator_struct* validate_path(std::string path_str) {
-    int type_value = TYPE_OTHER;
-    std::error_code ec;
-
-    std::cout << "path_str: \"" + path_str + "\"\n";
-
-    // Check if provided path exists.
-    std::ifstream test_path_exists(path_str);
-    if (test_path_exists) {
-        // Path exists. Check if dir or file.
-        if (std::filesystem::is_directory(path_str, ec)) {
-            // Is dir.
-            type_value = TYPE_DIR;
-        } else if ((! ec) && (std::filesystem::is_regular_file(path_str, ec))) {
-            // Is file.
-            type_value = TYPE_FILE;
-        }
-    }
-
-    // Return values.
-    path_validator_struct* return_struct_ptr = initialize_path_validator_struct(type_value, ec);
-    return return_struct_ptr;
-}
-
-
 /**
  * Finds and processes all files in directory.
  * Assumes directory is full of image files.
  */
 void process_dir(std::string path_str) {
+    std::cout << "Handling dir." << std::endl;
 
     // Process all files in directory.
     for (const auto & entry : std::filesystem::directory_iterator(path_str)) {
@@ -385,6 +93,23 @@ void process_dir(std::string path_str) {
         std::string file_path_str{entry.path().u8string()};
         // std::cout << file_path_str << std::endl;
 
+        // Check if new path value is directory or file.
+        path_validator_struct* return_struct = validate_path(file_path_str);
+        int path_type = return_struct->file_type;
+        if (return_struct->err_code) {
+            std::cerr << "Error verifying file type: " << return_struct->err_code.message() << std::endl;
+        }
+        free_path_validator_struct(return_struct);
+
+        // Handle based on provided type.
+        if (path_type == TYPE_DIR) {
+            // Process dir.
+            process_dir(file_path_str);
+        } else if (path_type == TYPE_FILE) {
+            // Process file.
+            process_file(file_path_str);
+        }
+
         // Send individual file path for processing.
         process_file(entry.path());
     }
@@ -395,6 +120,7 @@ void process_dir(std::string path_str) {
  * Processes a single image file.
  */
 void process_file(std::string path_str) {
+    std::cout << "Handling file." << std::endl;
 
     Image image(path_str);
     image.display_properties();
diff --git a/part_1/makefile b/part_1/makefile
index 1ece90e..7540236 100644
--- a/part_1/makefile
+++ b/part_1/makefile
@@ -10,7 +10,7 @@ CC = nvcc
 CFLAGS = -std=c++17
 TARGET = main.out
 LIBRARIES =
-DEPENDENCIES = ./main.cu ./structs.cu ./image.cu
+DEPENDENCIES = ./main.cu ./image.cu ./logging.cu ./utility.cu
 # ARGS = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}`
 ARGS = $(filter-out $@,$(MAKECMDGOALS))
 
diff --git a/part_1/structs.cu b/part_1/utility.cu
similarity index 55%
rename from part_1/structs.cu
rename to part_1/utility.cu
index 95da97e..ec66384 100644
--- a/part_1/structs.cu
+++ b/part_1/utility.cu
@@ -1,12 +1,11 @@
 /**
- * File for struct logic.
+ * File for utility logic.
  */
 
-
 // User Import Headers.
 #ifndef user_headers
     #define user_headers
-    #include "structs.h"
+    #include "utility.h"
 #endif
 
 
@@ -50,3 +49,31 @@ void free_path_validator_struct(path_validator_struct* path_validator_ptr) {
     free(path_validator_ptr);
 }
 
+
+/**
+ * Validates provided path and if valid, determines path type.
+ * Returns struct of data.
+ */
+path_validator_struct* validate_path(std::string path_str) {
+    int type_value = TYPE_OTHER;
+    std::error_code ec;
+
+    std::cout << "path_str: \"" + path_str + "\"\n";
+
+    // Check if provided path exists.
+    std::ifstream test_path_exists(path_str);
+    if (test_path_exists) {
+        // Path exists. Check if dir or file.
+        if (std::filesystem::is_directory(path_str, ec)) {
+            // Is dir.
+            type_value = TYPE_DIR;
+        } else if ((! ec) && (std::filesystem::is_regular_file(path_str, ec))) {
+            // Is file.
+            type_value = TYPE_FILE;
+        }
+    }
+
+    // Return values.
+    path_validator_struct* return_struct_ptr = initialize_path_validator_struct(type_value, ec);
+    return return_struct_ptr;
+}
diff --git a/part_1/structs.h b/part_1/utility.h
similarity index 80%
rename from part_1/structs.h
rename to part_1/utility.h
index e0b239d..d20726d 100644
--- a/part_1/structs.h
+++ b/part_1/utility.h
@@ -1,5 +1,5 @@
 /**
- * Header file for project struct logic.
+ * Header file for project utility logic.
  */
 
 
@@ -7,6 +7,8 @@
 #include <cstdio>
 #include <cstdlib>
 #include <cctype>
+#include <filesystem>
+#include <fstream>
 #include <iostream>
 #include <string>
 
@@ -29,3 +31,4 @@ typedef struct {
 // // Function Prototypes.
 path_validator_struct* initialize_path_validator_struct(int file_type, std::error_code err_code);
 void free_path_validator_struct(path_validator_struct* path_validator_ptr);
+path_validator_struct* validate_path(std::string path_str);
-- 
GitLab