[DEV] write on buffer

This commit is contained in:
Edouard DUPIN 2017-10-09 23:47:42 +02:00
parent 99eae9d10f
commit fc67e46de5
5 changed files with 169 additions and 103 deletions

View File

@ -56,7 +56,7 @@ egami::Image egami::load(const etk::String& _fileName, const ivec2& _size) {
EGAMI_ERROR("Error to load SVG file '" << _fileName << "'"); EGAMI_ERROR("Error to load SVG file '" << _fileName << "'");
} }
#else #else
EGAMI_WARNING("egamy not compile with the ESVG dependency for file '" << _fileName << "'"); EGAMI_WARNING("egami not compile with the ESVG dependency for file '" << _fileName << "'");
#endif #endif
} else if (etk::end_with(tmpName, ".png") == true) { } else if (etk::end_with(tmpName, ".png") == true) {
#ifdef EGAMI_BUILD_PNG #ifdef EGAMI_BUILD_PNG
@ -65,7 +65,7 @@ egami::Image egami::load(const etk::String& _fileName, const ivec2& _size) {
EGAMI_ERROR("Error to load PNG file '" << _fileName << "'"); EGAMI_ERROR("Error to load PNG file '" << _fileName << "'");
} }
#else #else
EGAMI_WARNING("egamy not compile with the PNG dependency for file '" << _fileName << "'"); EGAMI_WARNING("egami not compile with the PNG dependency for file '" << _fileName << "'");
#endif #endif
} else if (etk::end_with(tmpName, ".jpg") == true) { } else if (etk::end_with(tmpName, ".jpg") == true) {
#ifdef EGAMI_BUILD_JPEG #ifdef EGAMI_BUILD_JPEG
@ -74,7 +74,7 @@ egami::Image egami::load(const etk::String& _fileName, const ivec2& _size) {
EGAMI_ERROR("Error to load JPG file '" << _fileName << "'"); EGAMI_ERROR("Error to load JPG file '" << _fileName << "'");
} }
#else #else
EGAMI_WARNING("egamy not compile with the JPEG dependency for file '" << _fileName << "'"); EGAMI_WARNING("egami not compile with the JPEG dependency for file '" << _fileName << "'");
#endif #endif
} else if (etk::end_with(tmpName, ".j2k") == true) { } else if (etk::end_with(tmpName, ".j2k") == true) {
#ifdef EGAMI_BUILD_JPEG2000 #ifdef EGAMI_BUILD_JPEG2000
@ -83,7 +83,7 @@ egami::Image egami::load(const etk::String& _fileName, const ivec2& _size) {
EGAMI_ERROR("Error to load JPEG2000 file '" << _fileName << "'"); EGAMI_ERROR("Error to load JPEG2000 file '" << _fileName << "'");
} }
#else #else
EGAMI_WARNING("egamy not compile with the JPEG 2000 (openjpeg) dependency for file '" << _fileName << "'"); EGAMI_WARNING("egami not compile with the JPEG 2000 (openjpeg) dependency for file '" << _fileName << "'");
#endif #endif
} else if (etk::end_with(tmpName, ".tif") == true) { } else if (etk::end_with(tmpName, ".tif") == true) {
#ifdef EGAMI_BUILD_TIFF #ifdef EGAMI_BUILD_TIFF
@ -92,7 +92,7 @@ egami::Image egami::load(const etk::String& _fileName, const ivec2& _size) {
EGAMI_ERROR("Error to load TIFF file '" << _fileName << "'"); EGAMI_ERROR("Error to load TIFF file '" << _fileName << "'");
} }
#else #else
EGAMI_WARNING("egamy not compile with the TIFF dependency for file '" << _fileName << "'"); EGAMI_WARNING("egami not compile with the TIFF dependency for file '" << _fileName << "'");
#endif #endif
} else { } else {
EGAMI_ERROR("Extention not managed '" << _fileName << "' Sopported extention : .edf / .bmp / .svg / .png / .jpg / .j2k / .tif"); EGAMI_ERROR("Extention not managed '" << _fileName << "' Sopported extention : .edf / .bmp / .svg / .png / .jpg / .j2k / .tif");
@ -116,7 +116,7 @@ egami::Image egami::load(const etk::String& _mineType, const etk::Vector<uint8_t
EGAMI_ERROR("Error to load PNG file '" << _buffer.size() << "'"); EGAMI_ERROR("Error to load PNG file '" << _buffer.size() << "'");
} }
#else #else
EGAMI_WARNING("egamy not compile with the PNG dependency for file '" << _buffer.size() << "'"); EGAMI_WARNING("egami not compile with the PNG dependency for file '" << _buffer.size() << "'");
#endif #endif
} else if (_mineType == "image/jpeg") { } else if (_mineType == "image/jpeg") {
#ifdef EGAMI_BUILD_JPEG #ifdef EGAMI_BUILD_JPEG
@ -125,7 +125,7 @@ egami::Image egami::load(const etk::String& _mineType, const etk::Vector<uint8_t
EGAMI_ERROR("Error to load JPG file '" << _buffer.size() << "'"); EGAMI_ERROR("Error to load JPG file '" << _buffer.size() << "'");
} }
#else #else
EGAMI_WARNING("egamy not compile with the JPEG dependency for file '" << _buffer.size() << "'"); EGAMI_WARNING("egami not compile with the JPEG dependency for file '" << _buffer.size() << "'");
#endif #endif
} else { } else {
EGAMI_ERROR("Extention not managed '" << _mineType << "' Sopported extention : image/bmp, image/png, image/jpg"); EGAMI_ERROR("Extention not managed '" << _mineType << "' Sopported extention : image/bmp, image/png, image/jpg");
@ -151,10 +151,15 @@ bool egami::store(const egami::Image& _input, const etk::String& _fileName) {
EGAMI_ERROR("Can not store in SVG file '" << _fileName << "'"); EGAMI_ERROR("Can not store in SVG file '" << _fileName << "'");
return false; return false;
} else if (etk::end_with(tmpName, ".png") == true) { } else if (etk::end_with(tmpName, ".png") == true) {
if (egami::storePNG(_fileName, _input) == false) { #ifdef EGAMI_BUILD_PNG
EGAMI_ERROR("Error to store PNG file '" << _fileName << "'"); if (egami::storePNG(_fileName, _input) == false) {
EGAMI_ERROR("Error to store PNG file '" << _fileName << "'");
return false;
}
#else
EGAMI_WARNING("egami not compile with the PNG dependency for file '" << _fileName << "'");
return false; return false;
} #endif
} else if (etk::end_with(tmpName, ".jpg") == true) { } else if (etk::end_with(tmpName, ".jpg") == true) {
EGAMI_ERROR("Can not store in JPEG file '" << _fileName << "'"); EGAMI_ERROR("Can not store in JPEG file '" << _fileName << "'");
return false; return false;
@ -171,8 +176,32 @@ bool egami::store(const egami::Image& _input, const etk::String& _fileName) {
return true; return true;
} }
bool egami::store(const egami::Image& _input, etk::Vector<uint8_t>& _buffer, const etk::String& _mineType) { bool egami::store(const egami::Image& _input, etk::Vector<uint8_t>& _buffer, const etk::String& _mineType) {
// clear output data.
return false; _buffer.clear();
// select the corect Loader :
if (_mineType == "image/bmp") {
if (egami::storeBMP(_buffer, _input) == false) {
EGAMI_ERROR("Error to store BMP for Raw output");
return false;
}
}else if (_mineType == "image/png") {
#ifdef EGAMI_BUILD_PNG
if (egami::storePNG(_buffer, _input) == false) {
EGAMI_ERROR("Error to store PNG for Raw output");
return false;
}
#else
EGAMI_WARNING("egami not compile with the PNG dependency for Raw output");
return false;
#endif
} else if (_mineType == "image/jpeg") {
EGAMI_ERROR("Can not store in JPEG for Raw output");
return false;
} else {
EGAMI_ERROR("Extention not managed for Raw output Sopported extention: .bmp / .png / .jpg");
return false;
}
return true;
} }

View File

@ -306,6 +306,25 @@ egami::Image egami::loadBMP(const etk::Vector<uint8_t>& _buffer) {
#if 1 #if 1
// Extended mode // Extended mode
bool egami::storeBMP(const etk::String& _fileName, const egami::Image& _inputImage) { bool egami::storeBMP(const etk::String& _fileName, const egami::Image& _inputImage) {
etk::FSNode fileName(_fileName);
EGAMI_VERBOSE("File='" << _fileName << "' ==> " << fileName << " ==> " << fileName.getFileSystemName());
if(fileName.fileOpenWrite() == false) {
EGAMI_ERROR("Can not crete the output file name='" << fileName << "'");
return false;
}
etk::Vector<uint8_t> allData;
bool ret = storeBMP(allData, _inputImage);
fileName.fileWriteAll(allData);
fileName.fileClose();
return ret;
}
bool egami::storeBMP(etk::Vector<uint8_t>& _buffer, const egami::Image& _inputImage) {
_buffer.clear();
_buffer.reserve( _inputImage.getSize().x()*_inputImage.getSize().y()*getFormatColorSize(_inputImage.getType())
+ sizeof(struct bitmapInfoHeaderExtended)
+ sizeof(struct bitmapFileHeader));
struct bitmapFileHeader m_FileHeader; struct bitmapFileHeader m_FileHeader;
struct bitmapInfoHeaderExtended m_InfoHeaderExtended; struct bitmapInfoHeaderExtended m_InfoHeaderExtended;
memset(&m_InfoHeaderExtended, 0, sizeof(bitmapInfoHeaderExtended)); memset(&m_InfoHeaderExtended, 0, sizeof(bitmapInfoHeaderExtended));
@ -350,22 +369,9 @@ bool egami::storeBMP(const etk::String& _fileName, const egami::Image& _inputIma
m_InfoHeaderExtended.biBitMaskBlue = 0xFF000000; m_InfoHeaderExtended.biBitMaskBlue = 0xFF000000;
m_InfoHeaderExtended.biBitMaskAlpha = 0x000000FF; m_InfoHeaderExtended.biBitMaskAlpha = 0x000000FF;
etk::FSNode fileName(_fileName);
if(false == fileName.fileOpenWrite() ) { _buffer.pushBack((uint8_t*)&m_FileHeader, sizeof(struct bitmapFileHeader));
EGAMI_ERROR("Can not find the file name=\"" << fileName << "\""); _buffer.pushBack((uint8_t*)&m_InfoHeaderExtended, sizeof(struct bitmapInfoHeaderExtended));
return false;
}
// Write header:
if (fileName.fileWrite(&m_FileHeader,sizeof(struct bitmapFileHeader),1) != 1) {
EGAMI_ERROR("error loading file header");
fileName.fileClose();
return false;
}
if (fileName.fileWrite(&m_InfoHeaderExtended,sizeof(struct bitmapInfoHeaderExtended),1) != 1) {
EGAMI_ERROR("error loading file header");
fileName.fileClose();
return false;
}
/* TODO: Avec ca, ca ne fonctionne pas ... ==> check /* TODO: Avec ca, ca ne fonctionne pas ... ==> check
if(fileName.fileSeek(m_FileHeader.bfOffBits, etk::FSN_SEEK_START) == false) { if(fileName.fileSeek(m_FileHeader.bfOffBits, etk::FSN_SEEK_START) == false) {
@ -384,7 +390,7 @@ bool egami::storeBMP(const etk::String& _fileName, const egami::Image& _inputIma
*pointer++ = tmpColor.g(); *pointer++ = tmpColor.g();
*pointer++ = tmpColor.b(); *pointer++ = tmpColor.b();
*pointer++ = tmpColor.a(); *pointer++ = tmpColor.a();
fileName.fileWrite(data,4,1); _buffer.pushBack(data, 4);
} }
} }
} else { } else {
@ -396,7 +402,7 @@ bool egami::storeBMP(const etk::String& _fileName, const egami::Image& _inputIma
*pointer++ = tmpColor.b(); *pointer++ = tmpColor.b();
*pointer++ = tmpColor.g(); *pointer++ = tmpColor.g();
*pointer++ = tmpColor.r(); *pointer++ = tmpColor.r();
fileName.fileWrite(data,3,1); _buffer.pushBack(data, 3);
} }
if (offset != 0) { if (offset != 0) {
uint8_t pointer[4]; uint8_t pointer[4];
@ -404,11 +410,10 @@ bool egami::storeBMP(const etk::String& _fileName, const egami::Image& _inputIma
pointer[1] = 0; pointer[1] = 0;
pointer[2] = 0; pointer[2] = 0;
pointer[3] = 0; pointer[3] = 0;
fileName.fileWrite(pointer,1,offset); _buffer.pushBack(pointer, offset);
} }
} }
} }
fileName.fileClose();
return true; return true;
} }
#else #else

View File

@ -27,6 +27,13 @@ namespace egami {
* @return true if all is done correctly, false otherwise. * @return true if all is done correctly, false otherwise.
*/ */
bool storeBMP(const etk::String& _fileName, const egami::Image& _inputImage); bool storeBMP(const etk::String& _fileName, const egami::Image& _inputImage);
/**
* @breif Store a bmp file in the image.
* @param[out] _buffer output file buffer.
* @param[in] _inputImage write data.
* @return true if all is done correctly, false otherwise.
*/
bool storeBMP(etk::Vector<uint8_t>& _buffer, const egami::Image& _inputImage);
} }

View File

@ -357,13 +357,94 @@ egami::Image egami::loadPNG(const etk::Vector<uint8_t>& _buffer) {
return out; return out;
} }
bool egami::storePNG(const etk::String& _fileName, const egami::Image& _inputImage) { bool genericWriter(png_structp png_ptr, png_infop info_ptr, const egami::Image& _inputImage) {
/* create file */ //png_init_io(png_ptr, fp);
/*FILE *fp = fopen(file_name, "wb"); /* write header */
if (!fp) { if (setjmp(png_jmpbuf(png_ptr))) {
abort_("[write_png_file] File %s could not be opened for writing", file_name); EGAMI_ERROR("Error jump setting");
png_destroy_write_struct(&png_ptr, &info_ptr);
return false;
} }
*/ png_byte bitDepth = 8;
png_byte colorType = 0;
switch(_inputImage.getType()) {
case egami::colorType::RGBA8:
colorType = PNG_COLOR_TYPE_RGB_ALPHA;
//bitDepth = 4;
break;
case egami::colorType::RGB8:
colorType = PNG_COLOR_TYPE_RGB;
//bitDepth = 3;
break;
default:
EGAMI_ERROR("PNG can not export an image with other type than RGB and RGBA request:" << _inputImage.getType());
png_destroy_write_struct(&png_ptr, &info_ptr);
return false;
}
png_set_IHDR(png_ptr,
info_ptr,
_inputImage.getSize().x(),
_inputImage.getSize().y(),
bitDepth,
colorType,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);
png_write_info(png_ptr, info_ptr);
/* write bytes */
if (setjmp(png_jmpbuf(png_ptr))) {
EGAMI_ERROR("Error while writing byte");
png_destroy_write_struct(&png_ptr, &info_ptr);
return false;
}
etk::Vector<png_bytep> rowPointers;
rowPointers.resize(_inputImage.getSize().y(), NULL);
uint8_t* imageData = (uint8_t*)_inputImage.getTextureDataPointer();
for (size_t iii=0; iii<rowPointers.size(); ++iii) {
rowPointers[iii] = &imageData[_inputImage.getSize().x()*getFormatColorSize(_inputImage.getType())*iii];
}
png_write_image(png_ptr, &rowPointers[0]);
/* end write */
if (setjmp(png_jmpbuf(png_ptr))) {
EGAMI_ERROR("Error while writing byte");
png_destroy_write_struct(&png_ptr, &info_ptr);
return false;
}
png_write_end(png_ptr, NULL);
png_destroy_write_struct(&png_ptr, &info_ptr);
return true;
}
bool egami::storePNG(etk::Vector<uint8_t>& _buffer, const egami::Image& _inputImage) {
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, userErrorFunction, userWarningFunction);
if (png_ptr == nullptr) {
EGAMI_ERROR("Can not Allocate PNG structure");
return false;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == nullptr) {
EGAMI_ERROR("Can not Allocate PNG info structure");
png_destroy_write_struct(&png_ptr, nullptr);
return false;
}
if (setjmp(png_jmpbuf(png_ptr))) {
EGAMI_ERROR("Error during init_io");
png_destroy_write_struct(&png_ptr, &info_ptr);
return false;
}
egami::ReaderInstanceBuffer tmpNode(_buffer);
egami::ReaderInstance* tmpPointer = &tmpNode;
// overwrite the write functions:
png_set_write_fn(png_ptr,
tmpPointer,
&Local_WriteData,
&local_FlushData);
return genericWriter(png_ptr, info_ptr, _inputImage);
}
bool egami::storePNG(const etk::String& _fileName, const egami::Image& _inputImage) {
etk::FSNode fileName(_fileName); etk::FSNode fileName(_fileName);
if(fileName.fileOpenWrite() == false) { if(fileName.fileOpenWrite() == false) {
EGAMI_ERROR("Can not find the file name='" << fileName << "'"); EGAMI_ERROR("Can not find the file name='" << fileName << "'");
@ -396,71 +477,8 @@ bool egami::storePNG(const etk::String& _fileName, const egami::Image& _inputIma
tmpPoiter, tmpPoiter,
&Local_WriteData, &Local_WriteData,
&local_FlushData); &local_FlushData);
/* bool out = genericWriter(png_ptr, info_ptr, _inputImage);
TODO:
out = genericWriter(png_ptr, info_ptr);
fileName.fileClose(); fileName.fileClose();
*/ return out;
//png_init_io(png_ptr, fp);
/* write header */
if (setjmp(png_jmpbuf(png_ptr))) {
EGAMI_ERROR("Error jump setting");
png_destroy_write_struct(&png_ptr, &info_ptr);
fileName.fileClose();
return false;
}
png_byte bitDepth = 8;
png_byte colorType = 0;
switch(_inputImage.getType()) {
case egami::colorType::RGBA8:
colorType = PNG_COLOR_TYPE_RGB_ALPHA;
//bitDepth = 4;
break;
case egami::colorType::RGB8:
colorType = PNG_COLOR_TYPE_RGB;
//bitDepth = 3;
break;
default:
EGAMI_ERROR("PNG can not export an image with other type than RGB and RGBA request:" << _inputImage.getType());
png_destroy_write_struct(&png_ptr, &info_ptr);
fileName.fileClose();
return false;
}
png_set_IHDR(png_ptr,
info_ptr,
_inputImage.getSize().x(),
_inputImage.getSize().y(),
bitDepth,
colorType,
PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);
png_write_info(png_ptr, info_ptr);
/* write bytes */
if (setjmp(png_jmpbuf(png_ptr))) {
EGAMI_ERROR("Error while writing byte");
png_destroy_write_struct(&png_ptr, &info_ptr);
fileName.fileClose();
return false;
}
etk::Vector<png_bytep> rowPointers;
rowPointers.resize(_inputImage.getSize().y(), NULL);
uint8_t* imageData = (uint8_t*)_inputImage.getTextureDataPointer();
for (size_t iii=0; iii<rowPointers.size(); ++iii) {
rowPointers[iii] = &imageData[_inputImage.getSize().x()*getFormatColorSize(_inputImage.getType())*iii];
}
png_write_image(png_ptr, &rowPointers[0]);
/* end write */
if (setjmp(png_jmpbuf(png_ptr))) {
EGAMI_ERROR("Error while writing byte");
png_destroy_write_struct(&png_ptr, &info_ptr);
fileName.fileClose();
return false;
}
png_write_end(png_ptr, NULL);
png_destroy_write_struct(&png_ptr, &info_ptr);
fileName.fileClose();
return true;
} }

View File

@ -27,5 +27,12 @@ namespace egami {
* @return true if all is done correctly, false otherwise. * @return true if all is done correctly, false otherwise.
*/ */
bool storePNG(const etk::String& _fileName, const egami::Image& _inputImage); bool storePNG(const etk::String& _fileName, const egami::Image& _inputImage);
/**
* @breif Store a PNG file in the image.
* @param[out] _buffer output file buffer.
* @param[in] _inputImage write data.
* @return true if all is done correctly, false otherwise.
*/
bool storePNG(etk::Vector<uint8_t>& _buffer, const egami::Image& _inputImage);
} }