text: #include <FishEngine/Texture.hpp>
  
  #include <bimg/bimg.h>
  #include <bx/readerwriter.h>
  #include <bimg/decode.h>
  #include <bx/file.h>
  
  #include <cstdio>
  #define DBG printf
  
  using namespace FishEngine;
  
  bx::DefaultAllocator s_allocator;
  
  void* load(bx::FileReaderI* _reader, bx::AllocatorI* _allocator, const char* _filePath, uint32_t* _size)
  {
  	if (bx::open(_reader, _filePath))
  	{
  		uint32_t size = (uint32_t)bx::getSize(_reader);
  		void* data = BX_ALLOC(_allocator, size);
  		bx::read(_reader, data, size);
  		bx::close(_reader);
  		if (NULL != _size)
  		{
  			*_size = size;
  		}
  		return data;
  	}
  	else
  	{
  		DBG("Failed to open: %s.", _filePath);
  	}
  
  	if (NULL != _size)
  	{
  		*_size = 0;
  	}
  
  	return NULL;
  }
  
  void unload(void* _ptr)
  {
  	BX_FREE(&s_allocator, _ptr);
  }
  
  static void imageReleaseCb(void* _ptr, void* _userData)
  {
  	BX_UNUSED(_ptr);
  	bimg::ImageContainer* imageContainer = (bimg::ImageContainer*)_userData;
  	bimg::imageFree(imageContainer);
  }
  
  
  
  bgfx::TextureHandle FishEngine::loadTexture2(void* data, uint32_t size,
  								const char* _filePath,
  								uint32_t _flags,
  //								uint8_t _skip,
  								bgfx::TextureInfo* _info,
  								bimg::Orientation::Enum* _orientation
  								)
  {
  //	BX_UNUSED(_skip);
  	bgfx::TextureHandle handle = BGFX_INVALID_HANDLE;
  //
  //	uint32_t size;
  //	void* data = load(_reader, &s_allocator, _filePath, &size);
  	if (NULL != data)
  	{
  		bimg::ImageContainer* imageContainer = bimg::imageParse(&s_allocator, data, size);
  
  		if (NULL != imageContainer)
  		{
  			if (NULL != _orientation)
  			{
  				*_orientation = imageContainer->m_orientation;
  			}
  
  			const bgfx::Memory* mem = bgfx::makeRef(
  				imageContainer->m_data
  				, imageContainer->m_size
  				, imageReleaseCb
  				, imageContainer
  			);
  			
  			// TODO: unload
  			//unload(data);
  
  			if (imageContainer->m_cubeMap)
  			{
  				handle = bgfx::createTextureCube(
  					uint16_t(imageContainer->m_width)
  					, 1 < imageContainer->m_numMips
  					, imageContainer->m_numLayers
  					, bgfx::TextureFormat::Enum(imageContainer->m_format)
  					, _flags
  					, mem
  				);
  			}
  			else if (1 < imageContainer->m_depth)
  			{
  				handle = bgfx::createTexture3D(
  					uint16_t(imageContainer->m_width)
  					, uint16_t(imageContainer->m_height)
  					, uint16_t(imageContainer->m_depth)
  					, 1 < imageContainer->m_numMips
  					, bgfx::TextureFormat::Enum(imageContainer->m_format)
  					, _flags
  					, mem
  				);
  			}
  			else if (bgfx::isTextureValid(0, false, imageContainer->m_numLayers, bgfx::TextureFormat::Enum(imageContainer->m_format), _flags))
  			{
  				handle = bgfx::createTexture2D(
  					uint16_t(imageContainer->m_width)
  					, uint16_t(imageContainer->m_height)
  					, 1 < imageContainer->m_numMips
  					, imageContainer->m_numLayers
  					, bgfx::TextureFormat::Enum(imageContainer->m_format)
  					, _flags
  					, mem
  				);
  			}
  
  			if (bgfx::isValid(handle))
  			{
  				bgfx::setName(handle, _filePath);
  			}
  
  			if (NULL != _info)
  			{
  				bgfx::calcTextureSize(
  					*_info
  					, uint16_t(imageContainer->m_width)
  					, uint16_t(imageContainer->m_height)
  					, uint16_t(imageContainer->m_depth)
  					, imageContainer->m_cubeMap
  					, 1 < imageContainer->m_numMips
  					, imageContainer->m_numLayers
  					, bgfx::TextureFormat::Enum(imageContainer->m_format)
  				);
  			}
  		}
  	}
  
  	return handle;
  }
  
  
  bgfx::TextureHandle loadTexture(bx::FileReaderI* _reader, const char* _filePath, uint32_t _flags, uint8_t _skip, bgfx::TextureInfo* _info, bimg::Orientation::Enum* _orientation)
  {
  	BX_UNUSED(_skip);
  	//	bgfx::TextureHandle handle = BGFX_INVALID_HANDLE;
  	
  	uint32_t size;
  	void* data = load(_reader, &s_allocator, _filePath, &size);
  	
  	auto ret = loadTexture2(data, size, _filePath, _flags, _info, _orientation);
  	unload(data);
  	return ret;
  }
  
  
  static bx::FileReader s_fileReader;
  
  bgfx::TextureHandle loadTexture(const char* _name, uint32_t _flags = BGFX_TEXTURE_NONE, uint8_t _skip = 0, bgfx::TextureInfo* _info = NULL, bimg::Orientation::Enum* _orientation = NULL)
  {
  	return loadTexture(&s_fileReader, _name, _flags, _skip, _info, _orientation);
  }
  
  bgfx::TextureHandle TextureUtils::LoadTexture(const char* path, uint32_t _flags)
  {
  	return loadTexture(path, _flags);
  }
  