From cb63ae2dfd9f6eb8a569607a319af793944ca431 Mon Sep 17 00:00:00 2001 From: Unbewohnte Date: Wed, 2 Mar 2022 06:19:58 +0300 Subject: [PATCH] [PPM] Comments support --- src/pnm.cpp | 75 ++++++++++++++++++++++++++++++++++++++++---------- tests/test.cpp | 46 +++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 14 deletions(-) diff --git a/src/pnm.cpp b/src/pnm.cpp index 0599df6..a52da50 100644 --- a/src/pnm.cpp +++ b/src/pnm.cpp @@ -70,8 +70,9 @@ public: // PPM image file format reader/writer class PPM { protected: - // PPM colored image magic number + // binary PPM format constants const std::string m_MAGIC_NUMBER = "P6"; + const char m_COMMENT_CHAR = '#'; // image width and height uint32_t m_width; @@ -80,6 +81,9 @@ protected: // maximum value for all color channels uint16_t m_max_color; + // stored comments + std::vector m_comments; + // actual pixel data std::vector m_pixel_data; @@ -117,6 +121,16 @@ public: m_pixel_data.at(i) = color; } + // Add comment line to the image + void add_comment(std::string comment) { + m_comments.push_back(comment); + } + + // Return all captured comments of an image + std::vector get_comments() { + return m_comments; + } + // Read PPM image from disk void read(std::string path) { // try to open file @@ -133,21 +147,49 @@ public: throw std::runtime_error("Does not have a magic number"); } - // width, height, max color - ppm_image_file >> entity; - m_width = std::stoi(entity); - - ppm_image_file >> entity; - m_height = std::stoi(entity); - - ppm_image_file >> entity; - m_max_color = std::stoi(entity); - + // width, height, max color while ignoring comments + uint8_t captured = 0; + while(captured < 3) { + ppm_image_file >> entity; + if (entity[0] == m_COMMENT_CHAR) { + // this is a comment, skip this line + getline(ppm_image_file, entity); + m_comments.push_back(entity); + continue; + } + + switch(captured) { + case 0: + // width + m_width = std::stoi(entity); + break; + + case 1: + // height + m_height = std::stoi(entity); + break; + + case 2: + // max color + m_max_color = std::stoi(entity); + break; + } + captured++; + } m_pixel_data.resize(m_width * m_height); - // skip one byte - char one[1]; - ppm_image_file.read(one, 1); + while(true) { + // skip one final byte... + char one[1]; + ppm_image_file.read(one, 1); + if (one[0] == m_COMMENT_CHAR) { + // ah, comment again... + getline(ppm_image_file, entity); + m_comments.push_back(entity); + } else { + break; + } + } // retrieve pixels char pixel_color[3]; @@ -185,6 +227,11 @@ public: // newline ppm_image_file << "\n"; + // comments + for (const std::string& comment : m_comments) { + ppm_image_file << m_COMMENT_CHAR << comment << "\n"; + } + // width, height, max color value ppm_image_file << m_width << " " << m_height << " " << m_max_color << "\n"; diff --git a/tests/test.cpp b/tests/test.cpp index 215bae3..1c7027d 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -54,11 +54,57 @@ void no_pixel_assign() { } catch(const std::exception& e) {} } +void write_comment() { + try { + pnm::PPM image; + + const uint32_t width = 512; + const uint32_t height = 512; + + for (uint32_t y = 0; y < height; y++) { + for (uint32_t x = 0; x < width; x++) { + image.put_pixel(x, y, pnm::RGB(x / 2, y / 2, x / 2 + y / 2)); + } + } + + image.add_comment("comment 1"); + image.add_comment("comment 2"); + image.add_comment("comment \n\n\n"); + + image.save("result_image.ppm"); + + } catch(const std::exception& e) { + std::string error_message("write_comment:", e.what()); + throw std::runtime_error(error_message); + } +} + +void read_comment() { + try { + write_comment(); + + pnm::PPM image; + image.read("result_image.ppm"); + + std::vector comments = image.get_comments(); + + if (comments.size() == 0) { + throw std::runtime_error("No comments found, though there should be"); + } + + } catch(const std::exception& e) { + std::string error_message("read_comment:", e.what()); + throw std::runtime_error(error_message); + } +} + int main() { try { make_test_img(); green_rectangle_on_top_of_existing_image(); no_pixel_assign(); + write_comment(); + read_comment(); } catch(const std::exception& e) { std::cout << "[ERROR] " << e.what() << "\n";