Browse Source

[PPM] Comments support

master
Unbewohnte 3 years ago
parent
commit
cb63ae2dfd
  1. 75
      src/pnm.cpp
  2. 46
      tests/test.cpp

75
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<std::string> m_comments;
// actual pixel data
std::vector<RGB> 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<std::string> 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";

46
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<std::string> 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";

Loading…
Cancel
Save