Util: Add TextureDecompress
This commit is contained in:
parent
7eb1d4e092
commit
8567293103
|
@ -2563,6 +2563,31 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
<h3>Texture Decompression Routines</h3>
|
||||||
|
<pre>
|
||||||
|
Copyright (C) 2009 Benjamin Dobell, Glass Echidna
|
||||||
|
Copyright (C) 2012 - 2022, Matthäus G. "Anteru" Chajdas (https://anteru.net)
|
||||||
|
Copyright (C) 2020 Richard Geldreich, Jr.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
</pre>
|
||||||
|
|
||||||
Some shaders provided with the application are sourced from:
|
Some shaders provided with the application are sourced from:
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="https://github.com/Matsilagi/RSRetroArch/">https://github.com/Matsilagi/RSRetroArch/</a></li>
|
<li><a href="https://github.com/Matsilagi/RSRetroArch/">https://github.com/Matsilagi/RSRetroArch/</a></li>
|
||||||
|
|
|
@ -65,6 +65,8 @@ add_library(util
|
||||||
sockets.h
|
sockets.h
|
||||||
state_wrapper.cpp
|
state_wrapper.cpp
|
||||||
state_wrapper.h
|
state_wrapper.h
|
||||||
|
texture_decompress.cpp
|
||||||
|
texture_decompress.h
|
||||||
wav_reader_writer.cpp
|
wav_reader_writer.cpp
|
||||||
wav_reader_writer.h
|
wav_reader_writer.h
|
||||||
window_info.cpp
|
window_info.cpp
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,198 @@
|
||||||
|
// See TextureDecompress.cpp for license info.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4201) // nonstandard extension used: nameless struct/union
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <math.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
enum BC4Mode
|
||||||
|
{
|
||||||
|
BC4_UNORM = 0,
|
||||||
|
BC4_SNORM = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BC5Mode
|
||||||
|
{
|
||||||
|
BC5_UNORM = 0,
|
||||||
|
BC5_SNORM = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
void DecompressBlockBC1(uint32_t x, uint32_t y, uint32_t stride,
|
||||||
|
const uint8_t* blockStorage, unsigned char* image);
|
||||||
|
void DecompressBlockBC2(uint32_t x, uint32_t y, uint32_t stride,
|
||||||
|
const uint8_t* blockStorage, unsigned char* image);
|
||||||
|
void DecompressBlockBC3(uint32_t x, uint32_t y, uint32_t stride,
|
||||||
|
const uint8_t* blockStorage, unsigned char* image);
|
||||||
|
void DecompressBlockBC4(uint32_t x, uint32_t y, uint32_t stride,
|
||||||
|
enum BC4Mode mode, const uint8_t* blockStorage, unsigned char* image);
|
||||||
|
void DecompressBlockBC5(uint32_t x, uint32_t y, uint32_t stride,
|
||||||
|
enum BC5Mode mode, const uint8_t* blockStorage, unsigned char* image);
|
||||||
|
|
||||||
|
namespace bc7decomp
|
||||||
|
{
|
||||||
|
|
||||||
|
enum eNoClamp { cNoClamp };
|
||||||
|
|
||||||
|
template <typename S> inline S clamp(S value, S low, S high) { return (value < low) ? low : ((value > high) ? high : value); }
|
||||||
|
|
||||||
|
class color_rgba
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint8_t m_comps[4];
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint8_t r;
|
||||||
|
uint8_t g;
|
||||||
|
uint8_t b;
|
||||||
|
uint8_t a;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
inline color_rgba() = default;
|
||||||
|
|
||||||
|
inline color_rgba(int y)
|
||||||
|
{
|
||||||
|
set(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline color_rgba(int y, int na)
|
||||||
|
{
|
||||||
|
set(y, na);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline color_rgba(int sr, int sg, int sb, int sa)
|
||||||
|
{
|
||||||
|
set(sr, sg, sb, sa);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline color_rgba(eNoClamp, int sr, int sg, int sb, int sa)
|
||||||
|
{
|
||||||
|
set_noclamp_rgba((uint8_t)sr, (uint8_t)sg, (uint8_t)sb, (uint8_t)sa);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline color_rgba& set_noclamp_y(int y)
|
||||||
|
{
|
||||||
|
m_comps[0] = (uint8_t)y;
|
||||||
|
m_comps[1] = (uint8_t)y;
|
||||||
|
m_comps[2] = (uint8_t)y;
|
||||||
|
m_comps[3] = (uint8_t)255;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline color_rgba &set_noclamp_rgba(int sr, int sg, int sb, int sa)
|
||||||
|
{
|
||||||
|
m_comps[0] = (uint8_t)sr;
|
||||||
|
m_comps[1] = (uint8_t)sg;
|
||||||
|
m_comps[2] = (uint8_t)sb;
|
||||||
|
m_comps[3] = (uint8_t)sa;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline color_rgba &set(int y)
|
||||||
|
{
|
||||||
|
m_comps[0] = static_cast<uint8_t>(clamp<int>(y, 0, 255));
|
||||||
|
m_comps[1] = m_comps[0];
|
||||||
|
m_comps[2] = m_comps[0];
|
||||||
|
m_comps[3] = 255;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline color_rgba &set(int y, int na)
|
||||||
|
{
|
||||||
|
m_comps[0] = static_cast<uint8_t>(clamp<int>(y, 0, 255));
|
||||||
|
m_comps[1] = m_comps[0];
|
||||||
|
m_comps[2] = m_comps[0];
|
||||||
|
m_comps[3] = static_cast<uint8_t>(clamp<int>(na, 0, 255));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline color_rgba &set(int sr, int sg, int sb, int sa)
|
||||||
|
{
|
||||||
|
m_comps[0] = static_cast<uint8_t>(clamp<int>(sr, 0, 255));
|
||||||
|
m_comps[1] = static_cast<uint8_t>(clamp<int>(sg, 0, 255));
|
||||||
|
m_comps[2] = static_cast<uint8_t>(clamp<int>(sb, 0, 255));
|
||||||
|
m_comps[3] = static_cast<uint8_t>(clamp<int>(sa, 0, 255));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline color_rgba &set_rgb(int sr, int sg, int sb)
|
||||||
|
{
|
||||||
|
m_comps[0] = static_cast<uint8_t>(clamp<int>(sr, 0, 255));
|
||||||
|
m_comps[1] = static_cast<uint8_t>(clamp<int>(sg, 0, 255));
|
||||||
|
m_comps[2] = static_cast<uint8_t>(clamp<int>(sb, 0, 255));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline color_rgba &set_rgb(const color_rgba &other)
|
||||||
|
{
|
||||||
|
r = other.r;
|
||||||
|
g = other.g;
|
||||||
|
b = other.b;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const uint8_t &operator[] (uint32_t index) const { assert(index < 4); return m_comps[index]; }
|
||||||
|
inline uint8_t &operator[] (uint32_t index) { assert(index < 4); return m_comps[index]; }
|
||||||
|
|
||||||
|
inline void clear()
|
||||||
|
{
|
||||||
|
m_comps[0] = 0;
|
||||||
|
m_comps[1] = 0;
|
||||||
|
m_comps[2] = 0;
|
||||||
|
m_comps[3] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator== (const color_rgba &rhs) const
|
||||||
|
{
|
||||||
|
if (m_comps[0] != rhs.m_comps[0]) return false;
|
||||||
|
if (m_comps[1] != rhs.m_comps[1]) return false;
|
||||||
|
if (m_comps[2] != rhs.m_comps[2]) return false;
|
||||||
|
if (m_comps[3] != rhs.m_comps[3]) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!= (const color_rgba &rhs) const
|
||||||
|
{
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator<(const color_rgba &rhs) const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if (m_comps[i] < rhs.m_comps[i])
|
||||||
|
return true;
|
||||||
|
else if (m_comps[i] != rhs.m_comps[i])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int get_601_luma() const { return (19595U * m_comps[0] + 38470U * m_comps[1] + 7471U * m_comps[2] + 32768U) >> 16U; }
|
||||||
|
inline int get_709_luma() const { return (13938U * m_comps[0] + 46869U * m_comps[1] + 4729U * m_comps[2] + 32768U) >> 16U; }
|
||||||
|
inline int get_luma(bool luma_601) const { return luma_601 ? get_601_luma() : get_709_luma(); }
|
||||||
|
|
||||||
|
static color_rgba comp_min(const color_rgba& a, const color_rgba& b) { return color_rgba(std::min(a[0], b[0]), std::min(a[1], b[1]), std::min(a[2], b[2]), std::min(a[3], b[3])); }
|
||||||
|
static color_rgba comp_max(const color_rgba& a, const color_rgba& b) { return color_rgba(std::max(a[0], b[0]), std::max(a[1], b[1]), std::max(a[2], b[2]), std::max(a[3], b[3])); }
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(color_rgba) == 4);
|
||||||
|
|
||||||
|
bool unpack_bc7(const void *pBlock, color_rgba *pPixels);
|
||||||
|
|
||||||
|
} // namespace bc7decomp
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
|
@ -93,6 +93,7 @@
|
||||||
<ClInclude Include="shiftjis.h" />
|
<ClInclude Include="shiftjis.h" />
|
||||||
<ClInclude Include="sockets.h" />
|
<ClInclude Include="sockets.h" />
|
||||||
<ClInclude Include="state_wrapper.h" />
|
<ClInclude Include="state_wrapper.h" />
|
||||||
|
<ClInclude Include="texture_decompress.h" />
|
||||||
<ClInclude Include="vulkan_builders.h" />
|
<ClInclude Include="vulkan_builders.h" />
|
||||||
<ClInclude Include="vulkan_device.h" />
|
<ClInclude Include="vulkan_device.h" />
|
||||||
<ClInclude Include="vulkan_entry_points.h" />
|
<ClInclude Include="vulkan_entry_points.h" />
|
||||||
|
@ -199,6 +200,7 @@
|
||||||
<ClCompile Include="page_fault_handler.cpp" />
|
<ClCompile Include="page_fault_handler.cpp" />
|
||||||
<ClCompile Include="sockets.cpp" />
|
<ClCompile Include="sockets.cpp" />
|
||||||
<ClCompile Include="state_wrapper.cpp" />
|
<ClCompile Include="state_wrapper.cpp" />
|
||||||
|
<ClCompile Include="texture_decompress.cpp" />
|
||||||
<ClCompile Include="vulkan_builders.cpp" />
|
<ClCompile Include="vulkan_builders.cpp" />
|
||||||
<ClCompile Include="vulkan_device.cpp" />
|
<ClCompile Include="vulkan_device.cpp" />
|
||||||
<ClCompile Include="vulkan_loader.cpp" />
|
<ClCompile Include="vulkan_loader.cpp" />
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
<ClInclude Include="elf_file.h" />
|
<ClInclude Include="elf_file.h" />
|
||||||
<ClInclude Include="x11_tools.h" />
|
<ClInclude Include="x11_tools.h" />
|
||||||
<ClInclude Include="opengl_context_egl_xlib.h" />
|
<ClInclude Include="opengl_context_egl_xlib.h" />
|
||||||
|
<ClInclude Include="texture_decompress.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="state_wrapper.cpp" />
|
<ClCompile Include="state_wrapper.cpp" />
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
<ClCompile Include="elf_file.cpp" />
|
<ClCompile Include="elf_file.cpp" />
|
||||||
<ClCompile Include="x11_tools.cpp" />
|
<ClCompile Include="x11_tools.cpp" />
|
||||||
<ClCompile Include="opengl_context_egl_xlib.cpp" />
|
<ClCompile Include="opengl_context_egl_xlib.cpp" />
|
||||||
|
<ClCompile Include="texture_decompress.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="metal_shaders.metal" />
|
<None Include="metal_shaders.metal" />
|
||||||
|
|
Loading…
Reference in New Issue