diff --git a/data/read.bmp b/data/read.bmp new file mode 100644 index 0000000..903890b Binary files /dev/null and b/data/read.bmp differ diff --git a/data/read.jpg b/data/read.jpg new file mode 100644 index 0000000..9816a0c Binary files /dev/null and b/data/read.jpg differ diff --git a/data/read.png b/data/read.png new file mode 100644 index 0000000..363c263 Binary files /dev/null and b/data/read.png differ diff --git a/data/read.svg b/data/read.svg new file mode 100644 index 0000000..5cd9ccf --- /dev/null +++ b/data/read.svg @@ -0,0 +1,113 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/data/read2.jpg b/data/read2.jpg new file mode 100644 index 0000000..8966487 Binary files /dev/null and b/data/read2.jpg differ diff --git a/data/read3.jpg b/data/read3.jpg new file mode 100644 index 0000000..2501c61 Binary files /dev/null and b/data/read3.jpg differ diff --git a/data/read4.jpg b/data/read4.jpg new file mode 100644 index 0000000..861aff9 Binary files /dev/null and b/data/read4.jpg differ diff --git a/egami/Image.cpp b/egami/Image.cpp index 0748efe..db449b3 100644 --- a/egami/Image.cpp +++ b/egami/Image.cpp @@ -42,6 +42,39 @@ std::ostream& egami::operator <<(std::ostream& _os, const enum egami::colorType return _os; } +int32_t egami::getFormatColorSize(enum colorType _type) { + switch (_type) { + case egami::colorType::undefined: + return 1; + break; + case egami::colorType::RGBA8: + return 1*4; + break; + case egami::colorType::RGB8: + return 1*3; + break; + case egami::colorType::RGBAf: + return 4*4; + break; + case egami::colorType::RGBf: + return 4*3; + break; + case egami::colorType::unsignedInt16: + return 2; + break; + case egami::colorType::unsignedInt32: + return 4; + break; + case egami::colorType::float32: + return 4; + break; + case egami::colorType::float64: + return 8; + break; + } + return 1; +} + egami::Image::Image() : m_data(nullptr) { diff --git a/egami/Image.hpp b/egami/Image.hpp index 3901efc..e963d97 100644 --- a/egami/Image.hpp +++ b/egami/Image.hpp @@ -26,6 +26,12 @@ namespace egami { float64, }; std::ostream& operator <<(std::ostream& _os, const enum egami::colorType _obj); + /** + * @brief Get the Color size use in octet + * @param[in] type of the color + * @return Number of byte requested by the color + */ + int32_t getFormatColorSize(enum colorType _type); class ImagePrivate { public: @@ -134,6 +140,7 @@ namespace egami { void set(const std::vector>& _data, const ivec2& _size); void set(const std::vector>& _data, const ivec2& _size); + void swap(egami::Image& _image); }; } diff --git a/egami/egami.cpp b/egami/egami.cpp index 837c2d0..9697722 100644 --- a/egami/egami.cpp +++ b/egami/egami.cpp @@ -7,10 +7,24 @@ #include #include -#include -#include +#ifdef EGAMI_BUILD_ESVG + #include +#endif +#ifdef EGAMI_BUILD_PNG + #include +#endif #include #include + +#ifdef EGAMI_BUILD_JPEG + #include +#endif +#ifdef EGAMI_BUILD_JPEG2000 + #include +#endif +#ifdef EGAMI_BUILD_TIFF + #include +#endif #include bool egami::scalable(const std::string& _fileName) { @@ -36,18 +50,52 @@ egami::Image egami::load(const std::string& _fileName, const ivec2& _size) { EGAMI_ERROR("Error to load BMP file '" << _fileName << "'"); } } else if (etk::end_with(tmpName, ".svg") == true) { - out = egami::loadSVG(_fileName, _size); - if (out.exist() == false) { - EGAMI_ERROR("Error to load SVG file '" << _fileName << "'"); - } - //egami::storeEDF(_fileName + ".edf", _output); + #ifdef EGAMI_BUILD_ESVG + out = egami::loadSVG(_fileName, _size); + if (out.exist() == false) { + EGAMI_ERROR("Error to load SVG file '" << _fileName << "'"); + } + #else + EGAMI_WARNING("egamy not compile with the ESVG dependency for file '" << _fileName << "'"); + #endif } else if (etk::end_with(tmpName, ".png") == true) { - out = egami::loadPNG(_fileName); - if (out.exist() == false) { - EGAMI_ERROR("Error to load PNG file '" << _fileName << "'"); - } + #ifdef EGAMI_BUILD_PNG + out = egami::loadPNG(_fileName); + if (out.exist() == false) { + EGAMI_ERROR("Error to load PNG file '" << _fileName << "'"); + } + #else + EGAMI_WARNING("egamy not compile with the PNG dependency for file '" << _fileName << "'"); + #endif + } else if (etk::end_with(tmpName, ".jpg") == true) { + #ifdef EGAMI_BUILD_JPEG + out = egami::loadJPG(_fileName); + if (out.exist() == false) { + EGAMI_ERROR("Error to load JPG file '" << _fileName << "'"); + } + #else + EGAMI_WARNING("egamy not compile with the JPEG dependency for file '" << _fileName << "'"); + #endif + } else if (etk::end_with(tmpName, ".j2k") == true) { + #ifdef EGAMI_BUILD_JPEG2000 + out = egami::loadJPG2000(_fileName); + if (out.exist() == false) { + EGAMI_ERROR("Error to load JPEG2000 file '" << _fileName << "'"); + } + #else + EGAMI_WARNING("egamy not compile with the JPEG 2000 (openjpeg) dependency for file '" << _fileName << "'"); + #endif + } else if (etk::end_with(tmpName, ".tif") == true) { + #ifdef EGAMI_BUILD_TIFF + out = egami::loadTIFF(_fileName); + if (out.exist() == false) { + EGAMI_ERROR("Error to load TIFF file '" << _fileName << "'"); + } + #else + EGAMI_WARNING("egamy not compile with the TIFF dependency for file '" << _fileName << "'"); + #endif } else { - EGAMI_ERROR("Extention not managed '" << _fileName << "' Sopported extention : .edf / .bmp / .svg / .png"); + EGAMI_ERROR("Extention not managed '" << _fileName << "' Sopported extention : .edf / .bmp / .svg / .png / .jpg / .j2k / .tif"); } return out; } @@ -72,8 +120,17 @@ bool egami::store(const egami::Image& _input, const std::string& _fileName) { } else if (etk::end_with(tmpName, ".png") == true) { EGAMI_ERROR("Can not store in PNG file '" << _fileName << "'"); return false; + } else if (etk::end_with(tmpName, ".jpg") == true) { + EGAMI_ERROR("Can not store in JPEG file '" << _fileName << "'"); + return false; + } else if (etk::end_with(tmpName, ".j2k") == true) { + EGAMI_ERROR("Can not store in JPEG 2000 file '" << _fileName << "'"); + return false; + } else if (etk::end_with(tmpName, ".tif") == true) { + EGAMI_ERROR("Can not store in TIFF file '" << _fileName << "'"); + return false; } else { - EGAMI_ERROR("Extention not managed '" << _fileName << "' Sopported extention: .edf / .bmp / .svg / .png"); + EGAMI_ERROR("Extention not managed '" << _fileName << "' Sopported extention: .edf / .bmp / .svg / .png / .jpg / .j2k / .tif"); return false; } return true; diff --git a/egami/wrapperBMP.cpp b/egami/wrapperBMP.cpp index 0948c38..3f7457b 100644 --- a/egami/wrapperBMP.cpp +++ b/egami/wrapperBMP.cpp @@ -40,6 +40,54 @@ enum modeBitmap { BITS_32_A8R8G8B8 }; + +static void display(struct bitmapFileHeader _header, struct bitmapInfoHeader _info) { + EGAMI_DEBUG(" -----------------------------------------------------------"); + EGAMI_DEBUG("Display caracteristic of the bitmap : "); + EGAMI_DEBUG(" Header of file :"); + EGAMI_DEBUG(" bfType =" << _header.bfType << " 19778 : must always be set to 'BM' to declare that this is a .bmp-file."); + EGAMI_DEBUG(" bfSize =" << _header.bfSize << " specifies the size of the file in bytes."); + EGAMI_DEBUG(" bfReserved=" << _header.bfReserved << " must always be set to zero."); + EGAMI_DEBUG(" bfOffBits =" << _header.bfOffBits << " 1078 : specifies the offset from the beginning of the file to the bitmap data."); + EGAMI_DEBUG(" info header of file :"); + EGAMI_DEBUG(" biSize =" << _info.biSize << " specifies the size of the BITMAPINFOHEADER structure, in bytes."); + EGAMI_DEBUG(" biWidth =" << _info.biWidth << " specifies the width of the image, in pixels."); + EGAMI_DEBUG(" biHeight =" << _info.biHeight << " specifies the height of the image, in pixels."); + EGAMI_DEBUG(" biPlanes =" << _info.biPlanes << " specifies the number of planes of the target device, must be set to zero."); + EGAMI_DEBUG(" biBitCount =" << _info.biBitCount << " specifies the number of bits per pixel."); + EGAMI_DEBUG(" biCompression =" << _info.biCompression << " Specifies the type of compression, usually set to zero (no compression)."); + EGAMI_DEBUG(" biSizeImage =" << _info.biSizeImage << " specifies the size of the image data, in bytes. If there is no compression, it is valid to set this member to zero."); + EGAMI_DEBUG(" biXPelsPerMeter=" << _info.biXPelsPerMeter << " specifies the the horizontal pixels per meter on the designated targer device, usually set to zero."); + EGAMI_DEBUG(" biYPelsPerMeter=" << _info.biYPelsPerMeter << " specifies the the vertical pixels per meter on the designated targer device, usually set to zero."); + EGAMI_DEBUG(" biClrUsed =" << _info.biClrUsed << " speglTexImage2Dcifies the number of colors used in the bitmap, if set to zero the number of colors is calculated using the biBitCount member."); + EGAMI_DEBUG(" biClrImportant =" << _info.biClrImportant << " specifies the number of color that are 'important' for the bitmap, if set to zero, all colors are important."); + /* + EGAMI_DEBUG("Bitmap : " << m_width << "x" << m_height); + switch(m_dataMode) + { + case BITS_16_R5G6B5: + EGAMI_DEBUG(" mode = 16 bits R5G6B5"); + break; + case BITS_16_X1R5G5B5: + EGAMI_DEBUG(" mode = 16 bits X1R5G5B5"); + break; + case BITS_24_R8G8B8: + EGAMI_DEBUG(" mode = 24 bits R8G8B8"); + break; + case BITS_32_X8R8G8B8: + EGAMI_DEBUG(" mode = 32 bits X8R8G8B8"); + break; + case BITS_32_A8R8G8B8: + EGAMI_DEBUG(" mode = 32 bits A8R8G8B8"); + break; + default: + EGAMI_DEBUG(" mode = ERROR"); + break; + }*/ +} + + + egami::Image egami::loadBMP(const std::string& _inputFile) { egami::Image out; enum modeBitmap m_dataMode = BITS_16_R5G6B5; @@ -51,7 +99,7 @@ egami::Image egami::loadBMP(const std::string& _inputFile) { etk::FSNode fileName(_inputFile); // get the fileSize ... /*if (fileName.size() < (int32_t)(sizeof(struct bitmapFileHeader) + sizeof(struct bitmapFileHeader) ) ) { - EWOL_ERROR("not enought data in the file named=\"" << fileName << "\""); + EGAMI_ERROR("not enought data in the file named=\"" << fileName << "\""); return; }*/ if (fileName.exist() == false) { @@ -73,6 +121,8 @@ egami::Image egami::loadBMP(const std::string& _inputFile) { fileName.fileClose(); return out; } + //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(); @@ -158,6 +208,15 @@ egami::Image egami::loadBMP(const std::string& _inputFile) { } break; case BITS_24_R8G8B8: { + int32_t offset = 0; + int32_t baseLine = m_width * 3; + if ((baseLine%4) == 1) { + offset = 3; + } else if ((baseLine%4) == 2) { + offset = 2; + } else if ((baseLine%4) == 3) { + offset = 1; + } uint8_t * pointer = (&m_data[0]); for(int32_t yyy=0; yyy check if(fileName.fileSeek(m_FileHeader.bfOffBits, etk::FSN_SEEK_START) == false) { EGAMI_ERROR("error with the 'bfOffBits' in the file named=\"" << fileName << "\""); @@ -278,61 +352,17 @@ bool egami::storeBMP(const std::string& _fileName, const egami::Image& _inputIma *pointer++ = tmpColor.b(); fileName.fileWrite(data,3,1); } + if (offset != 0) { + uint8_t pointer[4]; + pointer[0] = 0; + pointer[1] = 0; + pointer[2] = 0; + pointer[3] = 0; + fileName.fileWrite(pointer,1,offset); + } } } fileName.fileClose(); return true; } -/* -void ewol::texture::TextureBMP::display() -{ - if (NULL == m_data) { - EWOL_ERROR("Might loading error of this Bitmap ..."); - return; - } - EWOL_DEBUG(" -----------------------------------------------------------"); - if (false) { - EWOL_DEBUG("Display caracteristic of the bitmap : "); - EWOL_DEBUG(" Header of file :"); - EWOL_DEBUG(" bfType =" << m_FileHeader.bfType << " 19778 : must always be set to 'BM' to declare that this is a .bmp-file."); - EWOL_DEBUG(" bfSize =" << m_FileHeader.bfSize << " specifies the size of the file in bytes."); - EWOL_DEBUG(" bfReserved=" << m_FileHeader.bfReserved << " must always be set to zero."); - EWOL_DEBUG(" bfOffBits =" << m_FileHeader.bfOffBits << " 1078 : specifies the offset from the beginning of the file to the bitmap data."); - EWOL_DEBUG(" info header of file :"); - EWOL_DEBUG(" biSize =" << m_InfoHeader.biSize << " specifies the size of the BITMAPINFOHEADER structure, in bytes."); - EWOL_DEBUG(" biWidth =" << m_InfoHeader.biWidth << " specifies the width of the image, in pixels."); - EWOL_DEBUG(" biHeight =" << m_InfoHeader.biHeight << " specifies the height of the image, in pixels."); - EWOL_DEBUG(" biPlanes =" << m_InfoHeader.biPlanes << " specifies the number of planes of the target device, must be set to zero."); - EWOL_DEBUG(" biBitCount =" << m_InfoHeader.biBitCount << " specifies the number of bits per pixel."); - EWOL_DEBUG(" biCompression =" << m_InfoHeader.biCompression << " Specifies the type of compression, usually set to zero (no compression)."); - EWOL_DEBUG(" biSizeImage =" << m_InfoHeader.biSizeImage << " specifies the size of the image data, in bytes. If there is no compression, it is valid to set this member to zero."); - EWOL_DEBUG(" biXPelsPerMeter=" << m_InfoHeader.biXPelsPerMeter << " specifies the the horizontal pixels per meter on the designated targer device, usually set to zero."); - EWOL_DEBUG(" biYPelsPerMeter=" << m_InfoHeader.biYPelsPerMeter << " specifies the the vertical pixels per meter on the designated targer device, usually set to zero."); - EWOL_DEBUG(" biClrUsed =" << m_InfoHeader.biClrUsed << " speglTexImage2Dcifies the number of colors used in the bitmap, if set to zero the number of colors is calculated using the biBitCount member."); - EWOL_DEBUG(" biClrImportant =" << m_InfoHeader.biClrImportant << " specifies the number of color that are 'important' for the bitmap, if set to zero, all colors are important."); - } - EWOL_DEBUG("Bitmap : " << m_width << "x" << m_height); - switch(m_dataMode) - { - case BITS_16_R5G6B5: - EWOL_DEBUG(" mode = 16 bits R5G6B5"); - break; - case BITS_16_X1R5G5B5: - EWOL_DEBUG(" mode = 16 bits X1R5G5B5"); - break; - case BITS_24_R8G8B8: - EWOL_DEBUG(" mode = 24 bits R8G8B8"); - break; - case BITS_32_X8R8G8B8: - EWOL_DEBUG(" mode = 32 bits X8R8G8B8"); - break; - case BITS_32_A8R8G8B8: - EWOL_DEBUG(" mode = 32 bits A8R8G8B8"); - break; - default: - EWOL_DEBUG(" mode = ERROR"); - break; - } -} -*/ diff --git a/egami/wrapperJPG.cpp b/egami/wrapperJPG.cpp new file mode 100644 index 0000000..15bcf13 --- /dev/null +++ b/egami/wrapperJPG.cpp @@ -0,0 +1,131 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2011, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include +#include +#include +extern "C" { + #include "jpeglib.h" +} +#include + +struct my_error_mgr { + struct jpeg_error_mgr pub; /* "public" fields */ + jmp_buf setjmp_buffer; /* for return to caller */ +}; + +typedef struct my_error_mgr * my_error_ptr; + +/* + * Here's the routine that will replace the standard error_exit method: + */ +METHODDEF(void) my_error_exit(j_common_ptr _cinfo) { + // cinfo->err really points to a my_error_mgr struct, so coerce pointer + my_error_ptr myerr = (my_error_ptr)_cinfo->err; + // Always display the message. + // We could postpone this until after returning, if we chose. + (*_cinfo->err->output_message)(_cinfo); + // Return control to the setjmp point + longjmp(myerr->setjmp_buffer, 1); +} + +void put_scanline_someplace(const uint8_t* _buffer, int32_t _row_stride) { + EGAMI_ERROR("plop " << uint64_t(_buffer) << " row=" << _row_stride << " " << (_row_stride/3)); +} + + +egami::Image egami::loadJPG(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; + } + std::vector allData = fileName.fileReadAll(); + fileName.fileClose(); + + // 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; + // 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. + struct my_error_mgr jerr; + // More stuff + JSAMPARRAY buffer; + int row_stride; + + // Step 1: allocate and initialize JPEG decompression object + + // We set up the normal JPEG error routines, then override error_exit. + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = my_error_exit; + // Establish the setjmp return context for my_error_exit to use. + if (setjmp(jerr.setjmp_buffer)) { + // If we get here, the JPEG code has signaled an error. We need to clean up the JPEG object, close the input file, and return. + jpeg_destroy_decompress(&cinfo); + return out; + } + // Now we can initialize the JPEG decompression object. + jpeg_create_decompress(&cinfo); + + // Step 2: specify data source (eg, a file) + jpeg_mem_src(&cinfo, &allData[0], allData.size()); + + // Step 3: read file parameters with jpeg_read_header() + (void)jpeg_read_header(&cinfo, TRUE); + // We can ignore the return value from jpeg_read_header since + // (a) suspension is not possible with the stdio data source, and + // (b) we passed TRUE to reject a tables-only JPEG file as an error. + // See libjpeg.txt for more info. + + // Step 4: set parameters for decompression + // In this example, we don't need to change any of the defaults set by jpeg_read_header(), so we do nothing here. + + // Step 5: Start decompressor + (void) jpeg_start_decompress(&cinfo); + // We can ignore the return value since suspension is not possible with the stdio data source. + + // We may need to do some setup of our own at this point before reading the data. + // After jpeg_start_decompress() we have the correct scaled output image dimensions available, as well as the output colormap if we asked for color quantization. + // In this example, we need to make an output work buffer of the right size. + // JSAMPLEs per row in output buffer + row_stride = cinfo.output_width * cinfo.output_components; + // Make a one-row-high sample array that will go away when done with image + buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); + + // Step 6: while (scan lines remain to be read) jpeg_read_scanlines(...); + // Resize output image: + out.configure(ivec2(cinfo.output_width,cinfo.output_height), egami::colorType::RGB8); + uint8_t* dataOutPointer = (uint8_t*)out.getTextureDataPointer(); + + + // Here we use the library's state variable cinfo.output_scanline as the loop counter, so that we don't have to keep track ourselves. + int32_t yyy = 1; + while (cinfo.output_scanline < cinfo.output_height) { + // Get a simple line: + (void) jpeg_read_scanlines(&cinfo, buffer, 1); + // Direst push on the output (got output format RGB8) + uint8_t* tmpp = dataOutPointer + (row_stride*(cinfo.output_height-yyy)); + memcpy(tmpp, buffer[0], row_stride); + yyy++; + } + // Step 7: Finish decompression + (void) jpeg_finish_decompress(&cinfo); + // We can ignore the return value since suspension is not possible with the stdio data source. + + // Step 8: Release JPEG decompression object + // This is an important step since it will release a good deal of memory. + jpeg_destroy_decompress(&cinfo); + + // At this point you may want to check to see whether any corrupt-data warnings occurred (test whether jerr.pub.num_warnings is nonzero). + return out; +} + + diff --git a/egami/wrapperJPG.hpp b/egami/wrapperJPG.hpp new file mode 100644 index 0000000..e783dec --- /dev/null +++ b/egami/wrapperJPG.hpp @@ -0,0 +1,18 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2011, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include + +namespace egami { + /** + * @breif Load a jpeg file in the image. + * @param[in] _fileName Name of the file. + * @return Read Image. + */ + egami::Image loadJPG(const std::string& _fileName); +} + diff --git a/egami/wrapperJPG2000.cpp b/egami/wrapperJPG2000.cpp new file mode 100644 index 0000000..e1187b0 --- /dev/null +++ b/egami/wrapperJPG2000.cpp @@ -0,0 +1,32 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2011, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include +#include +#include + +egami::Image egami::loadJPG2000(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; + } + + + + + + + return out; +} + diff --git a/egami/wrapperJPG2000.hpp b/egami/wrapperJPG2000.hpp new file mode 100644 index 0000000..c12d41a --- /dev/null +++ b/egami/wrapperJPG2000.hpp @@ -0,0 +1,18 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2011, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include + +namespace egami { + /** + * @breif Load a jpeg 2000 file in the image. + * @param[in] _fileName Name of the file. + * @return Read Image. + */ + egami::Image loadJPG2000(const std::string& _fileName); +} + diff --git a/egami/wrapperPNG.cpp b/egami/wrapperPNG.cpp index 7cb2eef..25c2846 100644 --- a/egami/wrapperPNG.cpp +++ b/egami/wrapperPNG.cpp @@ -211,7 +211,7 @@ egami::Image egami::loadPNG(const std::string& _inputFile) { for (png_uint_32 xxx = 0; xxx < width; ++xxx) { png_byte* ptr = &(row[xxx*4]); tmpColor.set(ptr[0], ptr[1], ptr[2], ptr[3]); - out.set(ivec2(xxx,yyy), tmpColor); + out.set(ivec2(xxx,height-yyy-1), tmpColor); } } break; @@ -223,7 +223,7 @@ egami::Image egami::loadPNG(const std::string& _inputFile) { for (png_uint_32 xxx = 0; xxx < width; ++xxx) { png_byte* ptr = &(row[xxx*3]); tmpColor.set(ptr[0], ptr[1], ptr[2]); - out.set(ivec2(xxx,yyy), tmpColor); + out.set(ivec2(xxx,height-yyy-1), tmpColor); } } break; @@ -235,7 +235,7 @@ egami::Image egami::loadPNG(const std::string& _inputFile) { for (png_uint_32 xxx = 0; xxx < width; ++xxx) { png_byte* ptr = &(row[xxx]); tmpColor.set(ptr[0], ptr[0], ptr[0]); - out.set(ivec2(xxx,yyy), tmpColor); + out.set(ivec2(xxx,height-yyy-1), tmpColor); } } break; @@ -247,7 +247,7 @@ egami::Image egami::loadPNG(const std::string& _inputFile) { for (png_uint_32 xxx = 0; xxx < width; ++xxx) { png_byte* ptr = &(row[xxx*2]); tmpColor.set(ptr[0], ptr[0], ptr[0], ptr[1]); - out.set(ivec2(xxx,yyy), tmpColor); + out.set(ivec2(xxx,height-yyy-1), tmpColor); } } break; diff --git a/egami/wrapperTIFF.cpp b/egami/wrapperTIFF.cpp new file mode 100644 index 0000000..09f7d4d --- /dev/null +++ b/egami/wrapperTIFF.cpp @@ -0,0 +1,33 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2011, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include +#include +#include + + +egami::Image egami::loadTIFF(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; + } + + + + + + + return out; +} + diff --git a/egami/wrapperTIFF.hpp b/egami/wrapperTIFF.hpp new file mode 100644 index 0000000..bfba9ce --- /dev/null +++ b/egami/wrapperTIFF.hpp @@ -0,0 +1,18 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2011, Edouard DUPIN, all right reserved + * @license APACHE v2.0 (see license file) + */ +#pragma once + +#include + +namespace egami { + /** + * @breif Load a tiff file in the image. + * @param[in] _fileName Name of the file. + * @return Read Image. + */ + egami::Image loadTIFF(const std::string& _fileName); +} + diff --git a/lutin_egami-sample.py b/lutin_egami-sample.py index 68ab293..d3ff67f 100644 --- a/lutin_egami-sample.py +++ b/lutin_egami-sample.py @@ -25,15 +25,16 @@ def get_maintainer(): return ["Mr DUPIN Edouard "] def configure(target, my_module): - my_module.add_depend(['egami', 'test-debug']) + my_module.add_depend([ + 'egami', + 'test-debug' + ]) my_module.add_src_file([ 'sample/main.cpp', 'sample/read.cpp', 'sample/write.cpp' ]) - my_module.copy_path('sample/read.bmp') - my_module.copy_path('sample/read.svg') - my_module.copy_path('sample/read.png') + my_module.copy_path('data/*') return True diff --git a/lutin_egami-test.py b/lutin_egami-test.py index fcec1dc..c3d4624 100644 --- a/lutin_egami-test.py +++ b/lutin_egami-test.py @@ -25,11 +25,16 @@ def get_maintainer(): return ["Mr DUPIN Edouard "] def configure(target, my_module): - my_module.add_depend(['egami', 'gtest', 'test-debug']) + my_module.add_depend([ + 'egami', + 'gtest', + 'test-debug', + 'algue', + ]) my_module.add_src_file([ 'test/main.cpp' ]) - #my_module.add_export_path(tools.get_current_path(__file__)) + my_module.copy_path('data/*') return True diff --git a/lutin_egami.py b/lutin_egami.py index 3db315b..31adfff 100644 --- a/lutin_egami.py +++ b/lutin_egami.py @@ -31,8 +31,6 @@ def configure(target, my_module): 'egami/ImageMono.cpp', 'egami/egami.cpp', 'egami/debug.cpp', - 'egami/wrapperPNG.cpp', - 'egami/wrapperSVG.cpp', 'egami/wrapperBMP.cpp', 'egami/wrapperEDF.cpp' ]) @@ -43,14 +41,47 @@ def configure(target, my_module): ]) my_module.add_depend([ 'etk', - 'png', - 'esvg', 'edtaa3' ]) my_module.add_flag('c++', [ '-Wno-write-strings', '-Wall' ]) + my_module.add_optionnal_depend( + 'png', + ["c++", "-DEGAMI_BUILD_PNG"], + src_file=[ + 'egami/wrapperPNG.cpp', + ] + ) + my_module.add_optionnal_depend( + 'esvg', + ["c++", "-DEGAMI_BUILD_ESVG"], + src_file=[ + 'egami/wrapperSVG.cpp', + ] + ) + my_module.add_optionnal_depend( + 'jpeg', + ["c++", "-DEGAMI_BUILD_JPEG"], + src_file=[ + 'egami/wrapperJPG.cpp', + ] + ) + my_module.add_optionnal_depend( + 'openjpeg', + ["c++", "-DEGAMI_BUILD_JPEG2000"], + src_file=[ + 'egami/wrapperJPG2000.cpp', + ] + ) + my_module.add_optionnal_depend( + 'tiff', + ["c++", "-DEGAMI_BUILD_TIFF"], + src_file=[ + 'egami/wrapperTIFF.cpp', + ] + ) my_module.add_path(".") return True diff --git a/test/main.cpp b/test/main.cpp index bf519b7..c16c75a 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include int main(int argc, const char *argv[]) { @@ -18,9 +20,60 @@ int main(int argc, const char *argv[]) { return RUN_ALL_TESTS(); } - -TEST(TestPng, read) { - // TODO : Do real test ... - EXPECT_EQ(5, 6); +TEST(TestBMP, read) { + egami::Image image = egami::load("DATA:read.bmp"); + egami::store(image, "out/read.bmp.bmp"); + // Check if image is loaded + EXPECT_EQ(true, image.exist()); + // check image correct size + EXPECT_EQ(ivec2(227,149), image.getSize()); + // check image correct type + EXPECT_EQ(egami::colorType::RGB8, image.getType()); + // check integrity + std::string sha512 = algue::stringConvert(algue::sha512::encode((const uint8_t *)image.getTextureDataPointer(), egami::getFormatColorSize(image.getType()) * image.getSize().x() * image.getSize().y())); + EXPECT_EQ("3518a9693a349044d23c3a95262831144011086fdb339ef8532f9c6cebffe76b2c994b0a3e6d69addca15538a1cb559af3be445c5b622b5cf80c9291e7b8ca5b", sha512); } + +TEST(TestPNG, read) { + egami::Image image = egami::load("DATA:read.png"); + egami::store(image, "out/read.png.bmp"); + // Check if image is loaded + EXPECT_EQ(true, image.exist()); + // check image correct size + EXPECT_EQ(ivec2(227,149), image.getSize()); + // check image correct type + EXPECT_EQ(egami::colorType::RGB8, image.getType()); + // check integrity + std::string sha512 = algue::stringConvert(algue::sha512::encode((const uint8_t *)image.getTextureDataPointer(), egami::getFormatColorSize(image.getType()) * image.getSize().x() * image.getSize().y())); + EXPECT_EQ("42dbad7abf1e651da58c9df06521d63a878b5bd0db6e1cbe129db3c9782ce640a6709583ba9e6571d314f39b259321dcc392f98bf4412deb5ce8392566d2bc0f", sha512); +} + +TEST(TestSVG, read) { + egami::Image image = egami::load("DATA:read.svg"); + egami::store(image, "out/read.svg.bmp"); + // Check if image is loaded + EXPECT_EQ(true, image.exist()); + // check image correct size + EXPECT_EQ(ivec2(64,64), image.getSize()); + // check image correct type + EXPECT_EQ(egami::colorType::RGBA8, image.getType()); + // check integrity + std::string sha512 = algue::stringConvert(algue::sha512::encode((const uint8_t *)image.getTextureDataPointer(), egami::getFormatColorSize(image.getType()) * image.getSize().x() * image.getSize().y())); + EXPECT_EQ("7975d12caae94e67e85909f26b6dc0672d7e4686808d851b3207be6272b6d0153572cd643eea819c2f4dae9f7837165b4d5b34353da9f847d77afc2701945284", sha512); +} + + +TEST(TestJPG, read) { + egami::Image image = egami::load("DATA:read.jpg"); + egami::store(image, "out/read.jpg.bmp"); + // Check if image is loaded + EXPECT_EQ(true, image.exist()); + // check image correct size + EXPECT_EQ(ivec2(227,149), image.getSize()); + // check image correct type + EXPECT_EQ(egami::colorType::RGB8, image.getType()); + // check integrity + std::string sha512 = algue::stringConvert(algue::sha512::encode((const uint8_t *)image.getTextureDataPointer(), egami::getFormatColorSize(image.getType()) * image.getSize().x() * image.getSize().y())); + EXPECT_EQ("42dbad7abf1e651da58c9df06521d63a878b5bd0db6e1cbe129db3c9782ce640a6709583ba9e6571d314f39b259321dcc392f98bf4412deb5ce8392566d2bc0f", sha512); +}