#include #include namespace psemek::util { pixmap_monochrome read_pgm(std::istream & is) { auto fail = [](std::string str) { throw std::runtime_error("Error loading PGM image: " + str); }; std::string line; std::getline(is, line); bool binary = true; if (line == "P2") { binary = false; } else if (line == "P5") { binary = true; } else fail("unknown format " + line); std::size_t width, height; std::size_t max; pixmap_monochrome pixmap; is >> width >> height >> max; if (max != 255) fail("max value " + std::to_string(max) + " is not supported"); pixmap.resize(width, height); if (binary) is.read(reinterpret_cast(pixmap.data()), width * height * sizeof(pixmap.data()[0])); else fail("P2 format is not supported"); if (!is) fail("stream error"); return pixmap; } pixmap_rgb load_ppm(std::istream & is) { auto fail = [](std::string str) { throw std::runtime_error("Error loading PPM image: " + str); }; std::string line; std::getline(is, line); bool binary = true; if (line == "P3") { binary = false; } else if (line == "P6") { binary = true; } else fail("unknown format " + line); std::size_t width, height; std::size_t max; pixmap_rgb pixmap; is >> width >> height >> max; if (max != 255) fail("max value " + std::to_string(max) + " is not supported"); pixmap.resize(width, height); if (binary) is.read(reinterpret_cast(pixmap.data()), width * height * sizeof(pixmap.data()[0])); else fail("P3 format is not supported"); if (!is) fail("stream error"); return pixmap; } void write_pgm(pixmap_monochrome const & p, std::ostream & os) { os << "P5\n" << p.width() << " " << p.height() << "\n255\n"; os.write(reinterpret_cast(p.data()), p.width() * p.height() * sizeof(p.data()[0])); } void write_ppm(pixmap_rgb const & p, std::ostream & os) { os << "P6\n" << p.width() << " " << p.height() << "\n255\n"; os.write(reinterpret_cast(p.data()), p.width() * p.height() * sizeof(p.data()[0])); } }