psemek/libs/gfx/source/pixmap.cpp

110 lines
2.1 KiB
C++

#include <psemek/gfx/pixmap.hpp>
#include <iostream>
namespace psemek::gfx
{
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<char *>(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<char *>(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<char const *>(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<char const *>(p.data()), p.width() * p.height() * sizeof(p.data()[0]));
}
}