[DEV] add an API to load raw buffer
This commit is contained in:
parent
f345c9c664
commit
1181bc52e7
@ -9,6 +9,11 @@
|
|||||||
#include <egami/ImagePrivate.hpp>
|
#include <egami/ImagePrivate.hpp>
|
||||||
#include <ememory/memory.hpp>
|
#include <ememory/memory.hpp>
|
||||||
|
|
||||||
|
std::ostream& egami::operator <<(std::ostream& _os, const egami::Image& _obj) {
|
||||||
|
_os << "egami::Image{" << _obj.getSize() << " on GPU: " << _obj.getGPUSize() << " color=" << _obj.getType();
|
||||||
|
return _os;
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& egami::operator <<(std::ostream& _os, const enum egami::colorType _type) {
|
std::ostream& egami::operator <<(std::ostream& _os, const enum egami::colorType _type) {
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case egami::colorType::undefined:
|
case egami::colorType::undefined:
|
||||||
@ -80,6 +85,16 @@ egami::Image::Image() :
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
egami::Image::Image(const egami::Image& _image):
|
||||||
|
m_data(_image.m_data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
egami::Image& egami::Image::operator=(const egami::Image& _image) {
|
||||||
|
m_data = _image.m_data;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
egami::Image::~Image() {
|
egami::Image::~Image() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -204,22 +219,25 @@ const ivec2& egami::Image::getSize() const {
|
|||||||
return m_data->getSize();
|
return m_data->getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
#if defined(__TARGET_OS__Android) \
|
||||||
* @brief get the next power 2 if the input
|
|| defined(__TARGET_OS__IOs)
|
||||||
* @param[in] value Value that we want the next power of 2
|
/**
|
||||||
* @return result value
|
* @brief get the next power 2 if the input
|
||||||
*/
|
* @param[in] value Value that we want the next power of 2
|
||||||
static int32_t nextP2(int32_t _value) {
|
* @return result value
|
||||||
int32_t val=1;
|
*/
|
||||||
for (int32_t iii=1; iii<31; iii++) {
|
static int32_t nextP2(int32_t _value) {
|
||||||
if (_value <= val) {
|
int32_t val=1;
|
||||||
return val;
|
for (int32_t iii=1; iii<31; iii++) {
|
||||||
|
if (_value <= val) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
val *=2;
|
||||||
}
|
}
|
||||||
val *=2;
|
EGAMI_CRITICAL("impossible CASE....");
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
EGAMI_CRITICAL("impossible CASE....");
|
#endif
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
ivec2 egami::Image::getGPUSize() const {
|
ivec2 egami::Image::getGPUSize() const {
|
||||||
if (m_data == nullptr) {
|
if (m_data == nullptr) {
|
||||||
|
@ -79,6 +79,8 @@ namespace egami {
|
|||||||
* @note use @ref configure to set a correct image
|
* @note use @ref configure to set a correct image
|
||||||
*/
|
*/
|
||||||
Image();
|
Image();
|
||||||
|
Image(const egami::Image& _image);
|
||||||
|
Image& operator=(const egami::Image& _image);
|
||||||
Image(const ivec2& _size,
|
Image(const ivec2& _size,
|
||||||
enum colorType _type = egami::colorType::undefined);
|
enum colorType _type = egami::colorType::undefined);
|
||||||
~Image();
|
~Image();
|
||||||
@ -142,5 +144,6 @@ namespace egami {
|
|||||||
void set(const std::vector<etk::Color<float,4>>& _data, const ivec2& _size);
|
void set(const std::vector<etk::Color<float,4>>& _data, const ivec2& _size);
|
||||||
void set(const std::vector<etk::Color<uint8_t,4>>& _data, const ivec2& _size);
|
void set(const std::vector<etk::Color<uint8_t,4>>& _data, const ivec2& _size);
|
||||||
};
|
};
|
||||||
|
std::ostream& operator <<(std::ostream& _os, const egami::Image& _obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,6 +100,39 @@ egami::Image egami::load(const std::string& _fileName, const ivec2& _size) {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
egami::Image egami::load(const std::string& _mineType, const std::vector<uint8_t>& _buffer, const ivec2& _size) {
|
||||||
|
egami::Image out;
|
||||||
|
// select the corect Loader :
|
||||||
|
if (_mineType == "image/bmp") {
|
||||||
|
out = egami::loadBMP(_buffer);
|
||||||
|
if (out.exist() == false) {
|
||||||
|
EGAMI_ERROR("Error to load BMP file '" << _buffer.size() << "'");
|
||||||
|
}
|
||||||
|
}else if (_mineType == "image/png") {
|
||||||
|
#ifdef EGAMI_BUILD_PNG
|
||||||
|
out = egami::loadPNG(_buffer);
|
||||||
|
if (out.exist() == false) {
|
||||||
|
EGAMI_ERROR("Error to load PNG file '" << _buffer.size() << "'");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
EGAMI_WARNING("egamy not compile with the PNG dependency for file '" << _buffer.size() << "'");
|
||||||
|
#endif
|
||||||
|
} else if (_mineType == "image/jpg") {
|
||||||
|
#ifdef EGAMI_BUILD_JPEG
|
||||||
|
out = egami::loadJPG(_buffer);
|
||||||
|
if (out.exist() == false) {
|
||||||
|
EGAMI_ERROR("Error to load JPG file '" << _buffer.size() << "'");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
EGAMI_WARNING("egamy not compile with the JPEG dependency for file '" << _buffer.size() << "'");
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
EGAMI_ERROR("Extention not managed '" << _mineType << "' Sopported extention : image/bmp, image/png, image/jpg");
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
bool egami::store(const egami::Image& _input, const std::string& _fileName) {
|
bool egami::store(const egami::Image& _input, const std::string& _fileName) {
|
||||||
std::string tmpName = etk::tolower(_fileName);
|
std::string tmpName = etk::tolower(_fileName);
|
||||||
EGAMI_DEBUG("Store file : " << _fileName);
|
EGAMI_DEBUG("Store file : " << _fileName);
|
||||||
|
@ -19,6 +19,13 @@ namespace egami {
|
|||||||
* @param[in] _size Dimention of the file when resizable (SVG).
|
* @param[in] _size Dimention of the file when resizable (SVG).
|
||||||
*/
|
*/
|
||||||
egami::Image load(const std::string& _fileName, const ivec2& _size=ivec2(-1,-1) );
|
egami::Image load(const std::string& _fileName, const ivec2& _size=ivec2(-1,-1) );
|
||||||
|
/**
|
||||||
|
* @brief Load a specific ilage file in the requested image data.
|
||||||
|
* @param[in] _mineType mineType of the buffer.
|
||||||
|
* @param[in] _buffer memory file.
|
||||||
|
* @param[in] _size Dimention of the file when resizable (SVG).
|
||||||
|
*/
|
||||||
|
egami::Image load(const std::string& _mineType, const std::vector<uint8_t>& _buffer, const ivec2& _size=ivec2(-1,-1) );
|
||||||
/**
|
/**
|
||||||
* @brief Save an image in a file.
|
* @brief Save an image in a file.
|
||||||
* @param[in] _input Data of the image.
|
* @param[in] _input Data of the image.
|
||||||
@ -26,6 +33,13 @@ namespace egami {
|
|||||||
* @return true if the file is corectly Stored, false otherwise
|
* @return true if the file is corectly Stored, false otherwise
|
||||||
*/
|
*/
|
||||||
bool store(const egami::Image& _input, const std::string& _fileName);
|
bool store(const egami::Image& _input, const std::string& _fileName);
|
||||||
|
/**
|
||||||
|
* @brief Save an image in a memory buffer.
|
||||||
|
* @param[in] _input Data of the image.
|
||||||
|
* @param[out] _buffer Store file in this buffer.
|
||||||
|
* @return true if the file is corectly Stored, false otherwise
|
||||||
|
*/
|
||||||
|
bool store(const egami::Image& _input, std::vector<uint8_t>& _buffer);
|
||||||
/**
|
/**
|
||||||
* @brief know if a file can have multiple size definition.
|
* @brief know if a file can have multiple size definition.
|
||||||
* @param[in] _fileName Name of the file.
|
* @param[in] _fileName Name of the file.
|
||||||
|
@ -106,9 +106,22 @@ static void display(struct bitmapFileHeader _header, struct bitmapInfoHeader _in
|
|||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
egami::Image egami::loadBMP(const std::string& _inputFile) {
|
egami::Image egami::loadBMP(const std::string& _inputFile) {
|
||||||
|
etk::FSNode fileName(_inputFile);
|
||||||
|
if (fileName.exist() == false) {
|
||||||
|
EGAMI_ERROR("File does not existed='" << fileName << "'");
|
||||||
|
return egami::Image();
|
||||||
|
}
|
||||||
|
if(fileName.fileOpenRead() == false) {
|
||||||
|
EGAMI_ERROR("Can not find the file name='" << fileName << "'");
|
||||||
|
return egami::Image();
|
||||||
|
}
|
||||||
|
std::vector<uint8_t> allData = fileName.fileReadAll<uint8_t>();
|
||||||
|
fileName.fileClose();
|
||||||
|
return egami::loadBMP(allData);
|
||||||
|
}
|
||||||
|
|
||||||
|
egami::Image egami::loadBMP(const std::vector<uint8_t>& _buffer) {
|
||||||
egami::Image out;
|
egami::Image out;
|
||||||
enum modeBitmap m_dataMode = BITS_16_R5G6B5;
|
enum modeBitmap m_dataMode = BITS_16_R5G6B5;
|
||||||
int32_t m_width = 0;
|
int32_t m_width = 0;
|
||||||
@ -117,34 +130,18 @@ egami::Image egami::loadBMP(const std::string& _inputFile) {
|
|||||||
bool useExtended = false;
|
bool useExtended = false;
|
||||||
struct bitmapInfoHeader m_InfoHeader;
|
struct bitmapInfoHeader m_InfoHeader;
|
||||||
struct bitmapInfoHeaderExtended m_InfoHeaderExtended;
|
struct bitmapInfoHeaderExtended m_InfoHeaderExtended;
|
||||||
|
if (_buffer.size() < sizeof(struct bitmapFileHeader)) {
|
||||||
etk::FSNode fileName(_inputFile);
|
EGAMI_ERROR("error loading file header, not enough data");
|
||||||
// get the fileSize ...
|
|
||||||
/*if (fileName.size() < (int32_t)(sizeof(struct bitmapFileHeader) + sizeof(struct bitmapFileHeader) ) ) {
|
|
||||||
EGAMI_ERROR("not enought data in the file named=\"" << fileName << "\"");
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
if (fileName.exist() == false) {
|
|
||||||
EGAMI_ERROR("File does not existed=\"" << fileName << "\"");
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
if(fileName.fileOpenRead() ==false) {
|
|
||||||
EGAMI_ERROR("Can not find the file name=\"" << fileName << "\"");
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
// get the data :
|
|
||||||
if (fileName.fileRead(&m_FileHeader,sizeof(struct bitmapFileHeader),1) != 1) {
|
|
||||||
EGAMI_ERROR("error loading file header");
|
|
||||||
fileName.fileClose();
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
memcpy(&m_FileHeader, &_buffer[0], sizeof(struct bitmapFileHeader));
|
||||||
if (m_FileHeader.bfOffBits > sizeof(struct bitmapFileHeader) + sizeof(struct bitmapInfoHeader)) {
|
if (m_FileHeader.bfOffBits > sizeof(struct bitmapFileHeader) + sizeof(struct bitmapInfoHeader)) {
|
||||||
EGAMI_VERBOSE("Read bitmap in EXTENDED mode ...");
|
EGAMI_VERBOSE("Read bitmap in EXTENDED mode ...");
|
||||||
if (fileName.fileRead(&m_InfoHeaderExtended,sizeof(struct bitmapInfoHeaderExtended),1) != 1) {
|
if (_buffer.size() < sizeof(struct bitmapFileHeader) + sizeof(struct bitmapInfoHeaderExtended)) {
|
||||||
EGAMI_ERROR("error loading file header");
|
EGAMI_ERROR("error loading file header, not enough data");
|
||||||
fileName.fileClose();
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
memcpy(&m_FileHeader, &_buffer[sizeof(struct bitmapFileHeader)], sizeof(struct bitmapInfoHeaderExtended));
|
||||||
useExtended = true;
|
useExtended = true;
|
||||||
m_InfoHeader.biSize = m_InfoHeaderExtended.biSize;
|
m_InfoHeader.biSize = m_InfoHeaderExtended.biSize;
|
||||||
m_InfoHeader.biWidth = m_InfoHeaderExtended.biWidth;
|
m_InfoHeader.biWidth = m_InfoHeaderExtended.biWidth;
|
||||||
@ -158,29 +155,22 @@ egami::Image egami::loadBMP(const std::string& _inputFile) {
|
|||||||
m_InfoHeader.biYPelsPerMeter = m_InfoHeaderExtended.biYPelsPerMeter;
|
m_InfoHeader.biYPelsPerMeter = m_InfoHeaderExtended.biYPelsPerMeter;
|
||||||
} else {
|
} else {
|
||||||
EGAMI_VERBOSE("Read bitmap in BASIC mode ...");
|
EGAMI_VERBOSE("Read bitmap in BASIC mode ...");
|
||||||
if (fileName.fileRead(&m_InfoHeader,sizeof(struct bitmapInfoHeader),1) != 1) {
|
if (_buffer.size() < sizeof(struct bitmapFileHeader) + sizeof(struct bitmapInfoHeader)) {
|
||||||
EGAMI_ERROR("error loading file header");
|
EGAMI_ERROR("error loading file header, not enough data");
|
||||||
fileName.fileClose();
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
memcpy(&m_FileHeader, &_buffer[sizeof(struct bitmapFileHeader)], sizeof(struct bitmapInfoHeader));
|
||||||
useExtended = false;
|
useExtended = false;
|
||||||
}
|
}
|
||||||
|
int32_t offset = m_FileHeader.bfOffBits;
|
||||||
//display(m_FileHeader, m_InfoHeader);
|
//display(m_FileHeader, m_InfoHeader);
|
||||||
//EGAMI_ERROR("plopppppppppppppp " << m_FileHeader.bfOffBits);
|
|
||||||
if(fileName.fileSeek(m_FileHeader.bfOffBits, etk::seekNode_start) == false) {
|
|
||||||
EGAMI_ERROR("error with the 'bfOffBits' in the file named=\"" << fileName << "\"");
|
|
||||||
fileName.fileClose();
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
// check the header error :
|
// check the header error :
|
||||||
if (m_FileHeader.bfType != 0x4D42) {
|
if (m_FileHeader.bfType != 0x4D42) {
|
||||||
EGAMI_ERROR("the file=\"" << fileName << "\" is not a bitmap file ...");
|
EGAMI_ERROR("the Buffer is not a bitmap file ...");
|
||||||
fileName.fileClose();
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
if (m_FileHeader.bfReserved != 0x00000000) {
|
if (m_FileHeader.bfReserved != 0x00000000) {
|
||||||
EGAMI_ERROR("the bfReserved feald is not at 0 == > not supported format ...");
|
EGAMI_ERROR("the bfReserved feald is not at 0 == > not supported format ...");
|
||||||
fileName.fileClose();
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
m_width = m_InfoHeader.biWidth;
|
m_width = m_InfoHeader.biWidth;
|
||||||
@ -207,25 +197,21 @@ egami::Image egami::loadBMP(const std::string& _inputFile) {
|
|||||||
out.configure(ivec2(m_width,m_height), egami::colorType::RGBA8);
|
out.configure(ivec2(m_width,m_height), egami::colorType::RGBA8);
|
||||||
} else {
|
} else {
|
||||||
EGAMI_ERROR("the biBitCount & biCompression fealds are unknow == > not supported format ...");
|
EGAMI_ERROR("the biBitCount & biCompression fealds are unknow == > not supported format ...");
|
||||||
fileName.fileClose();;
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> m_data;
|
|
||||||
if(m_InfoHeader.biSizeImage != 0) {
|
if(m_InfoHeader.biSizeImage != 0) {
|
||||||
m_data.resize(m_InfoHeader.biSizeImage, 0);
|
if (_buffer.size() < offset + m_InfoHeader.biSizeImage) {
|
||||||
if (fileName.fileRead(&m_data[0],m_InfoHeader.biSizeImage,1) != 1){
|
|
||||||
EGAMI_CRITICAL("Can not read the file with the good size...");
|
EGAMI_CRITICAL("Can not read the file with the good size...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fileName.fileClose();
|
|
||||||
|
|
||||||
etk::Color<> tmpColor(0,0,0,0);
|
etk::Color<> tmpColor(0,0,0,0);
|
||||||
|
|
||||||
// need now to generate RGBA data ...
|
// need now to generate RGBA data ...
|
||||||
switch(m_dataMode) {
|
switch(m_dataMode) {
|
||||||
case BITS_16_R5G6B5: {
|
case BITS_16_R5G6B5: {
|
||||||
uint16_t * pointer = (uint16_t*)(&m_data[0]);
|
const uint16_t * pointer = (const uint16_t*)(&_buffer[offset]);
|
||||||
for(int32_t yyy=0; yyy<m_height; yyy++) {
|
for(int32_t yyy=0; yyy<m_height; yyy++) {
|
||||||
for(int32_t xxx=0; xxx<m_width; xxx++) {
|
for(int32_t xxx=0; xxx<m_width; xxx++) {
|
||||||
tmpColor.setB((uint8_t)((*pointer & 0xF800) >> 8));
|
tmpColor.setB((uint8_t)((*pointer & 0xF800) >> 8));
|
||||||
@ -239,7 +225,7 @@ egami::Image egami::loadBMP(const std::string& _inputFile) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BITS_16_X1R5G5B5: {
|
case BITS_16_X1R5G5B5: {
|
||||||
uint16_t * pointer = (uint16_t*)(&m_data[0]);
|
const uint16_t * pointer = (const uint16_t*)(&_buffer[offset]);
|
||||||
for(int32_t yyy=0; yyy<m_height; yyy++) {
|
for(int32_t yyy=0; yyy<m_height; yyy++) {
|
||||||
for(int32_t xxx=0; xxx<m_width; xxx++) {
|
for(int32_t xxx=0; xxx<m_width; xxx++) {
|
||||||
tmpColor.setB((int8_t)((*pointer & 0x7C00) >> 7));
|
tmpColor.setB((int8_t)((*pointer & 0x7C00) >> 7));
|
||||||
@ -262,7 +248,7 @@ egami::Image egami::loadBMP(const std::string& _inputFile) {
|
|||||||
} else if ((baseLine%4) == 3) {
|
} else if ((baseLine%4) == 3) {
|
||||||
offset = 1;
|
offset = 1;
|
||||||
}
|
}
|
||||||
uint8_t * pointer = (&m_data[0]);
|
const uint8_t * pointer = (&_buffer[offset]);
|
||||||
for(int32_t yyy=0; yyy<m_height; yyy++) {
|
for(int32_t yyy=0; yyy<m_height; yyy++) {
|
||||||
for(int32_t xxx=0; xxx<m_width; xxx++) {
|
for(int32_t xxx=0; xxx<m_width; xxx++) {
|
||||||
tmpColor.setB(*pointer++);
|
tmpColor.setB(*pointer++);
|
||||||
@ -278,7 +264,7 @@ egami::Image egami::loadBMP(const std::string& _inputFile) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BITS_32_X8R8G8B8: {
|
case BITS_32_X8R8G8B8: {
|
||||||
uint8_t * pointer = (&m_data[0]);
|
const uint8_t * pointer = (&_buffer[offset]);
|
||||||
for(int32_t yyy=0; yyy<m_height; yyy++) {
|
for(int32_t yyy=0; yyy<m_height; yyy++) {
|
||||||
for(int32_t xxx=0; xxx<m_width; xxx++) {
|
for(int32_t xxx=0; xxx<m_width; xxx++) {
|
||||||
pointer++;
|
pointer++;
|
||||||
@ -292,7 +278,7 @@ egami::Image egami::loadBMP(const std::string& _inputFile) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BITS_32_A8R8G8B8: {
|
case BITS_32_A8R8G8B8: {
|
||||||
uint8_t * pointer = (&m_data[0]);
|
const uint8_t * pointer = (&_buffer[offset]);
|
||||||
for(int32_t yyy=0; yyy<m_height; yyy++) {
|
for(int32_t yyy=0; yyy<m_height; yyy++) {
|
||||||
for(int32_t xxx=0; xxx<m_width; xxx++) {
|
for(int32_t xxx=0; xxx<m_width; xxx++) {
|
||||||
tmpColor.setB(*pointer++);
|
tmpColor.setB(*pointer++);
|
||||||
|
@ -14,6 +14,12 @@ namespace egami {
|
|||||||
* @return Generate image or empty image
|
* @return Generate image or empty image
|
||||||
*/
|
*/
|
||||||
egami::Image loadBMP(const std::string& _fileName);
|
egami::Image loadBMP(const std::string& _fileName);
|
||||||
|
/**
|
||||||
|
* @breif Load a bmp file in the image.
|
||||||
|
* @param[in] _buffer file buffer
|
||||||
|
* @return Generate image or empty image
|
||||||
|
*/
|
||||||
|
egami::Image loadBMP(const std::vector<uint8_t>& _buffer);
|
||||||
/**
|
/**
|
||||||
* @breif Store a bmp file in the image.
|
* @breif Store a bmp file in the image.
|
||||||
* @param[in] _fileName Name of the file.
|
* @param[in] _fileName Name of the file.
|
||||||
|
@ -40,19 +40,22 @@ void put_scanline_someplace(const uint8_t* _buffer, int32_t _row_stride) {
|
|||||||
|
|
||||||
|
|
||||||
egami::Image egami::loadJPG(const std::string& _inputFile) {
|
egami::Image egami::loadJPG(const std::string& _inputFile) {
|
||||||
egami::Image out;
|
|
||||||
etk::FSNode fileName(_inputFile);
|
etk::FSNode fileName(_inputFile);
|
||||||
if (fileName.exist() == false) {
|
if (fileName.exist() == false) {
|
||||||
EGAMI_ERROR("File does not existed='" << fileName << "'");
|
EGAMI_ERROR("File does not existed='" << fileName << "'");
|
||||||
return out;
|
return egami::Image();
|
||||||
}
|
}
|
||||||
if(fileName.fileOpenRead() == false) {
|
if(fileName.fileOpenRead() == false) {
|
||||||
EGAMI_ERROR("Can not find the file name='" << fileName << "'");
|
EGAMI_ERROR("Can not find the file name='" << fileName << "'");
|
||||||
return out;
|
return egami::Image();
|
||||||
}
|
}
|
||||||
std::vector<uint8_t> allData = fileName.fileReadAll<uint8_t>();
|
std::vector<uint8_t> allData = fileName.fileReadAll<uint8_t>();
|
||||||
fileName.fileClose();
|
fileName.fileClose();
|
||||||
|
return egami::loadJPG(allData);
|
||||||
|
}
|
||||||
|
|
||||||
|
egami::Image egami::loadJPG(const std::vector<uint8_t>& _buffer) {
|
||||||
|
egami::Image out;
|
||||||
// This struct contains the JPEG decompression parameters and pointers to working space (which is allocated as needed by the JPEG library).
|
// This struct contains the JPEG decompression parameters and pointers to working space (which is allocated as needed by the JPEG library).
|
||||||
struct jpeg_decompress_struct cinfo;
|
struct jpeg_decompress_struct cinfo;
|
||||||
// We use our private extension JPEG error handler. Note that this struct must live as long as the main JPEG parameter struct, to avoid dangling-pointer problems.
|
// We use our private extension JPEG error handler. Note that this struct must live as long as the main JPEG parameter struct, to avoid dangling-pointer problems.
|
||||||
@ -76,7 +79,7 @@ egami::Image egami::loadJPG(const std::string& _inputFile) {
|
|||||||
jpeg_create_decompress(&cinfo);
|
jpeg_create_decompress(&cinfo);
|
||||||
|
|
||||||
// Step 2: specify data source (eg, a file)
|
// Step 2: specify data source (eg, a file)
|
||||||
jpeg_mem_src(&cinfo, &allData[0], allData.size());
|
jpeg_mem_src(&cinfo, &_buffer[0], _buffer.size());
|
||||||
|
|
||||||
// Step 3: read file parameters with jpeg_read_header()
|
// Step 3: read file parameters with jpeg_read_header()
|
||||||
(void)jpeg_read_header(&cinfo, TRUE);
|
(void)jpeg_read_header(&cinfo, TRUE);
|
||||||
|
@ -14,5 +14,11 @@ namespace egami {
|
|||||||
* @return Read Image.
|
* @return Read Image.
|
||||||
*/
|
*/
|
||||||
egami::Image loadJPG(const std::string& _fileName);
|
egami::Image loadJPG(const std::string& _fileName);
|
||||||
|
/**
|
||||||
|
* @breif Load a jpeg file in the image.
|
||||||
|
* @param[in] _buffer file Buffer
|
||||||
|
* @return Read Image.
|
||||||
|
*/
|
||||||
|
egami::Image loadJPG(const std::vector<uint8_t>& _buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,12 +10,47 @@
|
|||||||
#include <egami/wrapperPNG.hpp>
|
#include <egami/wrapperPNG.hpp>
|
||||||
#include <etk/os/FSNode.hpp>
|
#include <etk/os/FSNode.hpp>
|
||||||
#include <png/png.h>
|
#include <png/png.h>
|
||||||
|
namespace egami {
|
||||||
|
class ReaderInstance {
|
||||||
|
public:
|
||||||
|
virtual ~ReaderInstance() = default;
|
||||||
|
virtual void read(png_bytep data, png_size_t length) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReaderInstanceFSNode : public egami::ReaderInstance {
|
||||||
|
private:
|
||||||
|
etk::FSNode& m_data;
|
||||||
|
public:
|
||||||
|
ReaderInstanceFSNode(etk::FSNode& _data):
|
||||||
|
m_data(_data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
void read(png_bytep data, png_size_t length) override {
|
||||||
|
m_data.fileRead(data, 1, length);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReaderInstanceBuffer : public egami::ReaderInstance {
|
||||||
|
private:
|
||||||
|
const std::vector<uint8_t>& m_data;
|
||||||
|
int32_t m_offset;
|
||||||
|
public:
|
||||||
|
ReaderInstanceBuffer(const std::vector<uint8_t>& _data, int32_t _offset):
|
||||||
|
m_data(_data),
|
||||||
|
m_offset(_offset) {
|
||||||
|
|
||||||
|
}
|
||||||
|
void read(png_bytep data, png_size_t length) override {
|
||||||
|
memcpy(data, &m_data[m_offset], length);
|
||||||
|
m_offset += length;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
// we must change the access of the IO of the png lib :
|
// we must change the access of the IO of the png lib :
|
||||||
static void local_ReadData(png_structp png_ptr, png_bytep data, png_size_t length) {
|
static void local_ReadData(png_structp png_ptr, png_bytep data, png_size_t length) {
|
||||||
etk::FSNode* fileNode = static_cast<etk::FSNode*>(png_get_io_ptr(png_ptr));
|
egami::ReaderInstance* instance = static_cast<egami::ReaderInstance*>(png_get_io_ptr(png_ptr));
|
||||||
if (fileNode != nullptr) {
|
if (instance != nullptr) {
|
||||||
fileNode->fileRead(data, 1, length);
|
instance->read(data, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -44,74 +79,18 @@ void user_warning_fn(png_structp _pngPtr, png_const_charp _warningMsg) {
|
|||||||
EGAMI_WARNING("libpng warning: '" << _warningMsg << "'");
|
EGAMI_WARNING("libpng warning: '" << _warningMsg << "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
egami::Image egami::loadPNG(const std::string& _inputFile) {
|
static egami::Image genericLoader(png_structp _pngPtr, png_infop _infoPtr) {
|
||||||
egami::Image out;
|
egami::Image out;
|
||||||
etk::FSNode fileName(_inputFile);
|
|
||||||
if (fileName.exist() == false) {
|
|
||||||
EGAMI_ERROR("File does not existed='" << fileName << "'");
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
if(fileName.fileOpenRead() == false) {
|
|
||||||
EGAMI_ERROR("Can not find the file name='" << fileName << "'");
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
unsigned char header[8];
|
|
||||||
png_infop info_ptr;
|
|
||||||
png_structp png_ptr;
|
|
||||||
|
|
||||||
if (fileName.fileRead(header,1,8) != 8) {
|
|
||||||
EGAMI_ERROR("error loading file header");
|
|
||||||
fileName.fileClose();
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
if (png_sig_cmp(header, 0, 8)) {
|
|
||||||
EGAMI_ERROR("Invalid file :" << fileName);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PNG read setup
|
|
||||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, user_error_fn, user_warning_fn);
|
|
||||||
if (png_ptr == nullptr) {
|
|
||||||
EGAMI_ERROR("Can not Allocate PNG structure");
|
|
||||||
fileName.fileClose();
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
info_ptr = png_create_info_struct(png_ptr);
|
|
||||||
if (info_ptr == nullptr) {
|
|
||||||
EGAMI_ERROR("Can not Allocate PNG info structure");
|
|
||||||
png_destroy_read_struct(&png_ptr, nullptr, nullptr);
|
|
||||||
fileName.fileClose();
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
|
||||||
EGAMI_ERROR(" Can not set the JUMP buffer adresses");
|
|
||||||
// Free all of the memory associated with the png_ptr and info_ptr
|
|
||||||
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
|
|
||||||
fileName.fileClose();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// overwrite the read and write function :
|
|
||||||
png_set_read_fn(png_ptr,
|
|
||||||
&fileName,
|
|
||||||
&local_ReadData);
|
|
||||||
/*
|
|
||||||
png_set_write_fn(png_ptr,
|
|
||||||
&fileName,
|
|
||||||
&LocalWriteData,
|
|
||||||
&localFlushData);
|
|
||||||
*/
|
|
||||||
// If we have already read some of the signature
|
// If we have already read some of the signature
|
||||||
png_set_sig_bytes(png_ptr, 8);
|
png_set_sig_bytes(_pngPtr, 8);
|
||||||
|
|
||||||
png_read_info(png_ptr, info_ptr);
|
png_read_info(_pngPtr, _infoPtr);
|
||||||
png_uint_32 width = 0;
|
png_uint_32 width = 0;
|
||||||
png_uint_32 height = 0;
|
png_uint_32 height = 0;
|
||||||
int bit_depth = 0;
|
int bit_depth = 0;
|
||||||
int colorType = 0;
|
int colorType = 0;
|
||||||
int interlace_type = 0;
|
int interlace_type = 0;
|
||||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &colorType, &interlace_type, nullptr, nullptr);
|
png_get_IHDR(_pngPtr, _infoPtr, &width, &height, &bit_depth, &colorType, &interlace_type, nullptr, nullptr);
|
||||||
// reallocate the image
|
// reallocate the image
|
||||||
EGAMI_VERBOSE("Load PNG image : (" << width << "," << height << ")" );
|
EGAMI_VERBOSE("Load PNG image : (" << width << "," << height << ")" );
|
||||||
switch (colorType) {
|
switch (colorType) {
|
||||||
@ -133,34 +112,34 @@ egami::Image egami::loadPNG(const std::string& _inputFile) {
|
|||||||
|
|
||||||
// Tell libpng to strip 16 bits/color files down to 8 bits/color. Use accurate scaling if it's available, otherwise just chop off the low byte.
|
// Tell libpng to strip 16 bits/color files down to 8 bits/color. Use accurate scaling if it's available, otherwise just chop off the low byte.
|
||||||
#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
|
#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
|
||||||
png_set_scale_16(png_ptr);
|
png_set_scale_16(_pngPtr);
|
||||||
#else
|
#else
|
||||||
png_set_strip_16(png_ptr);
|
png_set_strip_16(_pngPtr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Strip alpha bytes from the input data without combining with the background (not recommended).
|
// Strip alpha bytes from the input data without combining with the background (not recommended).
|
||||||
//png_set_strip_alpha(png_ptr);
|
//png_set_strip_alpha(_pngPtr);
|
||||||
|
|
||||||
// Extract multiple pixels with bit depths of 1, 2, and 4 from a single byte into separate bytes (useful for paletted and grayscale images).
|
// Extract multiple pixels with bit depths of 1, 2, and 4 from a single byte into separate bytes (useful for paletted and grayscale images).
|
||||||
png_set_packing(png_ptr);
|
png_set_packing(_pngPtr);
|
||||||
|
|
||||||
// Change the order of packed pixels to least significant bit first (not useful if you are using png_set_packing).
|
// Change the order of packed pixels to least significant bit first (not useful if you are using png_set_packing).
|
||||||
png_set_packswap(png_ptr);
|
png_set_packswap(_pngPtr);
|
||||||
|
|
||||||
/* Expand paletted colors into true RGB triplets */
|
/* Expand paletted colors into true RGB triplets */
|
||||||
if (colorType == PNG_COLOR_TYPE_PALETTE) {
|
if (colorType == PNG_COLOR_TYPE_PALETTE) {
|
||||||
png_set_palette_to_rgb(png_ptr);
|
png_set_palette_to_rgb(_pngPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel
|
// Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel
|
||||||
if ( colorType == PNG_COLOR_TYPE_GRAY
|
if ( colorType == PNG_COLOR_TYPE_GRAY
|
||||||
&& bit_depth < 8) {
|
&& bit_depth < 8) {
|
||||||
png_set_expand_gray_1_2_4_to_8(png_ptr);
|
png_set_expand_gray_1_2_4_to_8(_pngPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expand paletted or RGB images with transparency to full alpha channels so the data will be available as RGBA quartets.
|
// Expand paletted or RGB images with transparency to full alpha channels so the data will be available as RGBA quartets.
|
||||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) != 0) {
|
if (png_get_valid(_pngPtr, _infoPtr, PNG_INFO_tRNS) != 0) {
|
||||||
png_set_tRNS_to_alpha(png_ptr);
|
png_set_tRNS_to_alpha(_pngPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the background color to draw transparent and alpha images over.
|
/* Set the background color to draw transparent and alpha images over.
|
||||||
@ -171,19 +150,19 @@ egami::Image egami::loadPNG(const std::string& _inputFile) {
|
|||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
png_color::16 my_background, *image_background;
|
png_color::16 my_background, *image_background;
|
||||||
if (png_get_bKGD(png_ptr, info_ptr, &image_background) != 0) {
|
if (png_get_bKGD(_pngPtr, _infoPtr, &image_background) != 0) {
|
||||||
png_set_background(png_ptr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
|
png_set_background(_pngPtr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
|
||||||
} else {
|
} else {
|
||||||
png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
|
png_set_background(_pngPtr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
/* Optional call to gamma correct and add the background to the palette
|
/* Optional call to gamma correct and add the background to the palette
|
||||||
* and update info structure. REQUIRED if you are expecting libpng to
|
* and update info structure. REQUIRED if you are expecting libpng to
|
||||||
* update the palette for you (ie you selected such a transform above).
|
* update the palette for you (ie you selected such a transform above).
|
||||||
*/
|
*/
|
||||||
png_read_update_info(png_ptr, info_ptr);
|
png_read_update_info(_pngPtr, _infoPtr);
|
||||||
|
|
||||||
// Allocate the memory to hold the image using the fields of info_ptr.
|
// Allocate the memory to hold the image using the fields of _infoPtr.
|
||||||
// The easiest way to read the image:
|
// The easiest way to read the image:
|
||||||
png_bytep row_pointers[height];
|
png_bytep row_pointers[height];
|
||||||
/* Clear the pointer array */
|
/* Clear the pointer array */
|
||||||
@ -191,15 +170,13 @@ egami::Image egami::loadPNG(const std::string& _inputFile) {
|
|||||||
row_pointers[row] = nullptr;
|
row_pointers[row] = nullptr;
|
||||||
}
|
}
|
||||||
for (png_uint_32 row = 0; row < height; row++) {
|
for (png_uint_32 row = 0; row < height; row++) {
|
||||||
row_pointers[row] = (png_bytep)png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
|
row_pointers[row] = (png_bytep)png_malloc(_pngPtr, png_get_rowbytes(_pngPtr, _infoPtr));
|
||||||
}
|
}
|
||||||
EGAMI_DEBUG("Load image: " << _inputFile);
|
png_read_image(_pngPtr, row_pointers);
|
||||||
png_read_image(png_ptr, row_pointers);
|
// Read rest of file, and get additional chunks in _infoPtr - REQUIRED
|
||||||
EGAMI_DEBUG("Load image: " << _inputFile << " DONE");
|
png_read_end(_pngPtr, _infoPtr);
|
||||||
// Read rest of file, and get additional chunks in info_ptr - REQUIRED
|
|
||||||
png_read_end(png_ptr, info_ptr);
|
|
||||||
|
|
||||||
//png_set_expand(png_ptr);
|
//png_set_expand(_pngPtr);
|
||||||
|
|
||||||
etk::Color<> tmpColor(0,0,0,0);
|
etk::Color<> tmpColor(0,0,0,0);
|
||||||
switch (colorType) {
|
switch (colorType) {
|
||||||
@ -252,21 +229,117 @@ egami::Image egami::loadPNG(const std::string& _inputFile) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
EGAMI_ERROR("Must be RGB+alpha?/GRAY+alpha? not supported : " << (int64_t)png_get_color_type(png_ptr, info_ptr));
|
EGAMI_ERROR("Must be RGB+alpha?/GRAY+alpha? not supported : " << (int64_t)png_get_color_type(_pngPtr, _infoPtr));
|
||||||
if ((png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_PALETTE) != 0) {
|
if ((png_get_color_type(_pngPtr, _infoPtr) & PNG_COLOR_MASK_PALETTE) != 0) {
|
||||||
EGAMI_ERROR(" palette");
|
EGAMI_ERROR(" palette");
|
||||||
}
|
}
|
||||||
if ((png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_COLOR) != 0) {
|
if ((png_get_color_type(_pngPtr, _infoPtr) & PNG_COLOR_MASK_COLOR) != 0) {
|
||||||
EGAMI_ERROR(" color");
|
EGAMI_ERROR(" color");
|
||||||
}
|
}
|
||||||
if ((png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_ALPHA) != 0) {
|
if ((png_get_color_type(_pngPtr, _infoPtr) & PNG_COLOR_MASK_ALPHA) != 0) {
|
||||||
EGAMI_ERROR(" Alpha");
|
EGAMI_ERROR(" Alpha");
|
||||||
}
|
}
|
||||||
return egami::Image();
|
return egami::Image();
|
||||||
}
|
}
|
||||||
fileName.fileClose();
|
|
||||||
// Clean up after the read, and free any memory allocated - REQUIRED
|
// Clean up after the read, and free any memory allocated - REQUIRED
|
||||||
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
|
png_destroy_read_struct(&_pngPtr, &_infoPtr, nullptr);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
egami::Image egami::loadPNG(const std::string& _inputFile) {
|
||||||
|
egami::Image out;
|
||||||
|
etk::FSNode fileName(_inputFile);
|
||||||
|
if (fileName.exist() == false) {
|
||||||
|
EGAMI_ERROR("File does not existed='" << fileName << "'");
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
if(fileName.fileOpenRead() == false) {
|
||||||
|
EGAMI_ERROR("Can not find the file name='" << fileName << "'");
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
unsigned char header[8];
|
||||||
|
|
||||||
|
if (fileName.fileRead(header,1,8) != 8) {
|
||||||
|
EGAMI_ERROR("error loading file header");
|
||||||
|
fileName.fileClose();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
if (png_sig_cmp(header, 0, 8)) {
|
||||||
|
EGAMI_ERROR("Invalid file :" << fileName);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PNG read setup
|
||||||
|
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, user_error_fn, user_warning_fn);
|
||||||
|
if (png_ptr == nullptr) {
|
||||||
|
EGAMI_ERROR("Can not Allocate PNG structure");
|
||||||
|
fileName.fileClose();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||||
|
if (info_ptr == nullptr) {
|
||||||
|
EGAMI_ERROR("Can not Allocate PNG info structure");
|
||||||
|
png_destroy_read_struct(&png_ptr, nullptr, nullptr);
|
||||||
|
fileName.fileClose();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||||
|
EGAMI_ERROR(" Can not set the JUMP buffer adresses");
|
||||||
|
// Free all of the memory associated with the png_ptr and info_ptr
|
||||||
|
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
|
||||||
|
fileName.fileClose();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
ReaderInstanceFSNode tmpNode(fileName);
|
||||||
|
|
||||||
|
ReaderInstance* tmpPoiter = &tmpNode;
|
||||||
|
|
||||||
|
// overwrite the read and write function :
|
||||||
|
png_set_read_fn(png_ptr,
|
||||||
|
tmpPoiter,
|
||||||
|
&local_ReadData);
|
||||||
|
/*
|
||||||
|
png_set_write_fn(png_ptr,
|
||||||
|
&fileName,
|
||||||
|
&LocalWriteData,
|
||||||
|
&localFlushData);
|
||||||
|
*/
|
||||||
|
out = genericLoader(png_ptr, info_ptr);
|
||||||
|
fileName.fileClose();
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
egami::Image egami::loadPNG(const std::vector<uint8_t>& _buffer) {
|
||||||
|
egami::Image out;
|
||||||
|
unsigned char header[8];
|
||||||
|
if (png_sig_cmp(&_buffer[0], 0, 8)) {
|
||||||
|
EGAMI_ERROR("Invalid start buffer:");
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PNG read setup
|
||||||
|
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, user_error_fn, user_warning_fn);
|
||||||
|
if (png_ptr == nullptr) {
|
||||||
|
EGAMI_ERROR("Can not Allocate PNG structure");
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||||
|
if (info_ptr == nullptr) {
|
||||||
|
EGAMI_ERROR("Can not Allocate PNG info structure");
|
||||||
|
png_destroy_read_struct(&png_ptr, nullptr, nullptr);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
egami::ReaderInstanceBuffer tmpNode(_buffer, 8);
|
||||||
|
|
||||||
|
egami::ReaderInstance* tmpPoiter = &tmpNode;
|
||||||
|
|
||||||
|
// overwrite the read and write function :
|
||||||
|
png_set_read_fn(png_ptr,
|
||||||
|
tmpPoiter,
|
||||||
|
&local_ReadData);
|
||||||
|
out = genericLoader(png_ptr, info_ptr);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
@ -14,5 +14,11 @@ namespace egami {
|
|||||||
* @return Read Image.
|
* @return Read Image.
|
||||||
*/
|
*/
|
||||||
egami::Image loadPNG(const std::string& _fileName);
|
egami::Image loadPNG(const std::string& _fileName);
|
||||||
|
/**
|
||||||
|
* @breif Load a png file in the image.
|
||||||
|
* @param[in] _buffer File buffer.
|
||||||
|
* @return Read Image.
|
||||||
|
*/
|
||||||
|
egami::Image loadPNG(const std::vector<uint8_t>& _buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user