OpenGL Mathematics (GLM)
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
 
 
 

103 lines
2.8 KiB

#include "file.hpp"
#include <cstdio>
#include <cassert>
namespace gli{
namespace detail
{
static unsigned char const FOURCC_KMG100[] = {0xAB, 0x4B, 0x49, 0x4D, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A};
struct kmgHeader10
{
std::uint32_t Endianness;
std::uint32_t Format;
std::uint32_t Target;
std::uint32_t SwizzleRed;
std::uint32_t SwizzleGreen;
std::uint32_t SwizzleBlue;
std::uint32_t SwizzleAlpha;
std::uint32_t PixelWidth;
std::uint32_t PixelHeight;
std::uint32_t PixelDepth;
std::uint32_t Layers;
std::uint32_t Levels;
std::uint32_t Faces;
std::uint32_t GenerateMipmaps;
std::uint32_t BaseLevel;
std::uint32_t MaxLevel;
};
inline texture load_kmg100(char const * Data, std::size_t Size)
{
detail::kmgHeader10 const & Header(*reinterpret_cast<detail::kmgHeader10 const *>(Data));
size_t Offset = sizeof(detail::kmgHeader10);
texture Texture(
static_cast<target>(Header.Target),
static_cast<format>(Header.Format),
texture::extent_type(Header.PixelWidth, Header.PixelHeight, Header.PixelDepth),
Header.Layers,
Header.Faces,
Header.Levels,
texture::swizzles_type(Header.SwizzleRed, Header.SwizzleGreen, Header.SwizzleBlue, Header.SwizzleAlpha));
for(texture::size_type Layer = 0, Layers = Texture.layers(); Layer < Layers; ++Layer)
for(texture::size_type Level = 0, Levels = Texture.levels(); Level < Levels; ++Level)
{
texture::size_type const FaceSize = static_cast<texture::size_type>(Texture.size(Level));
for(texture::size_type Face = 0, Faces = Texture.faces(); Face < Faces; ++Face)
{
std::memcpy(Texture.data(Layer, Face, Level), Data + Offset, FaceSize);
Offset += FaceSize;
GLI_ASSERT(Offset <= Size);
}
}
return texture(
Texture, Texture.target(), Texture.format(),
Texture.base_layer(), Texture.max_layer(),
Texture.base_face(), Texture.max_face(),
Header.BaseLevel, Header.MaxLevel,
Texture.swizzles());
}
}//namespace detail
inline texture load_kmg(char const * Data, std::size_t Size)
{
GLI_ASSERT(Data && (Size >= sizeof(detail::kmgHeader10)));
// KMG100
{
if(memcmp(Data, detail::FOURCC_KMG100, sizeof(detail::FOURCC_KMG100)) == 0)
return detail::load_kmg100(Data + sizeof(detail::FOURCC_KMG100), Size - sizeof(detail::FOURCC_KMG100));
}
return texture();
}
inline texture load_kmg(char const * Filename)
{
FILE* File = detail::open_file(Filename, "rb");
if(!File)
return texture();
long Beg = std::ftell(File);
std::fseek(File, 0, SEEK_END);
long End = std::ftell(File);
std::fseek(File, 0, SEEK_SET);
std::vector<char> Data(static_cast<std::size_t>(End - Beg));
std::fread(&Data[0], 1, Data.size(), File);
std::fclose(File);
return load_kmg(&Data[0], Data.size());
}
inline texture load_kmg(std::string const & Filename)
{
return load_kmg(Filename.c_str());
}
}//namespace gli