Просмотр исходного кода

Some refactoring in ImageLoader

Panagiotis Christopoulos Charitos 6 лет назад
Родитель
Сommit
cfe9c03217

+ 248 - 212
src/anki/resource/ImageLoader.cpp

@@ -6,26 +6,183 @@
 #include <anki/resource/ImageLoader.h>
 #include <anki/resource/ImageLoader.h>
 #include <anki/util/Logger.h>
 #include <anki/util/Logger.h>
 #include <anki/util/Filesystem.h>
 #include <anki/util/Filesystem.h>
-#include <anki/util/Assert.h>
 #include <anki/util/Array.h>
 #include <anki/util/Array.h>
 
 
 namespace anki
 namespace anki
 {
 {
 
 
-static U8 tgaHeaderUncompressed[12] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-static U8 tgaHeaderCompressed[12] = {0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static const U8 tgaHeaderUncompressed[12] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static const U8 tgaHeaderCompressed[12] = {0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
 
-static ANKI_USE_RESULT Error loadUncompressedTga(ResourceFilePtr fs,
-	U32& width,
-	U32& height,
-	U32& bpp,
-	DynamicArray<U8>& data,
-	GenericMemoryPoolAllocator<U8>& alloc)
+class AnkiTextureHeader
+{
+public:
+	Array<U8, 8> m_magic;
+	U32 m_width;
+	U32 m_height;
+	U32 m_depthOrLayerCount;
+	ImageLoaderTextureType m_type;
+	ImageLoaderColorFormat m_colorFormat;
+	ImageLoaderDataCompression m_compressionFormats;
+	U32 m_normal;
+	U32 m_mipCount;
+	U8 m_padding[88];
+};
+static_assert(sizeof(AnkiTextureHeader) == 128, "Check sizeof AnkiTextureHeader");
+
+/// Get the size in bytes of a single surface
+static PtrSize calcSurfaceSize(
+	const U32 width, const U32 height, const ImageLoaderDataCompression comp, const ImageLoaderColorFormat cf)
+{
+	PtrSize out = 0;
+
+	ANKI_ASSERT(width >= 4 || height >= 4);
+
+	switch(comp)
+	{
+	case ImageLoaderDataCompression::RAW:
+		out = width * height * ((cf == ImageLoaderColorFormat::RGB8) ? 3 : 4);
+		break;
+	case ImageLoaderDataCompression::S3TC:
+		out = (width / 4) * (height / 4) * ((cf == ImageLoaderColorFormat::RGB8) ? 8 : 16); // block size
+		break;
+	case ImageLoaderDataCompression::ETC:
+		out = (width / 4) * (height / 4) * 8;
+		break;
+	default:
+		ANKI_ASSERT(0);
+	}
+
+	ANKI_ASSERT(out > 0);
+
+	return out;
+}
+
+/// Get the size in bytes of a single volume
+static PtrSize calcVolumeSize(const U width,
+	const U height,
+	const U depth,
+	const ImageLoaderDataCompression comp,
+	const ImageLoaderColorFormat cf)
+{
+	PtrSize out = 0;
+
+	ANKI_ASSERT(width >= 4 || height >= 4 || depth >= 4);
+
+	switch(comp)
+	{
+	case ImageLoaderDataCompression::RAW:
+		out = width * height * depth * ((cf == ImageLoaderColorFormat::RGB8) ? 3 : 4);
+		break;
+	default:
+		ANKI_ASSERT(0);
+	}
+
+	ANKI_ASSERT(out > 0);
+
+	return out;
+}
+
+/// Calculate the size of a compressed or uncomressed color data
+static PtrSize calcSizeOfSegment(const AnkiTextureHeader& header, ImageLoaderDataCompression comp)
+{
+	PtrSize out = 0;
+	U32 width = header.m_width;
+	U32 height = header.m_height;
+	U32 mips = header.m_mipCount;
+	ANKI_ASSERT(mips > 0);
+
+	if(header.m_type != ImageLoaderTextureType::_3D)
+	{
+		U32 surfCountPerMip = 0;
+
+		switch(header.m_type)
+		{
+		case ImageLoaderTextureType::_2D:
+			surfCountPerMip = 1;
+			break;
+		case ImageLoaderTextureType::CUBE:
+			surfCountPerMip = 6;
+			break;
+		case ImageLoaderTextureType::_2D_ARRAY:
+			surfCountPerMip = header.m_depthOrLayerCount;
+			break;
+		default:
+			ANKI_ASSERT(0);
+			break;
+		}
+
+		while(mips-- != 0)
+		{
+			out += calcSurfaceSize(width, height, comp, header.m_colorFormat) * surfCountPerMip;
+
+			width /= 2;
+			height /= 2;
+		}
+	}
+	else
+	{
+		U depth = header.m_depthOrLayerCount;
+
+		while(mips-- != 0)
+		{
+			out += calcVolumeSize(width, height, depth, comp, header.m_colorFormat);
+
+			width /= 2;
+			height /= 2;
+			depth /= 2;
+		}
+	}
+
+	return out;
+}
+
+class ImageLoader::FileInterface
+{
+public:
+	virtual ANKI_USE_RESULT Error read(void* buff, PtrSize size) = 0;
+	virtual ANKI_USE_RESULT Error seek(PtrSize offset, FileSeekOrigin origin) = 0;
+};
+
+class ImageLoader::RsrcFile : public FileInterface
+{
+public:
+	ResourceFilePtr m_rfile;
+
+	ANKI_USE_RESULT Error read(void* buff, PtrSize size) final
+	{
+		return m_rfile->read(buff, size);
+	}
+
+	ANKI_USE_RESULT Error seek(PtrSize offset, FileSeekOrigin origin) final
+	{
+		return m_rfile->seek(offset, origin);
+	}
+};
+
+class ImageLoader::SystemFile : public FileInterface
+{
+public:
+	File m_file;
+
+	ANKI_USE_RESULT Error read(void* buff, PtrSize size) final
+	{
+		return m_file.read(buff, size);
+	}
+
+	ANKI_USE_RESULT Error seek(PtrSize offset, FileSeekOrigin origin) final
+	{
+		return m_file.seek(offset, origin);
+	}
+};
+
+Error ImageLoader::loadUncompressedTga(
+	FileInterface& fs, U32& width, U32& height, U32& bpp, DynamicArray<U8>& data, GenericMemoryPoolAllocator<U8>& alloc)
 {
 {
 	Array<U8, 6> header6;
 	Array<U8, 6> header6;
 
 
 	// read the info from header
 	// read the info from header
-	ANKI_CHECK(fs->read((char*)&header6[0], sizeof(header6)));
+	ANKI_CHECK(fs.read((char*)&header6[0], sizeof(header6)));
 
 
 	width = header6[1] * 256 + header6[0];
 	width = header6[1] * 256 + header6[0];
 	height = header6[3] * 256 + header6[2];
 	height = header6[3] * 256 + header6[2];
@@ -42,7 +199,7 @@ static ANKI_USE_RESULT Error loadUncompressedTga(ResourceFilePtr fs,
 	I imageSize = bytesPerPxl * width * height;
 	I imageSize = bytesPerPxl * width * height;
 	data.create(alloc, imageSize);
 	data.create(alloc, imageSize);
 
 
-	ANKI_CHECK(fs->read(reinterpret_cast<char*>(&data[0]), imageSize));
+	ANKI_CHECK(fs.read(reinterpret_cast<char*>(&data[0]), imageSize));
 
 
 	// swap red with blue
 	// swap red with blue
 	for(I i = 0; i < imageSize; i += bytesPerPxl)
 	for(I i = 0; i < imageSize; i += bytesPerPxl)
@@ -55,15 +212,11 @@ static ANKI_USE_RESULT Error loadUncompressedTga(ResourceFilePtr fs,
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 
-static ANKI_USE_RESULT Error loadCompressedTga(ResourceFilePtr fs,
-	U32& width,
-	U32& height,
-	U32& bpp,
-	DynamicArray<U8>& data,
-	GenericMemoryPoolAllocator<U8>& alloc)
+Error ImageLoader::loadCompressedTga(
+	FileInterface& fs, U32& width, U32& height, U32& bpp, DynamicArray<U8>& data, GenericMemoryPoolAllocator<U8>& alloc)
 {
 {
 	Array<U8, 6> header6;
 	Array<U8, 6> header6;
-	ANKI_CHECK(fs->read(reinterpret_cast<char*>(&header6[0]), sizeof(header6)));
+	ANKI_CHECK(fs.read(reinterpret_cast<char*>(&header6[0]), sizeof(header6)));
 
 
 	width = header6[1] * 256 + header6[0];
 	width = header6[1] * 256 + header6[0];
 	height = header6[3] * 256 + header6[2];
 	height = header6[3] * 256 + header6[2];
@@ -88,14 +241,14 @@ static ANKI_USE_RESULT Error loadCompressedTga(ResourceFilePtr fs,
 	{
 	{
 		U8 chunkheader = 0;
 		U8 chunkheader = 0;
 
 
-		ANKI_CHECK(fs->read((char*)&chunkheader, sizeof(U8)));
+		ANKI_CHECK(fs.read((char*)&chunkheader, sizeof(U8)));
 
 
 		if(chunkheader < 128)
 		if(chunkheader < 128)
 		{
 		{
 			chunkheader++;
 			chunkheader++;
 			for(int counter = 0; counter < chunkheader; counter++)
 			for(int counter = 0; counter < chunkheader; counter++)
 			{
 			{
-				ANKI_CHECK(fs->read((char*)&colorbuffer[0], bytesPerPxl));
+				ANKI_CHECK(fs.read((char*)&colorbuffer[0], bytesPerPxl));
 
 
 				data[currentbyte] = colorbuffer[2];
 				data[currentbyte] = colorbuffer[2];
 				data[currentbyte + 1] = colorbuffer[1];
 				data[currentbyte + 1] = colorbuffer[1];
@@ -119,7 +272,7 @@ static ANKI_USE_RESULT Error loadCompressedTga(ResourceFilePtr fs,
 		else
 		else
 		{
 		{
 			chunkheader = U8(chunkheader - 127);
 			chunkheader = U8(chunkheader - 127);
-			ANKI_CHECK(fs->read(&colorbuffer[0], bytesPerPxl));
+			ANKI_CHECK(fs.read(&colorbuffer[0], bytesPerPxl));
 
 
 			for(int counter = 0; counter < chunkheader; counter++)
 			for(int counter = 0; counter < chunkheader; counter++)
 			{
 			{
@@ -148,16 +301,12 @@ static ANKI_USE_RESULT Error loadCompressedTga(ResourceFilePtr fs,
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 
-static ANKI_USE_RESULT Error loadTga(ResourceFilePtr fs,
-	U32& width,
-	U32& height,
-	U32& bpp,
-	DynamicArray<U8>& data,
-	GenericMemoryPoolAllocator<U8>& alloc)
+Error ImageLoader::loadTga(
+	FileInterface& fs, U32& width, U32& height, U32& bpp, DynamicArray<U8>& data, GenericMemoryPoolAllocator<U8>& alloc)
 {
 {
 	char myTgaHeader[12];
 	char myTgaHeader[12];
 
 
-	ANKI_CHECK(fs->read(&myTgaHeader[0], sizeof(myTgaHeader)));
+	ANKI_CHECK(fs.read(&myTgaHeader[0], sizeof(myTgaHeader)));
 
 
 	if(memcmp(tgaHeaderUncompressed, &myTgaHeader[0], sizeof(myTgaHeader)) == 0)
 	if(memcmp(tgaHeaderUncompressed, &myTgaHeader[0], sizeof(myTgaHeader)) == 0)
 	{
 	{
@@ -182,149 +331,25 @@ static ANKI_USE_RESULT Error loadTga(ResourceFilePtr fs,
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 
-class AnkiTextureHeader
-{
-public:
-	Array<U8, 8> m_magic;
-	U32 m_width;
-	U32 m_height;
-	U32 m_depthOrLayerCount;
-	ImageLoader::TextureType m_type;
-	ImageLoader::ColorFormat m_colorFormat;
-	ImageLoader::DataCompression m_compressionFormats;
-	U32 m_normal;
-	U32 m_mipLevels;
-	U8 m_padding[88];
-};
-
-static_assert(sizeof(AnkiTextureHeader) == 128, "Check sizeof AnkiTextureHeader");
-
-/// Get the size in bytes of a single surface
-static PtrSize calcSurfaceSize(
-	const U32 width, const U32 height, const ImageLoader::DataCompression comp, const ImageLoader::ColorFormat cf)
-{
-	PtrSize out = 0;
-
-	ANKI_ASSERT(width >= 4 || height >= 4);
-
-	switch(comp)
-	{
-	case ImageLoader::DataCompression::RAW:
-		out = width * height * ((cf == ImageLoader::ColorFormat::RGB8) ? 3 : 4);
-		break;
-	case ImageLoader::DataCompression::S3TC:
-		out = (width / 4) * (height / 4) * ((cf == ImageLoader::ColorFormat::RGB8) ? 8 : 16); // block size
-		break;
-	case ImageLoader::DataCompression::ETC:
-		out = (width / 4) * (height / 4) * 8;
-		break;
-	default:
-		ANKI_ASSERT(0);
-	}
-
-	ANKI_ASSERT(out > 0);
-
-	return out;
-}
-
-/// Get the size in bytes of a single volume
-static PtrSize calcVolumeSize(const U width,
-	const U height,
-	const U depth,
-	const ImageLoader::DataCompression comp,
-	const ImageLoader::ColorFormat cf)
-{
-	PtrSize out = 0;
-
-	ANKI_ASSERT(width >= 4 || height >= 4 || depth >= 4);
-
-	switch(comp)
-	{
-	case ImageLoader::DataCompression::RAW:
-		out = width * height * depth * ((cf == ImageLoader::ColorFormat::RGB8) ? 3 : 4);
-		break;
-	default:
-		ANKI_ASSERT(0);
-	}
-
-	ANKI_ASSERT(out > 0);
-
-	return out;
-}
-
-/// Calculate the size of a compressed or uncomressed color data
-static PtrSize calcSizeOfSegment(const AnkiTextureHeader& header, ImageLoader::DataCompression comp)
-{
-	PtrSize out = 0;
-	U32 width = header.m_width;
-	U32 height = header.m_height;
-	U32 mips = header.m_mipLevels;
-	ANKI_ASSERT(mips > 0);
-
-	if(header.m_type != ImageLoader::TextureType::_3D)
-	{
-		U32 surfCountPerMip = 0;
-
-		switch(header.m_type)
-		{
-		case ImageLoader::TextureType::_2D:
-			surfCountPerMip = 1;
-			break;
-		case ImageLoader::TextureType::CUBE:
-			surfCountPerMip = 6;
-			break;
-		case ImageLoader::TextureType::_2D_ARRAY:
-			surfCountPerMip = header.m_depthOrLayerCount;
-			break;
-		default:
-			ANKI_ASSERT(0);
-			break;
-		}
-
-		while(mips-- != 0)
-		{
-			out += calcSurfaceSize(width, height, comp, header.m_colorFormat) * surfCountPerMip;
-
-			width /= 2;
-			height /= 2;
-		}
-	}
-	else
-	{
-		U depth = header.m_depthOrLayerCount;
-
-		while(mips-- != 0)
-		{
-			out += calcVolumeSize(width, height, depth, comp, header.m_colorFormat);
-
-			width /= 2;
-			height /= 2;
-			depth /= 2;
-		}
-	}
-
-	return out;
-}
-
-static ANKI_USE_RESULT Error loadAnkiTexture(ResourceFilePtr file,
+Error ImageLoader::loadAnkiTexture(FileInterface& file,
 	U32 maxTextureSize,
 	U32 maxTextureSize,
-	ImageLoader::DataCompression& preferredCompression,
-	DynamicArray<ImageLoader::Surface>& surfaces,
-	DynamicArray<ImageLoader::Volume>& volumes,
+	ImageLoaderDataCompression& preferredCompression,
+	DynamicArray<ImageLoaderSurface>& surfaces,
+	DynamicArray<ImageLoaderVolume>& volumes,
 	GenericMemoryPoolAllocator<U8>& alloc,
 	GenericMemoryPoolAllocator<U8>& alloc,
 	U32& width,
 	U32& width,
 	U32& height,
 	U32& height,
 	U32& depth,
 	U32& depth,
 	U32& layerCount,
 	U32& layerCount,
 	U8& toLoadMipCount,
 	U8& toLoadMipCount,
-	ImageLoader::TextureType& textureType,
-	ImageLoader::ColorFormat& colorFormat)
+	ImageLoaderTextureType& textureType,
+	ImageLoaderColorFormat& colorFormat)
 {
 {
 	//
 	//
 	// Read and check the header
 	// Read and check the header
 	//
 	//
 	AnkiTextureHeader header;
 	AnkiTextureHeader header;
-	ANKI_CHECK(file->read(&header, sizeof(AnkiTextureHeader)));
+	ANKI_CHECK(file.read(&header, sizeof(AnkiTextureHeader)));
 
 
 	if(std::memcmp(&header.m_magic[0], "ANKITEX1", 8) != 0)
 	if(std::memcmp(&header.m_magic[0], "ANKITEX1", 8) != 0)
 	{
 	{
@@ -345,26 +370,26 @@ static ANKI_USE_RESULT Error loadAnkiTexture(ResourceFilePtr file,
 		return Error::USER_DATA;
 		return Error::USER_DATA;
 	}
 	}
 
 
-	if(header.m_type < ImageLoader::TextureType::_2D || header.m_type > ImageLoader::TextureType::_2D_ARRAY)
+	if(header.m_type < ImageLoaderTextureType::_2D || header.m_type > ImageLoaderTextureType::_2D_ARRAY)
 	{
 	{
 		ANKI_RESOURCE_LOGE("Incorrect header: texture type");
 		ANKI_RESOURCE_LOGE("Incorrect header: texture type");
 		return Error::USER_DATA;
 		return Error::USER_DATA;
 	}
 	}
 
 
-	if(header.m_colorFormat < ImageLoader::ColorFormat::RGB8 || header.m_colorFormat > ImageLoader::ColorFormat::RGBA8)
+	if(header.m_colorFormat < ImageLoaderColorFormat::RGB8 || header.m_colorFormat > ImageLoaderColorFormat::RGBA8)
 	{
 	{
 		ANKI_RESOURCE_LOGE("Incorrect header: color format");
 		ANKI_RESOURCE_LOGE("Incorrect header: color format");
 		return Error::USER_DATA;
 		return Error::USER_DATA;
 	}
 	}
 
 
-	if((header.m_compressionFormats & preferredCompression) == ImageLoader::DataCompression::NONE)
+	if((header.m_compressionFormats & preferredCompression) == ImageLoaderDataCompression::NONE)
 	{
 	{
 		ANKI_RESOURCE_LOGW("File does not contain the requested compression");
 		ANKI_RESOURCE_LOGW("File does not contain the requested compression");
 
 
 		// Fallback
 		// Fallback
-		preferredCompression = ImageLoader::DataCompression::RAW;
+		preferredCompression = ImageLoaderDataCompression::RAW;
 
 
-		if((header.m_compressionFormats & preferredCompression) == ImageLoader::DataCompression::NONE)
+		if((header.m_compressionFormats & preferredCompression) == ImageLoaderDataCompression::NONE)
 		{
 		{
 			ANKI_RESOURCE_LOGE("File does not contain raw compression");
 			ANKI_RESOURCE_LOGE("File does not contain raw compression");
 			return Error::USER_DATA;
 			return Error::USER_DATA;
@@ -383,7 +408,7 @@ static ANKI_USE_RESULT Error loadAnkiTexture(ResourceFilePtr file,
 	// Check mip levels
 	// Check mip levels
 	U size = min(header.m_width, header.m_height);
 	U size = min(header.m_width, header.m_height);
 	U maxSize = max(header.m_width, header.m_height);
 	U maxSize = max(header.m_width, header.m_height);
-	if(header.m_type == ImageLoader::TextureType::_3D)
+	if(header.m_type == ImageLoaderTextureType::_3D)
 	{
 	{
 		maxSize = max<U>(maxSize, header.m_depthOrLayerCount);
 		maxSize = max<U>(maxSize, header.m_depthOrLayerCount);
 		size = min<U>(size, header.m_depthOrLayerCount);
 		size = min<U>(size, header.m_depthOrLayerCount);
@@ -403,33 +428,33 @@ static ANKI_USE_RESULT Error loadAnkiTexture(ResourceFilePtr file,
 		maxSize /= 2;
 		maxSize /= 2;
 	}
 	}
 
 
-	if(header.m_mipLevels > tmpMipLevels)
+	if(header.m_mipCount > tmpMipLevels)
 	{
 	{
 		ANKI_RESOURCE_LOGE("Incorrect number of mip levels");
 		ANKI_RESOURCE_LOGE("Incorrect number of mip levels");
 		return Error::USER_DATA;
 		return Error::USER_DATA;
 	}
 	}
 
 
-	toLoadMipCount = U8(min<U32>(toLoadMipCount, header.m_mipLevels));
+	toLoadMipCount = U8(min<U32>(toLoadMipCount, header.m_mipCount));
 
 
 	colorFormat = header.m_colorFormat;
 	colorFormat = header.m_colorFormat;
 
 
 	U faceCount = 1;
 	U faceCount = 1;
 	switch(header.m_type)
 	switch(header.m_type)
 	{
 	{
-	case ImageLoader::TextureType::_2D:
+	case ImageLoaderTextureType::_2D:
 		depth = 1;
 		depth = 1;
 		layerCount = 1;
 		layerCount = 1;
 		break;
 		break;
-	case ImageLoader::TextureType::CUBE:
+	case ImageLoaderTextureType::CUBE:
 		depth = 1;
 		depth = 1;
 		layerCount = 1;
 		layerCount = 1;
 		faceCount = 6;
 		faceCount = 6;
 		break;
 		break;
-	case ImageLoader::TextureType::_3D:
+	case ImageLoaderTextureType::_3D:
 		depth = header.m_depthOrLayerCount;
 		depth = header.m_depthOrLayerCount;
 		layerCount = 1;
 		layerCount = 1;
 		break;
 		break;
-	case ImageLoader::TextureType::_2D_ARRAY:
+	case ImageLoaderTextureType::_2D_ARRAY:
 		depth = 1;
 		depth = 1;
 		layerCount = header.m_depthOrLayerCount;
 		layerCount = header.m_depthOrLayerCount;
 		break;
 		break;
@@ -443,33 +468,30 @@ static ANKI_USE_RESULT Error loadAnkiTexture(ResourceFilePtr file,
 	// Move file pointer
 	// Move file pointer
 	//
 	//
 
 
-	if(preferredCompression == ImageLoader::DataCompression::RAW)
+	if(preferredCompression == ImageLoaderDataCompression::RAW)
 	{
 	{
 		// Do nothing
 		// Do nothing
 	}
 	}
-	else if(preferredCompression == ImageLoader::DataCompression::S3TC)
+	else if(preferredCompression == ImageLoaderDataCompression::S3TC)
 	{
 	{
-		if((header.m_compressionFormats & ImageLoader::DataCompression::RAW) != ImageLoader::DataCompression::NONE)
+		if((header.m_compressionFormats & ImageLoaderDataCompression::RAW) != ImageLoaderDataCompression::NONE)
 		{
 		{
 			// If raw compression is present then skip it
 			// If raw compression is present then skip it
-			ANKI_CHECK(file->seek(
-				calcSizeOfSegment(header, ImageLoader::DataCompression::RAW), ResourceFile::SeekOrigin::CURRENT));
+			ANKI_CHECK(file.seek(calcSizeOfSegment(header, ImageLoaderDataCompression::RAW), FileSeekOrigin::CURRENT));
 		}
 		}
 	}
 	}
-	else if(preferredCompression == ImageLoader::DataCompression::ETC)
+	else if(preferredCompression == ImageLoaderDataCompression::ETC)
 	{
 	{
-		if((header.m_compressionFormats & ImageLoader::DataCompression::RAW) != ImageLoader::DataCompression::NONE)
+		if((header.m_compressionFormats & ImageLoaderDataCompression::RAW) != ImageLoaderDataCompression::NONE)
 		{
 		{
 			// If raw compression is present then skip it
 			// If raw compression is present then skip it
-			ANKI_CHECK(file->seek(
-				calcSizeOfSegment(header, ImageLoader::DataCompression::RAW), ResourceFile::SeekOrigin::CURRENT));
+			ANKI_CHECK(file.seek(calcSizeOfSegment(header, ImageLoaderDataCompression::RAW), FileSeekOrigin::CURRENT));
 		}
 		}
 
 
-		if((header.m_compressionFormats & ImageLoader::DataCompression::S3TC) != ImageLoader::DataCompression::NONE)
+		if((header.m_compressionFormats & ImageLoaderDataCompression::S3TC) != ImageLoaderDataCompression::NONE)
 		{
 		{
 			// If s3tc compression is present then skip it
 			// If s3tc compression is present then skip it
-			ANKI_CHECK(file->seek(
-				calcSizeOfSegment(header, ImageLoader::DataCompression::S3TC), ResourceFile::SeekOrigin::CURRENT));
+			ANKI_CHECK(file.seek(calcSizeOfSegment(header, ImageLoaderDataCompression::S3TC), FileSeekOrigin::CURRENT));
 		}
 		}
 	}
 	}
 
 
@@ -478,7 +500,7 @@ static ANKI_USE_RESULT Error loadAnkiTexture(ResourceFilePtr file,
 	//
 	//
 
 
 	// Allocate the surfaces
 	// Allocate the surfaces
-	if(header.m_type != ImageLoader::TextureType::_3D)
+	if(header.m_type != ImageLoaderTextureType::_3D)
 	{
 	{
 		surfaces.create(alloc, toLoadMipCount * layerCount * faceCount);
 		surfaces.create(alloc, toLoadMipCount * layerCount * faceCount);
 
 
@@ -486,7 +508,7 @@ static ANKI_USE_RESULT Error loadAnkiTexture(ResourceFilePtr file,
 		U32 mipWidth = header.m_width;
 		U32 mipWidth = header.m_width;
 		U32 mipHeight = header.m_height;
 		U32 mipHeight = header.m_height;
 		U32 index = 0;
 		U32 index = 0;
-		for(U32 mip = 0; mip < header.m_mipLevels; mip++)
+		for(U32 mip = 0; mip < header.m_mipCount; mip++)
 		{
 		{
 			for(U32 l = 0; l < layerCount; l++)
 			for(U32 l = 0; l < layerCount; l++)
 			{
 			{
@@ -499,17 +521,17 @@ static ANKI_USE_RESULT Error loadAnkiTexture(ResourceFilePtr file,
 					// Check if this mipmap can be skipped because of size
 					// Check if this mipmap can be skipped because of size
 					if(maxSize <= maxTextureSize)
 					if(maxSize <= maxTextureSize)
 					{
 					{
-						ImageLoader::Surface& surf = surfaces[index++];
+						ImageLoaderSurface& surf = surfaces[index++];
 						surf.m_width = mipWidth;
 						surf.m_width = mipWidth;
 						surf.m_height = mipHeight;
 						surf.m_height = mipHeight;
 
 
 						surf.m_data.create(alloc, dataSize);
 						surf.m_data.create(alloc, dataSize);
 
 
-						ANKI_CHECK(file->read(&surf.m_data[0], dataSize));
+						ANKI_CHECK(file.read(&surf.m_data[0], dataSize));
 					}
 					}
 					else
 					else
 					{
 					{
-						ANKI_CHECK(file->seek(dataSize, ResourceFile::SeekOrigin::CURRENT));
+						ANKI_CHECK(file.seek(dataSize, FileSeekOrigin::CURRENT));
 					}
 					}
 				}
 				}
 			}
 			}
@@ -525,7 +547,7 @@ static ANKI_USE_RESULT Error loadAnkiTexture(ResourceFilePtr file,
 		U32 mipWidth = header.m_width;
 		U32 mipWidth = header.m_width;
 		U32 mipHeight = header.m_height;
 		U32 mipHeight = header.m_height;
 		U32 mipDepth = header.m_depthOrLayerCount;
 		U32 mipDepth = header.m_depthOrLayerCount;
-		for(U32 mip = 0; mip < header.m_mipLevels; mip++)
+		for(U32 mip = 0; mip < header.m_mipCount; mip++)
 		{
 		{
 			const U32 dataSize =
 			const U32 dataSize =
 				U32(calcVolumeSize(mipWidth, mipHeight, mipDepth, preferredCompression, header.m_colorFormat));
 				U32(calcVolumeSize(mipWidth, mipHeight, mipDepth, preferredCompression, header.m_colorFormat));
@@ -533,18 +555,18 @@ static ANKI_USE_RESULT Error loadAnkiTexture(ResourceFilePtr file,
 			// Check if this mipmap can be skipped because of size
 			// Check if this mipmap can be skipped because of size
 			if(maxSize <= maxTextureSize)
 			if(maxSize <= maxTextureSize)
 			{
 			{
-				ImageLoader::Volume& vol = volumes[mip];
+				ImageLoaderVolume& vol = volumes[mip];
 				vol.m_width = mipWidth;
 				vol.m_width = mipWidth;
 				vol.m_height = mipHeight;
 				vol.m_height = mipHeight;
 				vol.m_depth = mipDepth;
 				vol.m_depth = mipDepth;
 
 
 				vol.m_data.create(alloc, dataSize);
 				vol.m_data.create(alloc, dataSize);
 
 
-				ANKI_CHECK(file->read(&vol.m_data[0], dataSize));
+				ANKI_CHECK(file.read(&vol.m_data[0], dataSize));
 			}
 			}
 			else
 			else
 			{
 			{
-				ANKI_CHECK(file->seek(dataSize, ResourceFile::SeekOrigin::CURRENT));
+				ANKI_CHECK(file.seek(dataSize, FileSeekOrigin::CURRENT));
 			}
 			}
 
 
 			mipWidth /= 2;
 			mipWidth /= 2;
@@ -556,7 +578,21 @@ static ANKI_USE_RESULT Error loadAnkiTexture(ResourceFilePtr file,
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 
-Error ImageLoader::load(ResourceFilePtr file, const CString& filename, U32 maxTextureSize)
+Error ImageLoader::load(ResourceFilePtr rfile, const CString& filename, U32 maxTextureSize)
+{
+	RsrcFile file;
+	file.m_rfile = rfile;
+	return loadInternal(file, filename, maxTextureSize);
+}
+
+Error ImageLoader::load(const CString& filename, U32 maxTextureSize)
+{
+	SystemFile file;
+	ANKI_CHECK(file.m_file.open(filename, FileOpenFlag::READ | FileOpenFlag::BINARY));
+	return loadInternal(file, filename, maxTextureSize);
+}
+
+Error ImageLoader::loadInternal(FileInterface& file, const CString& filename, U32 maxTextureSize)
 {
 {
 	// get the extension
 	// get the extension
 	StringAuto ext(m_alloc);
 	StringAuto ext(m_alloc);
@@ -570,14 +606,14 @@ Error ImageLoader::load(ResourceFilePtr file, const CString& filename, U32 maxTe
 
 
 	// load from this extension
 	// load from this extension
 	U32 bpp = 0;
 	U32 bpp = 0;
-	m_textureType = TextureType::_2D;
-	m_compression = DataCompression::RAW;
+	m_textureType = ImageLoaderTextureType::_2D;
+	m_compression = ImageLoaderDataCompression::RAW;
 
 
 	if(ext == "tga")
 	if(ext == "tga")
 	{
 	{
 		m_surfaces.create(m_alloc, 1);
 		m_surfaces.create(m_alloc, 1);
 
 
-		m_mipLevels = 1;
+		m_mipCount = 1;
 		m_depth = 1;
 		m_depth = 1;
 		m_layerCount = 1;
 		m_layerCount = 1;
 		ANKI_CHECK(loadTga(file, m_surfaces[0].m_width, m_surfaces[0].m_height, bpp, m_surfaces[0].m_data, m_alloc));
 		ANKI_CHECK(loadTga(file, m_surfaces[0].m_width, m_surfaces[0].m_height, bpp, m_surfaces[0].m_data, m_alloc));
@@ -587,11 +623,11 @@ Error ImageLoader::load(ResourceFilePtr file, const CString& filename, U32 maxTe
 
 
 		if(bpp == 32)
 		if(bpp == 32)
 		{
 		{
-			m_colorFormat = ColorFormat::RGBA8;
+			m_colorFormat = ImageLoaderColorFormat::RGBA8;
 		}
 		}
 		else if(bpp == 24)
 		else if(bpp == 24)
 		{
 		{
-			m_colorFormat = ColorFormat::RGB8;
+			m_colorFormat = ImageLoaderColorFormat::RGB8;
 		}
 		}
 		else
 		else
 		{
 		{
@@ -601,9 +637,9 @@ Error ImageLoader::load(ResourceFilePtr file, const CString& filename, U32 maxTe
 	else if(ext == "ankitex")
 	else if(ext == "ankitex")
 	{
 	{
 #if 0
 #if 0
-		compression = ImageLoader::DataCompression::RAW;
+		compression = ImageLoaderDataCompression::RAW;
 #else
 #else
-		m_compression = ImageLoader::DataCompression::S3TC;
+		m_compression = ImageLoaderDataCompression::S3TC;
 #endif
 #endif
 
 
 		ANKI_CHECK(loadAnkiTexture(file,
 		ANKI_CHECK(loadAnkiTexture(file,
@@ -616,7 +652,7 @@ Error ImageLoader::load(ResourceFilePtr file, const CString& filename, U32 maxTe
 			m_height,
 			m_height,
 			m_depth,
 			m_depth,
 			m_layerCount,
 			m_layerCount,
-			m_mipLevels,
+			m_mipCount,
 			m_textureType,
 			m_textureType,
 			m_colorFormat));
 			m_colorFormat));
 	}
 	}
@@ -629,25 +665,25 @@ Error ImageLoader::load(ResourceFilePtr file, const CString& filename, U32 maxTe
 	return Error::NONE;
 	return Error::NONE;
 }
 }
 
 
-const ImageLoader::Surface& ImageLoader::getSurface(U level, U face, U layer) const
+const ImageLoaderSurface& ImageLoader::getSurface(U32 level, U32 face, U32 layer) const
 {
 {
-	ANKI_ASSERT(level < m_mipLevels);
+	ANKI_ASSERT(level < m_mipCount);
 
 
-	U idx = 0;
+	U32 idx = 0;
 
 
 	switch(m_textureType)
 	switch(m_textureType)
 	{
 	{
-	case TextureType::_2D:
+	case ImageLoaderTextureType::_2D:
 		idx = level;
 		idx = level;
 		break;
 		break;
-	case TextureType::CUBE:
+	case ImageLoaderTextureType::CUBE:
 		ANKI_ASSERT(face < 6);
 		ANKI_ASSERT(face < 6);
 		idx = level * 6 + face;
 		idx = level * 6 + face;
 		break;
 		break;
-	case TextureType::_3D:
+	case ImageLoaderTextureType::_3D:
 		ANKI_ASSERT(0 && "Can't use that for 3D textures");
 		ANKI_ASSERT(0 && "Can't use that for 3D textures");
 		break;
 		break;
-	case TextureType::_2D_ARRAY:
+	case ImageLoaderTextureType::_2D_ARRAY:
 		idx = level * m_layerCount + layer;
 		idx = level * m_layerCount + layer;
 		break;
 		break;
 	default:
 	default:
@@ -657,22 +693,22 @@ const ImageLoader::Surface& ImageLoader::getSurface(U level, U face, U layer) co
 	return m_surfaces[idx];
 	return m_surfaces[idx];
 }
 }
 
 
-const ImageLoader::Volume& ImageLoader::getVolume(U level) const
+const ImageLoaderVolume& ImageLoader::getVolume(U32 level) const
 {
 {
-	ANKI_ASSERT(m_textureType == TextureType::_3D);
+	ANKI_ASSERT(m_textureType == ImageLoaderTextureType::_3D);
 	return m_volumes[level];
 	return m_volumes[level];
 }
 }
 
 
 void ImageLoader::destroy()
 void ImageLoader::destroy()
 {
 {
-	for(Surface& surf : m_surfaces)
+	for(ImageLoaderSurface& surf : m_surfaces)
 	{
 	{
 		surf.m_data.destroy(m_alloc);
 		surf.m_data.destroy(m_alloc);
 	}
 	}
 
 
 	m_surfaces.destroy(m_alloc);
 	m_surfaces.destroy(m_alloc);
 
 
-	for(Volume& v : m_volumes)
+	for(ImageLoaderVolume& v : m_volumes)
 	{
 	{
 		v.m_data.destroy(m_alloc);
 		v.m_data.destroy(m_alloc);
 	}
 	}

+ 116 - 80
src/anki/resource/ImageLoader.h

@@ -7,65 +7,68 @@
 
 
 #include <anki/resource/Common.h>
 #include <anki/resource/Common.h>
 #include <anki/resource/ResourceFilesystem.h>
 #include <anki/resource/ResourceFilesystem.h>
-#include <anki/util/Functions.h>
-#include <anki/util/Enum.h>
 
 
 namespace anki
 namespace anki
 {
 {
 
 
-/// Image loader.
-class ImageLoader
+/// Texture type
+/// @memberof ImageLoader
+enum class ImageLoaderTextureType : U32
 {
 {
-public:
-	/// Texture type
-	enum class TextureType : U32
-	{
-		NONE,
-		_2D,
-		CUBE,
-		_3D,
-		_2D_ARRAY
-	};
-
-	/// The acceptable color types of AnKi
-	enum class ColorFormat : U32
-	{
-		NONE,
-		RGB8, ///< RGB
-		RGBA8 ///< RGB plus alpha
-	};
+	NONE,
+	_2D,
+	CUBE,
+	_3D,
+	_2D_ARRAY
+};
 
 
-	/// The data compression
-	enum class DataCompression : U32
-	{
-		NONE,
-		RAW = 1 << 0,
-		S3TC = 1 << 1,
-		ETC = 1 << 2
-	};
+/// The acceptable color types of AnKi
+/// @memberof ImageLoader
+enum class ImageLoaderColorFormat : U32
+{
+	NONE,
+	RGB8, ///< RGB
+	RGBA8 ///< RGB plus alpha
+};
 
 
-	ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(DataCompression, friend)
+/// The data compression
+/// @memberof ImageLoader
+enum class ImageLoaderDataCompression : U32
+{
+	NONE,
+	RAW = 1 << 0,
+	S3TC = 1 << 1,
+	ETC = 1 << 2
+};
+ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(ImageLoaderDataCompression, inline)
 
 
-	/// An image surface
-	class Surface
-	{
-	public:
-		U32 m_width;
-		U32 m_height;
-		U32 m_mipLevel;
-		DynamicArray<U8> m_data;
-	};
-
-	class Volume
-	{
-	public:
-		U32 m_width;
-		U32 m_height;
-		U32 m_depth;
-		U32 m_mipLevel;
-		DynamicArray<U8> m_data;
-	};
+/// An image surface
+/// @memberof ImageLoader
+class ImageLoaderSurface
+{
+public:
+	U32 m_width;
+	U32 m_height;
+	U32 m_mipLevel;
+	DynamicArray<U8> m_data;
+};
 
 
+/// An image volume
+/// @memberof ImageLoader
+class ImageLoaderVolume
+{
+public:
+	U32 m_width;
+	U32 m_height;
+	U32 m_depth;
+	U32 m_mipLevel;
+	DynamicArray<U8> m_data;
+};
+
+/// Loads bitmaps from regular system files or resource files. Supported formats are .tga and .ankitex.
+class ImageLoader
+{
+public:
 	ImageLoader(GenericMemoryPoolAllocator<U8> alloc)
 	ImageLoader(GenericMemoryPoolAllocator<U8> alloc)
 		: m_alloc(alloc)
 		: m_alloc(alloc)
 	{
 	{
@@ -76,22 +79,22 @@ public:
 		destroy();
 		destroy();
 	}
 	}
 
 
-	ColorFormat getColorFormat() const
+	ImageLoaderColorFormat getColorFormat() const
 	{
 	{
-		ANKI_ASSERT(m_colorFormat != ColorFormat::NONE);
+		ANKI_ASSERT(m_colorFormat != ImageLoaderColorFormat::NONE);
 		return m_colorFormat;
 		return m_colorFormat;
 	}
 	}
 
 
-	DataCompression getCompression() const
+	ImageLoaderDataCompression getCompression() const
 	{
 	{
-		ANKI_ASSERT(m_compression != DataCompression::NONE);
+		ANKI_ASSERT(m_compression != ImageLoaderDataCompression::NONE);
 		return m_compression;
 		return m_compression;
 	}
 	}
 
 
-	U32 getMipLevelsCount() const
+	U32 getMipmapCount() const
 	{
 	{
-		ANKI_ASSERT(m_mipLevels != 0);
-		return m_mipLevels;
+		ANKI_ASSERT(m_mipCount != 0);
+		return m_mipCount;
 	}
 	}
 
 
 	U32 getWidth() const
 	U32 getWidth() const
@@ -106,59 +109,92 @@ public:
 
 
 	U32 getDepth() const
 	U32 getDepth() const
 	{
 	{
-		ANKI_ASSERT(m_textureType == TextureType::_3D);
+		ANKI_ASSERT(m_textureType == ImageLoaderTextureType::_3D);
 		return m_depth;
 		return m_depth;
 	}
 	}
 
 
 	U32 getLayerCount() const
 	U32 getLayerCount() const
 	{
 	{
-		ANKI_ASSERT(m_textureType == TextureType::_2D_ARRAY);
+		ANKI_ASSERT(m_textureType == ImageLoaderTextureType::_2D_ARRAY);
 		return m_layerCount;
 		return m_layerCount;
 	}
 	}
 
 
-	TextureType getTextureType() const
+	ImageLoaderTextureType getTextureType() const
 	{
 	{
-		ANKI_ASSERT(m_textureType != TextureType::NONE);
+		ANKI_ASSERT(m_textureType != ImageLoaderTextureType::NONE);
 		return m_textureType;
 		return m_textureType;
 	}
 	}
 
 
-	const Surface& getSurface(U level, U face, U layer) const;
+	const ImageLoaderSurface& getSurface(U32 level, U32 face, U32 layer) const;
 
 
-	const Volume& getVolume(U level) const;
+	const ImageLoaderVolume& getVolume(U32 level) const;
 
 
-	GenericMemoryPoolAllocator<U8> getAllocator() const
-	{
-		return m_alloc;
-	}
-
-	/// Load an image file.
+	/// Load a resource image file.
 	ANKI_USE_RESULT Error load(ResourceFilePtr file, const CString& filename, U32 maxTextureSize = MAX_U32);
 	ANKI_USE_RESULT Error load(ResourceFilePtr file, const CString& filename, U32 maxTextureSize = MAX_U32);
 
 
-	Atomic<I32>& getRefcount()
-	{
-		return m_refcount;
-	}
+	/// Load a system image file.
+	ANKI_USE_RESULT Error load(const CString& filename, U32 maxTextureSize = MAX_U32);
 
 
 private:
 private:
+	class FileInterface;
+	class RsrcFile;
+	class SystemFile;
+
 	GenericMemoryPoolAllocator<U8> m_alloc;
 	GenericMemoryPoolAllocator<U8> m_alloc;
-	Atomic<I32> m_refcount = {0};
 
 
 	/// [mip][depth or face or layer]. Loader doesn't support cube arrays ATM so face and layer won't be used at the
 	/// [mip][depth or face or layer]. Loader doesn't support cube arrays ATM so face and layer won't be used at the
 	/// same time.
 	/// same time.
-	DynamicArray<Surface> m_surfaces;
+	DynamicArray<ImageLoaderSurface> m_surfaces;
 
 
-	DynamicArray<Volume> m_volumes;
+	DynamicArray<ImageLoaderVolume> m_volumes;
 
 
-	U8 m_mipLevels = 0;
+	U8 m_mipCount = 0;
 	U32 m_width = 0;
 	U32 m_width = 0;
 	U32 m_height = 0;
 	U32 m_height = 0;
 	U32 m_depth = 0;
 	U32 m_depth = 0;
 	U32 m_layerCount = 0;
 	U32 m_layerCount = 0;
-	DataCompression m_compression = DataCompression::NONE;
-	ColorFormat m_colorFormat = ColorFormat::NONE;
-	TextureType m_textureType = TextureType::NONE;
+	ImageLoaderDataCompression m_compression = ImageLoaderDataCompression::NONE;
+	ImageLoaderColorFormat m_colorFormat = ImageLoaderColorFormat::NONE;
+	ImageLoaderTextureType m_textureType = ImageLoaderTextureType::NONE;
 
 
 	void destroy();
 	void destroy();
+
+	static ANKI_USE_RESULT Error loadUncompressedTga(FileInterface& fs,
+		U32& width,
+		U32& height,
+		U32& bpp,
+		DynamicArray<U8>& data,
+		GenericMemoryPoolAllocator<U8>& alloc);
+
+	static ANKI_USE_RESULT Error loadCompressedTga(FileInterface& fs,
+		U32& width,
+		U32& height,
+		U32& bpp,
+		DynamicArray<U8>& data,
+		GenericMemoryPoolAllocator<U8>& alloc);
+
+	static ANKI_USE_RESULT Error loadTga(FileInterface& fs,
+		U32& width,
+		U32& height,
+		U32& bpp,
+		DynamicArray<U8>& data,
+		GenericMemoryPoolAllocator<U8>& alloc);
+
+	static ANKI_USE_RESULT Error loadAnkiTexture(FileInterface& file,
+		U32 maxTextureSize,
+		ImageLoaderDataCompression& preferredCompression,
+		DynamicArray<ImageLoaderSurface>& surfaces,
+		DynamicArray<ImageLoaderVolume>& volumes,
+		GenericMemoryPoolAllocator<U8>& alloc,
+		U32& width,
+		U32& height,
+		U32& depth,
+		U32& layerCount,
+		U8& toLoadMipCount,
+		ImageLoaderTextureType& textureType,
+		ImageLoaderColorFormat& colorFormat);
+
+	ANKI_USE_RESULT Error loadInternal(FileInterface& file, const CString& filename, U32 maxTextureSize);
 };
 };
 
 
 } // end namespace anki
 } // end namespace anki

+ 2 - 2
src/anki/resource/MeshLoader.cpp

@@ -237,7 +237,7 @@ Error MeshLoader::storeIndexBuffer(void* ptr, PtrSize size)
 	}
 	}
 	else
 	else
 	{
 	{
-		ANKI_CHECK(m_file->seek(size, ResourceFile::SeekOrigin::CURRENT));
+		ANKI_CHECK(m_file->seek(size, FileSeekOrigin::CURRENT));
 	}
 	}
 
 
 	++m_loadedChunk;
 	++m_loadedChunk;
@@ -257,7 +257,7 @@ Error MeshLoader::storeVertexBuffer(U32 bufferIdx, void* ptr, PtrSize size)
 	}
 	}
 	else
 	else
 	{
 	{
-		ANKI_CHECK(m_file->seek(size, ResourceFile::SeekOrigin::CURRENT));
+		ANKI_CHECK(m_file->seek(size, FileSeekOrigin::CURRENT));
 	}
 	}
 
 
 	++m_loadedChunk;
 	++m_loadedChunk;

+ 3 - 3
src/anki/resource/ResourceFilesystem.cpp

@@ -47,7 +47,7 @@ public:
 		return m_file.readF32(f);
 		return m_file.readF32(f);
 	}
 	}
 
 
-	ANKI_USE_RESULT Error seek(PtrSize offset, SeekOrigin origin) override
+	ANKI_USE_RESULT Error seek(PtrSize offset, FileSeekOrigin origin) override
 	{
 	{
 		return m_file.seek(offset, origin);
 		return m_file.seek(offset, origin);
 	}
 	}
@@ -162,10 +162,10 @@ public:
 		return Error::NONE;
 		return Error::NONE;
 	}
 	}
 
 
-	ANKI_USE_RESULT Error seek(PtrSize offset, SeekOrigin origin) override
+	ANKI_USE_RESULT Error seek(PtrSize offset, FileSeekOrigin origin) override
 	{
 	{
 		// Rewind if needed
 		// Rewind if needed
-		if(origin == SeekOrigin::BEGINNING)
+		if(origin == FileSeekOrigin::BEGINNING)
 		{
 		{
 			if(unzCloseCurrentFile(m_archive) || unzOpenCurrentFile(m_archive))
 			if(unzCloseCurrentFile(m_archive) || unzOpenCurrentFile(m_archive))
 			{
 			{

+ 1 - 3
src/anki/resource/ResourceFilesystem.h

@@ -24,8 +24,6 @@ class ConfigSet;
 class ResourceFile : public NonCopyable
 class ResourceFile : public NonCopyable
 {
 {
 public:
 public:
-	using SeekOrigin = File::SeekOrigin;
-
 	ResourceFile(GenericMemoryPoolAllocator<U8> alloc)
 	ResourceFile(GenericMemoryPoolAllocator<U8> alloc)
 		: m_alloc(alloc)
 		: m_alloc(alloc)
 	{
 	{
@@ -50,7 +48,7 @@ public:
 	/// Set the position indicator to a new position
 	/// Set the position indicator to a new position
 	/// @param offset Number of bytes to offset from origin
 	/// @param offset Number of bytes to offset from origin
 	/// @param origin Position used as reference for the offset
 	/// @param origin Position used as reference for the offset
-	virtual ANKI_USE_RESULT Error seek(PtrSize offset, SeekOrigin origin) = 0;
+	virtual ANKI_USE_RESULT Error seek(PtrSize offset, FileSeekOrigin origin) = 0;
 
 
 	/// Get the size of the file.
 	/// Get the size of the file.
 	virtual PtrSize getSize() const = 0;
 	virtual PtrSize getSize() const = 0;

+ 15 - 15
src/anki/resource/TextureResource.cpp

@@ -83,25 +83,25 @@ Error TextureResource::load(const ResourceFilename& filename, Bool async)
 
 
 	switch(loader.getTextureType())
 	switch(loader.getTextureType())
 	{
 	{
-	case ImageLoader::TextureType::_2D:
+	case ImageLoaderTextureType::_2D:
 		init.m_type = TextureType::_2D;
 		init.m_type = TextureType::_2D;
 		init.m_depth = 1;
 		init.m_depth = 1;
 		faces = 1;
 		faces = 1;
 		init.m_layerCount = 1;
 		init.m_layerCount = 1;
 		break;
 		break;
-	case ImageLoader::TextureType::CUBE:
+	case ImageLoaderTextureType::CUBE:
 		init.m_type = TextureType::CUBE;
 		init.m_type = TextureType::CUBE;
 		init.m_depth = 1;
 		init.m_depth = 1;
 		faces = 6;
 		faces = 6;
 		init.m_layerCount = 1;
 		init.m_layerCount = 1;
 		break;
 		break;
-	case ImageLoader::TextureType::_2D_ARRAY:
+	case ImageLoaderTextureType::_2D_ARRAY:
 		init.m_type = TextureType::_2D_ARRAY;
 		init.m_type = TextureType::_2D_ARRAY;
 		init.m_layerCount = loader.getLayerCount();
 		init.m_layerCount = loader.getLayerCount();
 		init.m_depth = 1;
 		init.m_depth = 1;
 		faces = 1;
 		faces = 1;
 		break;
 		break;
-	case ImageLoader::TextureType::_3D:
+	case ImageLoaderTextureType::_3D:
 		init.m_type = TextureType::_3D;
 		init.m_type = TextureType::_3D;
 		init.m_depth = loader.getDepth();
 		init.m_depth = loader.getDepth();
 		init.m_layerCount = 1;
 		init.m_layerCount = 1;
@@ -112,28 +112,28 @@ Error TextureResource::load(const ResourceFilename& filename, Bool async)
 	}
 	}
 
 
 	// Internal format
 	// Internal format
-	if(loader.getColorFormat() == ImageLoader::ColorFormat::RGB8)
+	if(loader.getColorFormat() == ImageLoaderColorFormat::RGB8)
 	{
 	{
 		switch(loader.getCompression())
 		switch(loader.getCompression())
 		{
 		{
-		case ImageLoader::DataCompression::RAW:
+		case ImageLoaderDataCompression::RAW:
 			init.m_format = Format::R8G8B8_UNORM;
 			init.m_format = Format::R8G8B8_UNORM;
 			break;
 			break;
-		case ImageLoader::DataCompression::S3TC:
+		case ImageLoaderDataCompression::S3TC:
 			init.m_format = Format::BC1_RGB_UNORM_BLOCK;
 			init.m_format = Format::BC1_RGB_UNORM_BLOCK;
 			break;
 			break;
 		default:
 		default:
 			ANKI_ASSERT(0);
 			ANKI_ASSERT(0);
 		}
 		}
 	}
 	}
-	else if(loader.getColorFormat() == ImageLoader::ColorFormat::RGBA8)
+	else if(loader.getColorFormat() == ImageLoaderColorFormat::RGBA8)
 	{
 	{
 		switch(loader.getCompression())
 		switch(loader.getCompression())
 		{
 		{
-		case ImageLoader::DataCompression::RAW:
+		case ImageLoaderDataCompression::RAW:
 			init.m_format = Format::R8G8B8A8_UNORM;
 			init.m_format = Format::R8G8B8A8_UNORM;
 			break;
 			break;
-		case ImageLoader::DataCompression::S3TC:
+		case ImageLoaderDataCompression::S3TC:
 			init.m_format = Format::BC3_UNORM_BLOCK;
 			init.m_format = Format::BC3_UNORM_BLOCK;
 			break;
 			break;
 		default:
 		default:
@@ -146,7 +146,7 @@ Error TextureResource::load(const ResourceFilename& filename, Bool async)
 	}
 	}
 
 
 	// mipmapsCount
 	// mipmapsCount
-	init.m_mipmapCount = U8(loader.getMipLevelsCount());
+	init.m_mipmapCount = U8(loader.getMipmapCount());
 
 
 	// Create the texture
 	// Create the texture
 	m_tex = getManager().getGrManager().newTexture(init);
 	m_tex = getManager().getGrManager().newTexture(init);
@@ -181,7 +181,7 @@ Error TextureResource::load(const ResourceFilename& filename, Bool async)
 
 
 Error TextureResource::load(LoadingContext& ctx)
 Error TextureResource::load(LoadingContext& ctx)
 {
 {
-	const U32 copyCount = ctx.m_layerCount * ctx.m_faces * ctx.m_loader.getMipLevelsCount();
+	const U32 copyCount = ctx.m_layerCount * ctx.m_faces * ctx.m_loader.getMipmapCount();
 
 
 	for(U32 b = 0; b < copyCount; b += MAX_COPIES_BEFORE_FLUSH)
 	for(U32 b = 0; b < copyCount; b += MAX_COPIES_BEFORE_FLUSH)
 	{
 	{
@@ -196,7 +196,7 @@ Error TextureResource::load(LoadingContext& ctx)
 		for(U32 i = begin; i < end; ++i)
 		for(U32 i = begin; i < end; ++i)
 		{
 		{
 			U32 mip, layer, face;
 			U32 mip, layer, face;
-			unflatten3dArrayIndex(ctx.m_layerCount, ctx.m_faces, ctx.m_loader.getMipLevelsCount(), i, layer, face, mip);
+			unflatten3dArrayIndex(ctx.m_layerCount, ctx.m_faces, ctx.m_loader.getMipmapCount(), i, layer, face, mip);
 
 
 			if(ctx.m_texType == TextureType::_3D)
 			if(ctx.m_texType == TextureType::_3D)
 			{
 			{
@@ -218,7 +218,7 @@ Error TextureResource::load(LoadingContext& ctx)
 		for(U32 i = begin; i < end; ++i)
 		for(U32 i = begin; i < end; ++i)
 		{
 		{
 			U32 mip, layer, face;
 			U32 mip, layer, face;
-			unflatten3dArrayIndex(ctx.m_layerCount, ctx.m_faces, ctx.m_loader.getMipLevelsCount(), i, layer, face, mip);
+			unflatten3dArrayIndex(ctx.m_layerCount, ctx.m_faces, ctx.m_loader.getMipmapCount(), i, layer, face, mip);
 
 
 			PtrSize surfOrVolSize;
 			PtrSize surfOrVolSize;
 			const void* surfOrVolData;
 			const void* surfOrVolData;
@@ -273,7 +273,7 @@ Error TextureResource::load(LoadingContext& ctx)
 		for(U32 i = begin; i < end; ++i)
 		for(U32 i = begin; i < end; ++i)
 		{
 		{
 			U32 mip, layer, face;
 			U32 mip, layer, face;
-			unflatten3dArrayIndex(ctx.m_layerCount, ctx.m_faces, ctx.m_loader.getMipLevelsCount(), i, layer, face, mip);
+			unflatten3dArrayIndex(ctx.m_layerCount, ctx.m_faces, ctx.m_loader.getMipmapCount(), i, layer, face, mip);
 
 
 			if(ctx.m_texType == TextureType::_3D)
 			if(ctx.m_texType == TextureType::_3D)
 			{
 			{

+ 1 - 1
src/anki/util/File.cpp

@@ -420,7 +420,7 @@ Error File::writeText(CString format, ...)
 	return err;
 	return err;
 }
 }
 
 
-Error File::seek(PtrSize offset, SeekOrigin origin)
+Error File::seek(PtrSize offset, FileSeekOrigin origin)
 {
 {
 	ANKI_ASSERT(m_file);
 	ANKI_ASSERT(m_file);
 	ANKI_ASSERT(m_flags != FileOpenFlag::NONE);
 	ANKI_ASSERT(m_flags != FileOpenFlag::NONE);

+ 11 - 9
src/anki/util/File.h

@@ -17,6 +17,7 @@ namespace anki
 /// @{
 /// @{
 
 
 /// Open mode
 /// Open mode
+/// @memberof File
 enum class FileOpenFlag : U8
 enum class FileOpenFlag : U8
 {
 {
 	NONE = 0,
 	NONE = 0,
@@ -29,6 +30,15 @@ enum class FileOpenFlag : U8
 };
 };
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(FileOpenFlag, inline)
 ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(FileOpenFlag, inline)
 
 
+/// Passed to seek function
+/// @memberof File
+enum class FileSeekOrigin
+{
+	BEGINNING = SEEK_SET,
+	CURRENT = SEEK_CUR,
+	END = SEEK_END
+};
+
 /// An abstraction over typical files and files in ziped archives. This class can read from regular C files, zip files
 /// An abstraction over typical files and files in ziped archives. This class can read from regular C files, zip files
 /// and on Android from the packed asset files.
 /// and on Android from the packed asset files.
 /// To identify the file:
 /// To identify the file:
@@ -37,14 +47,6 @@ ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(FileOpenFlag, inline)
 class File : public NonCopyable
 class File : public NonCopyable
 {
 {
 public:
 public:
-	/// Passed to seek function
-	enum class SeekOrigin
-	{
-		BEGINNING = SEEK_SET,
-		CURRENT = SEEK_CUR,
-		END = SEEK_END
-	};
-
 	/// Default constructor
 	/// Default constructor
 	File() = default;
 	File() = default;
 
 
@@ -102,7 +104,7 @@ public:
 	/// Set the position indicator to a new position.
 	/// Set the position indicator to a new position.
 	/// @param offset Number of bytes to offset from origin
 	/// @param offset Number of bytes to offset from origin
 	/// @param origin Position used as reference for the offset
 	/// @param origin Position used as reference for the offset
-	ANKI_USE_RESULT Error seek(PtrSize offset, SeekOrigin origin);
+	ANKI_USE_RESULT Error seek(PtrSize offset, FileSeekOrigin origin);
 
 
 	/// The the size of the file.
 	/// The the size of the file.
 	PtrSize getSize() const;
 	PtrSize getSize() const;