Support reading grayscale pngs
This commit is contained in:
parent
12e2bff790
commit
6661299573
2 changed files with 25 additions and 10 deletions
|
|
@ -24,5 +24,6 @@ namespace psemek::gfx
|
||||||
void write_ppm(pixmap_rgb const & p, std::ostream & os);
|
void write_ppm(pixmap_rgb const & p, std::ostream & os);
|
||||||
|
|
||||||
pixmap_rgba read_png(std::istream & is);
|
pixmap_rgba read_png(std::istream & is);
|
||||||
|
pixmap_monochrome read_png_monochrome(std::istream & is);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,13 @@
|
||||||
#include <psemek/log/log.hpp>
|
#include <psemek/log/log.hpp>
|
||||||
#include <psemek/util/at_scope_exit.hpp>
|
#include <psemek/util/at_scope_exit.hpp>
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <png.h>
|
#include <png.h>
|
||||||
|
|
||||||
namespace psemek::gfx
|
namespace psemek::gfx
|
||||||
{
|
{
|
||||||
|
|
||||||
pixmap_rgba read_png(std::istream & is)
|
template <typename Pixel>
|
||||||
|
basic_pixmap<Pixel> read_png_impl(std::istream & is, png_byte expected_color_type)
|
||||||
{
|
{
|
||||||
png_error_ptr error = [](png_structp, png_const_charp str)
|
png_error_ptr error = [](png_structp, png_const_charp str)
|
||||||
{
|
{
|
||||||
|
|
@ -52,17 +51,22 @@ namespace psemek::gfx
|
||||||
auto const color_type = png_get_color_type(png, info);
|
auto const color_type = png_get_color_type(png, info);
|
||||||
auto const bit_depth = png_get_bit_depth(png, info);
|
auto const bit_depth = png_get_bit_depth(png, info);
|
||||||
|
|
||||||
if (color_type != PNG_COLOR_TYPE_RGBA)
|
if (color_type != expected_color_type)
|
||||||
throw std::runtime_error("PNG color types other than RGBA are not supported");
|
throw std::runtime_error("PNG color type not supported");
|
||||||
|
|
||||||
if (bit_depth != 8)
|
if (bit_depth == 16)
|
||||||
throw std::runtime_error("PNG bit depths other than 8 are not supported");
|
png_set_strip_16(png);
|
||||||
|
|
||||||
pixmap_rgba result({width, height});
|
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
||||||
|
png_set_expand_gray_1_2_4_to_8(png);
|
||||||
|
|
||||||
|
png_read_update_info(png, info);
|
||||||
|
|
||||||
|
basic_pixmap<Pixel> result({width, height});
|
||||||
|
|
||||||
auto const row_bytes = png_get_rowbytes(png, info);
|
auto const row_bytes = png_get_rowbytes(png, info);
|
||||||
if (row_bytes != width * 4)
|
if (row_bytes != width * sizeof(Pixel))
|
||||||
throw std::runtime_error("PNG row bytes is wrong");
|
throw std::runtime_error("PNG row bytes mismatch");
|
||||||
|
|
||||||
for (std::uint32_t i = 0; i < height; ++i)
|
for (std::uint32_t i = 0; i < height; ++i)
|
||||||
png_read_row(png, reinterpret_cast<png_bytep>(result.data() + i * width), nullptr);
|
png_read_row(png, reinterpret_cast<png_bytep>(result.data() + i * width), nullptr);
|
||||||
|
|
@ -70,4 +74,14 @@ namespace psemek::gfx
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pixmap_rgba read_png(std::istream & is)
|
||||||
|
{
|
||||||
|
return read_png_impl<color_rgba>(is, PNG_COLOR_TYPE_RGBA);
|
||||||
|
}
|
||||||
|
|
||||||
|
pixmap_monochrome read_png_monochrome(std::istream & is)
|
||||||
|
{
|
||||||
|
return read_png_impl<std::uint8_t>(is, PNG_COLOR_TYPE_GRAY);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue