Initial checkin of v1.04 - KTX file format support, basic ETC1 compression/decompression, Linux makefile with proper gcc options, lots of high-level improvements to get crnlib into a state where I can more easily add additional formats.
This commit is contained in:
+136
-9
@@ -7,10 +7,13 @@
|
||||
#include "crn_dynamic_stream.h"
|
||||
#include "crn_buffer_stream.h"
|
||||
#include "crn_ryg_dxt.hpp"
|
||||
#include "crn_etc.h"
|
||||
|
||||
#define CRND_HEADER_FILE_ONLY
|
||||
#include "../inc/crn_decomp.h"
|
||||
|
||||
#include "crn_rg_etc1.h"
|
||||
|
||||
namespace crnlib
|
||||
{
|
||||
static void* realloc_func(void* p, size_t size, size_t* pActual_size, bool movable, void* pUser_data)
|
||||
@@ -31,13 +34,17 @@ namespace crnlib
|
||||
crnlib_global_initializer()
|
||||
{
|
||||
crn_threading_init();
|
||||
|
||||
ryg_dxt::sInitDXT();
|
||||
|
||||
|
||||
crnlib_enable_fail_exceptions(true);
|
||||
|
||||
// Redirect crn_decomp.h's memory allocations into crnlib, which may be further redirected by the outside caller.
|
||||
crnd::crnd_set_memory_callbacks(realloc_func, msize_func, NULL);
|
||||
|
||||
ryg_dxt::sInitDXT();
|
||||
|
||||
pack_etc1_block_init();
|
||||
|
||||
rg_etc1::pack_etc1_block_init();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -194,8 +201,8 @@ void *crn_compress(const crn_comp_params &comp_params, const crn_mipmap_params &
|
||||
|
||||
void *crn_decompress_crn_to_dds(const void *pCRN_file_data, crn_uint32 &file_size)
|
||||
{
|
||||
dds_texture tex;
|
||||
if (!tex.load_crn_from_memory("from_memory.crn", pCRN_file_data, file_size))
|
||||
mipmapped_texture tex;
|
||||
if (!tex.read_crn_from_memory(pCRN_file_data, file_size, "from_memory.crn"))
|
||||
{
|
||||
file_size = 0;
|
||||
return NULL;
|
||||
@@ -218,7 +225,7 @@ bool crn_decompress_dds_to_images(const void *pDDS_file_data, crn_uint32 dds_fil
|
||||
{
|
||||
memset(&tex_desc, 0, sizeof(tex_desc));
|
||||
|
||||
dds_texture tex;
|
||||
mipmapped_texture tex;
|
||||
buffer_stream in_stream(pDDS_file_data, dds_file_size);
|
||||
data_stream_serializer in_serializer(in_stream);
|
||||
if (!tex.read_dds(in_serializer))
|
||||
@@ -295,7 +302,7 @@ namespace crnlib
|
||||
{
|
||||
if (m_image.is_valid())
|
||||
{
|
||||
m_image.set_block_pixels(0, 0, reinterpret_cast<const color_quad_u8 *>(pPixels), m_pack_params, m_dxt1_optimizer, m_dxt5_optimizer);
|
||||
m_image.set_block_pixels(0, 0, reinterpret_cast<const color_quad_u8 *>(pPixels), m_pack_params, m_set_block_pixels_context);
|
||||
memcpy(pDst_block, &m_image.get_element(0, 0, 0), m_image.get_bytes_per_block());
|
||||
}
|
||||
}
|
||||
@@ -304,8 +311,7 @@ namespace crnlib
|
||||
dxt_image m_image;
|
||||
crn_comp_params m_comp_params;
|
||||
dxt_image::pack_params m_pack_params;
|
||||
dxt1_endpoint_optimizer m_dxt1_optimizer;
|
||||
dxt5_endpoint_optimizer m_dxt5_optimizer;
|
||||
dxt_image::set_block_pixels_context m_set_block_pixels_context;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -330,3 +336,124 @@ void crn_free_block_compressor(crn_block_compressor_context_t pContext)
|
||||
{
|
||||
crnlib_delete(static_cast<crn_block_compressor *>(pContext));
|
||||
}
|
||||
|
||||
bool crn_decompress_block(const void *pSrc_block, crn_uint32 *pDst_pixels_u32, crn_format crn_fmt)
|
||||
{
|
||||
color_quad_u8* pDst_pixels = reinterpret_cast<color_quad_u8*>(pDst_pixels_u32);
|
||||
|
||||
switch (crn_get_fundamental_dxt_format(crn_fmt))
|
||||
{
|
||||
case cCRNFmtETC1:
|
||||
{
|
||||
const etc1_block& block = *reinterpret_cast<const etc1_block*>(pSrc_block);
|
||||
unpack_etc1(block, pDst_pixels, false);
|
||||
break;
|
||||
}
|
||||
case cCRNFmtDXT1:
|
||||
{
|
||||
const dxt1_block* pDXT1_block = reinterpret_cast<const dxt1_block*>(pSrc_block);
|
||||
|
||||
color_quad_u8 colors[cDXT1SelectorValues];
|
||||
pDXT1_block->get_block_colors(colors, static_cast<uint16>(pDXT1_block->get_low_color()), static_cast<uint16>(pDXT1_block->get_high_color()));
|
||||
|
||||
for (uint i = 0; i < cDXTBlockSize * cDXTBlockSize; i++)
|
||||
{
|
||||
const uint s = pDXT1_block->get_selector(i & 3, i >> 2);
|
||||
|
||||
pDst_pixels[i] = colors[s];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case cCRNFmtDXT3:
|
||||
{
|
||||
const dxt3_block* pDXT3_block = reinterpret_cast<const dxt3_block*>(pSrc_block);
|
||||
|
||||
const dxt1_block* pDXT1_block = reinterpret_cast<const dxt1_block*>(pSrc_block) + 1;
|
||||
color_quad_u8 colors[cDXT1SelectorValues];
|
||||
pDXT1_block->get_block_colors(colors, static_cast<uint16>(pDXT1_block->get_low_color()), static_cast<uint16>(pDXT1_block->get_high_color()));
|
||||
|
||||
for (uint i = 0; i < cDXTBlockSize * cDXTBlockSize; i++)
|
||||
{
|
||||
const uint s = pDXT1_block->get_selector(i & 3, i >> 2);
|
||||
const uint a = pDXT3_block->get_alpha(i & 3, i >> 2, true);
|
||||
|
||||
pDst_pixels[i] = colors[s];
|
||||
pDst_pixels[i].a = static_cast<uint8>(a);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case cCRNFmtDXT5:
|
||||
{
|
||||
const dxt5_block* pDXT5_block = reinterpret_cast<const dxt5_block*>(pSrc_block);
|
||||
|
||||
const dxt1_block* pDXT1_block = reinterpret_cast<const dxt1_block*>(pSrc_block) + 1;
|
||||
color_quad_u8 colors[cDXT1SelectorValues];
|
||||
pDXT1_block->get_block_colors(colors, static_cast<uint16>(pDXT1_block->get_low_color()), static_cast<uint16>(pDXT1_block->get_high_color()));
|
||||
|
||||
uint values[cDXT5SelectorValues];
|
||||
dxt5_block::get_block_values(values, pDXT5_block->get_low_alpha(), pDXT5_block->get_high_alpha());
|
||||
|
||||
for (uint i = 0; i < cDXTBlockSize * cDXTBlockSize; i++)
|
||||
{
|
||||
const uint s = pDXT1_block->get_selector(i & 3, i >> 2);
|
||||
const uint a = pDXT5_block->get_selector(i & 3, i >> 2);
|
||||
|
||||
pDst_pixels[i] = colors[s];
|
||||
pDst_pixels[i].a = static_cast<uint8>(values[a]);
|
||||
}
|
||||
}
|
||||
|
||||
case cCRNFmtDXN_XY:
|
||||
case cCRNFmtDXN_YX:
|
||||
{
|
||||
const dxt5_block* pDXT5_block0 = reinterpret_cast<const dxt5_block*>(pSrc_block);
|
||||
const dxt5_block* pDXT5_block1 = reinterpret_cast<const dxt5_block*>(pSrc_block) + 1;
|
||||
|
||||
uint values0[cDXT5SelectorValues];
|
||||
dxt5_block::get_block_values(values0, pDXT5_block0->get_low_alpha(), pDXT5_block0->get_high_alpha());
|
||||
|
||||
uint values1[cDXT5SelectorValues];
|
||||
dxt5_block::get_block_values(values1, pDXT5_block1->get_low_alpha(), pDXT5_block1->get_high_alpha());
|
||||
|
||||
for (uint i = 0; i < cDXTBlockSize * cDXTBlockSize; i++)
|
||||
{
|
||||
const uint s0 = pDXT5_block0->get_selector(i & 3, i >> 2);
|
||||
const uint s1 = pDXT5_block1->get_selector(i & 3, i >> 2);
|
||||
|
||||
if (crn_fmt == cCRNFmtDXN_XY)
|
||||
pDst_pixels[i].set_noclamp_rgba(values0[s0], values1[s1], 255, 255);
|
||||
else
|
||||
pDst_pixels[i].set_noclamp_rgba(values1[s1], values0[s0], 255, 255);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case cCRNFmtDXT5A:
|
||||
{
|
||||
const dxt5_block* pDXT5_block = reinterpret_cast<const dxt5_block*>(pSrc_block);
|
||||
|
||||
uint values[cDXT5SelectorValues];
|
||||
dxt5_block::get_block_values(values, pDXT5_block->get_low_alpha(), pDXT5_block->get_high_alpha());
|
||||
|
||||
for (uint i = 0; i < cDXTBlockSize * cDXTBlockSize; i++)
|
||||
{
|
||||
const uint s = pDXT5_block->get_selector(i & 3, i >> 2);
|
||||
|
||||
pDst_pixels[i].set_noclamp_rgba(255, 255, 255, values[s]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user