// Copyright (C) 2008 Davis E. King (davis@dlib.net), Nils Labugt
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_PNG_IMPORT
#define DLIB_PNG_IMPORT
#include <memory>
#include <cstring>
#include <functional>
#include <istream>
#include <fstream>
#include "png_loader_abstract.h"
#include "image_loader.h"
#include "../pixel.h"
#include "../type_traits.h"
#include "../test_for_odr_violations.h"
#include "../dir_nav.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
class png_loader : noncopyable
{
public:
png_loader( std::istream& in );
png_loader( const char* filename );
png_loader( const std::string& filename );
png_loader( const dlib::file& f );
png_loader( const unsigned char* image_buffer, std::size_t buffer_size );
bool is_gray() const;
bool is_graya() const;
bool is_rgb() const;
bool is_rgba() const;
unsigned int bit_depth () const;
long nr() const;
long nc() const;
template<class image_type>
void get_image( image_type& img) const
{
#ifndef DLIB_PNG_SUPPORT
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
You are getting this error because you are trying to use the png_loader
object but you haven't defined DLIB_PNG_SUPPORT. You must do so to use
this object. You must also make sure you set your build environment
to link against the libpng library.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
COMPILE_TIME_ASSERT(sizeof(T) == 0);
#else
using pixel_type = pixel_type_t<image_type>;
auto t = make_image_view(img);
t.set_size( height, width );
const auto assign_gray = [&](const auto** lines)
{
for ( int n = 0; n < height; ++n )
for ( int m = 0; m < width; ++m )
assign_pixel( t[n][m], lines[n][m]);
};
const auto assign_gray_alpha = [&](const auto** lines)
{
for ( int n = 0; n < height; ++n )
{
for ( int m = 0; m < width; ++m )
{
if (!pixel_traits<pixel_type>::has_alpha)
{
assign_pixel(t[n][m], lines[n][m*2]);
}
else
{
rgb_alpha_pixel pix;
assign_pixel(pix, lines[n][m*2]);
assign_pixel(pix.alpha, lines[n][m*2+1]);
assign_pixel(t[n][m], pix);
}
}
}
};
const auto assign_rgb = [&](const auto** lines)
{
for ( int n = 0; n < height;++n )
{
for ( int m = 0; m < width;++m )
{
rgb_pixel p;
p.red = static_cast<uint8>(lines[n][m*3]);
p.green = static_cast<uint8>(lines[n][m*3+1]);
p.blue = static_cast<uint8>(lines[n][m*3+2]);
assign_pixel( t[n][m], p );
}
}
};
const auto assign_rgba = [&](const auto** lines)
{
if (!pixel_traits<pixel_type>::has_alpha)
assign_all_pixels(t,0);
for ( int n = 0; n < height; ++n )
{
for ( int m = 0; m < width; ++m )
{
rgb_alpha_pixel p;
p.red = static_cast<uint8>(lines[n][m*4]);
p.green = static_cast<uint8>(lines[n][m*4+1]);
p.blue = static_cast<uint8>(lines[n][m*4+2]);
p.alpha = static_cast<uint8>(lines[n][m*4+3]);
assign_pixel( t[n][m], p );
}
}
};
const auto assign = [&](const auto** lines)
{
if (is_gray())
assign_gray(lines);
else if (is_graya())
assign_gray_alpha(lines);
else if (is_rgb())
assign_rgb(lines);
else if (is_rgba())
assign_rgba(lines);
};
if (bit_depth_ == 8)
assign((const uint8_t**)(rows));
else if (bit_depth_ == 16)
assign((const uint16_t**)(rows));
#endif
}
private:
void load(std::function<std::size_t(char*,std::size_t)> clb);
void load(std::istream& in);
int height{0};
int width{0};
int bit_depth_{0};
int color_type{0};
unsigned char** rows{nullptr};
std::shared_ptr<void> finalizer;
};
// ----------------------------------------------------------------------------------------
template <class image_type>
void load_png (
image_type& img,
std::istream& in
)
{
png_loader(in).get_image(img);
}
template <class image_type>
void load_png (
image_type& img,
const std::string& file_name
)
{
png_loader(file_name).get_image(img);
}
template <
class image_type,
class Byte,
std::enable_if_t<is_byte<Byte>::value, bool> = true
>
void load_png (
image_type& img,
const Byte* image_buffer,
std::size_t buffer_size
)
{
png_loader((const unsigned char*)image_buffer, buffer_size).get_image(img);
}
// ----------------------------------------------------------------------------------------
}
#ifdef NO_MAKEFILE
#include "png_loader.cpp"
#endif
#endif // DLIB_PNG_IMPORT