Support reading PBM images & fix all Netpbm readers
This commit is contained in:
parent
44883e0226
commit
dba0c78daf
2 changed files with 77 additions and 2 deletions
|
|
@ -58,6 +58,7 @@ namespace psemek::gfx
|
|||
using pixmap_rgba = basic_pixmap<color_rgba>;
|
||||
using pixmap_float = basic_pixmap<float>;
|
||||
|
||||
pixmap_monochrome read_pbm(std::istream & is);
|
||||
pixmap_monochrome read_pgm(std::istream & is);
|
||||
pixmap_rgb read_ppm(std::istream & is);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,70 @@
|
|||
#include <psemek/gfx/pixmap.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
namespace psemek::gfx
|
||||
{
|
||||
|
||||
pixmap_monochrome read_pbm(std::istream & is)
|
||||
{
|
||||
auto fail = [](std::string str)
|
||||
{
|
||||
throw std::runtime_error("Error loading PBM image: " + str);
|
||||
};
|
||||
|
||||
std::string line;
|
||||
std::getline(is, line);
|
||||
|
||||
bool binary = true;
|
||||
|
||||
if (line == "P1")
|
||||
{
|
||||
binary = false;
|
||||
}
|
||||
else if (line == "P4")
|
||||
{
|
||||
binary = true;
|
||||
}
|
||||
else
|
||||
fail("unknown format " + line);
|
||||
|
||||
if (!binary)
|
||||
fail("P1 format is not supported");
|
||||
|
||||
std::getline(is, line);
|
||||
std::istringstream sline(line);
|
||||
|
||||
std::size_t width, height;
|
||||
pixmap_monochrome pixmap;
|
||||
|
||||
sline >> width >> height;
|
||||
|
||||
pixmap.resize(width, height);
|
||||
|
||||
std::size_t bytes = width * height;
|
||||
if ((bytes % 8) == 0)
|
||||
bytes = bytes / 8;
|
||||
else
|
||||
bytes = (bytes + 7) / 8;
|
||||
std::vector<std::uint8_t> data(bytes);
|
||||
is.read(reinterpret_cast<char *>(data.data()), bytes);
|
||||
|
||||
for (std::size_t i = 0; i < width * height; ++i)
|
||||
{
|
||||
std::size_t b = i / 8;
|
||||
std::size_t o = 7 - (i % 8);
|
||||
bool const white = (data[b] & (1 << o)) == 0;
|
||||
pixmap.data()[i] = white ? 255 : 0;
|
||||
}
|
||||
|
||||
if (!is)
|
||||
fail("stream error");
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
pixmap_monochrome read_pgm(std::istream & is)
|
||||
{
|
||||
auto fail = [](std::string str)
|
||||
|
|
@ -28,11 +88,18 @@ namespace psemek::gfx
|
|||
else
|
||||
fail("unknown format " + line);
|
||||
|
||||
std::getline(is, line);
|
||||
std::istringstream sline(line);
|
||||
|
||||
std::size_t width, height;
|
||||
std::size_t max;
|
||||
pixmap_monochrome pixmap;
|
||||
|
||||
is >> width >> height >> max;
|
||||
sline >> width >> height;
|
||||
|
||||
std::getline(is, line);
|
||||
sline.str(line);
|
||||
sline >> max;
|
||||
|
||||
if (max != 255)
|
||||
fail("max value " + std::to_string(max) + " is not supported");
|
||||
|
|
@ -73,11 +140,18 @@ namespace psemek::gfx
|
|||
else
|
||||
fail("unknown format " + line);
|
||||
|
||||
std::getline(is, line);
|
||||
std::istringstream sline(line);
|
||||
|
||||
std::size_t width, height;
|
||||
std::size_t max;
|
||||
pixmap_rgb pixmap;
|
||||
|
||||
is >> width >> height >> max;
|
||||
sline >> width >> height;
|
||||
|
||||
std::getline(is, line);
|
||||
sline.str(line);
|
||||
sline >> max;
|
||||
|
||||
if (max != 255)
|
||||
fail("max value " + std::to_string(max) + " is not supported");
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue