v1.03 prerelease - Full Linux port of crnlib/crunch, in progress - still more testing to do, and some cmd line options (such as -timestamp) don't work under linux yet, but the core stuff (compression/decompression/transcoding) should work fine and performance under Linux is comparable to Windows. The 3 examples haven't been ported yet.

This commit is contained in:
richgel99@gmail.com
2012-04-26 07:14:21 +00:00
parent fffd983ffa
commit f63e26aee6
89 changed files with 3547 additions and 3829 deletions
+1 -2
View File
@@ -3,7 +3,6 @@
// Ported from the PowerView DOS image viewer, a product I wrote back in 1993. Not currently used in the open source release of crnlib. // Ported from the PowerView DOS image viewer, a product I wrote back in 1993. Not currently used in the open source release of crnlib.
#include "crn_core.h" #include "crn_core.h"
#include "crn_arealist.h" #include "crn_arealist.h"
#include <stdio.h>
#define RECT_DEBUG #define RECT_DEBUG
@@ -20,7 +19,7 @@ namespace crnlib
#ifdef _MSC_VER #ifdef _MSC_VER
_vsnprintf_s(buf, sizeof(buf), pMsg, args); _vsnprintf_s(buf, sizeof(buf), pMsg, args);
#else #else
_vsnprintf(buf, sizeof(buf), pMsg, args); vsnprintf(buf, sizeof(buf), pMsg, args);
#endif #endif
va_end(args); va_end(args);
+8 -16
View File
@@ -1,8 +1,9 @@
// File: crn_assert.cpp // File: crn_assert.cpp
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#include "crn_core.h" #include "crn_core.h"
#if CRNLIB_USE_WIN32_API
#include "crn_winhdr.h" #include "crn_winhdr.h"
#include <stdio.h> #endif
static bool g_fail_exceptions; static bool g_fail_exceptions;
static bool g_exit_on_failure = true; static bool g_exit_on_failure = true;
@@ -16,15 +17,11 @@ void crnlib_assert(const char* pExp, const char* pFile, unsigned line)
{ {
char buf[512]; char buf[512];
#if defined(WIN32) && defined(_MSC_VER)
sprintf_s(buf, sizeof(buf), "%s(%u): Assertion failed: \"%s\"\n", pFile, line, pExp); sprintf_s(buf, sizeof(buf), "%s(%u): Assertion failed: \"%s\"\n", pFile, line, pExp);
#else
sprintf(buf, "%s(%u): Assertion failed: \"%s\"\n", pFile, line, pExp);
#endif
crnlib_output_debug_string(buf); crnlib_output_debug_string(buf);
printf(buf); fputs(buf, stderr);
if (crnlib_is_debugger_present()) if (crnlib_is_debugger_present())
crnlib_debug_break(); crnlib_debug_break();
@@ -34,22 +31,21 @@ void crnlib_fail(const char* pExp, const char* pFile, unsigned line)
{ {
char buf[512]; char buf[512];
#if defined(WIN32) && defined(_MSC_VER)
sprintf_s(buf, sizeof(buf), "%s(%u): Failure: \"%s\"\n", pFile, line, pExp); sprintf_s(buf, sizeof(buf), "%s(%u): Failure: \"%s\"\n", pFile, line, pExp);
#else
sprintf(buf, "%s(%u): Failure: \"%s\"\n", pFile, line, pExp);
#endif
crnlib_output_debug_string(buf); crnlib_output_debug_string(buf);
printf(buf); fputs(buf, stderr);
if (crnlib_is_debugger_present()) if (crnlib_is_debugger_present())
crnlib_debug_break(); crnlib_debug_break();
#if CRNLIB_USE_WIN32_API
if (g_fail_exceptions) if (g_fail_exceptions)
RaiseException(CRNLIB_FAIL_EXCEPTION_CODE, 0, 0, NULL); RaiseException(CRNLIB_FAIL_EXCEPTION_CODE, 0, 0, NULL);
else if (g_exit_on_failure) else
#endif
if (g_exit_on_failure)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@@ -58,11 +54,7 @@ void trace(const char* pFmt, va_list args)
if (crnlib_is_debugger_present()) if (crnlib_is_debugger_present())
{ {
char buf[512]; char buf[512];
#if defined(WIN32) && defined(_MSC_VER)
vsprintf_s(buf, sizeof(buf), pFmt, args); vsprintf_s(buf, sizeof(buf), pFmt, args);
#else
vsprintf(buf, pFmt, args);
#endif
crnlib_output_debug_string(buf); crnlib_output_debug_string(buf);
} }
+16 -21
View File
@@ -2,7 +2,6 @@
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#pragma once #pragma once
#include "crn_data_stream.h" #include "crn_data_stream.h"
#include <stdio.h>
namespace crnlib namespace crnlib
{ {
@@ -13,13 +12,13 @@ namespace crnlib
{ {
} }
cfile_stream(FILE* pFile, const wchar_t* pFilename, uint attribs, bool has_ownership) : cfile_stream(FILE* pFile, const char* pFilename, uint attribs, bool has_ownership) :
data_stream(), m_pFile(NULL), m_size(0), m_ofs(0), m_has_ownership(false) data_stream(), m_pFile(NULL), m_size(0), m_ofs(0), m_has_ownership(false)
{ {
open(pFile, pFilename, attribs, has_ownership); open(pFile, pFilename, attribs, has_ownership);
} }
cfile_stream(const wchar_t* pFilename, uint attribs = cDataStreamReadable | cDataStreamSeekable, bool open_existing = false) : cfile_stream(const char* pFilename, uint attribs = cDataStreamReadable | cDataStreamSeekable, bool open_existing = false) :
data_stream(), m_pFile(NULL), m_size(0), m_ofs(0), m_has_ownership(false) data_stream(), m_pFile(NULL), m_size(0), m_ofs(0), m_has_ownership(false)
{ {
open(pFilename, attribs, open_existing); open(pFilename, attribs, open_existing);
@@ -55,7 +54,7 @@ namespace crnlib
return false; return false;
} }
bool open(FILE* pFile, const wchar_t* pFilename, uint attribs, bool has_ownership) bool open(FILE* pFile, const char* pFilename, uint attribs, bool has_ownership)
{ {
CRNLIB_ASSERT(pFile); CRNLIB_ASSERT(pFile);
CRNLIB_ASSERT(pFilename); CRNLIB_ASSERT(pFilename);
@@ -67,17 +66,17 @@ namespace crnlib
m_has_ownership = has_ownership; m_has_ownership = has_ownership;
m_attribs = static_cast<uint16>(attribs); m_attribs = static_cast<uint16>(attribs);
m_ofs = _ftelli64(m_pFile); m_ofs = crn_ftell(m_pFile);
_fseeki64(m_pFile, 0, SEEK_END); crn_fseek(m_pFile, 0, SEEK_END);
m_size = _ftelli64(m_pFile); m_size = crn_ftell(m_pFile);
_fseeki64(m_pFile, m_ofs, SEEK_SET); crn_fseek(m_pFile, m_ofs, SEEK_SET);
m_opened = true; m_opened = true;
return true; return true;
} }
bool open(const wchar_t* pFilename, uint attribs = cDataStreamReadable | cDataStreamSeekable, bool open_existing = false) bool open(const char* pFilename, uint attribs = cDataStreamReadable | cDataStreamSeekable, bool open_existing = false)
{ {
CRNLIB_ASSERT(pFilename); CRNLIB_ASSERT(pFilename);
@@ -85,13 +84,13 @@ namespace crnlib
m_attribs = static_cast<uint16>(attribs); m_attribs = static_cast<uint16>(attribs);
const wchar_t* pMode; const char* pMode;
if ((is_readable()) && (is_writable())) if ((is_readable()) && (is_writable()))
pMode = open_existing ? L"r+b" : L"w+b"; pMode = open_existing ? "r+b" : "w+b";
else if (is_writable()) else if (is_writable())
pMode = open_existing ? L"ab" : L"wb"; pMode = open_existing ? "ab" : "wb";
else if (is_readable()) else if (is_readable())
pMode = L"rb"; pMode = "rb";
else else
{ {
set_error(); set_error();
@@ -99,11 +98,7 @@ namespace crnlib
} }
FILE* pFile = NULL; FILE* pFile = NULL;
#ifdef _MSC_VER crn_fopen(&pFile, pFilename, pMode);
_wfopen_s(&pFile, pFilename, pMode);
#else
pFile = _wfopen(pFilename, pMode);
#endif
m_has_ownership = true; m_has_ownership = true;
if (!pFile) if (!pFile)
@@ -209,7 +204,7 @@ namespace crnlib
if (static_cast<uint64>(new_ofs) != m_ofs) if (static_cast<uint64>(new_ofs) != m_ofs)
{ {
if (_fseeki64(m_pFile, new_ofs, SEEK_SET) != 0) if (crn_fseek(m_pFile, new_ofs, SEEK_SET) != 0)
{ {
set_error(); set_error();
return false; return false;
@@ -221,7 +216,7 @@ namespace crnlib
return true; return true;
} }
static bool read_file_into_array(const wchar_t* pFilename, vector<uint8>& buf) static bool read_file_into_array(const char* pFilename, vector<uint8>& buf)
{ {
cfile_stream in_stream(pFilename); cfile_stream in_stream(pFilename);
if (!in_stream.is_opened()) if (!in_stream.is_opened())
@@ -229,7 +224,7 @@ namespace crnlib
return in_stream.read_array(buf); return in_stream.read_array(buf);
} }
static bool write_array_to_file(const wchar_t* pFilename, const vector<uint8>& buf) static bool write_array_to_file(const char* pFilename, const vector<uint8>& buf)
{ {
cfile_stream out_stream(pFilename, cDataStreamWritable|cDataStreamSeekable); cfile_stream out_stream(pFilename, cDataStreamWritable|cDataStreamSeekable);
if (!out_stream.is_opened()) if (!out_stream.is_opened())
+5 -5
View File
@@ -140,7 +140,7 @@ namespace crnlib
inline uint get_num_training_vecs() const { return m_training_vecs.size(); } inline uint get_num_training_vecs() const { return m_training_vecs.size(); }
const VectorType& get_training_vec(uint index) const { return m_training_vecs[index].first; } const VectorType& get_training_vec(uint index) const { return m_training_vecs[index].first; }
const uint get_training_vec_weight(uint index) const { return m_training_vecs[index].second; } uint get_training_vec_weight(uint index) const { return m_training_vecs[index].second; }
typedef crnlib::vector< std::pair<VectorType, uint> > training_vec_array; typedef crnlib::vector< std::pair<VectorType, uint> > training_vec_array;
@@ -170,7 +170,7 @@ namespace crnlib
return m_codebook; return m_codebook;
} }
const uint find_best_codebook_entry(const VectorType& v) const uint find_best_codebook_entry(const VectorType& v) const
{ {
uint cur_node_index = 0; uint cur_node_index = 0;
@@ -218,7 +218,7 @@ namespace crnlib
} }
} }
const uint find_best_codebook_entry_fs(const VectorType& v) const uint find_best_codebook_entry_fs(const VectorType& v) const
{ {
float best_dist = math::cNearlyInfinite; float best_dist = math::cNearlyInfinite;
uint best_index = 0; uint best_index = 0;
@@ -362,7 +362,7 @@ namespace crnlib
void compute_split_estimate(VectorType& left_child_res, VectorType& right_child_res, const vq_node& parent_node) void compute_split_estimate(VectorType& left_child_res, VectorType& right_child_res, const vq_node& parent_node)
{ {
VectorType furthest; VectorType furthest(0);
double furthest_dist = -1.0f; double furthest_dist = -1.0f;
for (uint i = 0; i < parent_node.m_vectors.size(); i++) for (uint i = 0; i < parent_node.m_vectors.size(); i++)
@@ -377,7 +377,7 @@ namespace crnlib
} }
} }
VectorType opposite; VectorType opposite(0);
double opposite_dist = -1.0f; double opposite_dist = -1.0f;
for (uint i = 0; i < parent_node.m_vectors.size(); i++) for (uint i = 0; i < parent_node.m_vectors.size(); i++)
+14 -14
View File
@@ -11,8 +11,8 @@ namespace crnlib
{ {
cSigned = false, cSigned = false,
cFloat = false, cFloat = false,
cMin = UINT8_MIN, cMin = cUINT8_MIN,
cMax = UINT8_MAX cMax = cUINT8_MAX
}; };
}; };
@@ -22,8 +22,8 @@ namespace crnlib
{ {
cSigned = true, cSigned = true,
cFloat = false, cFloat = false,
cMin = INT16_MIN, cMin = cINT16_MIN,
cMax = INT16_MAX cMax = cINT16_MAX
}; };
}; };
@@ -33,8 +33,8 @@ namespace crnlib
{ {
cSigned = false, cSigned = false,
cFloat = false, cFloat = false,
cMin = UINT16_MIN, cMin = cUINT16_MIN,
cMax = UINT16_MAX cMax = cUINT16_MAX
}; };
}; };
@@ -44,8 +44,8 @@ namespace crnlib
{ {
cSigned = true, cSigned = true,
cFloat = false, cFloat = false,
cMin = INT32_MIN, cMin = cINT32_MIN,
cMax = INT32_MAX cMax = cINT32_MAX
}; };
}; };
@@ -55,8 +55,8 @@ namespace crnlib
{ {
cSigned = false, cSigned = false,
cFloat = false, cFloat = false,
cMin = UINT32_MIN, cMin = cUINT32_MIN,
cMax = UINT32_MAX cMax = cUINT32_MAX
}; };
}; };
@@ -66,8 +66,8 @@ namespace crnlib
{ {
cSigned = false, cSigned = false,
cFloat = true, cFloat = true,
cMin = INT32_MIN, cMin = cINT32_MIN,
cMax = INT32_MAX cMax = cINT32_MAX
}; };
}; };
@@ -77,8 +77,8 @@ namespace crnlib
{ {
cSigned = false, cSigned = false,
cFloat = true, cFloat = true,
cMin = INT32_MIN, cMin = cINT32_MIN,
cMax = INT32_MAX cMax = cINT32_MAX
}; };
}; };
+157 -124
View File
@@ -5,41 +5,67 @@
#include "crn_console.h" #include "crn_console.h"
#include "crn_cfile_stream.h" #include "crn_cfile_stream.h"
#ifdef WIN32
#define CRNLIB_CMD_LINE_ALLOW_SLASH_PARAMS 1
#endif
#if CRNLIB_USE_WIN32_API
#include "crn_winhdr.h"
#endif
namespace crnlib namespace crnlib
{ {
void get_command_line(dynamic_string& cmd_line, int argc, char *argv[])
{
argc, argv;
#if CRNLIB_USE_WIN32_API
cmd_line.set(GetCommandLineA());
#else
cmd_line.clear();
for (int i = 0; i < argc; i++)
{
dynamic_string tmp(argv[i]);
if ((tmp.front() != '"') && (tmp.front() != '-') && (tmp.front() != '@'))
tmp = "\"" + tmp + "\"";
if (cmd_line.get_len())
cmd_line += " ";
cmd_line += tmp;
}
#endif
}
command_line_params::command_line_params() command_line_params::command_line_params()
{ {
} }
void command_line_params::clear() void command_line_params::clear()
{ {
m_params.clear(); m_params.clear();
m_param_map.clear(); m_param_map.clear();
} }
bool command_line_params::split_params(const wchar_t* p, dynamic_wstring_array& params) bool command_line_params::split_params(const char* p, dynamic_string_array& params)
{ {
bool within_param = false; bool within_param = false;
bool within_quote = false; bool within_quote = false;
uint ofs = 0; uint ofs = 0;
dynamic_wstring str; dynamic_string str;
while (p[ofs]) while (p[ofs])
{ {
const wchar_t c = p[ofs]; const char c = p[ofs];
if (within_param) if (within_param)
{ {
if (within_quote) if (within_quote)
{ {
if (c == L'"') if (c == '"')
within_quote = false; within_quote = false;
str.append_char(c); str.append_char(c);
} }
else if ((c == L' ') || (c == L'\t')) else if ((c == ' ') || (c == '\t'))
{ {
if (!str.is_empty()) if (!str.is_empty())
{ {
@@ -50,141 +76,144 @@ namespace crnlib
} }
else else
{ {
if (c == L'"') if (c == '"')
within_quote = true; within_quote = true;
str.append_char(c); str.append_char(c);
} }
} }
else if ((c != L' ') && (c != L'\t')) else if ((c != ' ') && (c != '\t'))
{ {
within_param = true; within_param = true;
if (c == L'"') if (c == '"')
within_quote = true; within_quote = true;
str.append_char(c); str.append_char(c);
} }
ofs++; ofs++;
} }
if (within_quote) if (within_quote)
{ {
console::error(L"Unmatched quote in command line \"%s\"", p); console::error("Unmatched quote in command line \"%s\"", p);
return false; return false;
} }
if (!str.is_empty()) if (!str.is_empty())
params.push_back(str); params.push_back(str);
return true; return true;
} }
bool command_line_params::load_string_file(const wchar_t* pFilename, dynamic_wstring_array& strings) bool command_line_params::load_string_file(const char* pFilename, dynamic_string_array& strings)
{ {
cfile_stream in_stream; cfile_stream in_stream;
if (!in_stream.open(pFilename, cDataStreamReadable | cDataStreamSeekable)) if (!in_stream.open(pFilename, cDataStreamReadable | cDataStreamSeekable))
{ {
console::error(L"Unable to open file \"%s\" for reading!", pFilename); console::error("Unable to open file \"%s\" for reading!", pFilename);
return false; return false;
} }
dynamic_string ansi_str; dynamic_string ansi_str;
for ( ; ; ) for ( ; ; )
{ {
if (!in_stream.read_line(ansi_str)) if (!in_stream.read_line(ansi_str))
break; break;
ansi_str.trim(); ansi_str.trim();
if (ansi_str.is_empty()) if (ansi_str.is_empty())
continue; continue;
strings.push_back(dynamic_wstring(ansi_str.get_ptr())); strings.push_back(dynamic_string(ansi_str.get_ptr()));
} }
return true; return true;
} }
bool command_line_params::parse(const dynamic_wstring_array& params, uint n, const param_desc* pParam_desc) bool command_line_params::parse(const dynamic_string_array& params, uint n, const param_desc* pParam_desc)
{ {
CRNLIB_ASSERT(n && pParam_desc); CRNLIB_ASSERT(n && pParam_desc);
m_params = params; m_params = params;
uint arg_index = 0; uint arg_index = 0;
while (arg_index < params.size()) while (arg_index < params.size())
{ {
const uint cur_arg_index = arg_index; const uint cur_arg_index = arg_index;
const dynamic_wstring& src_param = params[arg_index++]; const dynamic_string& src_param = params[arg_index++];
if (src_param.is_empty()) if (src_param.is_empty())
continue; continue;
#if CRNLIB_CMD_LINE_ALLOW_SLASH_PARAMS
if ((src_param[0] == L'/') || (src_param[0] == L'-')) if ((src_param[0] == '/') || (src_param[0] == '-'))
#else
if (src_param[0] == '-')
#endif
{ {
if (src_param.get_len() < 2) if (src_param.get_len() < 2)
{ {
console::error(L"Invalid command line parameter: \"%s\"", src_param.get_ptr()); console::error("Invalid command line parameter: \"%s\"", src_param.get_ptr());
return false; return false;
} }
dynamic_wstring key_str(src_param); dynamic_string key_str(src_param);
key_str.right(1); key_str.right(1);
int modifier = 0; int modifier = 0;
wchar_t c = key_str[key_str.get_len() - 1]; char c = key_str[key_str.get_len() - 1];
if (c == L'+') if (c == '+')
modifier = 1; modifier = 1;
else if (c == L'-') else if (c == '-')
modifier = -1; modifier = -1;
if (modifier) if (modifier)
key_str.left(key_str.get_len() - 1); key_str.left(key_str.get_len() - 1);
uint param_index; uint param_index;
for (param_index = 0; param_index < n; param_index++) for (param_index = 0; param_index < n; param_index++)
if (key_str == pParam_desc[param_index].m_pName) if (key_str == pParam_desc[param_index].m_pName)
break; break;
if (param_index == n) if (param_index == n)
{ {
console::error(L"Unrecognized command line parameter: \"%s\"", src_param.get_ptr()); console::error("Unrecognized command line parameter: \"%s\"", src_param.get_ptr());
return false; return false;
} }
const param_desc& desc = pParam_desc[param_index]; const param_desc& desc = pParam_desc[param_index];
const uint cMaxValues = 16; const uint cMaxValues = 16;
dynamic_wstring val_str[cMaxValues]; dynamic_string val_str[cMaxValues];
uint num_val_strs = 0; uint num_val_strs = 0;
if (desc.m_num_values) if (desc.m_num_values)
{ {
CRNLIB_ASSERT(desc.m_num_values <= cMaxValues); CRNLIB_ASSERT(desc.m_num_values <= cMaxValues);
if ((arg_index + desc.m_num_values) > params.size()) if ((arg_index + desc.m_num_values) > params.size())
{ {
console::error(L"Expected %u value(s) after command line parameter: \"%s\"", desc.m_num_values, src_param.get_ptr()); console::error("Expected %u value(s) after command line parameter: \"%s\"", desc.m_num_values, src_param.get_ptr());
return false; return false;
} }
for (uint v = 0; v < desc.m_num_values; v++) for (uint v = 0; v < desc.m_num_values; v++)
val_str[num_val_strs++] = params[arg_index++]; val_str[num_val_strs++] = params[arg_index++];
} }
dynamic_wstring_array strings; dynamic_string_array strings;
if ((desc.m_support_listing_file) && (val_str[0].get_len() >= 2) && (val_str[0][0] == L'@')) if ((desc.m_support_listing_file) && (val_str[0].get_len() >= 2) && (val_str[0][0] == '@'))
{ {
dynamic_wstring filename(val_str[0]); dynamic_string filename(val_str[0]);
filename.right(1); filename.right(1);
filename.unquote(); filename.unquote();
if (!load_string_file(filename.get_ptr(), strings)) if (!load_string_file(filename.get_ptr(), strings))
{ {
console::error(L"Failed loading listing file \"%s\"!", filename.get_ptr()); console::error("Failed loading listing file \"%s\"!", filename.get_ptr());
return false; return false;
} }
} }
@@ -196,7 +225,7 @@ namespace crnlib
strings.push_back(val_str[v]); strings.push_back(val_str[v]);
} }
} }
param_value pv; param_value pv;
pv.m_values.swap(strings); pv.m_values.swap(strings);
pv.m_index = cur_arg_index; pv.m_index = cur_arg_index;
@@ -209,18 +238,18 @@ namespace crnlib
pv.m_values.push_back(src_param); pv.m_values.push_back(src_param);
pv.m_values.back().unquote(); pv.m_values.back().unquote();
pv.m_index = cur_arg_index; pv.m_index = cur_arg_index;
m_param_map.insert(std::make_pair(g_empty_dynamic_wstring, pv)); m_param_map.insert(std::make_pair(g_empty_dynamic_string, pv));
} }
} }
return true; return true;
} }
bool command_line_params::parse(const wchar_t* pCmd_line, uint n, const param_desc* pParam_desc, bool skip_first_param) bool command_line_params::parse(const char* pCmd_line, uint n, const param_desc* pParam_desc, bool skip_first_param)
{ {
CRNLIB_ASSERT(n && pParam_desc); CRNLIB_ASSERT(n && pParam_desc);
dynamic_wstring_array p; dynamic_string_array p;
if (!split_params(pCmd_line, p)) if (!split_params(pCmd_line, p))
return 0; return 0;
@@ -232,110 +261,114 @@ namespace crnlib
return parse(p, n, pParam_desc); return parse(p, n, pParam_desc);
} }
bool command_line_params::is_param(uint index) const bool command_line_params::is_param(uint index) const
{ {
CRNLIB_ASSERT(index < m_params.size()); CRNLIB_ASSERT(index < m_params.size());
if (index >= m_params.size()) if (index >= m_params.size())
return false; return false;
const dynamic_wstring& w = m_params[index]; const dynamic_string& w = m_params[index];
if (w.is_empty()) if (w.is_empty())
return false; return false;
return (w.get_len() >= 2) && ((w[0] == L'-') || (w[0] == L'/')); #if CRNLIB_CMD_LINE_ALLOW_SLASH_PARAMS
return (w.get_len() >= 2) && ((w[0] == '-') || (w[0] == '/'));
#else
return (w.get_len() >= 2) && (w[0] == '-');
#endif
} }
uint command_line_params::find(uint num_keys, const wchar_t** ppKeys, crnlib::vector<param_map_const_iterator>* pIterators, crnlib::vector<uint>* pUnmatched_indices) const uint command_line_params::find(uint num_keys, const char** ppKeys, crnlib::vector<param_map_const_iterator>* pIterators, crnlib::vector<uint>* pUnmatched_indices) const
{ {
CRNLIB_ASSERT(ppKeys); CRNLIB_ASSERT(ppKeys);
if (pUnmatched_indices) if (pUnmatched_indices)
{ {
pUnmatched_indices->resize(m_params.size()); pUnmatched_indices->resize(m_params.size());
for (uint i = 0; i < m_params.size(); i++) for (uint i = 0; i < m_params.size(); i++)
(*pUnmatched_indices)[i] = i; (*pUnmatched_indices)[i] = i;
} }
uint n = 0; uint n = 0;
for (uint i = 0; i < num_keys; i++) for (uint i = 0; i < num_keys; i++)
{ {
const wchar_t* pKey = ppKeys[i]; const char* pKey = ppKeys[i];
param_map_const_iterator begin, end; param_map_const_iterator begin, end;
find(pKey, begin, end); find(pKey, begin, end);
while (begin != end) while (begin != end)
{ {
if (pIterators) if (pIterators)
pIterators->push_back(begin); pIterators->push_back(begin);
if (pUnmatched_indices) if (pUnmatched_indices)
{ {
int k = pUnmatched_indices->find(begin->second.m_index); int k = pUnmatched_indices->find(begin->second.m_index);
if (k >= 0) if (k >= 0)
pUnmatched_indices->erase_unordered(k); pUnmatched_indices->erase_unordered(k);
} }
n++; n++;
begin++; begin++;
} }
} }
return n; return n;
} }
void command_line_params::find(const wchar_t* pKey, param_map_const_iterator& begin, param_map_const_iterator& end) const void command_line_params::find(const char* pKey, param_map_const_iterator& begin, param_map_const_iterator& end) const
{ {
dynamic_wstring key(pKey); dynamic_string key(pKey);
begin = m_param_map.lower_bound(key); begin = m_param_map.lower_bound(key);
end = m_param_map.upper_bound(key); end = m_param_map.upper_bound(key);
} }
uint command_line_params::get_count(const wchar_t* pKey) const uint command_line_params::get_count(const char* pKey) const
{ {
param_map_const_iterator begin, end; param_map_const_iterator begin, end;
find(pKey, begin, end); find(pKey, begin, end);
uint n = 0; uint n = 0;
while (begin != end) while (begin != end)
{ {
n++; n++;
begin++; begin++;
} }
return n; return n;
} }
command_line_params::param_map_const_iterator command_line_params::get_param(const wchar_t* pKey, uint index) const command_line_params::param_map_const_iterator command_line_params::get_param(const char* pKey, uint index) const
{ {
param_map_const_iterator begin, end; param_map_const_iterator begin, end;
find(pKey, begin, end); find(pKey, begin, end);
if (begin == end) if (begin == end)
return m_param_map.end(); return m_param_map.end();
uint n = 0; uint n = 0;
while ((begin != end) && (n != index)) while ((begin != end) && (n != index))
{ {
n++; n++;
begin++; begin++;
} }
if (begin == end) if (begin == end)
return m_param_map.end(); return m_param_map.end();
return begin; return begin;
} }
bool command_line_params::has_value(const wchar_t* pKey, uint index) const bool command_line_params::has_value(const char* pKey, uint index) const
{ {
return get_num_values(pKey, index) != 0; return get_num_values(pKey, index) != 0;
} }
uint command_line_params::get_num_values(const wchar_t* pKey, uint index) const uint command_line_params::get_num_values(const char* pKey, uint index) const
{ {
param_map_const_iterator it = get_param(pKey, index); param_map_const_iterator it = get_param(pKey, index);
@@ -344,76 +377,76 @@ namespace crnlib
return it->second.m_values.size(); return it->second.m_values.size();
} }
bool command_line_params::get_value_as_bool(const wchar_t* pKey, uint index, bool def) const bool command_line_params::get_value_as_bool(const char* pKey, uint index, bool def) const
{ {
param_map_const_iterator it = get_param(pKey, index); param_map_const_iterator it = get_param(pKey, index);
if (it == end()) if (it == end())
return def; return def;
if (it->second.m_modifier) if (it->second.m_modifier)
return it->second.m_modifier > 0; return it->second.m_modifier > 0;
else else
return true; return true;
} }
int command_line_params::get_value_as_int(const wchar_t* pKey, uint index, int def, int l, int h, uint value_index) const int command_line_params::get_value_as_int(const char* pKey, uint index, int def, int l, int h, uint value_index) const
{ {
param_map_const_iterator it = get_param(pKey, index); param_map_const_iterator it = get_param(pKey, index);
if ((it == end()) || (value_index >= it->second.m_values.size())) if ((it == end()) || (value_index >= it->second.m_values.size()))
return def; return def;
int val; int val;
const wchar_t* p = it->second.m_values[value_index].get_ptr(); const char* p = it->second.m_values[value_index].get_ptr();
if (!string_to_int(p, val)) if (!string_to_int(p, val))
{ {
crnlib::console::warning(L"Invalid value specified for parameter \"%s\", using default value of %i", pKey, def); crnlib::console::warning("Invalid value specified for parameter \"%s\", using default value of %i", pKey, def);
return def; return def;
} }
if (val < l) if (val < l)
{ {
crnlib::console::warning(L"Value %i for parameter \"%s\" is out of range, clamping to %i", val, pKey, l); crnlib::console::warning("Value %i for parameter \"%s\" is out of range, clamping to %i", val, pKey, l);
val = l; val = l;
} }
else if (val > h) else if (val > h)
{ {
crnlib::console::warning(L"Value %i for parameter \"%s\" is out of range, clamping to %i", val, pKey, h); crnlib::console::warning("Value %i for parameter \"%s\" is out of range, clamping to %i", val, pKey, h);
val = h; val = h;
} }
return val; return val;
} }
float command_line_params::get_value_as_float(const wchar_t* pKey, uint index, float def, float l, float h, uint value_index) const float command_line_params::get_value_as_float(const char* pKey, uint index, float def, float l, float h, uint value_index) const
{ {
param_map_const_iterator it = get_param(pKey, index); param_map_const_iterator it = get_param(pKey, index);
if ((it == end()) || (value_index >= it->second.m_values.size())) if ((it == end()) || (value_index >= it->second.m_values.size()))
return def; return def;
float val; float val;
const wchar_t* p = it->second.m_values[value_index].get_ptr(); const char* p = it->second.m_values[value_index].get_ptr();
if (!string_to_float(p, val)) if (!string_to_float(p, val))
{ {
crnlib::console::warning(L"Invalid value specified for float parameter \"%s\", using default value of %f", pKey, def); crnlib::console::warning("Invalid value specified for float parameter \"%s\", using default value of %f", pKey, def);
return def; return def;
} }
if (val < l) if (val < l)
{ {
crnlib::console::warning(L"Value %f for parameter \"%s\" is out of range, clamping to %f", val, pKey, l); crnlib::console::warning("Value %f for parameter \"%s\" is out of range, clamping to %f", val, pKey, l);
val = l; val = l;
} }
else if (val > h) else if (val > h)
{ {
crnlib::console::warning(L"Value %f for parameter \"%s\" is out of range, clamping to %f", val, pKey, h); crnlib::console::warning("Value %f for parameter \"%s\" is out of range, clamping to %f", val, pKey, h);
val = h; val = h;
} }
return val; return val;
} }
bool command_line_params::get_value_as_string(const wchar_t* pKey, uint index, dynamic_wstring& value, uint value_index) const bool command_line_params::get_value_as_string(const char* pKey, uint index, dynamic_string& value, uint value_index) const
{ {
param_map_const_iterator it = get_param(pKey, index); param_map_const_iterator it = get_param(pKey, index);
if ((it == end()) || (value_index >= it->second.m_values.size())) if ((it == end()) || (value_index >= it->second.m_values.size()))
@@ -425,13 +458,13 @@ namespace crnlib
value = it->second.m_values[value_index]; value = it->second.m_values[value_index];
return true; return true;
} }
const dynamic_wstring& command_line_params::get_value_as_string_or_empty(const wchar_t* pKey, uint index, uint value_index) const const dynamic_string& command_line_params::get_value_as_string_or_empty(const char* pKey, uint index, uint value_index) const
{ {
param_map_const_iterator it = get_param(pKey, index); param_map_const_iterator it = get_param(pKey, index);
if ((it == end()) || (value_index >= it->second.m_values.size())) if ((it == end()) || (value_index >= it->second.m_values.size()))
return g_empty_dynamic_wstring; return g_empty_dynamic_string;
return it->second.m_values[value_index]; return it->second.m_values[value_index];
} }
+49 -47
View File
@@ -6,77 +6,79 @@
namespace crnlib namespace crnlib
{ {
void get_command_line(dynamic_string& cmd_line, int argc, char *argv[]);
class command_line_params class command_line_params
{ {
public: public:
struct param_value struct param_value
{ {
param_value() : m_index(0), m_modifier(0) { } inline param_value() : m_index(0), m_modifier(0) { }
dynamic_wstring_array m_values; dynamic_string_array m_values;
uint m_index; uint m_index;
int8 m_modifier; int8 m_modifier;
}; };
typedef std::multimap<dynamic_wstring, param_value> param_map; typedef std::multimap<dynamic_string, param_value> param_map;
typedef param_map::const_iterator param_map_const_iterator; typedef param_map::const_iterator param_map_const_iterator;
typedef param_map::iterator param_map_iterator; typedef param_map::iterator param_map_iterator;
command_line_params(); command_line_params();
void clear(); void clear();
static bool split_params(const wchar_t* p, dynamic_wstring_array& params); static bool split_params(const char* p, dynamic_string_array& params);
struct param_desc struct param_desc
{ {
const wchar_t* m_pName; const char* m_pName;
uint m_num_values; uint m_num_values;
bool m_support_listing_file; bool m_support_listing_file;
}; };
bool parse(const dynamic_wstring_array& params, uint n, const param_desc* pParam_desc); bool parse(const dynamic_string_array& params, uint n, const param_desc* pParam_desc);
bool parse(const wchar_t* pCmd_line, uint n, const param_desc* pParam_desc, bool skip_first_param = true); bool parse(const char* pCmd_line, uint n, const param_desc* pParam_desc, bool skip_first_param = true);
const dynamic_wstring_array& get_array() const { return m_params; } const dynamic_string_array& get_array() const { return m_params; }
bool is_param(uint index) const; bool is_param(uint index) const;
const param_map& get_map() const { return m_param_map; } const param_map& get_map() const { return m_param_map; }
uint get_num_params() const { return static_cast<uint>(m_param_map.size()); } uint get_num_params() const { return static_cast<uint>(m_param_map.size()); }
param_map_const_iterator begin() const { return m_param_map.begin(); } param_map_const_iterator begin() const { return m_param_map.begin(); }
param_map_const_iterator end() const { return m_param_map.end(); } param_map_const_iterator end() const { return m_param_map.end(); }
uint find(uint num_keys, const wchar_t** ppKeys, crnlib::vector<param_map_const_iterator>* pIterators, crnlib::vector<uint>* pUnmatched_indices) const; uint find(uint num_keys, const char** ppKeys, crnlib::vector<param_map_const_iterator>* pIterators, crnlib::vector<uint>* pUnmatched_indices) const;
void find(const wchar_t* pKey, param_map_const_iterator& begin, param_map_const_iterator& end) const; void find(const char* pKey, param_map_const_iterator& begin, param_map_const_iterator& end) const;
uint get_count(const wchar_t* pKey) const; uint get_count(const char* pKey) const;
// Returns end() if param cannot be found, or index is out of range. // Returns end() if param cannot be found, or index is out of range.
param_map_const_iterator get_param(const wchar_t* pKey, uint index) const; param_map_const_iterator get_param(const char* pKey, uint index) const;
bool has_key(const wchar_t* pKey) const { return get_param(pKey, 0) != end(); } bool has_key(const char* pKey) const { return get_param(pKey, 0) != end(); }
bool has_value(const wchar_t* pKey, uint index) const; bool has_value(const char* pKey, uint index) const;
uint get_num_values(const wchar_t* pKey, uint index) const; uint get_num_values(const char* pKey, uint index) const;
bool get_value_as_bool(const wchar_t* pKey, uint index = 0, bool def = false) const; bool get_value_as_bool(const char* pKey, uint index = 0, bool def = false) const;
int get_value_as_int(const wchar_t* pKey, uint index, int def, int l = INT_MIN, int h = INT_MAX, uint value_index = 0) const; int get_value_as_int(const char* pKey, uint index, int def, int l = INT_MIN, int h = INT_MAX, uint value_index = 0) const;
float get_value_as_float(const wchar_t* pKey, uint index, float def = 0.0f, float l = -math::cNearlyInfinite, float h = math::cNearlyInfinite, uint value_index = 0) const; float get_value_as_float(const char* pKey, uint index, float def = 0.0f, float l = -math::cNearlyInfinite, float h = math::cNearlyInfinite, uint value_index = 0) const;
bool get_value_as_string(const wchar_t* pKey, uint index, dynamic_wstring& value, uint value_index = 0) const; bool get_value_as_string(const char* pKey, uint index, dynamic_string& value, uint value_index = 0) const;
const dynamic_wstring& get_value_as_string_or_empty(const wchar_t* pKey, uint index = 0, uint value_index = 0) const; const dynamic_string& get_value_as_string_or_empty(const char* pKey, uint index = 0, uint value_index = 0) const;
private: private:
dynamic_wstring_array m_params; dynamic_string_array m_params;
param_map m_param_map; param_map m_param_map;
static bool load_string_file(const wchar_t* pFilename, dynamic_wstring_array& strings); static bool load_string_file(const char* pFilename, dynamic_string_array& strings);
}; };
} // namespace crnlib } // namespace crnlib
+475 -475
View File
File diff suppressed because it is too large Load Diff
+52 -52
View File
@@ -18,30 +18,30 @@ namespace crnlib
class crn_comp : public itexture_comp class crn_comp : public itexture_comp
{ {
CRNLIB_NO_COPY_OR_ASSIGNMENT_OP(crn_comp); CRNLIB_NO_COPY_OR_ASSIGNMENT_OP(crn_comp);
public: public:
crn_comp(); crn_comp();
virtual ~crn_comp(); virtual ~crn_comp();
virtual const wchar_t *get_ext() const { return L"CRN"; } virtual const char *get_ext() const { return "CRN"; }
virtual bool compress_init(const crn_comp_params& params); virtual bool compress_init(const crn_comp_params& params);
virtual bool compress_pass(const crn_comp_params& params, float *pEffective_bitrate); virtual bool compress_pass(const crn_comp_params& params, float *pEffective_bitrate);
virtual void compress_deinit(); virtual void compress_deinit();
virtual const crnlib::vector<uint8>& get_comp_data() const { return m_comp_data; } virtual const crnlib::vector<uint8>& get_comp_data() const { return m_comp_data; }
virtual crnlib::vector<uint8>& get_comp_data() { return m_comp_data; } virtual crnlib::vector<uint8>& get_comp_data() { return m_comp_data; }
uint get_comp_data_size() const { return m_comp_data.size(); } uint get_comp_data_size() const { return m_comp_data.size(); }
const uint8* get_comp_data_ptr() const { return m_comp_data.size() ? &m_comp_data[0] : NULL; } const uint8* get_comp_data_ptr() const { return m_comp_data.size() ? &m_comp_data[0] : NULL; }
private: private:
task_pool m_task_pool; task_pool m_task_pool;
const crn_comp_params* m_pParams; const crn_comp_params* m_pParams;
image_u8 m_images[cCRNMaxFaces][cCRNMaxLevels]; image_u8 m_images[cCRNMaxFaces][cCRNMaxLevels];
struct struct level_tag
{ {
uint m_width, m_height; uint m_width, m_height;
uint m_chunk_width, m_chunk_height; uint m_chunk_width, m_chunk_height;
@@ -50,130 +50,130 @@ namespace crnlib
uint m_first_chunk; uint m_first_chunk;
uint m_group_first_chunk; uint m_group_first_chunk;
} m_levels[cCRNMaxLevels]; } m_levels[cCRNMaxLevels];
struct mip_group struct mip_group
{ {
mip_group() : m_first_chunk(0), m_num_chunks(0) { } mip_group() : m_first_chunk(0), m_num_chunks(0) { }
uint m_first_chunk; uint m_first_chunk;
uint m_num_chunks; uint m_num_chunks;
}; };
crnlib::vector<mip_group> m_mip_groups; crnlib::vector<mip_group> m_mip_groups;
enum comp enum comp
{ {
cColor, cColor,
cAlpha0, cAlpha0,
cAlpha1, cAlpha1,
cNumComps cNumComps
}; };
bool m_has_comp[cNumComps]; bool m_has_comp[cNumComps];
struct chunk_detail struct chunk_detail
{ {
chunk_detail() { utils::zero_object(*this); } chunk_detail() { utils::zero_object(*this); }
uint m_first_endpoint_index; uint m_first_endpoint_index;
uint m_first_selector_index; uint m_first_selector_index;
}; };
typedef crnlib::vector<chunk_detail> chunk_detail_vec; typedef crnlib::vector<chunk_detail> chunk_detail_vec;
chunk_detail_vec m_chunk_details; chunk_detail_vec m_chunk_details;
crnlib::vector<uint> m_endpoint_indices[cNumComps]; crnlib::vector<uint> m_endpoint_indices[cNumComps];
crnlib::vector<uint> m_selector_indices[cNumComps]; crnlib::vector<uint> m_selector_indices[cNumComps];
uint m_total_chunks; uint m_total_chunks;
dxt_hc::pixel_chunk_vec m_chunks; dxt_hc::pixel_chunk_vec m_chunks;
crnd::crn_header m_crn_header; crnd::crn_header m_crn_header;
crnlib::vector<uint8> m_comp_data; crnlib::vector<uint8> m_comp_data;
dxt_hc m_hvq; dxt_hc m_hvq;
symbol_histogram m_chunk_encoding_hist; symbol_histogram m_chunk_encoding_hist;
static_huffman_data_model m_chunk_encoding_dm; static_huffman_data_model m_chunk_encoding_dm;
symbol_histogram m_endpoint_index_hist[2]; symbol_histogram m_endpoint_index_hist[2];
static_huffman_data_model m_endpoint_index_dm[2]; // color, alpha static_huffman_data_model m_endpoint_index_dm[2]; // color, alpha
symbol_histogram m_selector_index_hist[2]; symbol_histogram m_selector_index_hist[2];
static_huffman_data_model m_selector_index_dm[2]; // color, alpha static_huffman_data_model m_selector_index_dm[2]; // color, alpha
crnlib::vector<uint8> m_packed_chunks[cCRNMaxLevels]; crnlib::vector<uint8> m_packed_chunks[cCRNMaxLevels];
crnlib::vector<uint8> m_packed_data_models; crnlib::vector<uint8> m_packed_data_models;
crnlib::vector<uint8> m_packed_color_endpoints; crnlib::vector<uint8> m_packed_color_endpoints;
crnlib::vector<uint8> m_packed_color_selectors; crnlib::vector<uint8> m_packed_color_selectors;
crnlib::vector<uint8> m_packed_alpha_endpoints; crnlib::vector<uint8> m_packed_alpha_endpoints;
crnlib::vector<uint8> m_packed_alpha_selectors; crnlib::vector<uint8> m_packed_alpha_selectors;
void clear(); void clear();
void append_chunks(const image_u8& img, uint num_chunks_x, uint num_chunks_y, dxt_hc::pixel_chunk_vec& chunks, float weight); void append_chunks(const image_u8& img, uint num_chunks_x, uint num_chunks_y, dxt_hc::pixel_chunk_vec& chunks, float weight);
static float color_endpoint_similarity_func(uint index_a, uint index_b, void* pContext); static float color_endpoint_similarity_func(uint index_a, uint index_b, void* pContext);
static float alpha_endpoint_similarity_func(uint index_a, uint index_b, void* pContext); static float alpha_endpoint_similarity_func(uint index_a, uint index_b, void* pContext);
void sort_color_endpoint_codebook(crnlib::vector<uint>& remapping, const crnlib::vector<uint>& endpoints); void sort_color_endpoint_codebook(crnlib::vector<uint>& remapping, const crnlib::vector<uint>& endpoints);
void sort_alpha_endpoint_codebook(crnlib::vector<uint>& remapping, const crnlib::vector<uint>& endpoints); void sort_alpha_endpoint_codebook(crnlib::vector<uint>& remapping, const crnlib::vector<uint>& endpoints);
bool pack_color_endpoints(crnlib::vector<uint8>& data, const crnlib::vector<uint>& remapping, const crnlib::vector<uint>& endpoint_indices, uint trial_index); bool pack_color_endpoints(crnlib::vector<uint8>& data, const crnlib::vector<uint>& remapping, const crnlib::vector<uint>& endpoint_indices, uint trial_index);
bool pack_alpha_endpoints(crnlib::vector<uint8>& data, const crnlib::vector<uint>& remapping, const crnlib::vector<uint>& endpoint_indices, uint trial_index); bool pack_alpha_endpoints(crnlib::vector<uint8>& data, const crnlib::vector<uint>& remapping, const crnlib::vector<uint>& endpoint_indices, uint trial_index);
static float color_selector_similarity_func(uint index_a, uint index_b, void* pContext); static float color_selector_similarity_func(uint index_a, uint index_b, void* pContext);
static float alpha_selector_similarity_func(uint index_a, uint index_b, void* pContext); static float alpha_selector_similarity_func(uint index_a, uint index_b, void* pContext);
void sort_selector_codebook(crnlib::vector<uint>& remapping, const crnlib::vector<dxt_hc::selectors>& selectors, const uint8* pTo_linear); void sort_selector_codebook(crnlib::vector<uint>& remapping, const crnlib::vector<dxt_hc::selectors>& selectors, const uint8* pTo_linear);
bool pack_selectors( bool pack_selectors(
crnlib::vector<uint8>& packed_data, crnlib::vector<uint8>& packed_data,
const crnlib::vector<uint>& selector_indices, const crnlib::vector<uint>& selector_indices,
const crnlib::vector<dxt_hc::selectors>& selectors, const crnlib::vector<dxt_hc::selectors>& selectors,
const crnlib::vector<uint>& remapping, const crnlib::vector<uint>& remapping,
uint max_selector_value, uint max_selector_value,
const uint8* pTo_linear, const uint8* pTo_linear,
uint trial_index); uint trial_index);
bool alias_images(); bool alias_images();
void create_chunks(); void create_chunks();
bool quantize_chunks(); bool quantize_chunks();
void create_chunk_indices(); void create_chunk_indices();
bool pack_chunks( bool pack_chunks(
uint first_chunk, uint num_chunks, uint first_chunk, uint num_chunks,
bool clear_histograms, bool clear_histograms,
symbol_codec* pCodec, symbol_codec* pCodec,
const crnlib::vector<uint>* pColor_endpoint_remap, const crnlib::vector<uint>* pColor_endpoint_remap,
const crnlib::vector<uint>* pColor_selector_remap, const crnlib::vector<uint>* pColor_selector_remap,
const crnlib::vector<uint>* pAlpha_endpoint_remap, const crnlib::vector<uint>* pAlpha_endpoint_remap,
const crnlib::vector<uint>* pAlpha_selector_remap); const crnlib::vector<uint>* pAlpha_selector_remap);
bool pack_chunks_simulation( bool pack_chunks_simulation(
uint first_chunk, uint num_chunks, uint first_chunk, uint num_chunks,
uint& total_bits, uint& total_bits,
const crnlib::vector<uint>* pColor_endpoint_remap, const crnlib::vector<uint>* pColor_endpoint_remap,
const crnlib::vector<uint>* pColor_selector_remap, const crnlib::vector<uint>* pColor_selector_remap,
const crnlib::vector<uint>* pAlpha_endpoint_remap, const crnlib::vector<uint>* pAlpha_endpoint_remap,
const crnlib::vector<uint>* pAlpha_selector_remap); const crnlib::vector<uint>* pAlpha_selector_remap);
void optimize_color_endpoint_codebook_task(uint64 data, void* pData_ptr); void optimize_color_endpoint_codebook_task(uint64 data, void* pData_ptr);
bool optimize_color_endpoint_codebook(crnlib::vector<uint>& remapping); bool optimize_color_endpoint_codebook(crnlib::vector<uint>& remapping);
void optimize_color_selector_codebook_task(uint64 data, void* pData_ptr); void optimize_color_selector_codebook_task(uint64 data, void* pData_ptr);
bool optimize_color_selector_codebook(crnlib::vector<uint>& remapping); bool optimize_color_selector_codebook(crnlib::vector<uint>& remapping);
void optimize_alpha_endpoint_codebook_task(uint64 data, void* pData_ptr); void optimize_alpha_endpoint_codebook_task(uint64 data, void* pData_ptr);
bool optimize_alpha_endpoint_codebook(crnlib::vector<uint>& remapping); bool optimize_alpha_endpoint_codebook(crnlib::vector<uint>& remapping);
void optimize_alpha_selector_codebook_task(uint64 data, void* pData_ptr); void optimize_alpha_selector_codebook_task(uint64 data, void* pData_ptr);
bool optimize_alpha_selector_codebook(crnlib::vector<uint>& remapping); bool optimize_alpha_selector_codebook(crnlib::vector<uint>& remapping);
bool create_comp_data(); bool create_comp_data();
bool pack_data_models(); bool pack_data_models();
bool update_progress(uint phase_index, uint subphase_index, uint subphase_total); bool update_progress(uint phase_index, uint subphase_index, uint subphase_total);
bool compress_internal(); bool compress_internal();
static void append_vec(crnlib::vector<uint8>& a, const void* p, uint size); static void append_vec(crnlib::vector<uint8>& a, const void* p, uint size);
static void append_vec(crnlib::vector<uint8>& a, const crnlib::vector<uint8>& b); static void append_vec(crnlib::vector<uint8>& a, const crnlib::vector<uint8>& b);
}; };
+22 -35
View File
@@ -3,6 +3,7 @@
#include "crn_core.h" #include "crn_core.h"
#include "crn_console.h" #include "crn_console.h"
#include "crn_data_stream.h" #include "crn_data_stream.h"
#include "crn_threading.h"
namespace crnlib namespace crnlib
{ {
@@ -48,7 +49,7 @@ namespace crnlib
m_crlf = true; m_crlf = true;
} }
void console::vprintf(eConsoleMessageType type, const wchar_t* p, va_list args) void console::vprintf(eConsoleMessageType type, const char* p, va_list args)
{ {
init(); init();
@@ -56,12 +57,8 @@ namespace crnlib
m_num_messages[type]++; m_num_messages[type]++;
wchar_t buf[cConsoleBufSize]; char buf[cConsoleBufSize];
#ifdef _MSC_VER vsprintf_s(buf, cConsoleBufSize, p, args);
vswprintf_s(buf, cConsoleBufSize, p, args);
#else
vswprintf(buf, p, args);
#endif
bool handled = false; bool handled = false;
@@ -72,48 +69,38 @@ namespace crnlib
handled = true; handled = true;
} }
const wchar_t* pPrefix = NULL; const char* pPrefix = NULL;
if (m_prefixes) if (m_prefixes)
{ {
switch (type) switch (type)
{ {
case cDebugConsoleMessage: pPrefix = L"Debug: "; break; case cDebugConsoleMessage: pPrefix = "Debug: "; break;
case cWarningConsoleMessage: pPrefix = L"Warning: "; break; case cWarningConsoleMessage: pPrefix = "Warning: "; break;
case cErrorConsoleMessage: pPrefix = L"Error: "; break; case cErrorConsoleMessage: pPrefix = "Error: "; break;
default: break; default: break;
} }
} }
if ((!m_output_disabled) && (!handled)) if ((!m_output_disabled) && (!handled))
{ {
#ifdef _XBOX
if (pPrefix) if (pPrefix)
OutputDebugStringW(pPrefix); ::printf("%s", pPrefix);
OutputDebugStringW(buf); ::printf(m_crlf ? "%s\n" : "%s", buf);
if (m_crlf)
OutputDebugStringW(L"\n");
#else
if (pPrefix)
::wprintf(pPrefix);
::wprintf(m_crlf ? L"%s\n" : L"%s", buf);
#endif
} }
if ((type != cProgressConsoleMessage) && (m_pLog_stream)) if ((type != cProgressConsoleMessage) && (m_pLog_stream))
{ {
// Yes this is bad. // Yes this is bad.
dynamic_wstring utf16_buf(buf); dynamic_string tmp_buf(buf);
dynamic_string ansi_buf; tmp_buf.translate_lf_to_crlf();
utf16_buf.as_ansi(ansi_buf);
ansi_buf.translate_lf_to_crlf();
m_pLog_stream->printf(m_crlf ? "%s\r\n" : "%s", ansi_buf.get_ptr()); m_pLog_stream->printf(m_crlf ? "%s\r\n" : "%s", tmp_buf.get_ptr());
m_pLog_stream->flush(); m_pLog_stream->flush();
} }
} }
void console::printf(eConsoleMessageType type, const wchar_t* p, ...) void console::printf(eConsoleMessageType type, const char* p, ...)
{ {
va_list args; va_list args;
va_start(args, p); va_start(args, p);
@@ -121,7 +108,7 @@ namespace crnlib
va_end(args); va_end(args);
} }
void console::printf(const wchar_t* p, ...) void console::printf(const char* p, ...)
{ {
va_list args; va_list args;
va_start(args, p); va_start(args, p);
@@ -172,7 +159,7 @@ namespace crnlib
} }
} }
void console::progress(const wchar_t* p, ...) void console::progress(const char* p, ...)
{ {
va_list args; va_list args;
va_start(args, p); va_start(args, p);
@@ -180,7 +167,7 @@ namespace crnlib
va_end(args); va_end(args);
} }
void console::info(const wchar_t* p, ...) void console::info(const char* p, ...)
{ {
va_list args; va_list args;
va_start(args, p); va_start(args, p);
@@ -188,7 +175,7 @@ namespace crnlib
va_end(args); va_end(args);
} }
void console::message(const wchar_t* p, ...) void console::message(const char* p, ...)
{ {
va_list args; va_list args;
va_start(args, p); va_start(args, p);
@@ -196,7 +183,7 @@ namespace crnlib
va_end(args); va_end(args);
} }
void console::cons(const wchar_t* p, ...) void console::cons(const char* p, ...)
{ {
va_list args; va_list args;
va_start(args, p); va_start(args, p);
@@ -204,7 +191,7 @@ namespace crnlib
va_end(args); va_end(args);
} }
void console::debug(const wchar_t* p, ...) void console::debug(const char* p, ...)
{ {
va_list args; va_list args;
va_start(args, p); va_start(args, p);
@@ -212,7 +199,7 @@ namespace crnlib
va_end(args); va_end(args);
} }
void console::warning(const wchar_t* p, ...) void console::warning(const char* p, ...)
{ {
va_list args; va_list args;
va_start(args, p); va_start(args, p);
@@ -220,7 +207,7 @@ namespace crnlib
va_end(args); va_end(args);
} }
void console::error(const wchar_t* p, ...) void console::error(const char* p, ...)
{ {
va_list args; va_list args;
va_start(args, p); va_start(args, p);
+65 -34
View File
@@ -3,92 +3,123 @@
#pragma once #pragma once
#include "crn_dynamic_string.h" #include "crn_dynamic_string.h"
#ifdef WIN32
#include <tchar.h>
#include <conio.h>
#endif
namespace crnlib namespace crnlib
{ {
class dynamic_string; class dynamic_string;
class data_stream; class data_stream;
class mutex; class mutex;
enum eConsoleMessageType enum eConsoleMessageType
{ {
cDebugConsoleMessage, // debugging messages cDebugConsoleMessage, // debugging messages
cProgressConsoleMessage, // progress messages cProgressConsoleMessage, // progress messages
cInfoConsoleMessage, // ordinary messages cInfoConsoleMessage, // ordinary messages
cConsoleConsoleMessage, // user console output cConsoleConsoleMessage, // user console output
cMessageConsoleMessage, // high importance messages cMessageConsoleMessage, // high importance messages
cWarningConsoleMessage, // warnings cWarningConsoleMessage, // warnings
cErrorConsoleMessage, // errors cErrorConsoleMessage, // errors
cCMTTotal cCMTTotal
}; };
typedef bool (*console_output_func)(eConsoleMessageType type, const wchar_t* pMsg, void* pData); typedef bool (*console_output_func)(eConsoleMessageType type, const char* pMsg, void* pData);
class console class console
{ {
public: public:
static void init(); static void init();
static void deinit(); static void deinit();
static bool is_initialized() { return m_pMutex != NULL; } static bool is_initialized() { return m_pMutex != NULL; }
static void set_default_category(eConsoleMessageType category); static void set_default_category(eConsoleMessageType category);
static eConsoleMessageType get_default_category(); static eConsoleMessageType get_default_category();
static void add_console_output_func(console_output_func pFunc, void* pData); static void add_console_output_func(console_output_func pFunc, void* pData);
static void remove_console_output_func(console_output_func pFunc); static void remove_console_output_func(console_output_func pFunc);
static void printf(const wchar_t* p, ...); static void printf(const char* p, ...);
static void vprintf(eConsoleMessageType type, const wchar_t* p, va_list args); static void vprintf(eConsoleMessageType type, const char* p, va_list args);
static void printf(eConsoleMessageType type, const wchar_t* p, ...); static void printf(eConsoleMessageType type, const char* p, ...);
static void cons(const wchar_t* p, ...); static void cons(const char* p, ...);
static void debug(const wchar_t* p, ...); static void debug(const char* p, ...);
static void progress(const wchar_t* p, ...); static void progress(const char* p, ...);
static void info(const wchar_t* p, ...); static void info(const char* p, ...);
static void message(const wchar_t* p, ...); static void message(const char* p, ...);
static void warning(const wchar_t* p, ...); static void warning(const char* p, ...);
static void error(const wchar_t* p, ...); static void error(const char* p, ...);
// FIXME: All console state is currently global! // FIXME: All console state is currently global!
static void disable_prefixes(); static void disable_prefixes();
static void enable_prefixes(); static void enable_prefixes();
static bool get_prefixes() { return m_prefixes; } static bool get_prefixes() { return m_prefixes; }
static void disable_crlf(); static void disable_crlf();
static void enable_crlf(); static void enable_crlf();
static bool get_crlf() { return m_crlf; } static bool get_crlf() { return m_crlf; }
static void disable_output() { m_output_disabled = true; } static void disable_output() { m_output_disabled = true; }
static void enable_output() { m_output_disabled = false; } static void enable_output() { m_output_disabled = false; }
static bool get_output_disabled() { return m_output_disabled; } static bool get_output_disabled() { return m_output_disabled; }
static void set_log_stream(data_stream* pStream) { m_pLog_stream = pStream; } static void set_log_stream(data_stream* pStream) { m_pLog_stream = pStream; }
static data_stream* get_log_stream() { return m_pLog_stream; } static data_stream* get_log_stream() { return m_pLog_stream; }
static uint get_num_messages(eConsoleMessageType type) { return m_num_messages[type]; } static uint get_num_messages(eConsoleMessageType type) { return m_num_messages[type]; }
private: private:
static eConsoleMessageType m_default_category; static eConsoleMessageType m_default_category;
struct console_func struct console_func
{ {
console_func(console_output_func func = NULL, void* pData = NULL) : m_func(func), m_pData(pData) { } console_func(console_output_func func = NULL, void* pData = NULL) : m_func(func), m_pData(pData) { }
console_output_func m_func; console_output_func m_func;
void* m_pData; void* m_pData;
}; };
static crnlib::vector<console_func> m_output_funcs; static crnlib::vector<console_func> m_output_funcs;
static bool m_crlf, m_prefixes, m_output_disabled; static bool m_crlf, m_prefixes, m_output_disabled;
static data_stream* m_pLog_stream; static data_stream* m_pLog_stream;
static mutex* m_pMutex; static mutex* m_pMutex;
static uint m_num_messages[cCMTTotal]; static uint m_num_messages[cCMTTotal];
}; };
#if defined(WIN32)
inline int crn_getch()
{
return _getch();
}
#elif defined(__GNUC__)
#include <termios.h>
#include <unistd.h>
inline int crn_getch()
{
struct termios oldt, newt;
int ch;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
ch = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
return ch;
}
#else
inline int crn_getch()
{
printf("crn_getch: Unimplemented");
return 0;
}
#endif
} // namespace crnlib } // namespace crnlib
+10 -3
View File
@@ -1,7 +1,14 @@
// File: crn_core.cpp // File: crn_core.cpp
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#include "crn_core.h" #include "crn_core.h"
#include "crn_winhdr.h"
char *g_copyright_str = "Copyright (c) 2010-2012 Rich Geldreich and Tenacious Software LLC"; #if CRNLIB_USE_WIN32_API
char *g_sig_str = "C8cfRlaorj0wLtnMSxrBJxTC85rho2L9hUZKHcBL"; #include "crn_winhdr.h"
#endif
namespace crnlib
{
const char *g_copyright_str = "Copyright (c) 2010-2012 Rich Geldreich and Tenacious Software LLC";
const char *g_sig_str = "C8cfRlaorj0wLtnMSxrBJxTC85rho2L9hUZKHcBL";
} // namespace crnlib
+104 -29
View File
@@ -6,38 +6,34 @@
#pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union #pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union
#pragma warning (disable: 4127) // conditional expression is constant #pragma warning (disable: 4127) // conditional expression is constant
#pragma warning (disable: 4793) // function compiled as native #pragma warning (disable: 4793) // function compiled as native
#pragma warning (disable: 4324) // structure was padded due to __declspec(align())
#endif #endif
#if defined(WIN32) #if defined(WIN32) && !defined(CRNLIB_ANSI_CPLUSPLUS)
// MSVC or MinGW, x86 or x64, Win32 API's for threading and Win32 Interlocked API's or GCC built-ins for atomic ops.
#if 0
#ifdef NDEBUG #ifdef NDEBUG
// Ensure checked iterators are disabled. // Ensure checked iterators are disabled.
#define _SECURE_SCL 0 #define _SECURE_SCL 0
#define _HAS_ITERATOR_DEBUGGING 0 #define _HAS_ITERATOR_DEBUGGING 0
#endif #endif
#ifndef _DLL #ifndef _DLL
// If we're using the DLL form of the run-time libs, we're also going to be enabling exceptions because we'll be building CLR apps. // If we're using the DLL form of the run-time libs, we're also going to be enabling exceptions because we'll be building CLR apps.
// Otherwise, we disable exceptions for a small (up to 5%) speed boost. // Otherwise, we disable exceptions for a small speed boost.
#define _HAS_EXCEPTIONS 0 #define _HAS_EXCEPTIONS 0
#endif #endif
#endif
//#define _CRT_SECURE_NO_WARNINGS
#define NOMINMAX #define NOMINMAX
#define CRNLIB_PLATFORM_PC 1
#ifdef _WIN64
#define CRNLIB_PLATFORM_PC_X64 1
#else
#define CRNLIB_PLATFORM_PC_X86 1
#endif
#define CRNLIB_USE_WIN32_API 1 #define CRNLIB_USE_WIN32_API 1
#ifdef _WIN64 #if defined(__MINGW32__) || defined(__MINGW64__)
#define CRNLIB_USE_GCC_ATOMIC_BUILTINS 1
#else
#define CRNLIB_USE_WIN32_ATOMIC_FUNCTIONS 1
#endif
#define CRNLIB_PLATFORM_PC 1
#if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__)
#define CRNLIB_PLATFORM_PC_X64 1 #define CRNLIB_PLATFORM_PC_X64 1
#define CRNLIB_64BIT_POINTERS 1 #define CRNLIB_64BIT_POINTERS 1
#define CRNLIB_CPU_HAS_64BIT_REGISTERS 1 #define CRNLIB_CPU_HAS_64BIT_REGISTERS 1
@@ -48,15 +44,99 @@
#define CRNLIB_CPU_HAS_64BIT_REGISTERS 0 #define CRNLIB_CPU_HAS_64BIT_REGISTERS 0
#define CRNLIB_LITTLE_ENDIAN_CPU 1 #define CRNLIB_LITTLE_ENDIAN_CPU 1
#endif #endif
#define CRNLIB_USE_UNALIGNED_INT_LOADS 1
#define CRNLIB_RESTRICT __restrict
#define CRNLIB_FORCE_INLINE __forceinline
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
#define CRNLIB_USE_MSVC_INTRINSICS 1
#endif
#define CRNLIB_INT64_FORMAT_SPECIFIER "%I64i"
#define CRNLIB_UINT64_FORMAT_SPECIFIER "%I64u"
#define CRNLIB_STDCALL __stdcall
#define CRNLIB_MEMORY_IMPORT_BARRIER
#define CRNLIB_MEMORY_EXPORT_BARRIER
#elif defined(__GNUC__) && !defined(CRNLIB_ANSI_CPLUSPLUS)
// GCC x86 or x64, pthreads for threading and GCC built-ins for atomic ops.
#define CRNLIB_PLATFORM_PC 1
#if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__)
#define CRNLIB_PLATFORM_PC_X64 1
#define CRNLIB_64BIT_POINTERS 1
#define CRNLIB_CPU_HAS_64BIT_REGISTERS 1
#else
#define CRNLIB_PLATFORM_PC_X86 1
#define CRNLIB_64BIT_POINTERS 0
#define CRNLIB_CPU_HAS_64BIT_REGISTERS 0
#endif
#define CRNLIB_USE_UNALIGNED_INT_LOADS 1
#define CRNLIB_LITTLE_ENDIAN_CPU 1
#define CRNLIB_USE_PTHREADS_API 1
#define CRNLIB_USE_GCC_ATOMIC_BUILTINS 1
#define CRNLIB_RESTRICT
#define CRNLIB_FORCE_INLINE inline __attribute__((__always_inline__,__gnu_inline__))
#define CRNLIB_INT64_FORMAT_SPECIFIER "%lli"
#define CRNLIB_UINT64_FORMAT_SPECIFIER "%llu"
#define CRNLIB_STDCALL
#define CRNLIB_MEMORY_IMPORT_BARRIER
#define CRNLIB_MEMORY_EXPORT_BARRIER
#else
// Vanilla ANSI-C/C++
// No threading support, unaligned loads are NOT okay.
#if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__)
#define CRNLIB_64BIT_POINTERS 1
#define CRNLIB_CPU_HAS_64BIT_REGISTERS 1
#else
#define CRNLIB_64BIT_POINTERS 0
#define CRNLIB_CPU_HAS_64BIT_REGISTERS 0
#endif
#define CRNLIB_USE_UNALIGNED_INT_LOADS 0
#if __BIG_ENDIAN__
#define CRNLIB_BIG_ENDIAN_CPU 1
#else
#define CRNLIB_LITTLE_ENDIAN_CPU 1
#endif
#define CRNLIB_USE_GCC_ATOMIC_BUILTINS 0
#define CRNLIB_USE_WIN32_ATOMIC_FUNCTIONS 0
#define CRNLIB_RESTRICT
#define CRNLIB_FORCE_INLINE inline
#define CRNLIB_INT64_FORMAT_SPECIFIER "%I64i"
#define CRNLIB_UINT64_FORMAT_SPECIFIER "%I64u"
#define CRNLIB_STDCALL
#define CRNLIB_MEMORY_IMPORT_BARRIER
#define CRNLIB_MEMORY_EXPORT_BARRIER
#endif #endif
#define CRNLIB_SLOW_STRING_LEN_CHECKS 1
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include <limits.h> #include <limits.h>
#include <math.h> #include <math.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <algorithm> #include <algorithm>
#include <locale> #include <locale>
#include <memory.h>
#include <limits.h>
#include <algorithm>
#include <errno.h>
#ifdef min #ifdef min
#undef min #undef min
@@ -78,16 +158,15 @@
#ifndef NDEBUG #ifndef NDEBUG
#define NDEBUG #define NDEBUG
#endif #endif
#ifdef DEBUG
#error DEBUG cannot be defined in CRNLIB_BUILD_RELEASE
#endif
#endif #endif
#include "crn_platform.h"
#if defined(WIN32)
#include "crn_mutex.h"
#endif
#include "crn_assert.h"
#include "crn_types.h" #include "crn_types.h"
#include "crn_assert.h"
#include "crn_platform.h"
#include "crn_helpers.h" #include "crn_helpers.h"
#include "crn_traits.h" #include "crn_traits.h"
#include "crn_mem.h" #include "crn_mem.h"
@@ -95,9 +174,5 @@
#include "crn_utils.h" #include "crn_utils.h"
#include "crn_hash.h" #include "crn_hash.h"
#include "crn_vector.h" #include "crn_vector.h"
#include "crn_win32_timer.h" #include "crn_timer.h"
#include "crn_win32_threading.h"
#include "crn_dynamic_string.h" #include "crn_dynamic_string.h"
#include "crn_dynamic_wstring.h"
+3 -29
View File
@@ -2,7 +2,6 @@
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#include "crn_core.h" #include "crn_core.h"
#include "crn_data_stream.h" #include "crn_data_stream.h"
#include <stdio.h>
namespace crnlib namespace crnlib
{ {
@@ -12,7 +11,7 @@ namespace crnlib
{ {
} }
data_stream::data_stream(const wchar_t* pName, uint attribs) : data_stream::data_stream(const char* pName, uint attribs) :
m_name(pName), m_name(pName),
m_attribs(static_cast<uint16>(attribs)), m_attribs(static_cast<uint16>(attribs)),
m_opened(false), m_error(false), m_got_cr(false) m_opened(false), m_error(false), m_got_cr(false)
@@ -85,28 +84,11 @@ namespace crnlib
va_list args; va_list args;
va_start(args, p); va_start(args, p);
char buf[4096]; dynamic_string buf;
#ifdef _MSC_VER
int l = vsprintf_s(buf, sizeof(buf), p, args);
#else
int l = vsprintf(buf, p, args);
#endif
va_end(args);
if (l < 0)
return false;
return write(buf, l) == static_cast<uint>(l);
}
bool data_stream::printf(const wchar_t* p, ...)
{
va_list args;
va_start(args, p);
dynamic_wstring buf;
buf.format_args(p, args); buf.format_args(p, args);
va_end(args); va_end(args);
return write(buf.get_ptr(), buf.get_len() * sizeof(wchar_t)) == buf.get_len() * sizeof(wchar_t); return write(buf.get_ptr(), buf.get_len() * sizeof(char)) == buf.get_len() * sizeof(char);
} }
bool data_stream::write_line(const dynamic_string& str) bool data_stream::write_line(const dynamic_string& str)
@@ -117,14 +99,6 @@ namespace crnlib
return true; return true;
} }
bool data_stream::write_line(const dynamic_wstring& str)
{
if (!str.is_empty())
return write(str.get_ptr(), str.get_len() * sizeof(wchar_t)) == str.get_len() * sizeof(wchar_t);
return true;
}
bool data_stream::read_array(vector<uint8>& buf) bool data_stream::read_array(vector<uint8>& buf)
{ {
if (buf.size() < get_remaining()) if (buf.size() < get_remaining())
+31 -33
View File
@@ -10,82 +10,80 @@ namespace crnlib
cDataStreamWritable = 2, cDataStreamWritable = 2,
cDataStreamSeekable = 4 cDataStreamSeekable = 4
}; };
const int64 DATA_STREAM_SIZE_UNKNOWN = INT64_MAX; const int64 DATA_STREAM_SIZE_UNKNOWN = cINT64_MAX;
const int64 DATA_STREAM_SIZE_INFINITE = UINT64_MAX; const int64 DATA_STREAM_SIZE_INFINITE = cUINT64_MAX;
class data_stream class data_stream
{ {
data_stream(const data_stream&); data_stream(const data_stream&);
data_stream& operator= (const data_stream&); data_stream& operator= (const data_stream&);
public: public:
data_stream(); data_stream();
data_stream(const wchar_t* pName, uint attribs); data_stream(const char* pName, uint attribs);
virtual ~data_stream() { } virtual ~data_stream() { }
virtual data_stream *get_parent() { return NULL; } virtual data_stream *get_parent() { return NULL; }
virtual bool close() { m_opened = false; m_error = false; m_got_cr = false; return true; } virtual bool close() { m_opened = false; m_error = false; m_got_cr = false; return true; }
typedef uint16 attribs_t; typedef uint16 attribs_t;
inline attribs_t get_attribs() const { return m_attribs; } inline attribs_t get_attribs() const { return m_attribs; }
inline bool is_opened() const { return m_opened; } inline bool is_opened() const { return m_opened; }
inline bool is_readable() const { return utils::is_bit_set(m_attribs, cDataStreamReadable); } inline bool is_readable() const { return utils::is_bit_set(m_attribs, cDataStreamReadable); }
inline bool is_writable() const { return utils::is_bit_set(m_attribs, cDataStreamWritable); } inline bool is_writable() const { return utils::is_bit_set(m_attribs, cDataStreamWritable); }
inline bool is_seekable() const { return utils::is_bit_set(m_attribs, cDataStreamSeekable); } inline bool is_seekable() const { return utils::is_bit_set(m_attribs, cDataStreamSeekable); }
inline bool get_error() const { return m_error; } inline bool get_error() const { return m_error; }
inline const dynamic_wstring& get_name() const { return m_name; } inline const dynamic_string& get_name() const { return m_name; }
inline void set_name(const wchar_t* pName) { m_name.set(pName); } inline void set_name(const char* pName) { m_name.set(pName); }
virtual uint read(void* pBuf, uint len) = 0; virtual uint read(void* pBuf, uint len) = 0;
virtual uint64 skip(uint64 len); virtual uint64 skip(uint64 len);
virtual uint write(const void* pBuf, uint len) = 0; virtual uint write(const void* pBuf, uint len) = 0;
virtual bool flush() = 0; virtual bool flush() = 0;
virtual bool is_size_known() const { return true; } virtual bool is_size_known() const { return true; }
// Returns DATA_STREAM_SIZE_UNKNOWN if size hasn't been determined yet, or DATA_STREAM_SIZE_INFINITE for infinite streams. // Returns DATA_STREAM_SIZE_UNKNOWN if size hasn't been determined yet, or DATA_STREAM_SIZE_INFINITE for infinite streams.
virtual uint64 get_size() = 0; virtual uint64 get_size() = 0;
virtual uint64 get_remaining() = 0; virtual uint64 get_remaining() = 0;
virtual uint64 get_ofs() = 0; virtual uint64 get_ofs() = 0;
virtual bool seek(int64 ofs, bool relative) = 0; virtual bool seek(int64 ofs, bool relative) = 0;
virtual const void* get_ptr() const { return NULL; } virtual const void* get_ptr() const { return NULL; }
inline int read_byte() { uint8 c; if (read(&c, 1) != 1) return -1; return c; } inline int read_byte() { uint8 c; if (read(&c, 1) != 1) return -1; return c; }
inline bool write_byte(uint8 c) { return write(&c, 1) == 1; } inline bool write_byte(uint8 c) { return write(&c, 1) == 1; }
bool read_line(dynamic_string& str); bool read_line(dynamic_string& str);
bool printf(const char* p, ...); bool printf(const char* p, ...);
bool printf(const wchar_t* p, ...);
bool write_line(const dynamic_string& str); bool write_line(const dynamic_string& str);
bool write_line(const dynamic_wstring& str);
bool write_bom() { uint16 bom = 0xFEFF; return write(&bom, sizeof(bom)) == sizeof(bom); } bool write_bom() { uint16 bom = 0xFEFF; return write(&bom, sizeof(bom)) == sizeof(bom); }
bool read_array(vector<uint8>& buf); bool read_array(vector<uint8>& buf);
bool write_array(const vector<uint8>& buf); bool write_array(const vector<uint8>& buf);
protected: protected:
dynamic_wstring m_name; dynamic_string m_name;
attribs_t m_attribs; attribs_t m_attribs;
bool m_opened : 1; bool m_opened : 1;
bool m_error : 1; bool m_error : 1;
bool m_got_cr : 1; bool m_got_cr : 1;
inline void set_error() { m_error = true; } inline void set_error() { m_error = true; }
inline void clear_error() { m_error = false; } inline void clear_error() { m_error = false; }
inline void post_seek() { m_got_cr = false; } inline void post_seek() { m_got_cr = false; }
}; };
} // namespace crnlib } // namespace crnlib
+4 -4
View File
@@ -15,7 +15,7 @@ namespace crnlib
dds_comp(); dds_comp();
virtual ~dds_comp(); virtual ~dds_comp();
virtual const wchar_t *get_ext() const { return L"DDS"; } virtual const char *get_ext() const { return "DDS"; }
virtual bool compress_init(const crn_comp_params& params); virtual bool compress_init(const crn_comp_params& params);
virtual bool compress_pass(const crn_comp_params& params, float *pEffective_bitrate); virtual bool compress_pass(const crn_comp_params& params, float *pEffective_bitrate);
@@ -23,7 +23,7 @@ namespace crnlib
virtual const crnlib::vector<uint8>& get_comp_data() const { return m_comp_data; } virtual const crnlib::vector<uint8>& get_comp_data() const { return m_comp_data; }
virtual crnlib::vector<uint8>& get_comp_data() { return m_comp_data; } virtual crnlib::vector<uint8>& get_comp_data() { return m_comp_data; }
private: private:
dds_texture m_src_tex; dds_texture m_src_tex;
dds_texture m_packed_tex; dds_texture m_packed_tex;
@@ -31,7 +31,7 @@ namespace crnlib
crnlib::vector<uint8> m_comp_data; crnlib::vector<uint8> m_comp_data;
const crn_comp_params* m_pParams; const crn_comp_params* m_pParams;
pixel_format m_pixel_fmt; pixel_format m_pixel_fmt;
dxt_image::pack_params m_pack_params; dxt_image::pack_params m_pack_params;
@@ -39,7 +39,7 @@ namespace crnlib
qdxt1_params m_q1_params; qdxt1_params m_q1_params;
qdxt5_params m_q5_params; qdxt5_params m_q5_params;
dds_texture::qdxt_state *m_pQDXT_state; dds_texture::qdxt_state *m_pQDXT_state;
void clear(); void clear();
bool create_dds_tex(dds_texture &dds_tex); bool create_dds_tex(dds_texture &dds_tex);
bool convert_to_dxt(const crn_comp_params& params); bool convert_to_dxt(const crn_comp_params& params);
+74 -74
View File
@@ -216,7 +216,7 @@ namespace crnlib
if (m_pImage->is_grayscale()) if (m_pImage->is_grayscale())
m_format = m_pImage->has_alpha() ? PIXEL_FMT_A8L8 : PIXEL_FMT_L8; m_format = m_pImage->has_alpha() ? PIXEL_FMT_A8L8 : PIXEL_FMT_L8;
else else
m_format = m_pImage->has_alpha() ? PIXEL_FMT_A8R8G8B8 : PIXEL_FMT_R8G8B8; m_format = m_pImage->has_alpha() ? PIXEL_FMT_A8R8G8B8 : PIXEL_FMT_R8G8B8;
return true; return true;
@@ -380,7 +380,7 @@ namespace crnlib
return *this; return *this;
} }
bool dds_texture::write_dds(const wchar_t* pFilename) const bool dds_texture::write_dds(const char* pFilename) const
{ {
cfile_stream out_stream(pFilename, cDataStreamWritable | cDataStreamSeekable); cfile_stream out_stream(pFilename, cDataStreamWritable | cDataStreamSeekable);
if (!out_stream.is_opened()) if (!out_stream.is_opened())
@@ -390,7 +390,7 @@ namespace crnlib
return write_dds(out_serializer); return write_dds(out_serializer);
} }
bool dds_texture::read_dds(const wchar_t* pFilename) bool dds_texture::read_dds(const char* pFilename)
{ {
cfile_stream in_stream(pFilename); cfile_stream in_stream(pFilename);
if (!in_stream.is_opened()) if (!in_stream.is_opened())
@@ -417,7 +417,7 @@ namespace crnlib
clear(); clear();
set_last_error(L"Not a DDS file"); set_last_error("Not a DDS file");
uint8 hdr[4]; uint8 hdr[4];
if (!serializer.read(hdr, sizeof(hdr))) if (!serializer.read(hdr, sizeof(hdr)))
@@ -460,7 +460,7 @@ namespace crnlib
const uint all_faces_mask = DDSCAPS2_CUBEMAP_POSITIVEX|DDSCAPS2_CUBEMAP_NEGATIVEX|DDSCAPS2_CUBEMAP_POSITIVEY|DDSCAPS2_CUBEMAP_NEGATIVEY|DDSCAPS2_CUBEMAP_POSITIVEZ|DDSCAPS2_CUBEMAP_NEGATIVEZ; const uint all_faces_mask = DDSCAPS2_CUBEMAP_POSITIVEX|DDSCAPS2_CUBEMAP_NEGATIVEX|DDSCAPS2_CUBEMAP_POSITIVEY|DDSCAPS2_CUBEMAP_NEGATIVEY|DDSCAPS2_CUBEMAP_POSITIVEZ|DDSCAPS2_CUBEMAP_NEGATIVEZ;
if ((desc.ddsCaps.dwCaps2 & all_faces_mask) != all_faces_mask) if ((desc.ddsCaps.dwCaps2 & all_faces_mask) != all_faces_mask)
{ {
set_last_error(L"Incomplete cubemaps unsupported"); set_last_error("Incomplete cubemaps unsupported");
return false; return false;
} }
@@ -468,7 +468,7 @@ namespace crnlib
} }
else if (desc.ddsCaps.dwCaps2 & DDSCAPS2_VOLUME) else if (desc.ddsCaps.dwCaps2 & DDSCAPS2_VOLUME)
{ {
set_last_error(L"Volume textures unsupported"); set_last_error("Volume textures unsupported");
return false; return false;
} }
} }
@@ -479,7 +479,7 @@ namespace crnlib
// nvdxt just hangs // nvdxt just hangs
// dxtex.exe just makes all-white textures // dxtex.exe just makes all-white textures
// So screw it. // So screw it.
set_last_error(L"Palettized textures unsupported"); set_last_error("Palettized textures unsupported");
return false; return false;
} }
@@ -555,7 +555,7 @@ namespace crnlib
} }
default: default:
{ {
dynamic_wstring err_msg(cVarArg, L"Unsupported DDS FOURCC format: 0x%08X", desc.ddpfPixelFormat.dwFourCC); dynamic_string err_msg(cVarArg, "Unsupported DDS FOURCC format: 0x%08X", desc.ddpfPixelFormat.dwFourCC);
set_last_error(err_msg.get_ptr()); set_last_error(err_msg.get_ptr());
return false; return false;
} }
@@ -563,7 +563,7 @@ namespace crnlib
} }
else if ((desc.ddpfPixelFormat.dwRGBBitCount < 8) || (desc.ddpfPixelFormat.dwRGBBitCount > 32) || (desc.ddpfPixelFormat.dwRGBBitCount & 7)) else if ((desc.ddpfPixelFormat.dwRGBBitCount < 8) || (desc.ddpfPixelFormat.dwRGBBitCount > 32) || (desc.ddpfPixelFormat.dwRGBBitCount & 7))
{ {
set_last_error(L"Unsupported bit count"); set_last_error("Unsupported bit count");
return false; return false;
} }
else if (desc.ddpfPixelFormat.dwFlags & DDPF_RGB) else if (desc.ddpfPixelFormat.dwFlags & DDPF_RGB)
@@ -597,7 +597,7 @@ namespace crnlib
} }
else else
{ {
set_last_error(L"Unsupported format"); set_last_error("Unsupported format");
return false; return false;
} }
@@ -609,7 +609,7 @@ namespace crnlib
//bits_per_pixel = ((m_format == PIXEL_FMT_DXT1) || (m_format == PIXEL_FMT_DXT5A)) ? 4 : 8; //bits_per_pixel = ((m_format == PIXEL_FMT_DXT1) || (m_format == PIXEL_FMT_DXT5A)) ? 4 : 8;
bits_per_pixel = pixel_format_helpers::get_bpp(m_format); bits_per_pixel = pixel_format_helpers::get_bpp(m_format);
set_last_error(L"Load failed"); set_last_error("Load failed");
uint default_pitch; uint default_pitch;
if (desc.ddpfPixelFormat.dwFlags & DDPF_FOURCC) if (desc.ddpfPixelFormat.dwFlags & DDPF_FOURCC)
@@ -620,19 +620,19 @@ namespace crnlib
uint pitch = desc.lPitch; uint pitch = desc.lPitch;
if (!pitch) if (!pitch)
pitch = default_pitch; pitch = default_pitch;
#if 0 #if 0
else if (pitch & 3) else if (pitch & 3)
{ {
// MS's DDS docs say the pitch must be DWORD aligned - but this isn't always the case. // MS's DDS docs say the pitch must be DWORD aligned - but this isn't always the case.
// ATI Compressonator writes images with non-DWORD aligned pitches, and the DDSWithoutD3DX sample from MS doesn't compute the proper DWORD aligned pitch when reading DDS // ATI Compressonator writes images with non-DWORD aligned pitches, and the DDSWithoutD3DX sample from MS doesn't compute the proper DWORD aligned pitch when reading DDS
// files, so the docs must be wrong/outdated. // files, so the docs must be wrong/outdated.
console::warning(L"DDS file's pitch is not divisible by 4 - trying to load anyway."); console::warning("DDS file's pitch is not divisible by 4 - trying to load anyway.");
} }
#endif #endif
// Check for obviously wacky source pitches (probably a corrupted/invalid file). // Check for obviously wacky source pitches (probably a corrupted/invalid file).
else if (pitch > default_pitch * 8) else if (pitch > default_pitch * 8)
{ {
set_last_error(L"Invalid pitch"); set_last_error("Invalid pitch");
return false; return false;
} }
@@ -869,11 +869,11 @@ namespace crnlib
{ {
if (!m_width) if (!m_width)
{ {
set_last_error(L"Nothing to write"); set_last_error("Nothing to write");
return false; return false;
} }
set_last_error(L"Write_dds() failed"); set_last_error("Write_dds() failed");
if (!serializer.write("DDS ", sizeof(uint32))) if (!serializer.write("DDS ", sizeof(uint32)))
return false; return false;
@@ -1017,7 +1017,7 @@ namespace crnlib
desc.lPitch = (desc.dwWidth * bits_per_pixel) >> 3; desc.lPitch = (desc.dwWidth * bits_per_pixel) >> 3;
desc.dwFlags |= DDSD_LINEARSIZE; desc.dwFlags |= DDSD_LINEARSIZE;
} }
if (!c_crnlib_little_endian_platform) if (!c_crnlib_little_endian_platform)
utils::endian_switch_dwords(reinterpret_cast<uint32*>(&desc), sizeof(desc) / sizeof(uint32)); utils::endian_switch_dwords(reinterpret_cast<uint32*>(&desc), sizeof(desc) / sizeof(uint32));
@@ -1257,7 +1257,7 @@ namespace crnlib
CRNLIB_ASSERT(check()); CRNLIB_ASSERT(check());
} }
void dds_texture::init(uint width, uint height, uint levels, uint faces, pixel_format fmt, const wchar_t* pName) void dds_texture::init(uint width, uint height, uint levels, uint faces, pixel_format fmt, const char* pName)
{ {
clear(); clear();
@@ -2029,7 +2029,7 @@ namespace crnlib
{ {
dxt1_blocks.resize(state.m_pixel_blocks.size()); dxt1_blocks.resize(state.m_pixel_blocks.size());
float pow_mul = 1.0f; float pow_mul = 1.0f;
if (state.m_fmt == PIXEL_FMT_DXT5_CCxY) if (state.m_fmt == PIXEL_FMT_DXT5_CCxY)
{ {
// use a "deeper" codebook size curves when compressing chroma into DXT1, because it's not as important // use a "deeper" codebook size curves when compressing chroma into DXT1, because it's not as important
@@ -2099,7 +2099,7 @@ namespace crnlib
return true; return true;
} }
bool dds_texture::load_from_file(const wchar_t* pFilename, texture_file_types::format file_format) bool dds_texture::load_from_file(const char* pFilename, texture_file_types::format file_format)
{ {
clear(); clear();
@@ -2108,11 +2108,11 @@ namespace crnlib
if (file_format == texture_file_types::cFormatInvalid) if (file_format == texture_file_types::cFormatInvalid)
{ {
set_last_error(L"Unrecognized image format extension"); set_last_error("Unrecognized image format extension");
return false; return false;
} }
set_last_error(L"Image file load failed"); set_last_error("Image file load failed");
bool success = false; bool success = false;
switch (file_format) switch (file_format)
@@ -2143,7 +2143,7 @@ namespace crnlib
return success; return success;
} }
bool dds_texture::load_regular(const wchar_t* pFilename, texture_file_types::format file_format) bool dds_texture::load_regular(const char* pFilename, texture_file_types::format file_format)
{ {
file_format; file_format;
@@ -2153,7 +2153,7 @@ namespace crnlib
{ {
crnlib_delete(pImg); crnlib_delete(pImg);
set_last_error(L"Failed loading image file"); set_last_error("Failed loading image file");
return false; return false;
} }
@@ -2166,12 +2166,12 @@ namespace crnlib
return true; return true;
} }
bool dds_texture::load_dds(const wchar_t* pFilename) bool dds_texture::load_dds(const char* pFilename)
{ {
cfile_stream in_stream; cfile_stream in_stream;
if (!in_stream.open(pFilename)) if (!in_stream.open(pFilename))
{ {
set_last_error(L"Failed opening file"); set_last_error("Failed opening file");
return false; return false;
} }
@@ -2188,11 +2188,11 @@ namespace crnlib
return true; return true;
} }
bool dds_texture::load_crn_from_memory(const wchar_t* pFilename, const void *pData, uint data_size) bool dds_texture::load_crn_from_memory(const char* pFilename, const void *pData, uint data_size)
{ {
clear(); clear();
set_last_error(L"Image file load failed"); set_last_error("Image file load failed");
if ((!pData) || (data_size < 1)) return false; if ((!pData) || (data_size < 1)) return false;
@@ -2200,14 +2200,14 @@ namespace crnlib
tex_info.m_struct_size = sizeof(crnd::crn_texture_info); tex_info.m_struct_size = sizeof(crnd::crn_texture_info);
if (!crnd_get_texture_info(pData, data_size, &tex_info)) if (!crnd_get_texture_info(pData, data_size, &tex_info))
{ {
set_last_error(L"crnd_get_texture_info() failed"); set_last_error("crnd_get_texture_info() failed");
return false; return false;
} }
const pixel_format dds_fmt = (pixel_format)crnd::crnd_crn_format_to_fourcc(tex_info.m_format); const pixel_format dds_fmt = (pixel_format)crnd::crnd_crn_format_to_fourcc(tex_info.m_format);
if (dds_fmt == PIXEL_FMT_INVALID) if (dds_fmt == PIXEL_FMT_INVALID)
{ {
set_last_error(L"Unsupported DXT format"); set_last_error("Unsupported DXT format");
return false; return false;
} }
@@ -2229,7 +2229,7 @@ namespace crnlib
// Create temp buffer big enough to hold the largest mip level, and all faces if it's a cubemap. // Create temp buffer big enough to hold the largest mip level, and all faces if it's a cubemap.
dxt_data.resize(tex_info.m_bytes_per_block * tex_num_blocks_x * tex_num_blocks_y * tex_info.m_faces); dxt_data.resize(tex_info.m_bytes_per_block * tex_num_blocks_x * tex_num_blocks_y * tex_info.m_faces);
set_last_error(L"CRN unpack failed"); set_last_error("CRN unpack failed");
timer t; timer t;
double total_time = 0.0f; double total_time = 0.0f;
@@ -2305,7 +2305,7 @@ namespace crnlib
#if 0 #if 0
if (total_pixels) if (total_pixels)
{ {
console::info(L"load_crn: Total pixels: %u, ms: %3.3fms, megapixels/sec: %3.3f", console::info("load_crn: Total pixels: %u, ms: %3.3fms, megapixels/sec: %3.3f",
total_pixels, total_time * 1000.0f, total_pixels / total_time); total_pixels, total_time * 1000.0f, total_pixels / total_time);
} }
#endif #endif
@@ -2321,19 +2321,19 @@ namespace crnlib
return true; return true;
} }
bool dds_texture::load_crn(const wchar_t* pFilename) bool dds_texture::load_crn(const char* pFilename)
{ {
cfile_stream in_stream; cfile_stream in_stream;
if (!in_stream.open(pFilename)) if (!in_stream.open(pFilename))
{ {
set_last_error(L"Failed opening CRN file"); set_last_error("Failed opening CRN file");
return false; return false;
} }
crnlib::vector<uint8> crn_data; crnlib::vector<uint8> crn_data;
if (!in_stream.read_array(crn_data)) if (!in_stream.read_array(crn_data))
{ {
set_last_error(L"Failed reading CRN file"); set_last_error("Failed reading CRN file");
return false; return false;
} }
@@ -2343,7 +2343,7 @@ namespace crnlib
} }
bool dds_texture::write_to_file( bool dds_texture::write_to_file(
const wchar_t* pFilename, const char* pFilename,
texture_file_types::format file_format, texture_file_types::format file_format,
crn_comp_params* pCRN_comp_params, crn_comp_params* pCRN_comp_params,
uint32 *pActual_quality_level, float *pActual_bitrate) uint32 *pActual_quality_level, float *pActual_bitrate)
@@ -2353,7 +2353,7 @@ namespace crnlib
if (!is_valid()) if (!is_valid())
{ {
set_last_error(L"Unable to save empty texture"); set_last_error("Unable to save empty texture");
return false; return false;
} }
@@ -2386,26 +2386,26 @@ namespace crnlib
return success; return success;
} }
bool dds_texture::save_regular(const wchar_t* pFilename) bool dds_texture::save_regular(const char* pFilename)
{ {
image_u8 tmp; image_u8 tmp;
image_u8* pLevel_image = get_level_image(0, 0, tmp); image_u8* pLevel_image = get_level_image(0, 0, tmp);
if (!image_utils::save_to_file(pFilename, *pLevel_image, 0)) if (!image_utils::save_to_file(pFilename, *pLevel_image, 0))
{ {
set_last_error(L"File write failed"); set_last_error("File write failed");
return false; return false;
} }
return true; return true;
} }
bool dds_texture::save_dds(const wchar_t* pFilename) bool dds_texture::save_dds(const char* pFilename)
{ {
cfile_stream out_stream; cfile_stream out_stream;
if (!out_stream.open(pFilename, cDataStreamWritable | cDataStreamSeekable)) if (!out_stream.open(pFilename, cDataStreamWritable | cDataStreamSeekable))
{ {
set_last_error(L"Unable to open file"); set_last_error("Unable to open file");
return false; return false;
} }
@@ -2413,7 +2413,7 @@ namespace crnlib
if (!write_dds(serializer)) if (!write_dds(serializer))
{ {
set_last_error(L"File write failed"); set_last_error("File write failed");
return false; return false;
} }
@@ -2422,34 +2422,34 @@ namespace crnlib
void dds_texture::print_crn_comp_params(const crn_comp_params& p) void dds_texture::print_crn_comp_params(const crn_comp_params& p)
{ {
console::debug(L"CRN compression params:"); console::debug("CRN compression params:");
console::debug(L" File Type: %s", crn_get_file_type_ext(p.m_file_type)); console::debug(" File Type: %s", crn_get_file_type_ext(p.m_file_type));
console::debug(L" Quality level: %u", p.m_quality_level); console::debug(" Quality level: %u", p.m_quality_level);
console::debug(L" Target Bitrate: %f", p.m_target_bitrate); console::debug(" Target Bitrate: %f", p.m_target_bitrate);
console::debug(L" Faces: %u", p.m_faces); console::debug(" Faces: %u", p.m_faces);
console::debug(L" Width: %u", p.m_width); console::debug(" Width: %u", p.m_width);
console::debug(L" Height: %u", p.m_height); console::debug(" Height: %u", p.m_height);
console::debug(L" Levels: %u", p.m_levels); console::debug(" Levels: %u", p.m_levels);
console::debug(L" Pixel Format: %s", crn_get_format_string(p.m_format)); console::debug(" Pixel Format: %s", crn_get_format_string(p.m_format));
console::debug(L"Use manual CRN palette sizes: %u", p.get_flag(cCRNCompFlagManualPaletteSizes)); console::debug("Use manual CRN palette sizes: %u", p.get_flag(cCRNCompFlagManualPaletteSizes));
console::debug(L"Color endpoints: %u", p.m_crn_color_endpoint_palette_size); console::debug("Color endpoints: %u", p.m_crn_color_endpoint_palette_size);
console::debug(L"Color selectors: %u", p.m_crn_color_selector_palette_size); console::debug("Color selectors: %u", p.m_crn_color_selector_palette_size);
console::debug(L"Alpha endpoints: %u", p.m_crn_alpha_endpoint_palette_size); console::debug("Alpha endpoints: %u", p.m_crn_alpha_endpoint_palette_size);
console::debug(L"Alpha selectors: %u", p.m_crn_alpha_selector_palette_size); console::debug("Alpha selectors: %u", p.m_crn_alpha_selector_palette_size);
console::debug(L"Flags:"); console::debug("Flags:");
console::debug(L" Perceptual: %u", p.get_flag(cCRNCompFlagPerceptual)); console::debug(" Perceptual: %u", p.get_flag(cCRNCompFlagPerceptual));
console::debug(L" Hierarchical: %u", p.get_flag(cCRNCompFlagHierarchical)); console::debug(" Hierarchical: %u", p.get_flag(cCRNCompFlagHierarchical));
console::debug(L" UseBothBlockTypes: %u", p.get_flag(cCRNCompFlagUseBothBlockTypes)); console::debug(" UseBothBlockTypes: %u", p.get_flag(cCRNCompFlagUseBothBlockTypes));
console::debug(L" UseTransparentIndicesForBlack: %u", p.get_flag(cCRNCompFlagUseTransparentIndicesForBlack)); console::debug(" UseTransparentIndicesForBlack: %u", p.get_flag(cCRNCompFlagUseTransparentIndicesForBlack));
console::debug(L" DisableEndpointCaching: %u", p.get_flag(cCRNCompFlagDisableEndpointCaching)); console::debug(" DisableEndpointCaching: %u", p.get_flag(cCRNCompFlagDisableEndpointCaching));
console::debug(L"GrayscaleSampling: %u", p.get_flag(cCRNCompFlagGrayscaleSampling)); console::debug("GrayscaleSampling: %u", p.get_flag(cCRNCompFlagGrayscaleSampling));
console::debug(L" UseDXT1ATransparency: %u", p.get_flag(cCRNCompFlagDXT1AForTransparency)); console::debug(" UseDXT1ATransparency: %u", p.get_flag(cCRNCompFlagDXT1AForTransparency));
console::debug(L"AdaptiveTileColorPSNRDerating: %2.2fdB", p.m_crn_adaptive_tile_color_psnr_derating); console::debug("AdaptiveTileColorPSNRDerating: %2.2fdB", p.m_crn_adaptive_tile_color_psnr_derating);
console::debug(L"AdaptiveTileAlphaPSNRDerating: %2.2fdB", p.m_crn_adaptive_tile_alpha_psnr_derating); console::debug("AdaptiveTileAlphaPSNRDerating: %2.2fdB", p.m_crn_adaptive_tile_alpha_psnr_derating);
console::debug(L"NumHelperThreads: %u", p.m_num_helper_threads); console::debug("NumHelperThreads: %u", p.m_num_helper_threads);
} }
bool dds_texture::save_comp_texture(const wchar_t* pFilename, const crn_comp_params &orig_comp_params, uint32 *pActual_quality_level, float *pActual_bitrate) bool dds_texture::save_comp_texture(const char* pFilename, const crn_comp_params &orig_comp_params, uint32 *pActual_quality_level, float *pActual_bitrate)
{ {
crn_comp_params comp_params(orig_comp_params); crn_comp_params comp_params(orig_comp_params);
@@ -2458,7 +2458,7 @@ namespace crnlib
if (math::maximum(get_height(), get_width()) > cCRNMaxLevelResolution) if (math::maximum(get_height(), get_width()) > cCRNMaxLevelResolution)
{ {
set_last_error(L"Texture resolution is too big!"); set_last_error("Texture resolution is too big!");
return false; return false;
} }
@@ -2487,32 +2487,32 @@ namespace crnlib
crnlib::vector<uint8> comp_data; crnlib::vector<uint8> comp_data;
if (!create_compressed_texture(comp_params, comp_data, pActual_quality_level, pActual_bitrate)) if (!create_compressed_texture(comp_params, comp_data, pActual_quality_level, pActual_bitrate))
{ {
set_last_error(L"CRN compression failed"); set_last_error("CRN compression failed");
return false; return false;
} }
double total_time = t.get_elapsed_secs(); double total_time = t.get_elapsed_secs();
if (comp_params.get_flag(cCRNCompFlagDebugging)) if (comp_params.get_flag(cCRNCompFlagDebugging))
{ {
console::debug(L"\nTotal compression time: %3.3fs", total_time); console::debug("\nTotal compression time: %3.3fs", total_time);
} }
cfile_stream out_stream; cfile_stream out_stream;
if (!out_stream.open(pFilename, cDataStreamWritable | cDataStreamSeekable)) if (!out_stream.open(pFilename, cDataStreamWritable | cDataStreamSeekable))
{ {
set_last_error(L"Failed opening file"); set_last_error("Failed opening file");
return false; return false;
} }
if (out_stream.write(comp_data.get_ptr(), comp_data.size()) != comp_data.size()) if (out_stream.write(comp_data.get_ptr(), comp_data.size()) != comp_data.size())
{ {
set_last_error(L"Failed writing to file"); set_last_error("Failed writing to file");
return false; return false;
} }
if (!out_stream.close()) if (!out_stream.close())
{ {
set_last_error(L"Failed writing to file"); set_last_error("Failed writing to file");
return false; return false;
} }
+78 -78
View File
@@ -15,7 +15,7 @@
namespace crnlib namespace crnlib
{ {
extern const vec2I g_vertical_cross_image_offsets[6]; extern const vec2I g_vertical_cross_image_offsets[6];
class mip_level class mip_level
{ {
friend class dds_texture; friend class dds_texture;
@@ -23,29 +23,29 @@ namespace crnlib
public: public:
mip_level(); mip_level();
~mip_level(); ~mip_level();
mip_level(const mip_level& other); mip_level(const mip_level& other);
mip_level& operator= (const mip_level& rhs); mip_level& operator= (const mip_level& rhs);
// Assumes ownership. // Assumes ownership.
void assign(image_u8* p, pixel_format fmt = PIXEL_FMT_INVALID); void assign(image_u8* p, pixel_format fmt = PIXEL_FMT_INVALID);
void assign(dxt_image* p, pixel_format fmt = PIXEL_FMT_INVALID); void assign(dxt_image* p, pixel_format fmt = PIXEL_FMT_INVALID);
void clear(); void clear();
inline uint get_width() const { return m_width; } inline uint get_width() const { return m_width; }
inline uint get_height() const { return m_height; } inline uint get_height() const { return m_height; }
inline uint get_total_pixels() const { return m_width * m_height; } inline uint get_total_pixels() const { return m_width * m_height; }
inline image_u8* get_image() const { return m_pImage; } inline image_u8* get_image() const { return m_pImage; }
inline dxt_image* get_dxt_image() const { return m_pDXTImage; } inline dxt_image* get_dxt_image() const { return m_pDXTImage; }
image_u8* get_unpacked_image(image_u8& tmp, bool uncook) const; image_u8* get_unpacked_image(image_u8& tmp, bool uncook) const;
inline bool is_packed() const { return m_pDXTImage != NULL; } inline bool is_packed() const { return m_pDXTImage != NULL; }
inline bool is_valid() const { return (m_pImage != NULL) || (m_pDXTImage != NULL); } inline bool is_valid() const { return (m_pImage != NULL) || (m_pDXTImage != NULL); }
inline pixel_format_helpers::component_flags get_comp_flags() const { return m_comp_flags; } inline pixel_format_helpers::component_flags get_comp_flags() const { return m_comp_flags; }
inline void set_comp_flags(pixel_format_helpers::component_flags comp_flags) { m_comp_flags = comp_flags; } inline void set_comp_flags(pixel_format_helpers::component_flags comp_flags) { m_comp_flags = comp_flags; }
@@ -53,35 +53,35 @@ namespace crnlib
inline void set_format(pixel_format fmt) { m_format = fmt; } inline void set_format(pixel_format fmt) { m_format = fmt; }
bool convert(pixel_format fmt, bool cook, const dxt_image::pack_params& p); bool convert(pixel_format fmt, bool cook, const dxt_image::pack_params& p);
bool pack_to_dxt(const image_u8& img, pixel_format fmt, bool cook, const dxt_image::pack_params& p); bool pack_to_dxt(const image_u8& img, pixel_format fmt, bool cook, const dxt_image::pack_params& p);
bool pack_to_dxt(pixel_format fmt, bool cook, const dxt_image::pack_params& p); bool pack_to_dxt(pixel_format fmt, bool cook, const dxt_image::pack_params& p);
bool unpack_from_dxt(bool uncook = true); bool unpack_from_dxt(bool uncook = true);
bool set_alpha_to_luma(); bool set_alpha_to_luma();
bool convert(image_utils::conversion_type conv_type); bool convert(image_utils::conversion_type conv_type);
private: private:
uint m_width; uint m_width;
uint m_height; uint m_height;
pixel_format_helpers::component_flags m_comp_flags; pixel_format_helpers::component_flags m_comp_flags;
pixel_format m_format; pixel_format m_format;
image_u8* m_pImage; image_u8* m_pImage;
dxt_image* m_pDXTImage; dxt_image* m_pDXTImage;
void cook_image(image_u8& img) const; void cook_image(image_u8& img) const;
void uncook_image(image_u8& img) const; void uncook_image(image_u8& img) const;
}; };
// A face is an array of mip_level ptr's. // A face is an array of mip_level ptr's.
typedef crnlib::vector<mip_level*> mip_ptr_vec; typedef crnlib::vector<mip_level*> mip_ptr_vec;
// And an array of one, six, or N faces make up a texture. // And an array of one, six, or N faces make up a texture.
typedef crnlib::vector<mip_ptr_vec> face_vec; typedef crnlib::vector<mip_ptr_vec> face_vec;
class dds_texture class dds_texture
{ {
public: public:
@@ -93,8 +93,8 @@ namespace crnlib
dds_texture& operator= (const dds_texture& rhs); dds_texture& operator= (const dds_texture& rhs);
void clear(); void clear();
void init(uint width, uint height, uint levels, uint faces, pixel_format fmt, const wchar_t* pName); void init(uint width, uint height, uint levels, uint faces, pixel_format fmt, const char* pName);
// Assumes ownership. // Assumes ownership.
void assign(face_vec& faces); void assign(face_vec& faces);
@@ -109,10 +109,10 @@ namespace crnlib
inline bool is_valid() const { return m_faces.size() > 0; } inline bool is_valid() const { return m_faces.size() > 0; }
const dynamic_wstring& get_name() const { return m_name; } const dynamic_string& get_name() const { return m_name; }
void set_name(const dynamic_wstring& name) { m_name = name; } void set_name(const dynamic_string& name) { m_name = name; }
const dynamic_wstring& get_source_filename() const { return get_name(); } const dynamic_string& get_source_filename() const { return get_name(); }
texture_file_types::format get_source_file_type() const { return m_source_file_type; } texture_file_types::format get_source_file_type() const { return m_source_file_type; }
inline uint get_width() const { return m_width; } inline uint get_width() const { return m_width; }
@@ -133,34 +133,34 @@ namespace crnlib
inline const mip_level* get_level(uint face, uint mip) const { return m_faces[face][mip]; } inline const mip_level* get_level(uint face, uint mip) const { return m_faces[face][mip]; }
inline mip_level* get_level(uint face, uint mip) { return m_faces[face][mip]; } inline mip_level* get_level(uint face, uint mip) { return m_faces[face][mip]; }
bool has_alpha() const; bool has_alpha() const;
bool is_normal_map() const; bool is_normal_map() const;
bool is_vertical_cross() const; bool is_vertical_cross() const;
bool is_packed() const; bool is_packed() const;
texture_type determine_texture_type() const; texture_type determine_texture_type() const;
const dynamic_wstring& get_last_error() const { return m_last_error; } const dynamic_string& get_last_error() const { return m_last_error; }
void clear_last_error() { m_last_error.clear(); } void clear_last_error() { m_last_error.clear(); }
// Loading/saving // Loading/saving
bool read_dds(const wchar_t* pFilename); bool read_dds(const char* pFilename);
bool read_dds(data_stream_serializer& serializer); bool read_dds(data_stream_serializer& serializer);
bool write_dds(const wchar_t* pFilename) const; bool write_dds(const char* pFilename) const;
bool write_dds(data_stream_serializer& serializer) const; bool write_dds(data_stream_serializer& serializer) const;
bool load_crn_from_memory(const wchar_t* pFilename, const void *pData, uint data_size); bool load_crn_from_memory(const char* pFilename, const void *pData, uint data_size);
// If file_format is texture_file_types::cFormatInvalid, the format will be determined from the filename's extension. // If file_format is texture_file_types::cFormatInvalid, the format will be determined from the filename's extension.
bool load_from_file(const wchar_t* pFilename, texture_file_types::format file_format); bool load_from_file(const char* pFilename, texture_file_types::format file_format);
bool write_to_file( bool write_to_file(
const wchar_t* pFilename, const char* pFilename,
texture_file_types::format file_format, texture_file_types::format file_format,
crn_comp_params* pCRN_comp_params, crn_comp_params* pCRN_comp_params,
uint32 *pActual_quality_level, float *pActual_bitrate); uint32 *pActual_quality_level, float *pActual_bitrate);
// Conversion // Conversion
bool convert(pixel_format fmt, bool cook, const dxt_image::pack_params& p); bool convert(pixel_format fmt, bool cook, const dxt_image::pack_params& p);
bool convert(pixel_format fmt, const dxt_image::pack_params& p); bool convert(pixel_format fmt, const dxt_image::pack_params& p);
@@ -168,16 +168,16 @@ namespace crnlib
bool convert(image_utils::conversion_type conv_type); bool convert(image_utils::conversion_type conv_type);
bool unpack_from_dxt(bool uncook = true); bool unpack_from_dxt(bool uncook = true);
bool set_alpha_to_luma(); bool set_alpha_to_luma();
void discard_mipmaps(); void discard_mipmaps();
void discard_mips(); void discard_mips();
struct resample_params struct resample_params
{ {
resample_params() : resample_params() :
m_pFilter("kaiser"), m_pFilter("kaiser"),
m_wrapping(false), m_wrapping(false),
m_srgb(false), m_srgb(false),
@@ -186,8 +186,8 @@ namespace crnlib
m_gamma(1.75f), // or 2.2f m_gamma(1.75f), // or 2.2f
m_multithreaded(true) m_multithreaded(true)
{ {
} }
const char* m_pFilter; const char* m_pFilter;
bool m_wrapping; bool m_wrapping;
bool m_srgb; bool m_srgb;
@@ -196,45 +196,45 @@ namespace crnlib
float m_gamma; float m_gamma;
bool m_multithreaded; bool m_multithreaded;
}; };
bool resize(uint new_width, uint new_height, const resample_params& params); bool resize(uint new_width, uint new_height, const resample_params& params);
struct generate_mipmap_params : public resample_params struct generate_mipmap_params : public resample_params
{ {
generate_mipmap_params() : generate_mipmap_params() :
resample_params(), resample_params(),
m_min_mip_size(1), m_min_mip_size(1),
m_max_mips(0) m_max_mips(0)
{ {
} }
uint m_min_mip_size; uint m_min_mip_size;
uint m_max_mips; // actually the max # of total levels uint m_max_mips; // actually the max # of total levels
}; };
bool generate_mipmaps(const generate_mipmap_params& params, bool force); bool generate_mipmaps(const generate_mipmap_params& params, bool force);
bool crop(uint x, uint y, uint width, uint height); bool crop(uint x, uint y, uint width, uint height);
bool vertical_cross_to_cubemap(); bool vertical_cross_to_cubemap();
// Low-level clustered DXT (QDXT) compression // Low-level clustered DXT (QDXT) compression
struct qdxt_state struct qdxt_state
{ {
qdxt_state(task_pool& tp) : m_fmt(PIXEL_FMT_INVALID), m_qdxt1(tp), m_qdxt5a(tp), m_qdxt5b(tp) qdxt_state(task_pool& tp) : m_fmt(PIXEL_FMT_INVALID), m_qdxt1(tp), m_qdxt5a(tp), m_qdxt5b(tp)
{ {
} }
pixel_format m_fmt; pixel_format m_fmt;
qdxt1 m_qdxt1; qdxt1 m_qdxt1;
qdxt5 m_qdxt5a; qdxt5 m_qdxt5a;
qdxt5 m_qdxt5b; qdxt5 m_qdxt5b;
crnlib::vector<dxt_pixel_block> m_pixel_blocks; crnlib::vector<dxt_pixel_block> m_pixel_blocks;
qdxt1_params m_qdxt1_params; qdxt1_params m_qdxt1_params;
qdxt5_params m_qdxt5_params[2]; qdxt5_params m_qdxt5_params[2];
bool m_has_blocks[3]; bool m_has_blocks[3];
void clear() void clear()
{ {
m_fmt = PIXEL_FMT_INVALID; m_fmt = PIXEL_FMT_INVALID;
@@ -250,43 +250,43 @@ namespace crnlib
}; };
bool qdxt_pack_init(qdxt_state& state, dds_texture& dst_tex, const qdxt1_params& dxt1_params, const qdxt5_params& dxt5_params, pixel_format fmt, bool cook); bool qdxt_pack_init(qdxt_state& state, dds_texture& dst_tex, const qdxt1_params& dxt1_params, const qdxt5_params& dxt5_params, pixel_format fmt, bool cook);
bool qdxt_pack(qdxt_state& state, dds_texture& dst_tex, const qdxt1_params& dxt1_params, const qdxt5_params& dxt5_params); bool qdxt_pack(qdxt_state& state, dds_texture& dst_tex, const qdxt1_params& dxt1_params, const qdxt5_params& dxt5_params);
void swap(dds_texture& img); void swap(dds_texture& img);
bool check() const; bool check() const;
private: private:
dynamic_wstring m_name; dynamic_string m_name;
uint m_width; uint m_width;
uint m_height; uint m_height;
pixel_format_helpers::component_flags m_comp_flags; pixel_format_helpers::component_flags m_comp_flags;
pixel_format m_format; pixel_format m_format;
face_vec m_faces; face_vec m_faces;
texture_file_types::format m_source_file_type; texture_file_types::format m_source_file_type;
mutable dynamic_wstring m_last_error; mutable dynamic_string m_last_error;
inline void clear_last_error() const { m_last_error.clear(); } inline void clear_last_error() const { m_last_error.clear(); }
inline void set_last_error(const wchar_t* p) const { m_last_error = p; } inline void set_last_error(const char* p) const { m_last_error = p; }
void free_all_mips(); void free_all_mips();
bool read_dds_internal(data_stream_serializer& serializer); bool read_dds_internal(data_stream_serializer& serializer);
bool load_regular(const wchar_t* pFilename, texture_file_types::format file_format); bool load_regular(const char* pFilename, texture_file_types::format file_format);
bool load_dds(const wchar_t* pFilename); bool load_dds(const char* pFilename);
bool load_crn(const wchar_t* pFilename); bool load_crn(const char* pFilename);
void print_crn_comp_params(const crn_comp_params& p); void print_crn_comp_params(const crn_comp_params& p);
bool save_regular(const wchar_t* pFilename); bool save_regular(const char* pFilename);
bool save_dds(const wchar_t* pFilename); bool save_dds(const char* pFilename);
bool save_comp_texture(const wchar_t* pFilename, const crn_comp_params &comp_params, uint32 *pActual_quality_level, float *pActual_bitrate); bool save_comp_texture(const char* pFilename, const crn_comp_params &comp_params, uint32 *pActual_quality_level, float *pActual_bitrate);
}; };
inline void swap(dds_texture& a, dds_texture& b) inline void swap(dds_texture& a, dds_texture& b)
{ {
a.swap(b); a.swap(b);
} }
} // namespace crnlib } // namespace crnlib
+19 -16
View File
@@ -11,43 +11,46 @@ namespace crnlib
{ {
const uint8 g_dxt5_from_linear[cDXT5SelectorValues] = { 0U, 2U, 3U, 4U, 5U, 6U, 7U, 1U }; const uint8 g_dxt5_from_linear[cDXT5SelectorValues] = { 0U, 2U, 3U, 4U, 5U, 6U, 7U, 1U };
const uint8 g_dxt5_to_linear[cDXT5SelectorValues] = { 0U, 7U, 1U, 2U, 3U, 4U, 5U, 6U }; const uint8 g_dxt5_to_linear[cDXT5SelectorValues] = { 0U, 7U, 1U, 2U, 3U, 4U, 5U, 6U };
const uint8 g_dxt5_alpha6_to_linear[cDXT5SelectorValues] = { 0U, 5U, 1U, 2U, 3U, 4U, 0U, 0U }; const uint8 g_dxt5_alpha6_to_linear[cDXT5SelectorValues] = { 0U, 5U, 1U, 2U, 3U, 4U, 0U, 0U };
const uint8 g_dxt1_from_linear[cDXT1SelectorValues] = { 0U, 2U, 3U, 1U }; const uint8 g_dxt1_from_linear[cDXT1SelectorValues] = { 0U, 2U, 3U, 1U };
const uint8 g_dxt1_to_linear[cDXT1SelectorValues] = { 0U, 3U, 1U, 2U }; const uint8 g_dxt1_to_linear[cDXT1SelectorValues] = { 0U, 3U, 1U, 2U };
const uint8 g_six_alpha_invert_table[cDXT5SelectorValues] = { 1, 0, 5, 4, 3, 2, 6, 7 }; const uint8 g_six_alpha_invert_table[cDXT5SelectorValues] = { 1, 0, 5, 4, 3, 2, 6, 7 };
const uint8 g_eight_alpha_invert_table[cDXT5SelectorValues] = { 1, 0, 7, 6, 5, 4, 3, 2 }; const uint8 g_eight_alpha_invert_table[cDXT5SelectorValues] = { 1, 0, 7, 6, 5, 4, 3, 2 };
const wchar_t* get_dxt_format_string(dxt_format fmt) const char* get_dxt_format_string(dxt_format fmt)
{ {
switch (fmt) switch (fmt)
{ {
case cDXT1: return L"DXT1"; case cDXT1: return "DXT1";
case cDXT1A: return L"DXT1A"; case cDXT1A: return "DXT1A";
case cDXT3: return L"DXT3"; case cDXT3: return "DXT3";
case cDXT5: return L"DXT5"; case cDXT5: return "DXT5";
case cDXT5A: return L"DXT5A"; case cDXT5A: return "DXT5A";
case cDXN_XY: return L"DXN_XY"; case cDXN_XY: return "DXN_XY";
case cDXN_YX: return L"DXN_YX"; case cDXN_YX: return "DXN_YX";
default: break; default: break;
} }
CRNLIB_ASSERT(false); CRNLIB_ASSERT(false);
return L"?"; return "?";
} }
const wchar_t* get_dxt_compressor_name(crn_dxt_compressor_type c) const char* get_dxt_compressor_name(crn_dxt_compressor_type c)
{ {
switch (c) switch (c)
{ {
case cCRNDXTCompressorCRN: return L"CRN"; case cCRNDXTCompressorCRN: return "CRN";
case cCRNDXTCompressorCRNF: return L"CRNF"; case cCRNDXTCompressorCRNF: return "CRNF";
case cCRNDXTCompressorRYG: return L"RYG"; case cCRNDXTCompressorRYG: return "RYG";
#if CRNLIB_SUPPORT_ATI_COMPRESS
case cCRNDXTCompressorATI: return "ATI";
#endif
default: break; default: break;
} }
CRNLIB_ASSERT(false); CRNLIB_ASSERT(false);
return L"?"; return "?";
} }
uint get_dxt_format_bits_per_pixel(dxt_format fmt) uint get_dxt_format_bits_per_pixel(dxt_format fmt)
+58 -58
View File
@@ -1,6 +1,6 @@
// File: crn_dxt.h // File: crn_dxt.h
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#pragma once #pragma once
#include "../inc/crnlib.h" #include "../inc/crnlib.h"
#include "crn_color.h" #include "crn_color.h"
#include "crn_vec.h" #include "crn_vec.h"
@@ -25,7 +25,7 @@ namespace crnlib
cDXT1SelectorBits = 2U, cDXT1SelectorBits = 2U,
cDXT1SelectorValues = 1U << cDXT1SelectorBits, cDXT1SelectorValues = 1U << cDXT1SelectorBits,
cDXT1SelectorMask = cDXT1SelectorValues - 1U, cDXT1SelectorMask = cDXT1SelectorValues - 1U,
cDXTBlockShift = 2U, cDXTBlockShift = 2U,
cDXTBlockSize = 1U << cDXTBlockShift cDXTBlockSize = 1U << cDXTBlockShift
}; };
@@ -33,28 +33,28 @@ namespace crnlib
enum dxt_format enum dxt_format
{ {
cDXTInvalid = -1, cDXTInvalid = -1,
// cDXT1/1A must appear first! // cDXT1/1A must appear first!
cDXT1, cDXT1,
cDXT1A, cDXT1A,
cDXT3, cDXT3,
cDXT5, cDXT5,
cDXT5A, cDXT5A,
cDXN_XY, // inverted relative to standard ATI2, 360's DXN cDXN_XY, // inverted relative to standard ATI2, 360's DXN
cDXN_YX // standard ATI2 cDXN_YX // standard ATI2
}; };
const float cDXT1MaxLinearValue = 3.0f; const float cDXT1MaxLinearValue = 3.0f;
const float cDXT1InvMaxLinearValue = 1.0f/3.0f; const float cDXT1InvMaxLinearValue = 1.0f/3.0f;
const float cDXT5MaxLinearValue = 7.0f; const float cDXT5MaxLinearValue = 7.0f;
const float cDXT5InvMaxLinearValue = 1.0f/7.0f; const float cDXT5InvMaxLinearValue = 1.0f/7.0f;
// Converts DXT1 raw color selector index to a linear value. // Converts DXT1 raw color selector index to a linear value.
extern const uint8 g_dxt1_to_linear[cDXT1SelectorValues]; extern const uint8 g_dxt1_to_linear[cDXT1SelectorValues];
// Converts DXT5 raw alpha selector index to a linear value. // Converts DXT5 raw alpha selector index to a linear value.
extern const uint8 g_dxt5_to_linear[cDXT5SelectorValues]; extern const uint8 g_dxt5_to_linear[cDXT5SelectorValues];
@@ -63,33 +63,33 @@ namespace crnlib
// Converts DXT5 linear alpha selector index to a raw value (inverse of g_dxt5_to_linear). // Converts DXT5 linear alpha selector index to a raw value (inverse of g_dxt5_to_linear).
extern const uint8 g_dxt5_from_linear[cDXT5SelectorValues]; extern const uint8 g_dxt5_from_linear[cDXT5SelectorValues];
extern const uint8 g_dxt5_alpha6_to_linear[cDXT5SelectorValues]; extern const uint8 g_dxt5_alpha6_to_linear[cDXT5SelectorValues];
extern const uint8 g_six_alpha_invert_table[cDXT5SelectorValues]; extern const uint8 g_six_alpha_invert_table[cDXT5SelectorValues];
extern const uint8 g_eight_alpha_invert_table[cDXT5SelectorValues]; extern const uint8 g_eight_alpha_invert_table[cDXT5SelectorValues];
const wchar_t* get_dxt_format_string(dxt_format fmt); const char* get_dxt_format_string(dxt_format fmt);
uint get_dxt_format_bits_per_pixel(dxt_format fmt); uint get_dxt_format_bits_per_pixel(dxt_format fmt);
bool get_dxt_format_has_alpha(dxt_format fmt); bool get_dxt_format_has_alpha(dxt_format fmt);
const wchar_t* get_dxt_quality_string(crn_dxt_quality q); const char* get_dxt_quality_string(crn_dxt_quality q);
const wchar_t* get_dxt_compressor_name(crn_dxt_compressor_type c); const char* get_dxt_compressor_name(crn_dxt_compressor_type c);
struct dxt1_block struct dxt1_block
{ {
uint8 m_low_color[2]; uint8 m_low_color[2];
uint8 m_high_color[2]; uint8 m_high_color[2];
enum { cNumSelectorBytes = 4 }; enum { cNumSelectorBytes = 4 };
uint8 m_selectors[cNumSelectorBytes]; uint8 m_selectors[cNumSelectorBytes];
inline void clear() inline void clear()
{ {
utils::zero_this(this); utils::zero_this(this);
} }
// These methods assume the in-memory rep is in LE byte order. // These methods assume the in-memory rep is in LE byte order.
inline uint get_low_color() const inline uint get_low_color() const
{ {
@@ -100,73 +100,73 @@ namespace crnlib
{ {
return m_high_color[0] | (m_high_color[1] << 8U); return m_high_color[0] | (m_high_color[1] << 8U);
} }
inline void set_low_color(uint16 c) inline void set_low_color(uint16 c)
{ {
m_low_color[0] = static_cast<uint8>(c & 0xFF); m_low_color[0] = static_cast<uint8>(c & 0xFF);
m_low_color[1] = static_cast<uint8>((c >> 8) & 0xFF); m_low_color[1] = static_cast<uint8>((c >> 8) & 0xFF);
} }
inline void set_high_color(uint16 c) inline void set_high_color(uint16 c)
{ {
m_high_color[0] = static_cast<uint8>(c & 0xFF); m_high_color[0] = static_cast<uint8>(c & 0xFF);
m_high_color[1] = static_cast<uint8>((c >> 8) & 0xFF); m_high_color[1] = static_cast<uint8>((c >> 8) & 0xFF);
} }
inline bool is_constant_color_block() const { return get_low_color() == get_high_color(); } inline bool is_constant_color_block() const { return get_low_color() == get_high_color(); }
inline bool is_alpha_block() const { return get_low_color() <= get_high_color(); } inline bool is_alpha_block() const { return get_low_color() <= get_high_color(); }
inline bool is_non_alpha_block() const { return !is_alpha_block(); } inline bool is_non_alpha_block() const { return !is_alpha_block(); }
inline uint get_selector(uint x, uint y) const inline uint get_selector(uint x, uint y) const
{ {
CRNLIB_ASSERT((x < 4U) && (y < 4U)); CRNLIB_ASSERT((x < 4U) && (y < 4U));
return (m_selectors[y] >> (x * cDXT1SelectorBits)) & cDXT1SelectorMask; return (m_selectors[y] >> (x * cDXT1SelectorBits)) & cDXT1SelectorMask;
} }
inline void set_selector(uint x, uint y, uint val) inline void set_selector(uint x, uint y, uint val)
{ {
CRNLIB_ASSERT((x < 4U) && (y < 4U) && (val < 4U)); CRNLIB_ASSERT((x < 4U) && (y < 4U) && (val < 4U));
m_selectors[y] &= (~(cDXT1SelectorMask << (x * cDXT1SelectorBits))); m_selectors[y] &= (~(cDXT1SelectorMask << (x * cDXT1SelectorBits)));
m_selectors[y] |= (val << (x * cDXT1SelectorBits)); m_selectors[y] |= (val << (x * cDXT1SelectorBits));
} }
static uint16 pack_color(const color_quad_u8& color, bool scaled, uint bias = 127U); static uint16 pack_color(const color_quad_u8& color, bool scaled, uint bias = 127U);
static uint16 pack_color(uint r, uint g, uint b, bool scaled, uint bias = 127U); static uint16 pack_color(uint r, uint g, uint b, bool scaled, uint bias = 127U);
static color_quad_u8 unpack_color(uint16 packed_color, bool scaled, uint alpha = 255U); static color_quad_u8 unpack_color(uint16 packed_color, bool scaled, uint alpha = 255U);
static void unpack_color(uint& r, uint& g, uint& b, uint16 packed_color, bool scaled); static void unpack_color(uint& r, uint& g, uint& b, uint16 packed_color, bool scaled);
static uint get_block_colors3(color_quad_u8* pDst, uint16 color0, uint16 color1); static uint get_block_colors3(color_quad_u8* pDst, uint16 color0, uint16 color1);
static uint get_block_colors3_round(color_quad_u8* pDst, uint16 color0, uint16 color1); static uint get_block_colors3_round(color_quad_u8* pDst, uint16 color0, uint16 color1);
static uint get_block_colors4(color_quad_u8* pDst, uint16 color0, uint16 color1); static uint get_block_colors4(color_quad_u8* pDst, uint16 color0, uint16 color1);
static uint get_block_colors4_round(color_quad_u8* pDst, uint16 color0, uint16 color1); static uint get_block_colors4_round(color_quad_u8* pDst, uint16 color0, uint16 color1);
// pDst must point to an array at least cDXT1SelectorValues long. // pDst must point to an array at least cDXT1SelectorValues long.
static uint get_block_colors(color_quad_u8* pDst, uint16 color0, uint16 color1); static uint get_block_colors(color_quad_u8* pDst, uint16 color0, uint16 color1);
static uint get_block_colors_round(color_quad_u8* pDst, uint16 color0, uint16 color1); static uint get_block_colors_round(color_quad_u8* pDst, uint16 color0, uint16 color1);
static color_quad_u8 unpack_endpoint(uint32 endpoints, uint index, bool scaled, uint alpha = 255U); static color_quad_u8 unpack_endpoint(uint32 endpoints, uint index, bool scaled, uint alpha = 255U);
static uint pack_endpoints(uint lo, uint hi); static uint pack_endpoints(uint lo, uint hi);
static void get_block_colors_NV5x(color_quad_u8* pDst, uint16 packed_col0, uint16 packed_col1, bool color4); static void get_block_colors_NV5x(color_quad_u8* pDst, uint16 packed_col0, uint16 packed_col1, bool color4);
}; };
CRNLIB_DEFINE_BITWISE_COPYABLE(dxt1_block); CRNLIB_DEFINE_BITWISE_COPYABLE(dxt1_block);
struct dxt3_block struct dxt3_block
{ {
enum { cNumAlphaBytes = 8 }; enum { cNumAlphaBytes = 8 };
uint8 m_alpha[cNumAlphaBytes]; uint8 m_alpha[cNumAlphaBytes];
void set_alpha(uint x, uint y, uint value, bool scaled); void set_alpha(uint x, uint y, uint value, bool scaled);
uint get_alpha(uint x, uint y, bool scaled) const; uint get_alpha(uint x, uint y, bool scaled) const;
}; };
CRNLIB_DEFINE_BITWISE_COPYABLE(dxt3_block); CRNLIB_DEFINE_BITWISE_COPYABLE(dxt3_block);
struct dxt5_block struct dxt5_block
{ {
uint8 m_endpoints[2]; uint8 m_endpoints[2];
@@ -189,23 +189,23 @@ namespace crnlib
return m_endpoints[1]; return m_endpoints[1];
} }
inline void set_low_alpha(uint i) inline void set_low_alpha(uint i)
{ {
CRNLIB_ASSERT(i <= UINT8_MAX); CRNLIB_ASSERT(i <= cUINT8_MAX);
m_endpoints[0] = static_cast<uint8>(i); m_endpoints[0] = static_cast<uint8>(i);
} }
inline void set_high_alpha(uint i) inline void set_high_alpha(uint i)
{ {
CRNLIB_ASSERT(i <= UINT8_MAX); CRNLIB_ASSERT(i <= cUINT8_MAX);
m_endpoints[1] = static_cast<uint8>(i); m_endpoints[1] = static_cast<uint8>(i);
} }
inline bool is_alpha6_block() const { return get_low_alpha() <= get_high_alpha(); } inline bool is_alpha6_block() const { return get_low_alpha() <= get_high_alpha(); }
uint get_endpoints_as_word() const { return m_endpoints[0] | (m_endpoints[1] << 8); } uint get_endpoints_as_word() const { return m_endpoints[0] | (m_endpoints[1] << 8); }
uint get_selectors_as_word(uint index) { CRNLIB_ASSERT(index < 3); return m_selectors[index * 2] | (m_selectors[index * 2 + 1] << 8); } uint get_selectors_as_word(uint index) { CRNLIB_ASSERT(index < 3); return m_selectors[index * 2] | (m_selectors[index * 2 + 1] << 8); }
inline uint get_selector(uint x, uint y) const inline uint get_selector(uint x, uint y) const
{ {
CRNLIB_ASSERT((x < 4U) && (y < 4U)); CRNLIB_ASSERT((x < 4U) && (y < 4U));
@@ -244,7 +244,7 @@ namespace crnlib
if (byte_index < (cNumSelectorBytes - 1)) if (byte_index < (cNumSelectorBytes - 1))
m_selectors[byte_index + 1] = static_cast<uint8>(v >> 8); m_selectors[byte_index + 1] = static_cast<uint8>(v >> 8);
} }
enum { cMaxSelectorValues = 8 }; enum { cMaxSelectorValues = 8 };
// Results written to alpha channel. // Results written to alpha channel.
@@ -260,19 +260,19 @@ namespace crnlib
static uint unpack_endpoint(uint packed, uint index); static uint unpack_endpoint(uint packed, uint index);
static uint pack_endpoints(uint lo, uint hi); static uint pack_endpoints(uint lo, uint hi);
}; };
CRNLIB_DEFINE_BITWISE_COPYABLE(dxt5_block); CRNLIB_DEFINE_BITWISE_COPYABLE(dxt5_block);
struct dxt_pixel_block struct dxt_pixel_block
{ {
color_quad_u8 m_pixels[cDXTBlockSize][cDXTBlockSize]; // [y][x] color_quad_u8 m_pixels[cDXTBlockSize][cDXTBlockSize]; // [y][x]
inline void clear() inline void clear()
{ {
utils::zero_object(*this); utils::zero_object(*this);
} }
}; };
CRNLIB_DEFINE_BITWISE_COPYABLE(dxt_pixel_block); CRNLIB_DEFINE_BITWISE_COPYABLE(dxt_pixel_block);
} // namespace crnlib } // namespace crnlib
+270 -270
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -258,7 +258,7 @@ namespace crnlib
struct potential_solution struct potential_solution
{ {
potential_solution() : m_coords(), m_error(UINT64_MAX), m_alpha_block(false), m_valid(false) potential_solution() : m_coords(), m_error(cUINT64_MAX), m_alpha_block(false), m_valid(false)
{ {
} }
@@ -272,7 +272,7 @@ namespace crnlib
{ {
m_coords.clear(); m_coords.clear();
m_selectors.resize(0); m_selectors.resize(0);
m_error = UINT64_MAX; m_error = cUINT64_MAX;
m_alpha_block = false; m_alpha_block = false;
m_valid = false; m_valid = false;
} }
+1 -1
View File
@@ -62,7 +62,7 @@ namespace crnlib
m_trial_selectors.resize(m_unique_values.size()); m_trial_selectors.resize(m_unique_values.size());
m_best_selectors.resize(m_unique_values.size()); m_best_selectors.resize(m_unique_values.size());
r.m_error = UINT64_MAX; r.m_error = cUINT64_MAX;
for (uint i = 0; i < m_unique_values.size() - 1; i++) for (uint i = 0; i < m_unique_values.size() - 1; i++)
{ {
+1 -1
View File
@@ -20,7 +20,7 @@ namespace crnlib
m_pParams = &p; m_pParams = &p;
m_pResults = &r; m_pResults = &r;
r.m_error = UINT64_MAX; r.m_error = cUINT64_MAX;
r.m_low_color = 0; r.m_low_color = 0;
r.m_high_color = 0; r.m_high_color = 0;
+1 -1
View File
@@ -19,7 +19,7 @@ namespace crnlib
m_num_pixels(0), m_num_pixels(0),
m_pSelectors(NULL), m_pSelectors(NULL),
m_alpha_comp_index(0), m_alpha_comp_index(0),
m_error_to_beat(UINT64_MAX), m_error_to_beat(cUINT64_MAX),
m_dxt1_selectors(true), m_dxt1_selectors(true),
m_perceptual(true), m_perceptual(true),
m_highest_quality(true) m_highest_quality(true)
+2 -2
View File
@@ -507,7 +507,7 @@ namespace crnlib
static void refine_endpoints2(uint n, const color_quad_u8* pBlock, uint& low16, uint& high16, uint8* pSelectors, float axis[3]) static void refine_endpoints2(uint n, const color_quad_u8* pBlock, uint& low16, uint& high16, uint8* pSelectors, float axis[3])
{ {
uint64 orig_error = determine_error(n, pBlock, low16, high16, UINT64_MAX); uint64 orig_error = determine_error(n, pBlock, low16, high16, cUINT64_MAX);
if (!orig_error) if (!orig_error)
return; return;
@@ -623,7 +623,7 @@ namespace crnlib
{ {
improved = true; improved = true;
uint64 cur_error = determine_error(n, pBlock, low16, high16, UINT64_MAX); uint64 cur_error = determine_error(n, pBlock, low16, high16, cUINT64_MAX);
if (!cur_error) if (!cur_error)
return; return;
} }
+40 -40
View File
@@ -33,7 +33,7 @@ namespace crnlib
m_has_color_blocks(false), m_has_color_blocks(false),
m_has_alpha0_blocks(false), m_has_alpha0_blocks(false),
m_has_alpha1_blocks(false), m_has_alpha1_blocks(false),
m_main_thread_id(get_current_thread_id()), m_main_thread_id(crn_get_current_thread_id()),
m_canceled(false), m_canceled(false),
m_pTask_pool(NULL), m_pTask_pool(NULL),
m_prev_phase_index(-1), m_prev_phase_index(-1),
@@ -104,7 +104,7 @@ namespace crnlib
bool dxt_hc::compress(const params& p, uint num_chunks, const pixel_chunk* pChunks, task_pool& task_pool) bool dxt_hc::compress(const params& p, uint num_chunks, const pixel_chunk* pChunks, task_pool& task_pool)
{ {
m_pTask_pool = &task_pool; m_pTask_pool = &task_pool;
m_main_thread_id = get_current_thread_id(); m_main_thread_id = crn_get_current_thread_id();
bool result = compress_internal(p, num_chunks, pChunks); bool result = compress_internal(p, num_chunks, pChunks);
@@ -335,7 +335,7 @@ namespace crnlib
if (m_canceled) if (m_canceled)
return; return;
if ((get_current_thread_id() == m_main_thread_id) && ((chunk_index & 511) == 0)) if ((crn_get_current_thread_id() == m_main_thread_id) && ((chunk_index & 511) == 0))
{ {
if (!update_progress(0, chunk_index, m_num_chunks)) if (!update_progress(0, chunk_index, m_num_chunks))
return; return;
@@ -550,9 +550,9 @@ namespace crnlib
} }
} }
interlocked_increment32(&m_encoding_hist[best_encoding]); atomic_increment32(&m_encoding_hist[best_encoding]);
interlocked_exchange_add32(&m_total_tiles, g_chunk_encodings[best_encoding].m_num_tiles); atomic_exchange_add32(&m_total_tiles, g_chunk_encodings[best_encoding].m_num_tiles);
for (uint q = 0; q < cNumCompressedChunkVecs; q++) for (uint q = 0; q < cNumCompressedChunkVecs; q++)
{ {
@@ -664,15 +664,15 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
{ {
console::info(L"Total Pixels: %u, Chunks: %u, Blocks: %u, Adapted Tiles: %u", m_num_chunks * cChunkPixelWidth * cChunkPixelHeight, m_num_chunks, m_num_chunks * cChunkBlockWidth * cChunkBlockHeight, m_total_tiles); console::info("Total Pixels: %u, Chunks: %u, Blocks: %u, Adapted Tiles: %u", m_num_chunks * cChunkPixelWidth * cChunkPixelHeight, m_num_chunks, m_num_chunks * cChunkBlockWidth * cChunkBlockHeight, m_total_tiles);
console::info(L"Chunk encoding type symbol_histogram: "); console::info("Chunk encoding type symbol_histogram: ");
for (uint e = 0; e < cNumChunkEncodings; e++) for (uint e = 0; e < cNumChunkEncodings; e++)
console::info(L"%u ", m_encoding_hist[e]); console::info("%u ", m_encoding_hist[e]);
console::info(L"Blocks per chunk encoding type: "); console::info("Blocks per chunk encoding type: ");
for (uint e = 0; e < cNumChunkEncodings; e++) for (uint e = 0; e < cNumChunkEncodings; e++)
console::info(L"%u ", m_encoding_hist[e] * cChunkBlockWidth * cChunkBlockHeight); console::info("%u ", m_encoding_hist[e] * cChunkBlockWidth * cChunkBlockHeight);
} }
#endif #endif
@@ -689,7 +689,7 @@ namespace crnlib
if (m_canceled) if (m_canceled)
return; return;
if ((get_current_thread_id() == m_main_thread_id) && ((chunk_index & 63) == 0)) if ((crn_get_current_thread_id() == m_main_thread_id) && ((chunk_index & 63) == 0))
{ {
if (!update_progress(2, chunk_index, m_num_chunks)) if (!update_progress(2, chunk_index, m_num_chunks))
return; return;
@@ -719,7 +719,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Generating color training vectors"); console::info("Generating color training vectors");
#endif #endif
const float r_scale = .5f; const float r_scale = .5f;
@@ -804,7 +804,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Begin color cluster analysis"); console::info("Begin color cluster analysis");
timer t; timer t;
t.start(); t.start();
#endif #endif
@@ -816,7 +816,7 @@ namespace crnlib
if (m_params.m_debugging) if (m_params.m_debugging)
{ {
double total_time = t.get_elapsed_secs(); double total_time = t.get_elapsed_secs();
console::info(L"Codebook gen time: %3.3fs, Total color clusters: %u", total_time, vq.get_codebook_size()); console::info("Codebook gen time: %3.3fs, Total color clusters: %u", total_time, vq.get_codebook_size());
} }
#endif #endif
@@ -824,7 +824,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Begin color cluster assignment"); console::info("Begin color cluster assignment");
#endif #endif
assign_color_endpoint_clusters_state state(vq, training_vecs); assign_color_endpoint_clusters_state state(vq, training_vecs);
@@ -850,7 +850,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Completed color cluster assignment"); console::info("Completed color cluster assignment");
#endif #endif
return true; return true;
@@ -868,7 +868,7 @@ namespace crnlib
if (m_canceled) if (m_canceled)
return; return;
if ((get_current_thread_id() == m_main_thread_id) && ((chunk_index & 63) == 0)) if ((crn_get_current_thread_id() == m_main_thread_id) && ((chunk_index & 63) == 0))
{ {
if (!update_progress(7, m_num_chunks * a + chunk_index, m_num_chunks * m_num_alpha_blocks)) if (!update_progress(7, m_num_chunks * a + chunk_index, m_num_chunks * m_num_alpha_blocks))
return; return;
@@ -899,7 +899,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Generating alpha training vectors"); console::info("Generating alpha training vectors");
#endif #endif
determine_alpha_endpoint_clusters_state state; determine_alpha_endpoint_clusters_state state;
@@ -966,7 +966,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Begin alpha cluster analysis"); console::info("Begin alpha cluster analysis");
timer t; timer t;
t.start(); t.start();
#endif #endif
@@ -978,7 +978,7 @@ namespace crnlib
if (m_params.m_debugging) if (m_params.m_debugging)
{ {
double total_time = t.get_elapsed_secs(); double total_time = t.get_elapsed_secs();
console::info(L"Codebook gen time: %3.3fs, Total alpha clusters: %u", total_time, state.m_vq.get_codebook_size()); console::info("Codebook gen time: %3.3fs, Total alpha clusters: %u", total_time, state.m_vq.get_codebook_size());
} }
#endif #endif
@@ -986,7 +986,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Begin alpha cluster assignment"); console::info("Begin alpha cluster assignment");
#endif #endif
for (uint i = 0; i <= m_pTask_pool->get_num_threads(); i++) for (uint i = 0; i <= m_pTask_pool->get_num_threads(); i++)
@@ -1013,7 +1013,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Completed alpha cluster assignment"); console::info("Completed alpha cluster assignment");
#endif #endif
return true; return true;
@@ -1040,7 +1040,7 @@ namespace crnlib
if (m_canceled) if (m_canceled)
return; return;
if ((get_current_thread_id() == m_main_thread_id) && ((cluster_index & 63) == 0)) if ((crn_get_current_thread_id() == m_main_thread_id) && ((cluster_index & 63) == 0))
{ {
if (!update_progress(3, cluster_index, m_color_clusters.size())) if (!update_progress(3, cluster_index, m_color_clusters.size()))
return; return;
@@ -1151,7 +1151,7 @@ namespace crnlib
if (m_params.m_debugging) if (m_params.m_debugging)
{ {
if (total_empty_clusters) if (total_empty_clusters)
console::warning(L"Total empty color clusters: %u", total_empty_clusters); console::warning("Total empty color clusters: %u", total_empty_clusters);
} }
#endif #endif
} }
@@ -1163,7 +1163,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Computing optimal color cluster endpoints"); console::info("Computing optimal color cluster endpoints");
#endif #endif
for (uint i = 0; i <= m_pTask_pool->get_num_threads(); i++) for (uint i = 0; i <= m_pTask_pool->get_num_threads(); i++)
@@ -1192,7 +1192,7 @@ namespace crnlib
if (m_canceled) if (m_canceled)
return; return;
if ((get_current_thread_id() == m_main_thread_id) && ((cluster_index & 63) == 0)) if ((crn_get_current_thread_id() == m_main_thread_id) && ((cluster_index & 63) == 0))
{ {
if (!update_progress(8, cluster_index, m_alpha_clusters.size())) if (!update_progress(8, cluster_index, m_alpha_clusters.size()))
return; return;
@@ -1311,7 +1311,7 @@ namespace crnlib
if (m_params.m_debugging) if (m_params.m_debugging)
{ {
if (total_empty_clusters) if (total_empty_clusters)
console::warning(L"Total empty alpha clusters: %u", total_empty_clusters); console::warning("Total empty alpha clusters: %u", total_empty_clusters);
} }
#endif #endif
} }
@@ -1323,7 +1323,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Computing optimal alpha cluster endpoints"); console::info("Computing optimal alpha cluster endpoints");
#endif #endif
for (uint i = 0; i <= m_pTask_pool->get_num_threads(); i++) for (uint i = 0; i <= m_pTask_pool->get_num_threads(); i++)
@@ -1461,7 +1461,7 @@ namespace crnlib
if (m_canceled) if (m_canceled)
return; return;
if ((get_current_thread_id() == m_main_thread_id) && ((chunk_index & 127) == 0)) if ((crn_get_current_thread_id() == m_main_thread_id) && ((chunk_index & 127) == 0))
{ {
if (!update_progress(12 + comp_chunk_index, chunk_index, m_num_chunks)) if (!update_progress(12 + comp_chunk_index, chunk_index, m_num_chunks))
return; return;
@@ -1632,7 +1632,7 @@ namespace crnlib
{ {
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Computing selector training vectors"); console::info("Computing selector training vectors");
#endif #endif
const uint cColorDistToWeight = 2000; const uint cColorDistToWeight = 2000;
@@ -1775,7 +1775,7 @@ namespace crnlib
if (m_params.m_debugging) if (m_params.m_debugging)
{ {
double total_time = t.get_elapsed_secs(); double total_time = t.get_elapsed_secs();
console::info(L"Codebook gen time: %3.3fs, Selector codebook size: %u", total_time, selector_vq.get_codebook_size()); console::info("Codebook gen time: %3.3fs, Selector codebook size: %u", total_time, selector_vq.get_codebook_size());
} }
#endif #endif
@@ -1827,7 +1827,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Refining quantized color selectors"); console::info("Refining quantized color selectors");
#endif #endif
uint total_refined_selectors = 0; uint total_refined_selectors = 0;
@@ -1917,7 +1917,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Total refined pixels: %u, selectors: %u out of %u", total_refined_pixels, total_refined_selectors, total_selectors); console::info("Total refined pixels: %u, selectors: %u out of %u", total_refined_pixels, total_refined_selectors, total_selectors);
#endif #endif
return true; return true;
@@ -1930,7 +1930,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Refining quantized alpha selectors"); console::info("Refining quantized alpha selectors");
#endif #endif
uint total_refined_selectors = 0; uint total_refined_selectors = 0;
@@ -2021,7 +2021,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Total refined pixels: %u, selectors: %u out of %u", total_refined_pixels, total_refined_selectors, total_selectors); console::info("Total refined pixels: %u, selectors: %u out of %u", total_refined_pixels, total_refined_selectors, total_selectors);
#endif #endif
return true; return true;
@@ -2037,7 +2037,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Refining quantized color endpoints"); console::info("Refining quantized color endpoints");
#endif #endif
for (uint cluster_index = 0; cluster_index < m_color_clusters.size(); cluster_index++) for (uint cluster_index = 0; cluster_index < m_color_clusters.size(); cluster_index++)
@@ -2138,7 +2138,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Total refined pixels: %u, endpoints: %u out of %u", total_refined_pixels, total_refined_tiles, m_color_clusters.size()); console::info("Total refined pixels: %u, endpoints: %u out of %u", total_refined_pixels, total_refined_tiles, m_color_clusters.size());
#endif #endif
return true; return true;
@@ -2153,7 +2153,7 @@ namespace crnlib
uint total_refined_pixels = 0; uint total_refined_pixels = 0;
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Refining quantized alpha endpoints"); console::info("Refining quantized alpha endpoints");
#endif #endif
for (uint cluster_index = 0; cluster_index < m_alpha_clusters.size(); cluster_index++) for (uint cluster_index = 0; cluster_index < m_alpha_clusters.size(); cluster_index++)
@@ -2257,7 +2257,7 @@ namespace crnlib
#if CRNLIB_ENABLE_DEBUG_MESSAGES #if CRNLIB_ENABLE_DEBUG_MESSAGES
if (m_params.m_debugging) if (m_params.m_debugging)
console::info(L"Total refined pixels: %u, endpoints: %u out of %u", total_refined_pixels, total_refined_tiles, m_alpha_clusters.size()); console::info("Total refined pixels: %u, endpoints: %u out of %u", total_refined_pixels, total_refined_tiles, m_alpha_clusters.size());
#endif #endif
return true; return true;
@@ -2515,7 +2515,7 @@ namespace crnlib
bool dxt_hc::update_progress(uint phase_index, uint subphase_index, uint subphase_total) bool dxt_hc::update_progress(uint phase_index, uint subphase_index, uint subphase_total)
{ {
CRNLIB_ASSERT(get_current_thread_id() == m_main_thread_id); CRNLIB_ASSERT(crn_get_current_thread_id() == m_main_thread_id);
if (!m_params.m_pProgress_func) if (!m_params.m_pProgress_func)
return true; return true;
+6 -7
View File
@@ -9,8 +9,7 @@
#include "crn_image.h" #include "crn_image.h"
#include "crn_dxt_hc_common.h" #include "crn_dxt_hc_common.h"
#include "crn_tree_clusterizer.h" #include "crn_tree_clusterizer.h"
#include "crn_task_pool.h" #include "crn_threading.h"
#include "crn_spinlock.h"
#define CRN_NO_FUNCTION_DEFINITIONS #define CRN_NO_FUNCTION_DEFINITIONS
#include "../inc/crnlib.h" #include "../inc/crnlib.h"
@@ -163,8 +162,8 @@ namespace crnlib
uint8 m_selectors[cBlockPixelHeight][cBlockPixelWidth]; uint8 m_selectors[cBlockPixelHeight][cBlockPixelWidth];
uint8 get_by_index(uint i) const { CRNLIB_ASSERT(i < (cBlockPixelWidth * cBlockPixelHeight)); return *(&m_selectors[0][0] + i); } uint8 get_by_index(uint i) const { CRNLIB_ASSERT(i < (cBlockPixelWidth * cBlockPixelHeight)); const uint8* p = (const uint8*)m_selectors; return *(p + i); }
void set_by_index(uint i, uint v) { CRNLIB_ASSERT(i < (cBlockPixelWidth * cBlockPixelHeight)); *(&m_selectors[0][0] + i) = static_cast<uint8>(v); } void set_by_index(uint i, uint v) { CRNLIB_ASSERT(i < (cBlockPixelWidth * cBlockPixelHeight)); uint8* p = (uint8*)m_selectors; *(p + i) = static_cast<uint8>(v); }
}; };
typedef crnlib::vector<selectors> selectors_vec; typedef crnlib::vector<selectors> selectors_vec;
@@ -272,9 +271,9 @@ namespace crnlib
}; };
compressed_chunk_vec m_compressed_chunks[cNumCompressedChunkVecs]; compressed_chunk_vec m_compressed_chunks[cNumCompressedChunkVecs];
int32 m_encoding_hist[cNumChunkEncodings]; volatile atomic32_t m_encoding_hist[cNumChunkEncodings];
int32 m_total_tiles; atomic32_t m_total_tiles;
void compress_dxt1_block( void compress_dxt1_block(
dxt1_endpoint_optimizer::results& results, dxt1_endpoint_optimizer::results& results,
@@ -350,7 +349,7 @@ namespace crnlib
pixel_chunk_vec m_dbg_chunk_pixels_final; pixel_chunk_vec m_dbg_chunk_pixels_final;
uint32 m_main_thread_id; crn_thread_id_t m_main_thread_id;
bool m_canceled; bool m_canceled;
task_pool* m_pTask_pool; task_pool* m_pTask_pool;
+9 -9
View File
@@ -7,8 +7,8 @@
#endif #endif
#include "crn_ryg_dxt.hpp" #include "crn_ryg_dxt.hpp"
#include "crn_dxt_fast.h" #include "crn_dxt_fast.h"
#include "crn_task_pool.h"
#include "crn_console.h" #include "crn_console.h"
#include "crn_threading.h"
#if CRNLIB_SUPPORT_ATI_COMPRESS #if CRNLIB_SUPPORT_ATI_COMPRESS
#ifdef _DLL #ifdef _DLL
@@ -216,8 +216,8 @@ namespace crnlib
dxt_format m_fmt; dxt_format m_fmt;
const image_u8* m_pImg; const image_u8* m_pImg;
const dxt_image::pack_params* m_pParams; const dxt_image::pack_params* m_pParams;
uint32 m_main_thread; crn_thread_id_t m_main_thread;
int32 m_canceled; atomic32_t m_canceled;
}; };
void dxt_image::init_task(uint64 data, void* pData_ptr) void dxt_image::init_task(uint64 data, void* pData_ptr)
@@ -227,7 +227,7 @@ namespace crnlib
const image_u8& img = *pInit_params->m_pImg; const image_u8& img = *pInit_params->m_pImg;
const pack_params& p = *pInit_params->m_pParams; const pack_params& p = *pInit_params->m_pParams;
const bool is_main_thread = (get_current_thread_id() == pInit_params->m_main_thread); const bool is_main_thread = (crn_get_current_thread_id() == pInit_params->m_main_thread);
uint block_index = 0; uint block_index = 0;
@@ -252,7 +252,7 @@ namespace crnlib
prev_progress_percentage = progress_percentage; prev_progress_percentage = progress_percentage;
if (!(p.m_pProgress_callback)(progress_percentage, p.m_pProgress_callback_user_data_ptr)) if (!(p.m_pProgress_callback)(progress_percentage, p.m_pProgress_callback_user_data_ptr))
{ {
interlocked_exchange32(&pInit_params->m_canceled, CRNLIB_TRUE); atomic_exchange32(&pInit_params->m_canceled, CRNLIB_TRUE);
return; return;
} }
} }
@@ -351,7 +351,7 @@ namespace crnlib
if (fmt == cDXT1A) if (fmt == cDXT1A)
{ {
options.bDXT1UseAlpha = TRUE; options.bDXT1UseAlpha = true;
options.nAlphaThreshold = (ATI_TC_BYTE)p.m_dxt1a_alpha_threshold; options.nAlphaThreshold = (ATI_TC_BYTE)p.m_dxt1a_alpha_threshold;
} }
options.bDisableMultiThreading = (p.m_num_helper_threads == 0); options.bDisableMultiThreading = (p.m_num_helper_threads == 0);
@@ -370,7 +370,7 @@ namespace crnlib
if (p.m_perceptual) if (p.m_perceptual)
{ {
options.bUseChannelWeighting = TRUE; options.bUseChannelWeighting = true;
options.fWeightingRed = .212671f; options.fWeightingRed = .212671f;
options.fWeightingGreen = .715160f; options.fWeightingGreen = .715160f;
options.fWeightingBlue = .072169f; options.fWeightingBlue = .072169f;
@@ -405,7 +405,7 @@ namespace crnlib
init_params.m_fmt = fmt; init_params.m_fmt = fmt;
init_params.m_pImg = &img; init_params.m_pImg = &img;
init_params.m_pParams = &p; init_params.m_pParams = &p;
init_params.m_main_thread = get_current_thread_id(); init_params.m_main_thread = crn_get_current_thread_id();
init_params.m_canceled = false; init_params.m_canceled = false;
for (uint i = 0; i <= p.m_num_helper_threads; i++) for (uint i = 0; i <= p.m_num_helper_threads; i++)
@@ -1135,7 +1135,7 @@ namespace crnlib
int dxt_image::get_block_endpoints(uint block_x, uint block_y, uint element_index, color_quad_u8& low_endpoint, color_quad_u8& high_endpoint, bool scaled) const int dxt_image::get_block_endpoints(uint block_x, uint block_y, uint element_index, color_quad_u8& low_endpoint, color_quad_u8& high_endpoint, bool scaled) const
{ {
uint l, h; uint l = 0, h = 0;
get_block_endpoints(block_x, block_y, element_index, l, h); get_block_endpoints(block_x, block_y, element_index, l, h);
switch (m_element_type[element_index]) switch (m_element_type[element_index])
+2 -2
View File
@@ -61,8 +61,8 @@ namespace crnlib
uint get_le_word(uint index) const { CRNLIB_ASSERT(index < 4); return m_bytes[index*2] | (m_bytes[index * 2 + 1] << 8); } uint get_le_word(uint index) const { CRNLIB_ASSERT(index < 4); return m_bytes[index*2] | (m_bytes[index * 2 + 1] << 8); }
uint get_be_word(uint index) const { CRNLIB_ASSERT(index < 4); return m_bytes[index*2 + 1] | (m_bytes[index * 2] << 8); } uint get_be_word(uint index) const { CRNLIB_ASSERT(index < 4); return m_bytes[index*2 + 1] | (m_bytes[index * 2] << 8); }
void set_le_word(uint index, uint val) { CRNLIB_ASSERT((index < 4) && (val <= UINT16_MAX)); m_bytes[index*2] = static_cast<uint8>(val & 0xFF); m_bytes[index * 2 + 1] = static_cast<uint8>((val >> 8) & 0xFF); } void set_le_word(uint index, uint val) { CRNLIB_ASSERT((index < 4) && (val <= cUINT16_MAX)); m_bytes[index*2] = static_cast<uint8>(val & 0xFF); m_bytes[index * 2 + 1] = static_cast<uint8>((val >> 8) & 0xFF); }
void set_be_word(uint index, uint val) { CRNLIB_ASSERT((index < 4) && (val <= UINT16_MAX)); m_bytes[index*2+1] = static_cast<uint8>(val & 0xFF); m_bytes[index * 2] = static_cast<uint8>((val >> 8) & 0xFF); } void set_be_word(uint index, uint val) { CRNLIB_ASSERT((index < 4) && (val <= cUINT16_MAX)); m_bytes[index*2+1] = static_cast<uint8>(val & 0xFF); m_bytes[index * 2] = static_cast<uint8>((val >> 8) & 0xFF); }
void clear() void clear()
{ {
+53 -53
View File
@@ -8,32 +8,32 @@ namespace crnlib
class dynamic_stream : public data_stream class dynamic_stream : public data_stream
{ {
public: public:
dynamic_stream(uint initial_size, const wchar_t* pName = L"dynamic_stream", uint attribs = cDataStreamSeekable | cDataStreamWritable | cDataStreamReadable) : dynamic_stream(uint initial_size, const char* pName = "dynamic_stream", uint attribs = cDataStreamSeekable | cDataStreamWritable | cDataStreamReadable) :
data_stream(pName, attribs), data_stream(pName, attribs),
m_ofs(0) m_ofs(0)
{ {
open(initial_size, pName, attribs); open(initial_size, pName, attribs);
} }
dynamic_stream(const void* pBuf, uint size, const wchar_t* pName = L"dynamic_stream", uint attribs = cDataStreamSeekable | cDataStreamWritable | cDataStreamReadable) : dynamic_stream(const void* pBuf, uint size, const char* pName = "dynamic_stream", uint attribs = cDataStreamSeekable | cDataStreamWritable | cDataStreamReadable) :
data_stream(pName, attribs), data_stream(pName, attribs),
m_ofs(0) m_ofs(0)
{ {
open(pBuf, size, pName, attribs); open(pBuf, size, pName, attribs);
} }
dynamic_stream() : dynamic_stream() :
data_stream(), data_stream(),
m_ofs(0) m_ofs(0)
{ {
open(); open();
} }
virtual ~dynamic_stream() virtual ~dynamic_stream()
{ {
} }
bool open(uint initial_size = 0, const wchar_t* pName = L"dynamic_stream", uint attribs = cDataStreamSeekable | cDataStreamWritable | cDataStreamReadable) bool open(uint initial_size = 0, const char* pName = "dynamic_stream", uint attribs = cDataStreamSeekable | cDataStreamWritable | cDataStreamReadable)
{ {
close(); close();
@@ -41,24 +41,24 @@ namespace crnlib
m_buf.clear(); m_buf.clear();
m_buf.resize(initial_size); m_buf.resize(initial_size);
m_ofs = 0; m_ofs = 0;
m_name.set(pName ? pName : L"dynamic_stream"); m_name.set(pName ? pName : "dynamic_stream");
m_attribs = static_cast<attribs_t>(attribs); m_attribs = static_cast<attribs_t>(attribs);
return true; return true;
} }
bool reopen(const wchar_t* pName, uint attribs) bool reopen(const char* pName, uint attribs)
{ {
if (!m_opened) if (!m_opened)
{ {
return open(0, pName, attribs); return open(0, pName, attribs);
} }
m_name.set(pName ? pName : L"dynamic_stream"); m_name.set(pName ? pName : "dynamic_stream");
m_attribs = static_cast<attribs_t>(attribs); m_attribs = static_cast<attribs_t>(attribs);
return true; return true;
} }
bool open(const void* pBuf, uint size, const wchar_t* pName = L"dynamic_stream", uint attribs = cDataStreamSeekable | cDataStreamWritable | cDataStreamReadable) bool open(const void* pBuf, uint size, const char* pName = "dynamic_stream", uint attribs = cDataStreamSeekable | cDataStreamWritable | cDataStreamReadable)
{ {
if (!m_opened) if (!m_opened)
{ {
@@ -70,14 +70,14 @@ namespace crnlib
memcpy(&m_buf[0], pBuf, size); memcpy(&m_buf[0], pBuf, size);
} }
m_ofs = 0; m_ofs = 0;
m_name.set(pName ? pName : L"dynamic_stream"); m_name.set(pName ? pName : "dynamic_stream");
m_attribs = static_cast<attribs_t>(attribs); m_attribs = static_cast<attribs_t>(attribs);
return true; return true;
} }
return false; return false;
} }
virtual bool close() virtual bool close()
{ {
if (m_opened) if (m_opened)
@@ -87,10 +87,10 @@ namespace crnlib
m_ofs = 0; m_ofs = 0;
return true; return true;
} }
return false; return false;
} }
const crnlib::vector<uint8>& get_buf() const { return m_buf; } const crnlib::vector<uint8>& get_buf() const { return m_buf; }
crnlib::vector<uint8>& get_buf() { return m_buf; } crnlib::vector<uint8>& get_buf() { return m_buf; }
@@ -101,102 +101,102 @@ namespace crnlib
m_buf.reserve(size); m_buf.reserve(size);
} }
} }
virtual const void* get_ptr() const { return m_buf.empty() ? NULL : &m_buf[0]; } virtual const void* get_ptr() const { return m_buf.empty() ? NULL : &m_buf[0]; }
virtual uint read(void* pBuf, uint len) virtual uint read(void* pBuf, uint len)
{ {
CRNLIB_ASSERT(pBuf && (len <= 0x7FFFFFFF)); CRNLIB_ASSERT(pBuf && (len <= 0x7FFFFFFF));
if ((!m_opened) || (!is_readable()) || (!len)) if ((!m_opened) || (!is_readable()) || (!len))
return 0; return 0;
CRNLIB_ASSERT(m_ofs <= m_buf.size()); CRNLIB_ASSERT(m_ofs <= m_buf.size());
uint bytes_left = m_buf.size() - m_ofs; uint bytes_left = m_buf.size() - m_ofs;
len = math::minimum<uint>(len, bytes_left); len = math::minimum<uint>(len, bytes_left);
if (len) if (len)
memcpy(pBuf, &m_buf[m_ofs], len); memcpy(pBuf, &m_buf[m_ofs], len);
m_ofs += len; m_ofs += len;
return len; return len;
} }
virtual uint write(const void* pBuf, uint len) virtual uint write(const void* pBuf, uint len)
{ {
CRNLIB_ASSERT(pBuf && (len <= 0x7FFFFFFF)); CRNLIB_ASSERT(pBuf && (len <= 0x7FFFFFFF));
if ((!m_opened) || (!is_writable()) || (!len)) if ((!m_opened) || (!is_writable()) || (!len))
return 0; return 0;
CRNLIB_ASSERT(m_ofs <= m_buf.size()); CRNLIB_ASSERT(m_ofs <= m_buf.size());
uint new_ofs = m_ofs + len; uint new_ofs = m_ofs + len;
if (new_ofs > m_buf.size()) if (new_ofs > m_buf.size())
m_buf.resize(new_ofs); m_buf.resize(new_ofs);
memcpy(&m_buf[m_ofs], pBuf, len); memcpy(&m_buf[m_ofs], pBuf, len);
m_ofs = new_ofs; m_ofs = new_ofs;
return len; return len;
} }
virtual bool flush() virtual bool flush()
{ {
if (!m_opened) if (!m_opened)
return false; return false;
return true; return true;
} }
virtual uint64 get_size() virtual uint64 get_size()
{ {
if (!m_opened) if (!m_opened)
return 0; return 0;
return m_buf.size(); return m_buf.size();
} }
virtual uint64 get_remaining() virtual uint64 get_remaining()
{ {
if (!m_opened) if (!m_opened)
return 0; return 0;
CRNLIB_ASSERT(m_ofs <= m_buf.size()); CRNLIB_ASSERT(m_ofs <= m_buf.size());
return m_buf.size() - m_ofs; return m_buf.size() - m_ofs;
} }
virtual uint64 get_ofs() virtual uint64 get_ofs()
{ {
if (!m_opened) if (!m_opened)
return 0; return 0;
return m_ofs; return m_ofs;
} }
virtual bool seek(int64 ofs, bool relative) virtual bool seek(int64 ofs, bool relative)
{ {
if ((!m_opened) || (!is_seekable())) if ((!m_opened) || (!is_seekable()))
return false; return false;
int64 new_ofs = relative ? (m_ofs + ofs) : ofs; int64 new_ofs = relative ? (m_ofs + ofs) : ofs;
if (new_ofs < 0) if (new_ofs < 0)
return false; return false;
else if (new_ofs > m_buf.size()) else if (new_ofs > m_buf.size())
return false; return false;
m_ofs = static_cast<uint>(new_ofs); m_ofs = static_cast<uint>(new_ofs);
post_seek(); post_seek();
return true; return true;
} }
private: private:
crnlib::vector<uint8> m_buf; crnlib::vector<uint8> m_buf;
uint m_ofs; uint m_ofs;
+38 -65
View File
@@ -1,10 +1,7 @@
// File: crn_dynamic_string.cpp // File: crn_dynamic_string.cpp
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#include "crn_core.h" #include "crn_core.h"
#include "crn_dynamic_string.h" #include "crn_strutils.h"
#include "crn_dynamic_wstring.h"
#include "crn_winhdr.h"
#include <stdio.h>
namespace crnlib namespace crnlib
{ {
@@ -43,51 +40,6 @@ namespace crnlib
set(other); set(other);
} }
dynamic_string::dynamic_string(const wchar_t* pStr) :
m_buf_size(0), m_len(0), m_pStr(NULL)
{
set(pStr);
}
dynamic_string& dynamic_string::set(const wchar_t *pStr)
{
uint len = static_cast<uint>(wcslen(pStr));
if (!len)
{
clear();
return *this;
}
const uint num_needed = WideCharToMultiByte(CP_ACP, 0, pStr, len, NULL, 0, NULL, NULL);
if (num_needed <= 0)
{
clear();
return *this;
}
if (!ensure_buf(num_needed, false))
{
clear();
return *this;
}
const uint num_written = WideCharToMultiByte(CP_ACP, 0, pStr, len, get_ptr_raw(), num_needed, NULL, NULL);
CRNLIB_ASSERT(num_written == num_needed);
get_ptr_raw()[num_written] = 0;
m_len = static_cast<uint16>(num_written);
check();
return *this;
}
dynamic_wstring& dynamic_string::as_utf16(dynamic_wstring &buf)
{
buf.set(get_ptr());
return buf;
}
void dynamic_string::clear() void dynamic_string::clear()
{ {
check(); check();
@@ -133,7 +85,7 @@ namespace crnlib
{ {
CRNLIB_ASSERT(p); CRNLIB_ASSERT(p);
const int result = (case_sensitive ? strcmp : _stricmp)(get_ptr_priv(), p); const int result = (case_sensitive ? strcmp : crn_stricmp)(get_ptr_priv(), p);
if (result < 0) if (result < 0)
return -1; return -1;
@@ -153,9 +105,9 @@ namespace crnlib
CRNLIB_ASSERT(p); CRNLIB_ASSERT(p);
const uint len = math::minimum<uint>(max_len, static_cast<uint>(strlen(p))); const uint len = math::minimum<uint>(max_len, static_cast<uint>(strlen(p)));
CRNLIB_ASSERT(len < UINT16_MAX); CRNLIB_ASSERT(len < cUINT16_MAX);
if ((!len) || (len >= UINT16_MAX)) if ((!len) || (len >= cUINT16_MAX))
clear(); clear();
else if ((m_pStr) && (p >= m_pStr) && (p < (m_pStr + m_buf_size))) else if ((m_pStr) && (p >= m_pStr) && (p < (m_pStr + m_buf_size)))
{ {
@@ -206,8 +158,11 @@ namespace crnlib
bool dynamic_string::set_len(uint new_len, char fill_char) bool dynamic_string::set_len(uint new_len, char fill_char)
{ {
if ((new_len >= UINT16_MAX) || (!fill_char)) if ((new_len >= cUINT16_MAX) || (!fill_char))
{
CRNLIB_ASSERT(0);
return false; return false;
}
uint cur_len = m_len; uint cur_len = m_len;
@@ -226,22 +181,41 @@ namespace crnlib
return true; return true;
} }
dynamic_string& dynamic_string::set_from_raw_buf_and_assume_ownership(char *pBuf, uint buf_size_in_chars, uint len_in_chars)
{
CRNLIB_ASSERT(buf_size_in_chars <= cUINT16_MAX);
CRNLIB_ASSERT(math::is_power_of_2(buf_size_in_chars) || (buf_size_in_chars == cUINT16_MAX));
CRNLIB_ASSERT((len_in_chars + 1) <= buf_size_in_chars);
clear();
m_pStr = pBuf;
m_buf_size = static_cast<uint16>(buf_size_in_chars);
m_len = static_cast<uint16>(len_in_chars);
check();
return *this;
}
dynamic_string& dynamic_string::set_from_buf(const void* pBuf, uint buf_size) dynamic_string& dynamic_string::set_from_buf(const void* pBuf, uint buf_size)
{ {
CRNLIB_ASSERT(pBuf); CRNLIB_ASSERT(pBuf);
if (buf_size >= UINT16_MAX) if (buf_size >= cUINT16_MAX)
{ {
clear(); clear();
return *this; return *this;
} }
#ifdef CRNLIB_BUILD_DEBUG
if ((buf_size) && (memchr(pBuf, 0, buf_size) != NULL)) if ((buf_size) && (memchr(pBuf, 0, buf_size) != NULL))
{ {
CRNLIB_ASSERT(0); CRNLIB_ASSERT(0);
clear(); clear();
return *this; return *this;
} }
#endif
if (ensure_buf(buf_size, false)) if (ensure_buf(buf_size, false))
{ {
@@ -569,9 +543,12 @@ namespace crnlib
else else
{ {
CRNLIB_ASSERT(m_buf_size); CRNLIB_ASSERT(m_buf_size);
CRNLIB_ASSERT((m_buf_size == UINT16_MAX) || math::is_power_of_2((uint32)m_buf_size)); CRNLIB_ASSERT((m_buf_size == cUINT16_MAX) || math::is_power_of_2((uint32)m_buf_size));
CRNLIB_ASSERT(m_len < m_buf_size); CRNLIB_ASSERT(m_len < m_buf_size);
CRNLIB_ASSERT(!m_pStr[m_len]);
#if CRNLIB_SLOW_STRING_LEN_CHECKS
CRNLIB_ASSERT(strlen(m_pStr) == m_len); CRNLIB_ASSERT(strlen(m_pStr) == m_len);
#endif
} }
} }
#endif #endif
@@ -580,9 +557,9 @@ namespace crnlib
{ {
uint buf_size_needed = len + 1; uint buf_size_needed = len + 1;
CRNLIB_ASSERT(buf_size_needed <= UINT16_MAX); CRNLIB_ASSERT(buf_size_needed <= cUINT16_MAX);
if (buf_size_needed <= UINT16_MAX) if (buf_size_needed <= cUINT16_MAX)
{ {
if (buf_size_needed > m_buf_size) if (buf_size_needed > m_buf_size)
expand_buf(buf_size_needed, preserve_contents); expand_buf(buf_size_needed, preserve_contents);
@@ -593,7 +570,7 @@ namespace crnlib
bool dynamic_string::expand_buf(uint new_buf_size, bool preserve_contents) bool dynamic_string::expand_buf(uint new_buf_size, bool preserve_contents)
{ {
new_buf_size = math::minimum<uint>(UINT16_MAX, math::next_pow2(math::maximum<uint>(m_buf_size, new_buf_size))); new_buf_size = math::minimum<uint>(cUINT16_MAX, math::next_pow2(math::maximum<uint>(m_buf_size, new_buf_size)));
if (new_buf_size != m_buf_size) if (new_buf_size != m_buf_size)
{ {
@@ -625,8 +602,9 @@ namespace crnlib
{ {
uint buf_left = buf_size; uint buf_left = buf_size;
if (m_len > UINT16_MAX) //if (m_len > cUINT16_MAX)
return -1; // return -1;
CRNLIB_ASSUME(sizeof(m_len) == sizeof(uint16));
if (!utils::write_val((uint16)m_len, pBuf, buf_left, little_endian)) if (!utils::write_val((uint16)m_len, pBuf, buf_left, little_endian))
return -1; return -1;
@@ -687,9 +665,4 @@ namespace crnlib
swap(tmp); swap(tmp);
} }
dynamic_string& dynamic_string::operator= (const dynamic_wstring& rhs)
{
return set(rhs.get_ptr());
}
} // namespace crnlib } // namespace crnlib
+19 -9
View File
@@ -4,12 +4,9 @@
namespace crnlib namespace crnlib
{ {
class dynamic_wstring; enum { cMaxDynamicStringLen = cUINT16_MAX - 1 };
class dynamic_string class dynamic_string
{ {
friend class dynamic_wstring;
public: public:
inline dynamic_string() : m_buf_size(0), m_len(0), m_pStr(NULL) { } inline dynamic_string() : m_buf_size(0), m_len(0), m_pStr(NULL) { }
dynamic_string(eVarArg dummy, const char* p, ...); dynamic_string(eVarArg dummy, const char* p, ...);
@@ -19,25 +16,26 @@ namespace crnlib
inline ~dynamic_string() { if (m_pStr) crnlib_delete_array(m_pStr); } inline ~dynamic_string() { if (m_pStr) crnlib_delete_array(m_pStr); }
explicit dynamic_string(const wchar_t* pStr);
dynamic_string& set(const wchar_t *pStr);
dynamic_wstring& as_utf16(dynamic_wstring &buf);
// Truncates the string to 0 chars and frees the buffer. // Truncates the string to 0 chars and frees the buffer.
void clear(); void clear();
void optimize(); void optimize();
// Truncates the string to 0 chars, but does not free the buffer. // Truncates the string to 0 chars, but does not free the buffer.
void empty(); void empty();
inline const char *assume_ownership() { const char *p = m_pStr; m_pStr = NULL; m_len = 0; m_buf_size = 0; return p; }
inline uint get_len() const { return m_len; } inline uint get_len() const { return m_len; }
inline bool is_empty() const { return !m_len; } inline bool is_empty() const { return !m_len; }
inline const char* get_ptr() const { return m_pStr ? m_pStr : ""; } inline const char* get_ptr() const { return m_pStr ? m_pStr : ""; }
inline const char* c_str() const { return get_ptr(); }
inline const char* get_ptr_raw() const { return m_pStr; } inline const char* get_ptr_raw() const { return m_pStr; }
inline char* get_ptr_raw() { return m_pStr; } inline char* get_ptr_raw() { return m_pStr; }
inline char front() const { return m_len ? m_pStr[0] : '\0'; }
inline char back() const { return m_len ? m_pStr[m_len - 1] : '\0'; }
inline char operator[] (uint i) const { CRNLIB_ASSERT(i <= m_len); return get_ptr()[i]; } inline char operator[] (uint i) const { CRNLIB_ASSERT(i <= m_len); return get_ptr()[i]; }
inline operator size_t() const { return fast_hash(get_ptr(), m_len) ^ fast_hash(&m_len, sizeof(m_len)); } inline operator size_t() const { return fast_hash(get_ptr(), m_len) ^ fast_hash(&m_len, sizeof(m_len)); }
@@ -74,7 +72,6 @@ namespace crnlib
dynamic_string& set_from_buf(const void* pBuf, uint buf_size); dynamic_string& set_from_buf(const void* pBuf, uint buf_size);
dynamic_string& operator= (const dynamic_string& rhs) { return set(rhs); } dynamic_string& operator= (const dynamic_string& rhs) { return set(rhs); }
dynamic_string& operator= (const dynamic_wstring& rhs);
dynamic_string& operator= (const char* p) { return set(p); } dynamic_string& operator= (const char* p) { return set(p); }
dynamic_string& set_char(uint index, char c); dynamic_string& set_char(uint index, char c);
@@ -130,6 +127,9 @@ namespace crnlib
void translate_lf_to_crlf(); void translate_lf_to_crlf();
static inline char *create_raw_buffer(uint& buf_size_in_chars);
static inline void free_raw_buffer(char *p) { crnlib_delete_array(p); }
dynamic_string& set_from_raw_buf_and_assume_ownership(char *pBuf, uint buf_size_in_chars, uint len_in_chars);
private: private:
uint16 m_buf_size; uint16 m_buf_size;
uint16 m_len; uint16 m_len;
@@ -160,4 +160,14 @@ namespace crnlib
a.swap(b); a.swap(b);
} }
inline char *dynamic_string::create_raw_buffer(uint& buf_size_in_chars)
{
if (buf_size_in_chars > cUINT16_MAX)
{
CRNLIB_ASSERT(0);
return NULL;
}
buf_size_in_chars = math::minimum<uint>(cUINT16_MAX, math::next_pow2(buf_size_in_chars));
return crnlib_new_array<char>(buf_size_in_chars);
}
} // namespace crnlib } // namespace crnlib
+2 -2
View File
@@ -30,7 +30,7 @@ namespace crnlib
} }
template <typename T> template <typename T>
void construct_array(T* p, uint n) inline void construct_array(T* p, uint n)
{ {
T* q = p + n; T* q = p + n;
for ( ; p != q; ++p) for ( ; p != q; ++p)
@@ -38,7 +38,7 @@ namespace crnlib
} }
template <typename T, typename U> template <typename T, typename U>
void construct_array(T* p, uint n, const U& init) inline void construct_array(T* p, uint n, const U& init)
{ {
T* q = p + n; T* q = p + n;
for ( ; p != q; ++p) for ( ; p != q; ++p)
+3 -3
View File
@@ -228,7 +228,7 @@ namespace crnlib
sym_freq& sf = state.syms0[num_used_syms]; sym_freq& sf = state.syms0[num_used_syms];
sf.m_left = (uint16)i; sf.m_left = (uint16)i;
sf.m_right = UINT16_MAX; sf.m_right = cUINT16_MAX;
sf.m_freq = freq; sf.m_freq = freq;
num_used_syms++; num_used_syms++;
} }
@@ -263,8 +263,8 @@ namespace crnlib
#else #else
// Dummy node // Dummy node
sym_freq& sf = state.syms0[num_used_syms]; sym_freq& sf = state.syms0[num_used_syms];
sf.m_left = UINT16_MAX; sf.m_left = cUINT16_MAX;
sf.m_right = UINT16_MAX; sf.m_right = cUINT16_MAX;
sf.m_freq = UINT_MAX; sf.m_freq = UINT_MAX;
uint next_internal_node = num_used_syms + 1; uint next_internal_node = num_used_syms + 1;
+39 -35
View File
@@ -6,6 +6,8 @@
#include "crn_resampler.h" #include "crn_resampler.h"
#include "crn_threaded_resampler.h" #include "crn_threaded_resampler.h"
#include "crn_strutils.h" #include "crn_strutils.h"
#include "crn_file_utils.h"
#include "crn_threading.h"
#define STBI_HEADER_FILE_ONLY #define STBI_HEADER_FILE_ONLY
#include "crn_stb_image.cpp" #include "crn_stb_image.cpp"
@@ -18,10 +20,10 @@ namespace crnlib
namespace image_utils namespace image_utils
{ {
bool load_from_file_stb(const wchar_t* pFilename, image_u8& img) bool load_from_file_stb(const char* pFilename, image_u8& img)
{ {
int x = 0, y = 0, n = 0; int x = 0, y = 0, n = 0;
unsigned char* pData = stbi_load_w(pFilename, &x, &y, &n, 4); unsigned char* pData = stbi_load(pFilename, &x, &y, &n, 4);
if (!pData) if (!pData)
return false; return false;
@@ -66,20 +68,20 @@ namespace crnlib
return true; return true;
} }
bool save_to_file_stb(const wchar_t* pFilename, const image_u8& img, uint save_flags, int comp_index) bool save_to_file_stb(const char* pFilename, const image_u8& img, uint save_flags, int comp_index)
{ {
if (!img.get_width()) if (!img.get_width())
return false; return false;
bool bSaveBMP = false; bool bSaveBMP = false;
dynamic_wstring ext(pFilename); dynamic_string ext(pFilename);
if (get_extension(ext)) if (file_utils::get_extension(ext))
{ {
if (ext == L"bmp") if (ext == "bmp")
bSaveBMP = true; bSaveBMP = true;
else if (ext != L"tga") else if (ext != "tga")
{ {
console::error(L"crnlib::image_utils::save_to_file_stb: Can only write .BMP or .TGA files!\n"); console::error("crnlib::image_utils::save_to_file_stb: Can only write .BMP or .TGA files!\n");
return false; return false;
} }
} }
@@ -114,7 +116,7 @@ namespace crnlib
} }
} }
return (bSaveBMP ? stbi_write_bmp_w : stbi_write_tga_w)(pFilename, img.get_width(), img.get_height(), 1, &temp[0]) == CRNLIB_TRUE; return (bSaveBMP ? stbi_write_bmp : stbi_write_tga)(pFilename, img.get_width(), img.get_height(), 1, &temp[0]) == CRNLIB_TRUE;
} }
else if ((!img.is_component_valid(3)) || (save_flags & cSaveIgnoreAlpha)) else if ((!img.is_component_valid(3)) || (save_flags & cSaveIgnoreAlpha))
{ {
@@ -138,27 +140,27 @@ namespace crnlib
} }
} }
return (bSaveBMP ? stbi_write_bmp_w : stbi_write_tga_w)(pFilename, img.get_width(), img.get_height(), 3, &temp[0]) == CRNLIB_TRUE; return (bSaveBMP ? stbi_write_bmp : stbi_write_tga)(pFilename, img.get_width(), img.get_height(), 3, &temp[0]) == CRNLIB_TRUE;
} }
else else
{ {
return (bSaveBMP ? stbi_write_bmp_w : stbi_write_tga_w)(pFilename, img.get_width(), img.get_height(), 4, img.get_ptr()) == CRNLIB_TRUE; return (bSaveBMP ? stbi_write_bmp : stbi_write_tga)(pFilename, img.get_width(), img.get_height(), 4, img.get_ptr()) == CRNLIB_TRUE;
} }
} }
bool load_from_file(image_u8& dest, const wchar_t* pFilename, int flags) bool load_from_file(image_u8& dest, const char* pFilename, int flags)
{ {
flags; flags;
return image_utils::load_from_file_stb(pFilename, dest); return image_utils::load_from_file_stb(pFilename, dest);
} }
bool save_to_grayscale_file(const wchar_t* pFilename, const image_u8& src, int component, int flags) bool save_to_grayscale_file(const char* pFilename, const image_u8& src, int component, int flags)
{ {
flags; flags;
return image_utils::save_to_file_stb(pFilename, src, image_utils::cSaveGrayscale, component); return image_utils::save_to_file_stb(pFilename, src, image_utils::cSaveGrayscale, component);
} }
bool save_to_file(const wchar_t* pFilename, const image_u8& src, int flags, bool ignore_alpha) bool save_to_file(const char* pFilename, const image_u8& src, int flags, bool ignore_alpha)
{ {
if (src.is_grayscale()) if (src.is_grayscale())
return save_to_grayscale_file(pFilename, src, cSaveLuma, flags); return save_to_grayscale_file(pFilename, src, cSaveLuma, flags);
@@ -220,7 +222,7 @@ namespace crnlib
} }
} }
bool is_normal_map(const image_u8& img, const wchar_t* pFilename) bool is_normal_map(const image_u8& img, const char* pFilename)
{ {
float score = 0.0f; float score = 0.0f;
@@ -259,13 +261,13 @@ namespace crnlib
if (pFilename) if (pFilename)
{ {
dynamic_wstring str(pFilename); dynamic_string str(pFilename);
str.tolower(); str.tolower();
if (str.contains(L"normal") || str.contains(L"local") || str.contains(L"nmap")) if (str.contains("normal") || str.contains("local") || str.contains("nmap"))
score += 1.0f; score += 1.0f;
if (str.contains(L"diffuse") || str.contains(L"spec") || str.contains(L"gloss")) if (str.contains("diffuse") || str.contains("spec") || str.contains("gloss"))
score -= 1.0f; score -= 1.0f;
} }
@@ -712,32 +714,34 @@ namespace crnlib
if (!total_blocks) if (!total_blocks)
return 0.0f; return 0.0f;
//save_to_file_stb(L"ssim.tga", yimg, cSaveGrayscale); //save_to_file_stb("ssim.tga", yimg, cSaveGrayscale);
return total_ssim / total_blocks; return total_ssim / total_blocks;
} }
void print_ssim(const image_u8& src_img, const image_u8& dst_img) void print_ssim(const image_u8& src_img, const image_u8& dst_img)
{ {
double y_ssim = compute_ssim(src_img, dst_img, -1); src_img;
console::printf(L"Luma MSSIM: %f, Scaled: %f", y_ssim, (y_ssim - .8f) / .2f); dst_img;
//double y_ssim = compute_ssim(src_img, dst_img, -1);
//console::printf("Luma MSSIM: %f, Scaled: %f", y_ssim, (y_ssim - .8f) / .2f);
//double r_ssim = compute_ssim(src_img, dst_img, 0); //double r_ssim = compute_ssim(src_img, dst_img, 0);
//console::printf(L" R MSSIM: %f", r_ssim); //console::printf(" R MSSIM: %f", r_ssim);
//double g_ssim = compute_ssim(src_img, dst_img, 1); //double g_ssim = compute_ssim(src_img, dst_img, 1);
//console::printf(L" G MSSIM: %f", g_ssim); //console::printf(" G MSSIM: %f", g_ssim);
//double b_ssim = compute_ssim(src_img, dst_img, 2); //double b_ssim = compute_ssim(src_img, dst_img, 2);
//console::printf(L" B MSSIM: %f", b_ssim); //console::printf(" B MSSIM: %f", b_ssim);
} }
void error_metrics::print(const wchar_t* pName) const void error_metrics::print(const char* pName) const
{ {
if (mPeakSNR >= cInfinitePSNR) if (mPeakSNR >= cInfinitePSNR)
console::printf(L"%s Error: Max: %3u, Mean: %3.3f, RMS: %3.3f, PSNR: Infinite", pName, mMax, mMean, mRootMeanSquared); console::printf("%s Error: Max: %3u, Mean: %3.3f, MSE: %3.3f, RMS: %3.3f, PSNR: Infinite", pName, mMax, mMean, mMeanSquared, mRootMeanSquared);
else else
console::printf(L"%s Error: Max: %3u, Mean: %3.3f, RMS: %3.3f, PSNR: %3.3f", pName, mMax, mMean, mRootMeanSquared, mPeakSNR); console::printf("%s Error: Max: %3u, Mean: %3.3f, MSE: %3.3f, RMS: %3.3f, PSNR: %3.3f", pName, mMax, mMean, mMeanSquared, mRootMeanSquared, mPeakSNR);
} }
bool error_metrics::compute(const image_u8& a, const image_u8& b, uint first_channel, uint num_channels, bool average_component_error) bool error_metrics::compute(const image_u8& a, const image_u8& b, uint first_channel, uint num_channels, bool average_component_error)
@@ -808,35 +812,35 @@ namespace crnlib
void print_image_metrics(const image_u8& src_img, const image_u8& dst_img) void print_image_metrics(const image_u8& src_img, const image_u8& dst_img)
{ {
if ( (!src_img.get_width()) || (!dst_img.get_height()) || (src_img.get_width() != dst_img.get_width()) || (src_img.get_height() != dst_img.get_height()) ) if ( (!src_img.get_width()) || (!dst_img.get_height()) || (src_img.get_width() != dst_img.get_width()) || (src_img.get_height() != dst_img.get_height()) )
console::printf(L"print_image_metrics: Image resolutions don't match exactly (%ux%u) vs. (%ux%u)", src_img.get_width(), src_img.get_height(), dst_img.get_width(), dst_img.get_height()); console::printf("print_image_metrics: Image resolutions don't match exactly (%ux%u) vs. (%ux%u)", src_img.get_width(), src_img.get_height(), dst_img.get_width(), dst_img.get_height());
image_utils::error_metrics error_metrics; image_utils::error_metrics error_metrics;
if (src_img.has_rgb() || dst_img.has_rgb()) if (src_img.has_rgb() || dst_img.has_rgb())
{ {
error_metrics.compute(src_img, dst_img, 0, 3, false); error_metrics.compute(src_img, dst_img, 0, 3, false);
error_metrics.print(L"RGB Total "); error_metrics.print("RGB Total ");
error_metrics.compute(src_img, dst_img, 0, 3, true); error_metrics.compute(src_img, dst_img, 0, 3, true);
error_metrics.print(L"RGB Average"); error_metrics.print("RGB Average");
error_metrics.compute(src_img, dst_img, 0, 0); error_metrics.compute(src_img, dst_img, 0, 0);
error_metrics.print(L"Luma "); error_metrics.print("Luma ");
error_metrics.compute(src_img, dst_img, 0, 1); error_metrics.compute(src_img, dst_img, 0, 1);
error_metrics.print(L"Red "); error_metrics.print("Red ");
error_metrics.compute(src_img, dst_img, 1, 1); error_metrics.compute(src_img, dst_img, 1, 1);
error_metrics.print(L"Green "); error_metrics.print("Green ");
error_metrics.compute(src_img, dst_img, 2, 1); error_metrics.compute(src_img, dst_img, 2, 1);
error_metrics.print(L"Blue "); error_metrics.print("Blue ");
} }
if (src_img.has_alpha() || dst_img.has_alpha()) if (src_img.has_alpha() || dst_img.has_alpha())
{ {
error_metrics.compute(src_img, dst_img, 3, 1); error_metrics.compute(src_img, dst_img, 3, 1);
error_metrics.print(L"Alpha "); error_metrics.print("Alpha ");
} }
} }
+35 -35
View File
@@ -6,12 +6,12 @@
namespace crnlib namespace crnlib
{ {
enum pixel_format; enum pixel_format;
namespace image_utils namespace image_utils
{ {
bool load_from_file_stb(const wchar_t* pFilename, image_u8& img); bool load_from_file_stb(const char* pFilename, image_u8& img);
enum enum
{ {
cSaveIgnoreAlpha = 1, cSaveIgnoreAlpha = 1,
cSaveGrayscale = 2 cSaveGrayscale = 2
@@ -19,18 +19,18 @@ namespace crnlib
const int cSaveLuma = -1; const int cSaveLuma = -1;
bool save_to_file_stb(const wchar_t* pFilename, const image_u8& img, uint save_flags = 0, int comp_index = cSaveLuma); bool save_to_file_stb(const char* pFilename, const image_u8& img, uint save_flags = 0, int comp_index = cSaveLuma);
bool load_from_file(image_u8& dest, const wchar_t* pFilename, int flags = 0);
bool save_to_grayscale_file(const wchar_t* pFilename, const image_u8& src, int component, int flags = 0); bool load_from_file(image_u8& dest, const char* pFilename, int flags = 0);
bool save_to_grayscale_file(const char* pFilename, const image_u8& src, int component, int flags = 0);
bool save_to_file(const char* pFilename, const image_u8& src, int flags = 0, bool ignore_alpha = false);
bool save_to_file(const wchar_t* pFilename, const image_u8& src, int flags = 0, bool ignore_alpha = false);
bool has_alpha(const image_u8& img); bool has_alpha(const image_u8& img);
bool is_normal_map(const image_u8& img, const wchar_t* pFilename = NULL); bool is_normal_map(const image_u8& img, const char* pFilename = NULL);
void renorm_normal_map(image_u8& img); void renorm_normal_map(image_u8& img);
struct resample_params struct resample_params
{ {
resample_params() : resample_params() :
@@ -46,7 +46,7 @@ namespace crnlib
m_multithreaded(true) m_multithreaded(true)
{ {
} }
uint m_dst_width; uint m_dst_width;
uint m_dst_height; uint m_dst_height;
const char* m_pFilter; const char* m_pFilter;
@@ -58,40 +58,40 @@ namespace crnlib
float m_source_gamma; float m_source_gamma;
bool m_multithreaded; bool m_multithreaded;
}; };
bool resample_single_thread(const image_u8& src, image_u8& dst, const resample_params& params); bool resample_single_thread(const image_u8& src, image_u8& dst, const resample_params& params);
bool resample_multithreaded(const image_u8& src, image_u8& dst, const resample_params& params); bool resample_multithreaded(const image_u8& src, image_u8& dst, const resample_params& params);
bool resample(const image_u8& src, image_u8& dst, const resample_params& params); bool resample(const image_u8& src, image_u8& dst, const resample_params& params);
bool compute_delta(image_u8& dest, image_u8& a, image_u8& b, uint scale = 2); bool compute_delta(image_u8& dest, image_u8& a, image_u8& b, uint scale = 2);
class error_metrics class error_metrics
{ {
public: public:
error_metrics() { utils::zero_this(this); } error_metrics() { utils::zero_this(this); }
void print(const wchar_t* pName) const; void print(const char* pName) const;
// If num_channels==0, luma error is computed. // If num_channels==0, luma error is computed.
// If pHist != NULL, it must point to a 256 entry array. // If pHist != NULL, it must point to a 256 entry array.
bool compute(const image_u8& a, const image_u8& b, uint first_channel, uint num_channels, bool average_component_error = true); bool compute(const image_u8& a, const image_u8& b, uint first_channel, uint num_channels, bool average_component_error = true);
uint mMax; uint mMax;
double mMean; double mMean;
double mMeanSquared; double mMeanSquared;
double mRootMeanSquared; double mRootMeanSquared;
double mPeakSNR; double mPeakSNR;
inline bool operator== (const error_metrics& other) const inline bool operator== (const error_metrics& other) const
{ {
return mPeakSNR == other.mPeakSNR; return mPeakSNR == other.mPeakSNR;
} }
inline bool operator< (const error_metrics& other) const inline bool operator< (const error_metrics& other) const
{ {
return mPeakSNR < other.mPeakSNR; return mPeakSNR < other.mPeakSNR;
} }
inline bool operator> (const error_metrics& other) const inline bool operator> (const error_metrics& other) const
{ {
return mPeakSNR > other.mPeakSNR; return mPeakSNR > other.mPeakSNR;
@@ -99,43 +99,43 @@ namespace crnlib
}; };
void print_image_metrics(const image_u8& src_img, const image_u8& dst_img); void print_image_metrics(const image_u8& src_img, const image_u8& dst_img);
double compute_block_ssim(uint n, const uint8* pX, const uint8* pY); double compute_block_ssim(uint n, const uint8* pX, const uint8* pY);
double compute_ssim(const image_u8& a, const image_u8& b, int channel_index); double compute_ssim(const image_u8& a, const image_u8& b, int channel_index);
void print_ssim(const image_u8& src_img, const image_u8& dst_img); void print_ssim(const image_u8& src_img, const image_u8& dst_img);
enum conversion_type enum conversion_type
{ {
cConversion_Invalid = -1, cConversion_Invalid = -1,
cConversion_To_CCxY, cConversion_To_CCxY,
cConversion_From_CCxY, cConversion_From_CCxY,
cConversion_To_xGxR, cConversion_To_xGxR,
cConversion_From_xGxR, cConversion_From_xGxR,
cConversion_To_xGBR, cConversion_To_xGBR,
cConversion_From_xGBR, cConversion_From_xGBR,
cConversion_To_AGBR, cConversion_To_AGBR,
cConversion_From_AGBR, cConversion_From_AGBR,
cConversion_XY_to_XYZ, cConversion_XY_to_XYZ,
cConversion_Y_To_A, cConversion_Y_To_A,
cConversion_A_To_RGBA, cConversion_A_To_RGBA,
cConversion_Y_To_RGB, cConversion_Y_To_RGB,
cConversionTotal cConversionTotal
}; };
void convert_image(image_u8& img, conversion_type conv_type); void convert_image(image_u8& img, conversion_type conv_type);
image_utils::conversion_type get_conversion_type(bool cooking, pixel_format fmt); image_utils::conversion_type get_conversion_type(bool cooking, pixel_format fmt);
image_utils::conversion_type get_image_conversion_type_from_crn_format(crn_format fmt); image_utils::conversion_type get_image_conversion_type_from_crn_format(crn_format fmt);
double compute_std_dev(uint n, const color_quad_u8* pPixels, uint first_channel, uint num_channels); double compute_std_dev(uint n, const color_quad_u8* pPixels, uint first_channel, uint num_channels);
} }
} }
+39 -34
View File
@@ -4,17 +4,18 @@
#include "crn_lzma_codec.h" #include "crn_lzma_codec.h"
#include "crn_strutils.h" #include "crn_strutils.h"
#include "crn_checksum.h" #include "crn_checksum.h"
#include "lzma_lzmalib.h" #include "lzma_LzmaLib.h"
#include "crn_threading.h"
namespace crnlib namespace crnlib
{ {
lzma_codec::lzma_codec() : lzma_codec::lzma_codec() :
m_pCompress(LzmaCompress), m_pCompress(LzmaCompress),
m_pUncompress(LzmaUncompress) m_pUncompress(LzmaUncompress)
{ {
CRNLIB_ASSUME(cLZMAPropsSize == LZMA_PROPS_SIZE); CRNLIB_ASSUME(cLZMAPropsSize == LZMA_PROPS_SIZE);
} }
lzma_codec::~lzma_codec() lzma_codec::~lzma_codec()
{ {
} }
@@ -23,29 +24,29 @@ namespace crnlib
{ {
if (n > 1024U*1024U*1024U) if (n > 1024U*1024U*1024U)
return false; return false;
uint max_comp_size = n + math::maximum<uint>(128, n >> 8); uint max_comp_size = n + math::maximum<uint>(128, n >> 8);
buf.resize(sizeof(header) + max_comp_size); buf.resize(sizeof(header) + max_comp_size);
header* pHDR = reinterpret_cast<header*>(&buf[0]); header* pHDR = reinterpret_cast<header*>(&buf[0]);
uint8* pComp_data = &buf[sizeof(header)]; uint8* pComp_data = &buf[sizeof(header)];
utils::zero_object(*pHDR); utils::zero_object(*pHDR);
pHDR->m_uncomp_size = n; pHDR->m_uncomp_size = n;
pHDR->m_adler32 = adler32(p, n); pHDR->m_adler32 = adler32(p, n);
if (n) if (n)
{ {
size_t destLen = 0; size_t destLen = 0;
size_t outPropsSize = 0; size_t outPropsSize = 0;
int status = SZ_ERROR_INPUT_EOF; int status = SZ_ERROR_INPUT_EOF;
for (uint trial = 0; trial < 3; trial++) for (uint trial = 0; trial < 3; trial++)
{ {
destLen = max_comp_size; destLen = max_comp_size;
outPropsSize = cLZMAPropsSize; outPropsSize = cLZMAPropsSize;
status = (*m_pCompress)(pComp_data, &destLen, reinterpret_cast<const unsigned char*>(p), n, status = (*m_pCompress)(pComp_data, &destLen, reinterpret_cast<const unsigned char*>(p), n,
pHDR->m_lzma_props, &outPropsSize, pHDR->m_lzma_props, &outPropsSize,
-1, /* 0 <= level <= 9, default = 5 */ -1, /* 0 <= level <= 9, default = 5 */
@@ -54,83 +55,87 @@ namespace crnlib
-1, /* 0 <= lp <= 4, default = 0 */ -1, /* 0 <= lp <= 4, default = 0 */
-1, /* 0 <= pb <= 4, default = 2 */ -1, /* 0 <= pb <= 4, default = 2 */
-1, /* 5 <= fb <= 273, default = 32 */ -1, /* 5 <= fb <= 273, default = 32 */
#ifdef WIN32
(g_number_of_processors > 1) ? 2 : 1 (g_number_of_processors > 1) ? 2 : 1
#else
1
#endif
); );
if (status != SZ_ERROR_OUTPUT_EOF) if (status != SZ_ERROR_OUTPUT_EOF)
break; break;
max_comp_size += ((n+1)/2); max_comp_size += ((n+1)/2);
buf.resize(sizeof(header) + max_comp_size); buf.resize(sizeof(header) + max_comp_size);
pHDR = reinterpret_cast<header*>(&buf[0]); pHDR = reinterpret_cast<header*>(&buf[0]);
pComp_data = &buf[sizeof(header)]; pComp_data = &buf[sizeof(header)];
} }
if (status != SZ_OK) if (status != SZ_OK)
{ {
buf.clear(); buf.clear();
return false; return false;
} }
pHDR->m_comp_size = static_cast<uint>(destLen); pHDR->m_comp_size = static_cast<uint>(destLen);
buf.resize(CRNLIB_SIZEOF_U32(header) + static_cast<uint32>(destLen)); buf.resize(CRNLIB_SIZEOF_U32(header) + static_cast<uint32>(destLen));
} }
pHDR->m_sig = header::cSig; pHDR->m_sig = header::cSig;
pHDR->m_checksum = static_cast<uint8>(adler32((uint8*)pHDR + header::cChecksumSkipBytes, sizeof(header) - header::cChecksumSkipBytes)); pHDR->m_checksum = static_cast<uint8>(adler32((uint8*)pHDR + header::cChecksumSkipBytes, sizeof(header) - header::cChecksumSkipBytes));
return true; return true;
} }
bool lzma_codec::unpack(const void* p, uint n, crnlib::vector<uint8>& buf) bool lzma_codec::unpack(const void* p, uint n, crnlib::vector<uint8>& buf)
{ {
buf.resize(0); buf.resize(0);
if (n < sizeof(header)) if (n < sizeof(header))
return false; return false;
const header& hdr = *static_cast<const header*>(p); const header& hdr = *static_cast<const header*>(p);
if (hdr.m_sig != header::cSig) if (hdr.m_sig != header::cSig)
return false; return false;
if (static_cast<uint8>(adler32((const uint8*)&hdr + header::cChecksumSkipBytes, sizeof(hdr) - header::cChecksumSkipBytes)) != hdr.m_checksum) if (static_cast<uint8>(adler32((const uint8*)&hdr + header::cChecksumSkipBytes, sizeof(hdr) - header::cChecksumSkipBytes)) != hdr.m_checksum)
return false; return false;
if (!hdr.m_uncomp_size) if (!hdr.m_uncomp_size)
return true; return true;
if (!hdr.m_comp_size) if (!hdr.m_comp_size)
return false; return false;
if (hdr.m_uncomp_size > 1024U*1024U*1024U) if (hdr.m_uncomp_size > 1024U*1024U*1024U)
return false; return false;
if (!buf.try_resize(hdr.m_uncomp_size)) if (!buf.try_resize(hdr.m_uncomp_size))
return false; return false;
const uint8* pComp_data = static_cast<const uint8*>(p) + sizeof(header); const uint8* pComp_data = static_cast<const uint8*>(p) + sizeof(header);
size_t srcLen = n - sizeof(header); size_t srcLen = n - sizeof(header);
if (srcLen < hdr.m_comp_size) if (srcLen < hdr.m_comp_size)
return false; return false;
size_t destLen = hdr.m_uncomp_size; size_t destLen = hdr.m_uncomp_size;
int status = (*m_pUncompress)(&buf[0], &destLen, pComp_data, &srcLen, int status = (*m_pUncompress)(&buf[0], &destLen, pComp_data, &srcLen,
hdr.m_lzma_props, cLZMAPropsSize); hdr.m_lzma_props, cLZMAPropsSize);
if ((status != SZ_OK) || (destLen != hdr.m_uncomp_size)) if ((status != SZ_OK) || (destLen != hdr.m_uncomp_size))
{ {
buf.clear(); buf.clear();
return false; return false;
} }
if (adler32(&buf[0], buf.size()) != hdr.m_adler32) if (adler32(&buf[0], buf.size()) != hdr.m_adler32)
{ {
buf.clear(); buf.clear();
return false; return false;
} }
return true; return true;
} }
+3 -3
View File
@@ -12,14 +12,14 @@ namespace crnlib
~lzma_codec(); ~lzma_codec();
// Always available, because we're statically linking in lzmalib now vs. dynamically loading the DLL. // Always available, because we're statically linking in lzmalib now vs. dynamically loading the DLL.
const bool is_initialized() const { return true; } bool is_initialized() const { return true; }
bool pack(const void* p, uint n, crnlib::vector<uint8>& buf); bool pack(const void* p, uint n, crnlib::vector<uint8>& buf);
bool unpack(const void* p, uint n, crnlib::vector<uint8>& buf); bool unpack(const void* p, uint n, crnlib::vector<uint8>& buf);
private: private:
typedef int (__stdcall *LzmaCompressFuncPtr)(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, typedef int (CRNLIB_STDCALL *LzmaCompressFuncPtr)(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */ unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
int level, /* 0 <= level <= 9, default = 5 */ int level, /* 0 <= level <= 9, default = 5 */
unsigned dictSize, /* default = (1 << 24) */ unsigned dictSize, /* default = (1 << 24) */
@@ -30,7 +30,7 @@ namespace crnlib
int numThreads /* 1 or 2, default = 2 */ int numThreads /* 1 or 2, default = 2 */
); );
typedef int (__stdcall *LzmaUncompressFuncPtr)(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen, typedef int (CRNLIB_STDCALL *LzmaUncompressFuncPtr)(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen,
const unsigned char *props, size_t propsSize); const unsigned char *props, size_t propsSize);
LzmaCompressFuncPtr m_pCompress; LzmaCompressFuncPtr m_pCompress;
+8
View File
@@ -216,6 +216,14 @@ namespace crnlib
void compute_lower_pow2_dim(int& width, int& height); void compute_lower_pow2_dim(int& width, int& height);
void compute_upper_pow2_dim(int& width, int& height); void compute_upper_pow2_dim(int& width, int& height);
inline bool equal_tol(float a, float b, float t)
{
return fabs(a - b) < ((maximum(fabs(a), fabs(b)) + 1.0f) * t);
}
inline bool equal_tol(double a, double b, double t)
{
return fabs(a - b) < ((maximum(fabs(a), fabs(b)) + 1.0f) * t);
}
} }
} // namespace crnlib } // namespace crnlib
+92 -11
View File
@@ -1,15 +1,16 @@
// File: crn_mem.cpp // File: crn_mem.cpp
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#include "crn_core.h" #include "crn_core.h"
#include "crn_spinlock.h"
#include "crn_console.h" #include "crn_console.h"
#include "../inc/crnlib.h" #include "../inc/crnlib.h"
#include <malloc.h> #include <malloc.h>
#if CRNLIB_USE_WIN32_API
#include "crn_winhdr.h" #include "crn_winhdr.h"
#endif
#define CRNLIB_MEM_STATS 0 #define CRNLIB_MEM_STATS 0
#ifndef CRNLIB_USE_WIN32_API #if !CRNLIB_USE_WIN32_API
#define _msize malloc_usable_size #define _msize malloc_usable_size
#endif #endif
@@ -59,7 +60,7 @@ namespace crnlib
return new_total_allocated; return new_total_allocated;
} }
#endif // CRNLIB_MEM_STATS #endif // CRNLIB_MEM_STATS
static void* crnlib_default_realloc(void* p, size_t size, size_t* pActual_size, bool movable, void* pUser_data) static void* crnlib_default_realloc(void* p, size_t size, size_t* pActual_size, bool movable, void* pUser_data)
{ {
pUser_data; pUser_data;
@@ -88,7 +89,6 @@ namespace crnlib
#ifdef WIN32 #ifdef WIN32
p_new = ::_expand(p, size); p_new = ::_expand(p, size);
#else #else
p_new = NULL; p_new = NULL;
#endif #endif
@@ -121,15 +121,96 @@ namespace crnlib
return p ? _msize(p) : 0; return p ? _msize(p) : 0;
} }
#if 0
static __declspec(thread) void *g_pBuf;
static __declspec(thread) size_t g_buf_size;
static __declspec(thread) size_t g_buf_ofs;
static size_t crnlib_nofree_msize(void* p, void* pUser_data)
{
pUser_data;
return p ? ((const size_t*)p)[-1] : 0;
}
static void* crnlib_nofree_realloc(void* p, size_t size, size_t* pActual_size, bool movable, void* pUser_data)
{
pUser_data;
void* p_new;
if (!p)
{
size = math::align_up_value(size, CRNLIB_MIN_ALLOC_ALIGNMENT);
size_t actual_size = sizeof(size_t)*2 + size;
size_t num_remaining = g_buf_size - g_buf_ofs;
if (num_remaining < actual_size)
{
g_buf_size = CRNLIB_MAX(actual_size, 32*1024*1024);
g_buf_ofs = 0;
g_pBuf = malloc(g_buf_size);
if (!g_pBuf)
return NULL;
}
p_new = (uint8*)g_pBuf + g_buf_ofs;
((size_t*)p_new)[1] = size;
p_new = (size_t*)p_new + 2;
g_buf_ofs += actual_size;
if (pActual_size)
*pActual_size = size;
CRNLIB_ASSERT(crnlib_nofree_msize(p_new, NULL) == size);
}
else if (!size)
{
if (pActual_size)
*pActual_size = 0;
p_new = NULL;
}
else
{
size_t cur_size = crnlib_nofree_msize(p, NULL);
p_new = p;
if (!movable)
return NULL;
if (size > cur_size)
{
p_new = crnlib_nofree_realloc(NULL, size, NULL, true, NULL);
if (!p_new)
return NULL;
memcpy(p_new, p, cur_size);
cur_size = size;
}
if (pActual_size)
*pActual_size = cur_size;
}
return p_new;
}
static crn_realloc_func g_pRealloc = crnlib_nofree_realloc;
static crn_msize_func g_pMSize = crnlib_nofree_msize;
#else
static crn_realloc_func g_pRealloc = crnlib_default_realloc; static crn_realloc_func g_pRealloc = crnlib_default_realloc;
static crn_msize_func g_pMSize = crnlib_default_msize; static crn_msize_func g_pMSize = crnlib_default_msize;
#endif
static void* g_pUser_data; static void* g_pUser_data;
void crnlib_mem_error(const char* p_msg) void crnlib_mem_error(const char* p_msg)
{ {
crnlib_assert(p_msg, __FILE__, __LINE__); crnlib_assert(p_msg, __FILE__, __LINE__);
} }
void* crnlib_malloc(size_t size)
{
return crnlib_malloc(size, NULL);
}
void* crnlib_malloc(size_t size, size_t* pActual_size) void* crnlib_malloc(size_t size, size_t* pActual_size)
{ {
size = (size + sizeof(uint32) - 1U) & ~(sizeof(uint32) - 1U); size = (size + sizeof(uint32) - 1U) & ~(sizeof(uint32) - 1U);
@@ -182,7 +263,7 @@ namespace crnlib
size_t cur_size = p ? (*g_pMSize)(p, g_pUser_data) : 0; size_t cur_size = p ? (*g_pMSize)(p, g_pUser_data) : 0;
CRNLIB_ASSERT(!p || (cur_size >= sizeof(uint32))); CRNLIB_ASSERT(!p || (cur_size >= sizeof(uint32)));
#endif #endif
if ((size) && (size < sizeof(uint32))) if ((size) && (size < sizeof(uint32)))
size = sizeof(uint32); size = sizeof(uint32);
size_t actual_size = size; size_t actual_size = size;
@@ -253,19 +334,19 @@ namespace crnlib
return (*g_pMSize)(p, g_pUser_data); return (*g_pMSize)(p, g_pUser_data);
} }
void crnlib_print_mem_stats() void crnlib_print_mem_stats()
{ {
#if CRNLIB_MEM_STATS #if CRNLIB_MEM_STATS
if (console::is_initialized()) if (console::is_initialized())
{ {
console::debug(L"crnlib_print_mem_stats:"); console::debug("crnlib_print_mem_stats:");
console::debug(L"Current blocks: %u, allocated: %I64u, max ever allocated: %I64i", g_total_blocks, (int64)g_total_allocated, (int64)g_max_allocated); console::debug("Current blocks: %u, allocated: " CRNLIB_INT64_FORMAT_SPECIFIER ", max ever allocated: " CRNLIB_INT64_FORMAT_SPECIFIER, g_total_blocks, (int64)g_total_allocated, (int64)g_max_allocated);
} }
else else
{ {
printf("crnlib_print_mem_stats:\n"); printf("crnlib_print_mem_stats:\n");
printf("Current blocks: %u, allocated: %I64u, max ever allocated: %I64i\n", g_total_blocks, (int64)g_total_allocated, (int64)g_max_allocated); printf("Current blocks: %u, allocated: " CRNLIB_INT64_FORMAT_SPECIFIER ", max ever allocated: " CRNLIB_INT64_FORMAT_SPECIFIER "\n", g_total_blocks, (int64)g_total_allocated, (int64)g_max_allocated);
} }
#endif #endif
} }
+25 -1
View File
@@ -14,7 +14,8 @@ namespace crnlib
const uint32 CRNLIB_MAX_POSSIBLE_BLOCK_SIZE = 0x7FFF0000U; const uint32 CRNLIB_MAX_POSSIBLE_BLOCK_SIZE = 0x7FFF0000U;
#endif #endif
void* crnlib_malloc(size_t size, size_t* pActual_size = NULL); void* crnlib_malloc(size_t size);
void* crnlib_malloc(size_t size, size_t* pActual_size);
void* crnlib_realloc(void* p, size_t size, size_t* pActual_size = NULL, bool movable = true); void* crnlib_realloc(void* p, size_t size, size_t* pActual_size = NULL, bool movable = true);
void* crnlib_calloc(size_t count, size_t size, size_t* pActual_size = NULL); void* crnlib_calloc(size_t count, size_t size, size_t* pActual_size = NULL);
void crnlib_free(void* p); void crnlib_free(void* p);
@@ -183,3 +184,26 @@ namespace crnlib
} }
} // namespace crnlib } // namespace crnlib
#define CRNLIB_DEFINE_NEW_DELETE \
void* operator new (size_t size) \
{ \
void* p = crnlib::crnlib_malloc(size); \
if (!p) \
crnlib_fail("new: Out of memory!", __FILE__, __LINE__); \
return p; \
} \
void* operator new[] (size_t size) \
{ \
void* p = crnlib::crnlib_malloc(size); \
if (!p) \
crnlib_fail("new[]: Out of memory!", __FILE__, __LINE__); \
return p; \
} \
void operator delete (void* p_block) \
{ \
crnlib::crnlib_free(p_block); \
} \
void operator delete[] (void* p_block) \
{ \
crnlib::crnlib_free(p_block); \
}
+2 -51
View File
@@ -41,36 +41,7 @@ namespace crnlib
return g_all_pixel_formats[index]; return g_all_pixel_formats[index];
} }
const wchar_t* get_pixel_format_string(pixel_format fmt) const char* get_pixel_format_string(pixel_format fmt)
{
switch (fmt)
{
case PIXEL_FMT_INVALID: return L"INVALID";
case PIXEL_FMT_DXT1: return L"DXT1";
case PIXEL_FMT_DXT1A: return L"DXT1A";
case PIXEL_FMT_DXT2: return L"DXT2";
case PIXEL_FMT_DXT3: return L"DXT3";
case PIXEL_FMT_DXT4: return L"DXT4";
case PIXEL_FMT_DXT5: return L"DXT5";
case PIXEL_FMT_3DC: return L"3DC";
case PIXEL_FMT_DXN: return L"DXN";
case PIXEL_FMT_DXT5A: return L"DXT5A";
case PIXEL_FMT_DXT5_CCxY: return L"DXT5_CCxY";
case PIXEL_FMT_DXT5_xGxR: return L"DXT5_xGxR";
case PIXEL_FMT_DXT5_xGBR: return L"DXT5_xGBR";
case PIXEL_FMT_DXT5_AGBR: return L"DXT5_AGBR";
case PIXEL_FMT_R8G8B8: return L"R8G8B8";
case PIXEL_FMT_A8R8G8B8: return L"A8R8G8B8";
case PIXEL_FMT_A8: return L"A8";
case PIXEL_FMT_L8: return L"L8";
case PIXEL_FMT_A8L8: return L"A8L8";
default: break;
}
CRNLIB_ASSERT(false);
return L"?";
}
const char* get_pixel_format_stringa(pixel_format fmt)
{ {
switch (fmt) switch (fmt)
{ {
@@ -99,27 +70,7 @@ namespace crnlib
return "?"; return "?";
} }
const wchar_t* get_crn_format_string(crn_format fmt) const char* get_crn_format_string(crn_format fmt)
{
switch (fmt)
{
case cCRNFmtDXT1: return L"DXT1";
case cCRNFmtDXT3: return L"DXT3";
case cCRNFmtDXT5: return L"DXT5";
case cCRNFmtDXT5_CCxY: return L"DXT5_CCxY";
case cCRNFmtDXT5_xGBR: return L"DXT5_xGBR";
case cCRNFmtDXT5_AGBR: return L"DXT5_AGBR";
case cCRNFmtDXT5_xGxR: return L"DXT5_xGxR";
case cCRNFmtDXN_XY: return L"DXN_XY";
case cCRNFmtDXN_YX: return L"DXN_YX";
case cCRNFmtDXT5A: return L"DXT5A";
default: break;
}
CRNLIB_ASSERT(false);
return L"?";
}
const char* get_crn_format_stringa(crn_format fmt)
{ {
switch (fmt) switch (fmt)
{ {
+2 -4
View File
@@ -12,11 +12,9 @@ namespace crnlib
uint get_num_formats(); uint get_num_formats();
pixel_format get_pixel_format_by_index(uint index); pixel_format get_pixel_format_by_index(uint index);
const wchar_t* get_pixel_format_string(pixel_format fmt); const char* get_pixel_format_string(pixel_format fmt);
const char* get_pixel_format_stringa(pixel_format fmt);
const wchar_t* get_crn_format_string(crn_format fmt); const char* get_crn_format_string(crn_format fmt);
const char* get_crn_format_stringa(crn_format fmt);
inline bool is_grayscale(pixel_format fmt) inline bool is_grayscale(pixel_format fmt)
{ {
+78 -5
View File
@@ -1,6 +1,73 @@
// File: crn_platform.cpp // File: crn_platform.cpp
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#include "crn_core.h" #include "crn_core.h"
#if CRNLIB_USE_WIN32_API
#include "crn_winhdr.h"
#endif
#ifndef _MSC_VER
int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...)
{
if (!sizeOfBuffer)
return 0;
va_list args;
va_start(args, format);
int c = vsnprintf(buffer, sizeOfBuffer, format, args);
va_end(args);
buffer[sizeOfBuffer - 1] = '\0';
if (c < 0)
return sizeOfBuffer - 1;
return CRNLIB_MIN(c, (int)sizeOfBuffer - 1);
}
int vsprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, va_list args)
{
if (!sizeOfBuffer)
return 0;
int c = vsnprintf(buffer, sizeOfBuffer, format, args);
buffer[sizeOfBuffer - 1] = '\0';
if (c < 0)
return sizeOfBuffer - 1;
return CRNLIB_MIN(c, (int)sizeOfBuffer - 1);
}
char* strlwr(char* p)
{
char *q = p;
while (*q)
{
char c = *q;
*q++ = tolower(c);
}
return p;
}
char* strupr(char *p)
{
char *q = p;
while (*q)
{
char c = *q;
*q++ = toupper(c);
}
return p;
}
#endif // __GNUC__
void crnlib_debug_break(void)
{
CRNLIB_BREAKPOINT
}
#if CRNLIB_USE_WIN32_API
#include "crn_winhdr.h" #include "crn_winhdr.h"
bool crnlib_is_debugger_present(void) bool crnlib_is_debugger_present(void)
@@ -8,12 +75,18 @@ bool crnlib_is_debugger_present(void)
return IsDebuggerPresent() != 0; return IsDebuggerPresent() != 0;
} }
void crnlib_debug_break(void)
{
DebugBreak();
}
void crnlib_output_debug_string(const char* p) void crnlib_output_debug_string(const char* p)
{ {
OutputDebugStringA(p); OutputDebugStringA(p);
} }
#else
bool crnlib_is_debugger_present(void)
{
return false;
}
void crnlib_output_debug_string(const char* p)
{
puts(p);
}
#endif // CRNLIB_USE_WIN32_API
+82 -38
View File
@@ -2,44 +2,6 @@
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#pragma once #pragma once
#ifdef CRNLIB_PLATFORM_PC
const bool c_crnlib_little_endian_platform = true;
#else
const bool c_crnlib_little_endian_platform = false;
#endif
const bool c_crnlib_big_endian_platform = !c_crnlib_little_endian_platform;
inline bool crnlib_is_little_endian() { return c_crnlib_little_endian_platform; }
inline bool crnlib_is_big_endian() { return c_crnlib_big_endian_platform; }
inline bool crnlib_is_pc()
{
#ifdef CRNLIB_PLATFORM_PC
return true;
#else
return false;
#endif
}
inline bool crnlib_is_x86()
{
#ifdef CRNLIB_PLATFORM_PC_X86
return true;
#else
return false;
#endif
}
inline bool crnlib_is_x64()
{
#ifdef CRNLIB_PLATFORM_PC_X64
return true;
#else
return false;
#endif
}
bool crnlib_is_debugger_present(void); bool crnlib_is_debugger_present(void);
void crnlib_debug_break(void); void crnlib_debug_break(void);
void crnlib_output_debug_string(const char* p); void crnlib_output_debug_string(const char* p);
@@ -47,3 +9,85 @@ void crnlib_output_debug_string(const char* p);
// actually in crnlib_assert.cpp // actually in crnlib_assert.cpp
void crnlib_assert(const char* pExp, const char* pFile, unsigned line); void crnlib_assert(const char* pExp, const char* pFile, unsigned line);
void crnlib_fail(const char* pExp, const char* pFile, unsigned line); void crnlib_fail(const char* pExp, const char* pFile, unsigned line);
#if CRNLIB_LITTLE_ENDIAN_CPU
const bool c_crnlib_little_endian_platform = true;
#else
const bool c_crnlib_little_endian_platform = false;
#endif
const bool c_crnlib_big_endian_platform = !c_crnlib_little_endian_platform;
#ifdef __GNUC__
#define crn_fopen(pDstFile, f, m) *(pDstFile) = fopen64(f, m)
#define crn_fseek fseeko64
#define crn_ftell ftello64
#elif defined( _MSC_VER )
#define crn_fopen(pDstFile, f, m) fopen_s(pDstFile, f, m)
#define crn_fseek _fseeki64
#define crn_ftell _ftelli64
#else
#define crn_fopen(pDstFile, f, m) *(pDstFile) = fopen(f, m)
#define crn_fseek(s, o, w) fseek(s, static_cast<long>(o), w)
#define crn_ftell ftell
#endif
#if CRNLIB_USE_WIN32_API
#define CRNLIB_BREAKPOINT DebugBreak();
#define CRNLIB_BUILTIN_EXPECT(c, v) c
#elif defined(__GNUC__)
#define CRNLIB_BREAKPOINT asm("int $3");
#define CRNLIB_BUILTIN_EXPECT(c, v) __builtin_expect(c, v)
#else
#define CRNLIB_BREAKPOINT
#define CRNLIB_BUILTIN_EXPECT(c, v) c
#endif
#if defined(__GNUC__)
#define CRNLIB_ALIGNED(x) __attribute__((aligned(x)))
#elif defined(_MSC_VER)
#define CRNLIB_ALIGNED(x) __declspec(align(x))
#else
#define CRNLIB_ALIGNED(x)
#endif
#define CRNLIB_GET_ALIGNMENT(v) ((!sizeof(v)) ? 1 : (__alignof(v) ? __alignof(v) : sizeof(uint32)))
#ifndef _MSC_VER
int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...);
int vsprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, va_list args);
char* strlwr(char* p);
char* strupr(char *p);
#define _stricmp strcasecmp
#define _strnicmp strncasecmp
#endif
inline bool crnlib_is_little_endian() { return c_crnlib_little_endian_platform; }
inline bool crnlib_is_big_endian() { return c_crnlib_big_endian_platform; }
inline bool crnlib_is_pc()
{
#ifdef CRNLIB_PLATFORM_PC
return true;
#else
return false;
#endif
}
inline bool crnlib_is_x86()
{
#ifdef CRNLIB_PLATFORM_PC_X86
return true;
#else
return false;
#endif
}
inline bool crnlib_is_x64()
{
#ifdef CRNLIB_PLATFORM_PC_X64
return true;
#else
return false;
#endif
}
+2 -2
View File
@@ -156,7 +156,7 @@ namespace crnlib
uint c = pCodesizes[i]; uint c = pCodesizes[i];
if (c) if (c)
{ {
CRNLIB_ASSERT(next_code[c] <= UINT16_MAX); CRNLIB_ASSERT(next_code[c] <= cUINT16_MAX);
pCodes[i] = static_cast<uint16>(next_code[c]++); pCodes[i] = static_cast<uint16>(next_code[c]++);
CRNLIB_ASSERT(math::total_bits(pCodes[i]) <= pCodesizes[i]); CRNLIB_ASSERT(math::total_bits(pCodes[i]) <= pCodesizes[i]);
@@ -300,7 +300,7 @@ namespace crnlib
CRNLIB_ASSERT(t < (1U << table_bits)); CRNLIB_ASSERT(t < (1U << table_bits));
CRNLIB_ASSERT(pTables->m_lookup[t] == UINT32_MAX); CRNLIB_ASSERT(pTables->m_lookup[t] == cUINT32_MAX);
pTables->m_lookup[t] = sym_index | (codesize << 16U); pTables->m_lookup[t] = sym_index | (codesize << 16U);
} }
+14 -13
View File
@@ -61,7 +61,7 @@ namespace crnlib
CRNLIB_ASSERT(n && pBlocks); CRNLIB_ASSERT(n && pBlocks);
m_main_thread_id = get_current_thread_id(); m_main_thread_id = crn_get_current_thread_id();
m_num_blocks = n; m_num_blocks = n;
m_pBlocks = pBlocks; m_pBlocks = pBlocks;
@@ -99,6 +99,11 @@ namespace crnlib
if (debugging) if (debugging)
debug_img.resize(num_chunks_x * cChunkPixelWidth, num_chunks_y * cChunkPixelHeight); debug_img.resize(num_chunks_x * cChunkPixelWidth, num_chunks_y * cChunkPixelHeight);
float adaptive_tile_color_psnr_derating = 1.5f; // was 2.4f
if ((level) && (adaptive_tile_color_psnr_derating > .25f))
{
adaptive_tile_color_psnr_derating = math::maximum(.25f, adaptive_tile_color_psnr_derating / powf(3.1f, static_cast<float>(level))); // was 3.0f
}
for (uint chunk_y = 0; chunk_y < num_chunks_y; chunk_y++) for (uint chunk_y = 0; chunk_y < num_chunks_y; chunk_y++)
{ {
for (uint chunk_x = 0; chunk_x < num_chunks_x; chunk_x++) for (uint chunk_x = 0; chunk_x < num_chunks_x; chunk_x++)
@@ -197,13 +202,8 @@ namespace crnlib
if (mean_squared) if (mean_squared)
peak_snr = math::clamp<double>(log10(255.0f / root_mean_squared) * 20.0f, 0.0f, 500.0f); peak_snr = math::clamp<double>(log10(255.0f / root_mean_squared) * 20.0f, 0.0f, 500.0f);
float adaptive_tile_color_psnr_derating = 2.4f;
//if (level) //if (level)
// adaptive_tile_color_psnr_derating = math::lerp(adaptive_tile_color_psnr_derating * .5f, .3f, math::maximum((level - 1) / float(m_params.m_num_mips - 2), 1.0f)); // adaptive_tile_color_psnr_derating = math::lerp(adaptive_tile_color_psnr_derating * .5f, .3f, math::maximum((level - 1) / float(m_params.m_num_mips - 2), 1.0f));
if ((level) && (adaptive_tile_color_psnr_derating > .25f))
{
adaptive_tile_color_psnr_derating = math::maximum(.25f, adaptive_tile_color_psnr_derating / powf(3.0f, static_cast<float>(level)));
}
float color_derating = math::lerp( 0.0f, adaptive_tile_color_psnr_derating, (g_chunk_encodings[e].m_num_tiles - 1) / 3.0f ); float color_derating = math::lerp( 0.0f, adaptive_tile_color_psnr_derating, (g_chunk_encodings[e].m_num_tiles - 1) / 3.0f );
peak_snr = peak_snr - color_derating; peak_snr = peak_snr - color_derating;
@@ -306,7 +306,7 @@ namespace crnlib
#if GENERATE_DEBUG_IMAGES #if GENERATE_DEBUG_IMAGES
if (debugging) if (debugging)
image_utils::save_to_file_stb(dynamic_wstring(cVarArg, L"debug_%u.tga", level).get_ptr(), debug_img, image_utils::cSaveIgnoreAlpha); image_utils::save_to_file_stb(dynamic_string(cVarArg, "debug_%u.tga", level).get_ptr(), debug_img, image_utils::cSaveIgnoreAlpha);
#endif #endif
} // level } // level
@@ -440,7 +440,7 @@ namespace crnlib
if ((cluster_index & cluster_index_progress_mask) == 0) if ((cluster_index & cluster_index_progress_mask) == 0)
{ {
if (get_current_thread_id() == m_main_thread_id) if (crn_get_current_thread_id() == m_main_thread_id)
{ {
if (!update_progress(cluster_index, m_endpoint_cluster_indices.size() - 1)) if (!update_progress(cluster_index, m_endpoint_cluster_indices.size() - 1))
return; return;
@@ -547,7 +547,8 @@ namespace crnlib
{ {
const uint block_index = indices[block_iter]; const uint block_index = indices[block_iter];
const color_quad_u8* pSrc_pixels = &m_pBlocks[block_index].m_pixels[0][0]; //const color_quad_u8* pSrc_pixels = &m_pBlocks[block_index].m_pixels[0][0];
const color_quad_u8* pSrc_pixels = (const color_quad_u8*)m_pBlocks[block_index].m_pixels;
for (uint i = 0; i < cDXTBlockSize * cDXTBlockSize; i++) for (uint i = 0; i < cDXTBlockSize * cDXTBlockSize; i++)
{ {
@@ -646,7 +647,7 @@ namespace crnlib
if ((cluster_index & 255) == 0) if ((cluster_index & 255) == 0)
{ {
if (get_current_thread_id() == m_main_thread_id) if (crn_get_current_thread_id() == m_main_thread_id)
{ {
if (!update_progress(cluster_index, task_params.m_selector_cluster_indices.size() - 1)) if (!update_progress(cluster_index, task_params.m_selector_cluster_indices.size() - 1))
return; return;
@@ -681,7 +682,7 @@ namespace crnlib
if (m_params.m_dxt1a_alpha_threshold > 0) if (m_params.m_dxt1a_alpha_threshold > 0)
{ {
const color_quad_u8* pSrc_pixels = &m_pBlocks[block_index].m_pixels[0][0]; const color_quad_u8* pSrc_pixels = (const color_quad_u8*)m_pBlocks[block_index].m_pixels;
for (uint i = 0; i < cDXTBlockSize * cDXTBlockSize; i++) for (uint i = 0; i < cDXTBlockSize * cDXTBlockSize; i++)
{ {
@@ -809,7 +810,7 @@ namespace crnlib
{ {
CRNLIB_ASSERT(m_num_blocks); CRNLIB_ASSERT(m_num_blocks);
m_main_thread_id = get_current_thread_id(); m_main_thread_id = crn_get_current_thread_id();
m_canceled = false; m_canceled = false;
m_pDst_elements = pDst_elements; m_pDst_elements = pDst_elements;
@@ -824,7 +825,7 @@ namespace crnlib
const float quality = m_params.m_quality_level / (float)qdxt1_params::cMaxQuality; const float quality = m_params.m_quality_level / (float)qdxt1_params::cMaxQuality;
const float endpoint_quality = powf(quality, 1.8f * quality_power_mul); const float endpoint_quality = powf(quality, 1.8f * quality_power_mul);
const float selector_quality = powf(quality, 1.65f * quality_power_mul); const float selector_quality = powf(quality, 1.65f * quality_power_mul);
//const uint max_endpoint_clusters = math::clamp<uint>(static_cast<uint>(m_endpoint_clusterizer.get_codebook_size() * endpoint_quality), 128U, m_endpoint_clusterizer.get_codebook_size()); //const uint max_endpoint_clusters = math::clamp<uint>(static_cast<uint>(m_endpoint_clusterizer.get_codebook_size() * endpoint_quality), 128U, m_endpoint_clusterizer.get_codebook_size());
//const uint max_selector_clusters = math::clamp<uint>(static_cast<uint>(m_max_selector_clusters * selector_quality), 150U, m_max_selector_clusters); //const uint max_selector_clusters = math::clamp<uint>(static_cast<uint>(m_max_selector_clusters * selector_quality), 150U, m_max_selector_clusters);
const uint max_endpoint_clusters = math::clamp<uint>(static_cast<uint>(m_endpoint_clusterizer.get_codebook_size() * endpoint_quality), 96U, m_endpoint_clusterizer.get_codebook_size()); const uint max_endpoint_clusters = math::clamp<uint>(static_cast<uint>(m_endpoint_clusterizer.get_codebook_size() * endpoint_quality), 96U, m_endpoint_clusterizer.get_codebook_size());
+40 -42
View File
@@ -2,8 +2,6 @@
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#pragma once #pragma once
#include "crn_dxt.h" #include "crn_dxt.h"
#include "crn_task_pool.h"
#include "crn_spinlock.h"
#include "crn_hash_map.h" #include "crn_hash_map.h"
#include "crn_clusterizer.h" #include "crn_clusterizer.h"
#include "crn_hash.h" #include "crn_hash.h"
@@ -17,8 +15,8 @@ namespace crnlib
qdxt1_params() qdxt1_params()
{ {
clear(); clear();
} }
void clear() void clear()
{ {
m_quality_level = cMaxQuality; m_quality_level = cMaxQuality;
@@ -44,27 +42,27 @@ namespace crnlib
m_quality_level = quality_level; m_quality_level = quality_level;
m_dxt1a_alpha_threshold = pp.m_dxt1a_alpha_threshold; m_dxt1a_alpha_threshold = pp.m_dxt1a_alpha_threshold;
} }
enum { cMaxQuality = cCRNMaxQualityLevel }; enum { cMaxQuality = cCRNMaxQualityLevel };
uint m_quality_level; uint m_quality_level;
uint m_dxt1a_alpha_threshold; uint m_dxt1a_alpha_threshold;
crn_dxt_quality m_dxt_quality; crn_dxt_quality m_dxt_quality;
bool m_perceptual; bool m_perceptual;
bool m_use_alpha_blocks; bool m_use_alpha_blocks;
bool m_hierarchical; bool m_hierarchical;
struct mip_desc struct mip_desc
{ {
uint m_first_block; uint m_first_block;
uint m_block_width; uint m_block_width;
uint m_block_height; uint m_block_height;
}; };
uint m_num_mips; uint m_num_mips;
enum { cMaxMips = 128 }; enum { cMaxMips = 128 };
mip_desc m_mip_desc[cMaxMips]; mip_desc m_mip_desc[cMaxMips];
typedef bool (*progress_callback_func)(uint percentage_completed, void* pProgress_data); typedef bool (*progress_callback_func)(uint percentage_completed, void* pProgress_data);
progress_callback_func m_pProgress_func; progress_callback_func m_pProgress_func;
void* m_pProgress_data; void* m_pProgress_data;
@@ -75,67 +73,67 @@ namespace crnlib
class qdxt1 class qdxt1
{ {
CRNLIB_NO_COPY_OR_ASSIGNMENT_OP(qdxt1); CRNLIB_NO_COPY_OR_ASSIGNMENT_OP(qdxt1);
public: public:
qdxt1(task_pool& task_pool); qdxt1(task_pool& task_pool);
~qdxt1(); ~qdxt1();
void clear(); void clear();
bool init(uint n, const dxt_pixel_block* pBlocks, const qdxt1_params& params); bool init(uint n, const dxt_pixel_block* pBlocks, const qdxt1_params& params);
uint get_num_blocks() const { return m_num_blocks; } uint get_num_blocks() const { return m_num_blocks; }
const dxt_pixel_block* get_blocks() const { return m_pBlocks; } const dxt_pixel_block* get_blocks() const { return m_pBlocks; }
bool pack(dxt1_block* pDst_elements, uint elements_per_block, const qdxt1_params& params, float quality_power_mul); bool pack(dxt1_block* pDst_elements, uint elements_per_block, const qdxt1_params& params, float quality_power_mul);
private: private:
task_pool* m_pTask_pool; task_pool* m_pTask_pool;
uint32 m_main_thread_id; crn_thread_id_t m_main_thread_id;
bool m_canceled; bool m_canceled;
uint m_progress_start; uint m_progress_start;
uint m_progress_range; uint m_progress_range;
uint m_num_blocks; uint m_num_blocks;
const dxt_pixel_block* m_pBlocks; const dxt_pixel_block* m_pBlocks;
dxt1_block* m_pDst_elements; dxt1_block* m_pDst_elements;
uint m_elements_per_block; uint m_elements_per_block;
qdxt1_params m_params; qdxt1_params m_params;
uint m_max_selector_clusters; uint m_max_selector_clusters;
int m_prev_percentage_complete; int m_prev_percentage_complete;
typedef vec<6, float> vec6F; typedef vec<6, float> vec6F;
typedef clusterizer<vec6F> vec6F_clusterizer; typedef clusterizer<vec6F> vec6F_clusterizer;
vec6F_clusterizer m_endpoint_clusterizer; vec6F_clusterizer m_endpoint_clusterizer;
crnlib::vector< crnlib::vector<uint> > m_endpoint_cluster_indices; crnlib::vector< crnlib::vector<uint> > m_endpoint_cluster_indices;
typedef vec<16, float> vec16F; typedef vec<16, float> vec16F;
typedef threaded_clusterizer<vec16F> vec16F_clusterizer; typedef threaded_clusterizer<vec16F> vec16F_clusterizer;
typedef vec16F_clusterizer::weighted_vec weighted_selector_vec; typedef vec16F_clusterizer::weighted_vec weighted_selector_vec;
typedef vec16F_clusterizer::weighted_vec_array weighted_selector_vec_array; typedef vec16F_clusterizer::weighted_vec_array weighted_selector_vec_array;
vec16F_clusterizer m_selector_clusterizer; vec16F_clusterizer m_selector_clusterizer;
crnlib::vector< crnlib::vector<uint> > m_cached_selector_cluster_indices[qdxt1_params::cMaxQuality + 1]; crnlib::vector< crnlib::vector<uint> > m_cached_selector_cluster_indices[qdxt1_params::cMaxQuality + 1];
struct cluster_id struct cluster_id
{ {
cluster_id() : m_hash(0) cluster_id() : m_hash(0)
{ {
} }
cluster_id(const crnlib::vector<uint>& indices) cluster_id(const crnlib::vector<uint>& indices)
{ {
set(indices); set(indices);
} }
void set(const crnlib::vector<uint>& indices) void set(const crnlib::vector<uint>& indices)
{ {
m_cells.resize(indices.size()); m_cells.resize(indices.size());
@@ -145,29 +143,29 @@ namespace crnlib
std::sort(m_cells.begin(), m_cells.end()); std::sort(m_cells.begin(), m_cells.end());
m_hash = fast_hash(&m_cells[0], sizeof(m_cells[0]) * m_cells.size()); m_hash = fast_hash(&m_cells[0], sizeof(m_cells[0]) * m_cells.size());
} }
bool operator< (const cluster_id& rhs) const bool operator< (const cluster_id& rhs) const
{ {
return m_cells < rhs.m_cells; return m_cells < rhs.m_cells;
} }
bool operator== (const cluster_id& rhs) const bool operator== (const cluster_id& rhs) const
{ {
if (m_hash != rhs.m_hash) if (m_hash != rhs.m_hash)
return false; return false;
return m_cells == rhs.m_cells; return m_cells == rhs.m_cells;
} }
crnlib::vector<uint32> m_cells; crnlib::vector<uint32> m_cells;
size_t m_hash; size_t m_hash;
operator size_t() const { return m_hash; } operator size_t() const { return m_hash; }
}; };
typedef crnlib::hash_map<cluster_id, uint> cluster_hash; typedef crnlib::hash_map<cluster_id, uint> cluster_hash;
cluster_hash m_cluster_hash; cluster_hash m_cluster_hash;
spinlock m_cluster_hash_lock; spinlock m_cluster_hash_lock;
@@ -178,10 +176,10 @@ namespace crnlib
void pack_endpoints_task(uint64 data, void* pData_ptr); void pack_endpoints_task(uint64 data, void* pData_ptr);
void optimize_selectors_task(uint64 data, void* pData_ptr); void optimize_selectors_task(uint64 data, void* pData_ptr);
bool create_selector_clusters(uint max_selector_clusters, crnlib::vector< crnlib::vector<uint> >& selector_cluster_indices); bool create_selector_clusters(uint max_selector_clusters, crnlib::vector< crnlib::vector<uint> >& selector_cluster_indices);
inline dxt1_block& get_block(uint index) const { return m_pDst_elements[index * m_elements_per_block]; } inline dxt1_block& get_block(uint index) const { return m_pDst_elements[index * m_elements_per_block]; }
}; };
CRNLIB_DEFINE_BITWISE_MOVABLE(qdxt1::cluster_id); CRNLIB_DEFINE_BITWISE_MOVABLE(qdxt1::cluster_id);
} // namespace crnlib } // namespace crnlib
+7 -6
View File
@@ -62,7 +62,7 @@ namespace crnlib
CRNLIB_ASSERT(n && pBlocks); CRNLIB_ASSERT(n && pBlocks);
m_main_thread_id = get_current_thread_id(); m_main_thread_id = crn_get_current_thread_id();
m_num_blocks = n; m_num_blocks = n;
m_pBlocks = pBlocks; m_pBlocks = pBlocks;
@@ -286,7 +286,7 @@ namespace crnlib
#if QDXT5_DEBUGGING #if QDXT5_DEBUGGING
if (debugging) if (debugging)
image_utils::save_to_file_stb(dynamic_wstring(cVarArg, L"debug_%u.tga", level).get_ptr(), debug_img, image_utils::cSaveIgnoreAlpha); image_utils::save_to_file_stb(dynamic_wstring(cVarArg, "debug_%u.tga", level).get_ptr(), debug_img, image_utils::cSaveIgnoreAlpha);
#endif #endif
} // level } // level
@@ -419,7 +419,7 @@ namespace crnlib
if ((cluster_index & cluster_index_progress_mask) == 0) if ((cluster_index & cluster_index_progress_mask) == 0)
{ {
if (get_current_thread_id() == m_main_thread_id) if (crn_get_current_thread_id() == m_main_thread_id)
{ {
if (!update_progress(cluster_index, m_endpoint_cluster_indices.size() - 1)) if (!update_progress(cluster_index, m_endpoint_cluster_indices.size() - 1))
return; return;
@@ -444,7 +444,8 @@ namespace crnlib
{ {
const uint block_index = cluster_indices[block_iter]; const uint block_index = cluster_indices[block_iter];
const color_quad_u8* pSrc_pixels = &m_pBlocks[block_index].m_pixels[0][0]; //const color_quad_u8* pSrc_pixels = &m_pBlocks[block_index].m_pixels[0][0];
const color_quad_u8* pSrc_pixels = (const color_quad_u8*)m_pBlocks[block_index].m_pixels;
for (uint i = 0; i < cDXTBlockSize * cDXTBlockSize; i++) for (uint i = 0; i < cDXTBlockSize * cDXTBlockSize; i++)
{ {
@@ -521,7 +522,7 @@ namespace crnlib
if ((cluster_index & 255) == 0) if ((cluster_index & 255) == 0)
{ {
if (get_current_thread_id() == m_main_thread_id) if (crn_get_current_thread_id() == m_main_thread_id)
{ {
if (!update_progress(cluster_index, task_params.m_selector_cluster_indices.size() - 1)) if (!update_progress(cluster_index, task_params.m_selector_cluster_indices.size() - 1))
return; return;
@@ -735,7 +736,7 @@ namespace crnlib
{ {
CRNLIB_ASSERT(m_num_blocks); CRNLIB_ASSERT(m_num_blocks);
m_main_thread_id = get_current_thread_id(); m_main_thread_id = crn_get_current_thread_id();
m_canceled = false; m_canceled = false;
m_pDst_elements = pDst_elements; m_pDst_elements = pDst_elements;
+13 -15
View File
@@ -1,8 +1,6 @@
// File: crn_qdxt5.h // File: crn_qdxt5.h
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#pragma once #pragma once
#include "crn_task_pool.h"
#include "crn_spinlock.h"
#include "crn_hash_map.h" #include "crn_hash_map.h"
#include "crn_clusterizer.h" #include "crn_clusterizer.h"
#include "crn_hash.h" #include "crn_hash.h"
@@ -17,23 +15,23 @@ namespace crnlib
qdxt5_params() qdxt5_params()
{ {
clear(); clear();
} }
void clear() void clear()
{ {
m_quality_level = cMaxQuality; m_quality_level = cMaxQuality;
m_dxt_quality = cCRNDXTQualityUber; m_dxt_quality = cCRNDXTQualityUber;
m_pProgress_func = NULL; m_pProgress_func = NULL;
m_pProgress_data = NULL; m_pProgress_data = NULL;
m_num_mips = 0; m_num_mips = 0;
m_hierarchical = true; m_hierarchical = true;
utils::zero_object(m_mip_desc); utils::zero_object(m_mip_desc);
m_comp_index = 3; m_comp_index = 3;
m_progress_start = 0; m_progress_start = 0;
m_progress_range = 100; m_progress_range = 100;
m_use_both_block_types = true; m_use_both_block_types = true;
} }
@@ -50,7 +48,7 @@ namespace crnlib
uint m_quality_level; uint m_quality_level;
crn_dxt_quality m_dxt_quality; crn_dxt_quality m_dxt_quality;
bool m_hierarchical; bool m_hierarchical;
struct mip_desc struct mip_desc
{ {
uint m_first_block; uint m_first_block;
@@ -67,20 +65,20 @@ namespace crnlib
void* m_pProgress_data; void* m_pProgress_data;
uint m_progress_start; uint m_progress_start;
uint m_progress_range; uint m_progress_range;
uint m_comp_index; uint m_comp_index;
bool m_use_both_block_types; bool m_use_both_block_types;
}; };
class qdxt5 class qdxt5
{ {
CRNLIB_NO_COPY_OR_ASSIGNMENT_OP(qdxt5); CRNLIB_NO_COPY_OR_ASSIGNMENT_OP(qdxt5);
public: public:
qdxt5(task_pool& task_pool); qdxt5(task_pool& task_pool);
~qdxt5(); ~qdxt5();
void clear(); void clear();
bool init(uint n, const dxt_pixel_block* pBlocks, const qdxt5_params& params); bool init(uint n, const dxt_pixel_block* pBlocks, const qdxt5_params& params);
@@ -92,7 +90,7 @@ namespace crnlib
private: private:
task_pool* m_pTask_pool; task_pool* m_pTask_pool;
uint32 m_main_thread_id; crn_thread_id_t m_main_thread_id;
bool m_canceled; bool m_canceled;
uint m_progress_start; uint m_progress_start;
@@ -146,7 +144,7 @@ namespace crnlib
std::sort(m_cells.begin(), m_cells.end()); std::sort(m_cells.begin(), m_cells.end());
m_hash = fast_hash(&m_cells[0], sizeof(m_cells[0]) * m_cells.size()); m_hash = fast_hash(&m_cells[0], sizeof(m_cells[0]) * m_cells.size());
} }
bool operator< (const cluster_id& rhs) const bool operator< (const cluster_id& rhs) const
@@ -156,7 +154,7 @@ namespace crnlib
bool operator== (const cluster_id& rhs) const bool operator== (const cluster_id& rhs) const
{ {
if (m_hash != rhs.m_hash) if (m_hash != rhs.m_hash)
return false; return false;
return m_cells == rhs.m_cells; return m_cells == rhs.m_cells;
+14
View File
@@ -174,6 +174,13 @@ namespace crnlib
return m_kiss99.next() ^ (m_ranctx.next() + m_well512.next()); return m_kiss99.next() ^ (m_ranctx.next() + m_well512.next());
} }
uint64 random::urand64()
{
uint64 result = urand32();
result <<= 32ULL;
result |= urand32();
return result;
}
uint32 random::fast_urand32() uint32 random::fast_urand32()
{ {
return m_well512.next(); return m_well512.next();
@@ -317,6 +324,13 @@ namespace crnlib
return SHR3 ^ CONG; return SHR3 ^ CONG;
} }
uint64 fast_random::urand64()
{
uint64 result = urand32();
result <<= 32ULL;
result |= urand32();
return result;
}
int fast_random::irand(int l, int h) int fast_random::irand(int l, int h)
{ {
CRNLIB_ASSERT(l < h); CRNLIB_ASSERT(l < h);
+2
View File
@@ -63,6 +63,7 @@ namespace crnlib
void seed(uint32 i1, uint32 i2, uint32 i3); void seed(uint32 i1, uint32 i2, uint32 i3);
uint32 urand32(); uint32 urand32();
uint64 urand64();
// "Fast" variant uses no multiplies. // "Fast" variant uses no multiplies.
uint32 fast_urand32(); uint32 fast_urand32();
@@ -99,6 +100,7 @@ namespace crnlib
void seed(uint32 i); void seed(uint32 i);
uint32 urand32(); uint32 urand32();
uint64 urand64();
int irand(int l, int h); int irand(int l, int h);
+43 -16
View File
@@ -193,17 +193,23 @@ typedef unsigned char stbi_uc;
// (you must include the appropriate extension in the filename). // (you must include the appropriate extension in the filename).
// returns TRUE on success, FALSE if couldn't open file, error writing file // returns TRUE on success, FALSE if couldn't open file, error writing file
extern int stbi_write_bmp (char const *filename, int x, int y, int comp, const void *data); extern int stbi_write_bmp (char const *filename, int x, int y, int comp, const void *data);
#ifdef _MSC_VER
extern int stbi_write_bmp_w (wchar_t const *filename, int x, int y, int comp, const void *data); extern int stbi_write_bmp_w (wchar_t const *filename, int x, int y, int comp, const void *data);
#endif
extern int stbi_write_tga (char const *filename, int x, int y, int comp, const void *data); extern int stbi_write_tga (char const *filename, int x, int y, int comp, const void *data);
#ifdef _MSC_VER
extern int stbi_write_tga_w (wchar_t const *filename, int x, int y, int comp, const void *data); extern int stbi_write_tga_w (wchar_t const *filename, int x, int y, int comp, const void *data);
#endif #endif
#endif
// PRIMARY API - works on images of any type // PRIMARY API - works on images of any type
// load image by filename, open file, or memory buffer // load image by filename, open file, or memory buffer
#ifndef STBI_NO_STDIO #ifndef STBI_NO_STDIO
extern stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp); extern stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp);
#ifdef _MSC_VER
extern stbi_uc *stbi_load_w (wchar_t const *filename, int *x, int *y, int *comp, int req_comp); extern stbi_uc *stbi_load_w (wchar_t const *filename, int *x, int *y, int *comp, int req_comp);
#endif
extern stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); extern stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
extern int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); extern int stbi_info_from_file (FILE *f, int *x, int *y, int *comp);
#endif #endif
@@ -227,7 +233,7 @@ extern void stbi_ldr_to_hdr_scale(float scale);
// get a VERY brief reason for failure // get a VERY brief reason for failure
// NOT THREADSAFE // NOT THREADSAFE
extern char *stbi_failure_reason (void); extern const char *stbi_failure_reason (void);
// free the loaded image -- this is just stb_free() // free the loaded image -- this is just stb_free()
extern void stbi_image_free (void *retval_from_stbi_load); extern void stbi_image_free (void *retval_from_stbi_load);
@@ -418,14 +424,14 @@ typedef unsigned char validate_uint32[sizeof(uint32)==4];
// //
// this is not threadsafe // this is not threadsafe
static char *failure_reason; static const char *failure_reason;
char *stbi_failure_reason(void) const char *stbi_failure_reason(void)
{ {
return failure_reason; return failure_reason;
} }
static int e(char *str) static int e(const char *str)
{ {
failure_reason = str; failure_reason = str;
return 0; return 0;
@@ -485,6 +491,7 @@ unsigned char *stbi_load(char const *filename, int *x, int *y, int *comp, int re
return result; return result;
} }
#ifdef _MSC_VER
unsigned char *stbi_load_w(wchar_t const *filename, int *x, int *y, int *comp, int req_comp) unsigned char *stbi_load_w(wchar_t const *filename, int *x, int *y, int *comp, int req_comp)
{ {
FILE *f = _wfopen(filename, L"rb"); FILE *f = _wfopen(filename, L"rb");
@@ -494,6 +501,7 @@ unsigned char *stbi_load_w(wchar_t const *filename, int *x, int *y, int *comp, i
fclose(f); fclose(f);
return result; return result;
} }
#endif
unsigned char *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) unsigned char *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp)
{ {
@@ -748,7 +756,7 @@ static void getn(stbi *s, stbi_uc *buffer, int n)
{ {
#ifndef STBI_NO_STDIO #ifndef STBI_NO_STDIO
if (s->img_file) { if (s->img_file) {
fread(buffer, 1, n, s->img_file); size_t nr = fread(buffer, 1, n, s->img_file); nr;
return; return;
} }
#endif #endif
@@ -1615,11 +1623,13 @@ typedef uint8 *(*resample_row_func)(uint8 *out, uint8 *in0, uint8 *in1,
static uint8 *resample_row_1(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) static uint8 *resample_row_1(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs)
{ {
out, in_far, w, hs;
return in_near; return in_near;
} }
static uint8* resample_row_v_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) static uint8* resample_row_v_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs)
{ {
hs;
// need to generate two samples vertically for every one in input // need to generate two samples vertically for every one in input
int i; int i;
for (i=0; i < w; ++i) for (i=0; i < w; ++i)
@@ -1629,6 +1639,7 @@ static uint8* resample_row_v_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w,
static uint8* resample_row_h_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) static uint8* resample_row_h_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs)
{ {
hs, in_far;
// need to generate two samples horizontally for every one in input // need to generate two samples horizontally for every one in input
int i; int i;
uint8 *input = in_near; uint8 *input = in_near;
@@ -1654,6 +1665,7 @@ static uint8* resample_row_h_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w
static uint8 *resample_row_hv_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) static uint8 *resample_row_hv_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs)
{ {
hs;
// need to generate 2x2 samples for every one in input // need to generate 2x2 samples for every one in input
int i,t0,t1; int i,t0,t1;
if (w == 1) { if (w == 1) {
@@ -1675,6 +1687,7 @@ static uint8 *resample_row_hv_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w
static uint8 *resample_row_generic(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) static uint8 *resample_row_generic(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs)
{ {
in_far;
// resample with nearest-neighbor // resample with nearest-neighbor
int i,j; int i,j;
for (i=0; i < w; ++i) for (i=0; i < w; ++i)
@@ -2395,10 +2408,14 @@ static int create_png_image_raw(png *a, uint8 *raw, uint32 raw_len, int out_n, u
a->out = (uint8 *) stb_malloc(x * y * out_n); a->out = (uint8 *) stb_malloc(x * y * out_n);
if (!a->out) return e("outofmem", "Out of memory"); if (!a->out) return e("outofmem", "Out of memory");
if (!stbi_png_partial) { if (!stbi_png_partial) {
if (s->img_x == x && s->img_y == y) if ((s->img_x == x) && (s->img_y == y))
{
if (raw_len != (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG"); if (raw_len != (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG");
}
else // interlaced: else // interlaced:
{
if (raw_len < (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG"); if (raw_len < (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG");
}
} }
for (j=0; j < y; ++j) { for (j=0; j < y; ++j) {
uint8 *cur = a->out + stride*j; uint8 *cur = a->out + stride*j;
@@ -2528,6 +2545,7 @@ static int compute_transparency(png *z, uint8 tc[3], int out_n)
static int expand_palette(png *a, uint8 *palette, int len, int pal_img_n) static int expand_palette(png *a, uint8 *palette, int len, int pal_img_n)
{ {
len;
uint32 i, pixel_count = a->s.img_x * a->s.img_y; uint32 i, pixel_count = a->s.img_x * a->s.img_y;
uint8 *p, *temp_out, *orig = a->out; uint8 *p, *temp_out, *orig = a->out;
@@ -3164,7 +3182,7 @@ static stbi_uc *tga_load(stbi *s, int *x, int *y, int *comp, int req_comp)
unsigned char *tga_palette = NULL; unsigned char *tga_palette = NULL;
int i, j; int i, j;
unsigned char raw_data[4]; unsigned char raw_data[4];
unsigned char trans_data[4]; unsigned char trans_data[4] = { 0, 0, 0, 0 };
int RLE_count = 0; int RLE_count = 0;
int RLE_repeating = 0; int RLE_repeating = 0;
int read_next_pixel = 1; int read_next_pixel = 1;
@@ -3402,6 +3420,7 @@ int stbi_psd_test_file(FILE *f)
{ {
stbi s; stbi s;
int r,n = ftell(f); int r,n = ftell(f);
memset(&s, 0, sizeof(s));
start_file(&s, f); start_file(&s, f);
r = psd_test(&s); r = psd_test(&s);
fseek(f,n,SEEK_SET); fseek(f,n,SEEK_SET);
@@ -3608,7 +3627,7 @@ stbi_uc *stbi_psd_load_from_memory (stbi_uc const *buffer, int len, int *x, int
#ifndef STBI_NO_HDR #ifndef STBI_NO_HDR
static int hdr_test(stbi *s) static int hdr_test(stbi *s)
{ {
char *signature = "#?RADIANCE\n"; const char *signature = "#?RADIANCE\n";
int i; int i;
for (i=0; signature[i]; ++i) for (i=0; signature[i]; ++i)
if (get8(s) != signature[i]) if (get8(s) != signature[i])
@@ -3628,6 +3647,7 @@ int stbi_hdr_test_file(FILE *f)
{ {
stbi s; stbi s;
int r,n = ftell(f); int r,n = ftell(f);
memset(&s, 0, sizeof(s));
start_file(&s, f); start_file(&s, f);
r = hdr_test(&s); r = hdr_test(&s);
fseek(f,n,SEEK_SET); fseek(f,n,SEEK_SET);
@@ -3639,7 +3659,8 @@ int stbi_hdr_test_file(FILE *f)
static char *hdr_gettoken(stbi *z, char *buffer) static char *hdr_gettoken(stbi *z, char *buffer)
{ {
int len=0; int len=0;
char *s = buffer, c = '\0'; //char *s = buffer;
char c = '\0';
c = get8(z); c = get8(z);
@@ -3859,18 +3880,18 @@ static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp,
fwrite(&d[comp-1], 1, 1, f); fwrite(&d[comp-1], 1, 1, f);
switch (comp) { switch (comp) {
case 1: case 1:
case 2: writef(f, "111", d[0],d[0],d[0]); case 2: writef(f, (char*)"111", d[0],d[0],d[0]);
break; break;
case 4: case 4:
if (!write_alpha) { if (!write_alpha) {
for (k=0; k < 3; ++k) for (k=0; k < 3; ++k)
px[k] = bg[k] + ((d[k] - bg[k]) * d[3])/255; px[k] = bg[k] + ((d[k] - bg[k]) * d[3])/255;
writef(f, "111", px[1-rgb_dir],px[1],px[1+rgb_dir]); writef(f, (char*)"111", px[1-rgb_dir],px[1],px[1+rgb_dir]);
break; break;
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
case 3: case 3:
writef(f, "111", d[1-rgb_dir],d[1],d[1+rgb_dir]); writef(f, (char*)"111", d[1-rgb_dir],d[1],d[1+rgb_dir]);
break; break;
} }
if (write_alpha > 0) if (write_alpha > 0)
@@ -3894,6 +3915,7 @@ static int outfile(char const *filename, int rgb_dir, int vdir, int x, int y, in
return f != NULL; return f != NULL;
} }
#ifdef _MSC_VER
static int outfile_w(wchar_t const *filename, int rgb_dir, int vdir, int x, int y, int comp, const void *data, int alpha, int pad, char *fmt, ...) static int outfile_w(wchar_t const *filename, int rgb_dir, int vdir, int x, int y, int comp, const void *data, int alpha, int pad, char *fmt, ...)
{ {
FILE *f = _wfopen(filename, L"wb"); FILE *f = _wfopen(filename, L"wb");
@@ -3907,38 +3929,43 @@ static int outfile_w(wchar_t const *filename, int rgb_dir, int vdir, int x, int
} }
return f != NULL; return f != NULL;
} }
#endif
int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data) int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
{ {
int pad = (-x*3) & 3; int pad = (-x*3) & 3;
return outfile(filename,-1,-1,x,y,comp,data,0,pad, return outfile(filename,-1,-1,x,y,comp,data,0,pad,
"11 4 22 4" "4 44 22 444444", (char*)"11 4 22 4" "4 44 22 444444",
'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
} }
#ifdef _MSC_VER
int stbi_write_bmp_w(wchar_t const *filename, int x, int y, int comp, const void *data) int stbi_write_bmp_w(wchar_t const *filename, int x, int y, int comp, const void *data)
{ {
int pad = (-x*3) & 3; int pad = (-x*3) & 3;
return outfile_w(filename,-1,-1,x,y,comp,data,0,pad, return outfile_w(filename,-1,-1,x,y,comp,data,0,pad,
"11 4 22 4" "4 44 22 444444", (char*)"11 4 22 4" "4 44 22 444444",
'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
} }
#endif
int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data) int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
{ {
int has_alpha = !(comp & 1); int has_alpha = !(comp & 1);
return outfile(filename, -1,-1, x, y, comp, data, has_alpha, 0, return outfile(filename, -1,-1, x, y, comp, data, has_alpha, 0,
"111 221 2222 11", 0,0,2, 0,0,0, 0,0,x,y, 24+8*has_alpha, 8*has_alpha); (char*)"111 221 2222 11", 0,0,2, 0,0,0, 0,0,x,y, 24+8*has_alpha, 8*has_alpha);
} }
#ifdef _MSC_VER
int stbi_write_tga_w(wchar_t const *filename, int x, int y, int comp, const void *data) int stbi_write_tga_w(wchar_t const *filename, int x, int y, int comp, const void *data)
{ {
int has_alpha = !(comp & 1); int has_alpha = !(comp & 1);
return outfile_w(filename, -1,-1, x, y, comp, data, has_alpha, 0, return outfile_w(filename, -1,-1, x, y, comp, data, has_alpha, 0,
"111 221 2222 11", 0,0,2, 0,0,0, 0,0,x,y, 24+8*has_alpha, 8*has_alpha); (char*)"111 221 2222 11", 0,0,2, 0,0,0, 0,0,x,y, 24+8*has_alpha, 8*has_alpha);
} }
#endif
// any other image formats that do interleaved rgb data? // any other image formats that do interleaved rgb data?
// PNG: requires adler32,crc32 -- significant amount of code // PNG: requires adler32,crc32 -- significant amount of code
+64 -711
View File
@@ -2,10 +2,27 @@
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#include "crn_core.h" #include "crn_core.h"
#include "crn_strutils.h" #include "crn_strutils.h"
#include <direct.h>
namespace crnlib namespace crnlib
{ {
char* crn_strdup(const char* pStr)
{
if (!pStr)
pStr = "";
size_t l = strlen(pStr) + 1;
char *p = (char *)crnlib_malloc(l);
if (p)
memcpy(p, pStr, l);
return p;
}
int crn_stricmp(const char *p, const char *q)
{
return _stricmp(p, q);
}
char* strcpy_safe(char* pDst, uint dst_len, const char* pSrc) char* strcpy_safe(char* pDst, uint dst_len, const char* pSrc)
{ {
CRNLIB_ASSERT(pDst && pSrc && dst_len); CRNLIB_ASSERT(pDst && pSrc && dst_len);
@@ -164,76 +181,6 @@ namespace crnlib
return true; return true;
} }
bool string_to_int(const wchar_t*& pBuf, int& value)
{
value = 0;
CRNLIB_ASSERT(pBuf);
const wchar_t* p = pBuf;
while (*p && isspace(*p))
p++;
uint result = 0;
bool negative = false;
if (!iswdigit(*p))
{
if (p[0] == '-')
{
negative = true;
p++;
}
else
return false;
}
while (*p && iswdigit(*p))
{
if (result & 0xE0000000U)
return false;
const uint result8 = result << 3U;
const uint result2 = result << 1U;
if (result2 > (0xFFFFFFFFU - result8))
return false;
result = result8 + result2;
uint c = p[0] - L'0';
if (c > (0xFFFFFFFFU - result))
return false;
result += c;
p++;
}
if (negative)
{
if (result > 0x80000000U)
{
value = 0;
return false;
}
value = -static_cast<int>(result);
}
else
{
if (result > 0x7FFFFFFFU)
{
value = 0;
return false;
}
value = static_cast<int>(result);
}
pBuf = p;
return true;
}
bool string_to_int64(const char*& pBuf, int64& value) bool string_to_int64(const char*& pBuf, int64& value)
{ {
value = 0; value = 0;
@@ -348,50 +295,6 @@ namespace crnlib
return true; return true;
} }
bool string_to_uint(const wchar_t*& pBuf, uint& value)
{
value = 0;
CRNLIB_ASSERT(pBuf);
const wchar_t* p = pBuf;
while (*p && iswspace(*p))
p++;
uint result = 0;
if (!iswdigit(*p))
return false;
while (*p && iswdigit(*p))
{
if (result & 0xE0000000U)
return false;
const uint result8 = result << 3U;
const uint result2 = result << 1U;
if (result2 > (0xFFFFFFFFU - result8))
return false;
result = result8 + result2;
uint c = p[0] - L'0';
if (c > (0xFFFFFFFFU - result))
return false;
result += c;
p++;
}
value = result;
pBuf = p;
return true;
}
bool string_to_uint64(const char*& pBuf, uint64& value) bool string_to_uint64(const char*& pBuf, uint64& value)
{ {
value = 0; value = 0;
@@ -467,77 +370,66 @@ namespace crnlib
return false; return false;
} }
bool string_to_bool(const wchar_t* p, bool& value)
{
CRNLIB_ASSERT(p);
value = false;
if (_wcsicmp(p, L"false") == 0)
return true;
if (_wcsicmp(p, L"true") == 0)
{
value = true;
return true;
}
const wchar_t* q = p;
uint v;
if (string_to_uint(q, v))
{
if (!v)
return true;
else if (v == 1)
{
value = true;
return true;
}
}
return false;
}
bool string_to_float(const char*& p, float& value, uint round_digit) bool string_to_float(const char*& p, float& value, uint round_digit)
{
double d;
if (!string_to_double(p, d, round_digit))
{
value = 0;
return false;
}
value = static_cast<float>(d);
return true;
}
bool string_to_double(const char*& p, double& value, uint round_digit)
{
return string_to_double(p, p + 128, value, round_digit);
}
// I wrote this approx. 20 years ago in C/assembly using a limited FP emulator package, so it's a bit crude.
bool string_to_double(const char*& p, const char *pEnd, double& value, uint round_digit)
{ {
CRNLIB_ASSERT(p); CRNLIB_ASSERT(p);
value = 0; value = 0;
enum { AF_BLANK = 1, AF_SIGN = 2, AF_DPOINT = 3, AF_BADCHAR = 4, AF_OVRFLOW = 5, AF_EXPONENT = 6, AF_NODIGITS = 7 }; enum { AF_BLANK = 1, AF_SIGN = 2, AF_DPOINT = 3, AF_BADCHAR = 4, AF_OVRFLOW = 5, AF_EXPONENT = 6, AF_NODIGITS = 7 };
int status = 0;
const char* buf = p; const char* buf = p;
int status = 0; int got_sign_flag = 0, got_dp_flag = 0, got_num_flag = 0;
int got_e_flag = 0, got_e_sign_flag = 0, e_sign = 0;
uint whole_count = 0, frac_count = 0;
if (round_digit > 10) double whole = 0, frac = 0, scale = 1, exponent = 1;
round_digit = 10;
int got_sign_flag = 0; if (p >= pEnd)
int got_dp_flag = 0; {
int got_num_flag = 0; status = AF_NODIGITS;
goto af_exit;
int got_e_flag = 0; }
int got_e_sign_flag = 0;
int e_sign = 0;
uint whole_count = 0;
uint frac_count = 0;
float whole = 0;
float frac = 0;
float scale = 1;
float exponent = 1;
while (*buf) while (*buf)
{ {
if (!isspace(*buf)) if (!isspace(*buf))
break; break;
if (++buf >= pEnd)
buf++; {
status = AF_NODIGITS;
goto af_exit;
}
} }
p = buf;
while (*buf) while (*buf)
{ {
p = buf;
if (buf >= pEnd)
break;
int i = *buf++; int i = *buf++;
switch (i) switch (i)
@@ -616,7 +508,7 @@ namespace crnlib
whole_count++; whole_count++;
if (whole > 1e+30f) if (whole > 1e+100)
{ {
status = AF_OVRFLOW; status = AF_OVRFLOW;
goto af_exit; goto af_exit;
@@ -646,6 +538,10 @@ namespace crnlib
while (*buf) while (*buf)
{ {
p = buf;
if (buf >= pEnd)
break;
int i = *buf++; int i = *buf++;
if (i == '+') if (i == '+')
@@ -674,7 +570,7 @@ namespace crnlib
{ {
got_num_flag = 1; got_num_flag = 1;
if ((e = (e * 10) + (i - 48)) > 16) if ((e = (e * 10) + (i - 48)) > 100)
{ {
status = AF_EXPONENT; status = AF_EXPONENT;
goto af_exit; goto af_exit;
@@ -709,552 +605,9 @@ namespace crnlib
whole = -whole; whole = -whole;
value = whole; value = whole;
p = buf;
af_exit: af_exit:
return (status == 0); return (status == 0);
} }
bool string_to_float(const wchar_t*& p, float& value, uint round_digit)
{
CRNLIB_ASSERT(p);
value = 0;
enum { AF_BLANK = 1, AF_SIGN = 2, AF_DPOINT = 3, AF_BADCHAR = 4, AF_OVRFLOW = 5, AF_EXPONENT = 6, AF_NODIGITS = 7 };
const wchar_t* buf = p;
int status = 0;
if (round_digit > 10)
round_digit = 10;
int got_sign_flag = 0;
int got_dp_flag = 0;
int got_num_flag = 0;
int got_e_flag = 0;
int got_e_sign_flag = 0;
int e_sign = 0;
uint whole_count = 0;
uint frac_count = 0;
float whole = 0;
float frac = 0;
float scale = 1;
float exponent = 1;
while (*buf)
{
if (!iswspace(*buf))
break;
buf++;
}
while (*buf)
{
int i = *buf++;
switch (i)
{
case L'e':
case L'E':
{
got_e_flag = 1;
goto exit_while;
}
case L'+':
{
if ((got_num_flag) || (got_sign_flag))
{
status = AF_SIGN;
goto af_exit;
}
got_sign_flag = 1;
break;
}
case L'-':
{
if ((got_num_flag) || (got_sign_flag))
{
status = AF_SIGN;
goto af_exit;
}
got_sign_flag = -1;
break;
}
case L'.':
{
if (got_dp_flag)
{
status = AF_DPOINT;
goto af_exit;
}
got_dp_flag = 1;
break;
}
default:
{
if ((i < L'0') || (i > L'9'))
goto exit_while;
else
{
i -= L'0';
got_num_flag = 1;
if (got_dp_flag)
{
if (frac_count < round_digit)
{
frac = frac * 10.0f + i;
scale = scale * 10.0f;
}
else if (frac_count == round_digit)
{
if (i >= 5) /* check for round */
frac = frac + 1.0f;
}
frac_count++;
}
else
{
whole = whole * 10.0f + i;
whole_count++;
if (whole > 1e+30f)
{
status = AF_OVRFLOW;
goto af_exit;
}
}
}
break;
}
}
}
exit_while:
if (got_e_flag)
{
if ((got_num_flag == 0) && (got_dp_flag))
{
status = AF_EXPONENT;
goto af_exit;
}
int e = 0;
e_sign = 1;
got_num_flag = 0;
got_e_sign_flag = 0;
while (*buf)
{
int i = *buf++;
if (i == L'+')
{
if ((got_num_flag) || (got_e_sign_flag))
{
status = AF_EXPONENT;
goto af_exit;
}
e_sign = 1;
got_e_sign_flag = 1;
}
else if (i == L'-')
{
if ((got_num_flag) || (got_e_sign_flag))
{
status = AF_EXPONENT;
goto af_exit;
}
e_sign = -1;
got_e_sign_flag = 1;
}
else if ((i >= L'0') && (i <= L'9'))
{
got_num_flag = 1;
if ((e = (e * 10) + (i - 48)) > 16)
{
status = AF_EXPONENT;
goto af_exit;
}
}
else
break;
}
for (int i = 1; i <= e; i++) /* compute 10^e */
exponent = exponent * 10.0f;
}
if (((whole_count + frac_count) == 0) && (got_e_flag == 0))
{
status = AF_NODIGITS;
goto af_exit;
}
if (frac)
whole = whole + (frac / scale);
if (got_e_flag)
{
if (e_sign > 0)
whole = whole * exponent;
else
whole = whole / exponent;
}
if (got_sign_flag < 0)
whole = -whole;
value = whole;
p = buf;
af_exit:
return (status == 0);
}
bool split_path(const char* p, dynamic_string* pDrive, dynamic_string* pDir, dynamic_string* pFilename, dynamic_string* pExt)
{
CRNLIB_ASSERT(p);
char drive_buf[_MAX_DRIVE];
char dir_buf[_MAX_DIR];
char fname_buf[_MAX_FNAME];
char ext_buf[_MAX_EXT];
#ifdef _MSC_VER
errno_t error = _splitpath_s(p,
pDrive ? drive_buf : NULL, pDrive ? _MAX_DRIVE : 0,
pDir ? dir_buf : NULL, pDir ? _MAX_DIR : 0,
pFilename ? fname_buf : NULL, pFilename ? _MAX_FNAME : 0,
pExt ? ext_buf : NULL, pExt ? _MAX_EXT : 0);
if (error != 0)
return false;
#else
_splitpath(p,
pDrive ? drive_buf : NULL,
pDir ? dir_buf : NULL,
pFilename ? fname_buf : NULL,
pExt ? ext_buf : NULL);
#endif
if (pDrive) *pDrive = drive_buf;
if (pDir) *pDir = dir_buf;
if (pFilename) *pFilename = fname_buf;
if (pExt) *pExt = ext_buf;
return true;
}
bool split_path(const wchar_t* p, dynamic_wstring* pDrive, dynamic_wstring* pDir, dynamic_wstring* pFilename, dynamic_wstring* pExt)
{
CRNLIB_ASSERT(p);
wchar_t drive_buf[_MAX_DRIVE];
wchar_t dir_buf[_MAX_DIR];
wchar_t fname_buf[_MAX_FNAME];
wchar_t ext_buf[_MAX_EXT];
#ifdef _MSC_VER
errno_t error = _wsplitpath_s(p,
pDrive ? drive_buf : NULL, pDrive ? _MAX_DRIVE : 0,
pDir ? dir_buf : NULL, pDir ? _MAX_DIR : 0,
pFilename ? fname_buf : NULL, pFilename ? _MAX_FNAME : 0,
pExt ? ext_buf : NULL, pExt ? _MAX_EXT : 0);
if (error != 0)
return false;
#else
_wsplitpath(p,
pDrive ? drive_buf : NULL,
pDir ? dir_buf : NULL,
pFilename ? fname_buf : NULL,
pExt ? ext_buf : NULL);
#endif
if (pDrive) *pDrive = drive_buf;
if (pDir) *pDir = dir_buf;
if (pFilename) *pFilename = fname_buf;
if (pExt) *pExt = ext_buf;
return true;
}
bool split_path(const char* p, dynamic_string& path, dynamic_string& filename)
{
dynamic_string temp_drive, temp_path, temp_ext;
if (!split_path(p, &temp_drive, &temp_path, &filename, &temp_ext))
return false;
filename += temp_ext;
combine_path(path, temp_drive.get_ptr(), temp_path.get_ptr());
return true;
}
bool split_path(const wchar_t* p, dynamic_wstring& path, dynamic_wstring& filename)
{
dynamic_wstring temp_drive, temp_path, temp_ext;
if (!split_path(p, &temp_drive, &temp_path, &filename, &temp_ext))
return false;
filename += temp_ext;
combine_path(path, temp_drive.get_ptr(), temp_path.get_ptr());
return true;
}
bool get_pathname(const char* p, dynamic_string& path)
{
dynamic_string temp_drive, temp_path;
if (!split_path(p, &temp_drive, &temp_path, NULL, NULL))
return false;
combine_path(path, temp_drive.get_ptr(), temp_path.get_ptr());
return true;
}
bool get_pathname(const wchar_t* p, dynamic_wstring& path)
{
dynamic_wstring temp_drive, temp_path;
if (!split_path(p, &temp_drive, &temp_path, NULL, NULL))
return false;
combine_path(path, temp_drive.get_ptr(), temp_path.get_ptr());
return true;
}
bool get_filename(const char* p, dynamic_string& filename)
{
dynamic_string temp_ext;
if (!split_path(p, NULL, NULL, &filename, &temp_ext))
return false;
filename += temp_ext;
return true;
}
bool get_filename(const wchar_t* p, dynamic_wstring& filename)
{
dynamic_wstring temp_ext;
if (!split_path(p, NULL, NULL, &filename, &temp_ext))
return false;
filename += temp_ext;
return true;
}
void combine_path(dynamic_string& dst, const char* pA, const char* pB)
{
dynamic_string temp;
temp = pA;
if ((!temp.is_empty()) && (pB[0] != '\\') && (pB[0] != '/'))
{
char c = temp[temp.get_len() - 1];
if ((c != '\\') && (c != '/'))
{
temp.append_char('\\');
}
}
temp += pB;
dst.swap(temp);
}
void combine_path(dynamic_wstring& dst, const wchar_t* pA, const wchar_t* pB)
{
dynamic_wstring temp;
temp = pA;
if ((!temp.is_empty()) && (pB[0] != L'\\') && (pB[0] != L'/'))
{
wchar_t c = temp[temp.get_len() - 1];
if ((c != L'\\') && (c != L'/'))
{
temp.append_char(L'\\');
}
}
temp += pB;
dst.swap(temp);
}
void combine_path(dynamic_string& dst, const char* pA, const char* pB, const char* pC)
{
combine_path(dst, pA, pB);
combine_path(dst, dst.get_ptr(), pC);
}
void combine_path(dynamic_wstring& dst, const wchar_t* pA, const wchar_t* pB, const wchar_t* pC)
{
combine_path(dst, pA, pB);
combine_path(dst, dst.get_ptr(), pC);
}
void combine_path(dynamic_wstring& dst, const wchar_t* pA, const wchar_t* pB, const wchar_t* pC, const wchar_t *pD)
{
combine_path(dst, pA, pB);
combine_path(dst, dst.get_ptr(), pC);
combine_path(dst, dst.get_ptr(), pD);
}
bool full_path(dynamic_string& path)
{
#ifndef _XBOX
char buf[CRNLIB_MAX_PATH];
char* p = _fullpath(buf, path.get_ptr(), CRNLIB_MAX_PATH);
if (!p)
return false;
path.set(buf);
#endif
return true;
}
bool full_path(dynamic_wstring& path)
{
#ifndef _XBOX
wchar_t buf[CRNLIB_MAX_PATH];
wchar_t* p = _wfullpath(buf, path.get_ptr(), CRNLIB_MAX_PATH);
if (!p)
return false;
path.set(buf);
#endif
return true;
}
bool get_extension(dynamic_string& filename)
{
int sep = filename.find_right('\\');
if (sep < 0)
sep = filename.find_right('/');
int dot = filename.find_right('.');
if (dot < sep)
{
filename.clear();
return false;
}
filename.right(dot + 1);
return true;
}
bool get_extension(dynamic_wstring& filename)
{
int sep = filename.find_right(L'\\');
if (sep < 0)
sep = filename.find_right(L'/');
int dot = filename.find_right(L'.');
if (dot < sep)
{
filename.clear();
return false;
}
filename.right(dot + 1);
return true;
}
bool remove_extension(dynamic_string& filename)
{
int sep = filename.find_right('\\');
if (sep < 0)
sep = filename.find_right('/');
int dot = filename.find_right('.');
if (dot < sep)
return false;
filename.left(dot);
return true;
}
bool remove_extension(dynamic_wstring& filename)
{
int sep = filename.find_right(L'\\');
if (sep < 0)
sep = filename.find_right(L'/');
int dot = filename.find_right(L'.');
if (dot < sep)
return false;
filename.left(dot);
return true;
}
bool create_path(const dynamic_wstring& path)
{
bool unc = false;
dynamic_wstring cur_path;
const int l = path.get_len();
int n = 0;
while (n < l)
{
const wchar_t c = path.get_ptr()[n];
const bool sep = (c == L'/') || (c == L'\\');
if ((sep) || (n == (l - 1)))
{
if ((n == (l - 1)) && (!sep))
cur_path.append_char(c);
bool valid = false;
if ((cur_path.get_len() > 3) && (cur_path.get_ptr()[1] == L':'))
valid = true;
else if (cur_path.get_len() > 2)
{
if (unc)
valid = true;
unc = true;
}
if (valid)
_wmkdir(cur_path.get_ptr());
}
cur_path.append_char(c);
n++;
}
return true;
}
void trim_trailing_seperator(dynamic_wstring& path)
{
if ( (path.get_len()) && ( (path[path.get_len() - 1] == L'\\') || (path[path.get_len() - 1] == L'/') ) )
path.truncate(path.get_len() - 1);
}
} // namespace crnlib } // namespace crnlib
+19 -43
View File
@@ -2,58 +2,34 @@
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#pragma once #pragma once
#ifdef WIN32
#define CRNLIB_PATH_SEPERATOR_CHAR '\\'
#else
#define CRNLIB_PATH_SEPERATOR_CHAR '/'
#endif
namespace crnlib namespace crnlib
{ {
char* crn_strdup(const char* pStr);
int crn_stricmp(const char *p, const char *q);
char* strcpy_safe(char* pDst, uint dst_len, const char* pSrc); char* strcpy_safe(char* pDst, uint dst_len, const char* pSrc);
bool int_to_string(int value, char* pDst, uint len); bool int_to_string(int value, char* pDst, uint len);
bool uint_to_string(uint value, char* pDst, uint len); bool uint_to_string(uint value, char* pDst, uint len);
bool string_to_int(const char*& pBuf, int& value); bool string_to_int(const char*& pBuf, int& value);
bool string_to_int(const wchar_t*& pBuf, int& value);
bool string_to_uint(const char*& pBuf, uint& value); bool string_to_uint(const char*& pBuf, uint& value);
bool string_to_uint(const wchar_t*& pBuf, uint& value);
bool string_to_int64(const char*& pBuf, int64& value); bool string_to_int64(const char*& pBuf, int64& value);
bool string_to_uint64(const char*& pBuf, uint64& value); bool string_to_uint64(const char*& pBuf, uint64& value);
bool string_to_bool(const char* p, bool& value); bool string_to_bool(const char* p, bool& value);
bool string_to_bool(const wchar_t* p, bool& value);
bool string_to_float(const char*& p, float& value, uint round_digit = 512U);
bool string_to_float(const char*& p, float& value, uint round_digit = 10U);
bool string_to_float(const wchar_t*& p, float& value, uint round_digit = 10U); bool string_to_double(const char*& p, double& value, uint round_digit = 512U);
bool string_to_double(const char*& p, const char *pEnd, double& value, uint round_digit = 512U);
bool split_path(const char* p, dynamic_string* pDrive, dynamic_string* pDir, dynamic_string* pFilename, dynamic_string* pExt);
bool split_path(const wchar_t* p, dynamic_wstring* pDrive, dynamic_wstring* pDir, dynamic_wstring* pFilename, dynamic_wstring* pExt);
bool split_path(const char* p, dynamic_string& path, dynamic_string& filename);
bool split_path(const wchar_t* p, dynamic_wstring& path, dynamic_wstring& filename);
bool get_pathname(const char* p, dynamic_string& path);
bool get_pathname(const wchar_t* p, dynamic_wstring& path);
bool get_filename(const char* p, dynamic_string& filename);
bool get_filename(const wchar_t* p, dynamic_wstring& filename);
void combine_path(dynamic_string& dst, const char* pA, const char* pB);
void combine_path(dynamic_wstring& dst, const wchar_t* pA, const wchar_t* pB);
void combine_path(dynamic_string& dst, const char* pA, const char* pB, const char* pC);
void combine_path(dynamic_wstring& dst, const wchar_t* pA, const wchar_t* pB, const wchar_t* pC);
void combine_path(dynamic_wstring& dst, const wchar_t* pA, const wchar_t* pB, const wchar_t* pC, const wchar_t *pD);
bool full_path(dynamic_string& path);
bool full_path(dynamic_wstring& path);
bool get_extension(dynamic_string& filename);
bool get_extension(dynamic_wstring& filename);
bool remove_extension(dynamic_string& filename);
bool remove_extension(dynamic_wstring& filename);
bool create_path(const dynamic_wstring& path);
void trim_trailing_seperator(dynamic_wstring& path);
} // namespace crnlib } // namespace crnlib
+8 -8
View File
@@ -361,7 +361,7 @@ namespace crnlib
if (!max_freq) if (!max_freq)
return false; return false;
if (max_freq <= UINT16_MAX) if (max_freq <= cUINT16_MAX)
{ {
for (uint i = 0; i < total_syms; i++) for (uint i = 0; i < total_syms; i++)
sym_freq16[i] = static_cast<uint16>(pSym_freq[i]); sym_freq16[i] = static_cast<uint16>(pSym_freq[i]);
@@ -381,7 +381,7 @@ namespace crnlib
if (fl < 1) if (fl < 1)
fl = 1; fl = 1;
CRNLIB_ASSERT(fl <= UINT16_MAX); CRNLIB_ASSERT(fl <= cUINT16_MAX);
sym_freq16[i] = static_cast<uint16>(fl); sym_freq16[i] = static_cast<uint16>(fl);
} }
@@ -917,7 +917,7 @@ namespace crnlib
freq++; freq++;
model.m_sym_freq[sym] = static_cast<uint16>(freq); model.m_sym_freq[sym] = static_cast<uint16>(freq);
if (freq == UINT16_MAX) if (freq == cUINT16_MAX)
model.rescale(); model.rescale();
if (--model.m_symbols_until_update == 0) if (--model.m_symbols_until_update == 0)
@@ -1426,8 +1426,8 @@ namespace crnlib
{ {
uint32 t = pTables->m_lookup[m_bit_buf >> (cBitBufSize - pTables->m_table_bits)]; uint32 t = pTables->m_lookup[m_bit_buf >> (cBitBufSize - pTables->m_table_bits)];
CRNLIB_ASSERT(t != UINT32_MAX); CRNLIB_ASSERT(t != cUINT32_MAX);
sym = t & UINT16_MAX; sym = t & cUINT16_MAX;
len = t >> 16; len = t >> 16;
CRNLIB_ASSERT(model.m_code_sizes[sym] == len); CRNLIB_ASSERT(model.m_code_sizes[sym] == len);
@@ -1462,7 +1462,7 @@ namespace crnlib
freq++; freq++;
model.m_sym_freq[sym] = static_cast<uint16>(freq); model.m_sym_freq[sym] = static_cast<uint16>(freq);
if (freq == UINT16_MAX) if (freq == cUINT16_MAX)
model.rescale(); model.rescale();
if (--model.m_symbols_until_update == 0) if (--model.m_symbols_until_update == 0)
@@ -1614,8 +1614,8 @@ namespace crnlib
{ {
uint32 t = pTables->m_lookup[m_bit_buf >> (cBitBufSize - pTables->m_table_bits)]; uint32 t = pTables->m_lookup[m_bit_buf >> (cBitBufSize - pTables->m_table_bits)];
CRNLIB_ASSERT(t != UINT32_MAX); CRNLIB_ASSERT(t != cUINT32_MAX);
sym = t & UINT16_MAX; sym = t & cUINT16_MAX;
len = t >> 16; len = t >> 16;
CRNLIB_ASSERT(model.m_code_sizes[sym] == len); CRNLIB_ASSERT(model.m_code_sizes[sym] == len);
+30 -18
View File
@@ -26,7 +26,7 @@ namespace crnlib
{ {
if (local_params.get_flag(cCRNCompFlagPerceptual)) if (local_params.get_flag(cCRNCompFlagPerceptual))
{ {
//console::warning(L"Output pixel format is swizzled or not RGB, disabling perceptual color metrics"); console::info("Output pixel format is swizzled or not RGB, disabling perceptual color metrics");
// Destination compressed pixel format is swizzled or not RGB at all, so be sure perceptual colorspace metrics are disabled. // Destination compressed pixel format is swizzled or not RGB at all, so be sure perceptual colorspace metrics are disabled.
local_params.set_flag(cCRNCompFlagPerceptual, false); local_params.set_flag(cCRNCompFlagPerceptual, false);
@@ -53,6 +53,18 @@ namespace crnlib
((local_params.m_file_type == cCRNFileTypeCRN) && ((local_params.m_flags & cCRNCompFlagManualPaletteSizes) != 0)) ((local_params.m_file_type == cCRNFileTypeCRN) && ((local_params.m_flags & cCRNCompFlagManualPaletteSizes) != 0))
) )
{ {
if ( (local_params.m_file_type == cCRNFileTypeCRN) ||
((local_params.m_file_type == cCRNFileTypeDDS) && (local_params.m_quality_level < cCRNMaxQualityLevel)) )
{
console::info("Compressing using quality level %i", local_params.m_quality_level);
}
if (local_params.m_format == cCRNFmtDXT3)
{
if (local_params.m_file_type == cCRNFileTypeCRN)
console::warning("CRN format doesn't support DXT3");
else if ((local_params.m_file_type == cCRNFileTypeDDS) && (local_params.m_quality_level < cCRNMaxQualityLevel))
console::warning("Clustered DDS compressor doesn't support DXT3");
}
if (!pTexture_comp->compress_pass(local_params, pActual_bitrate)) if (!pTexture_comp->compress_pass(local_params, pActual_bitrate))
{ {
crnlib_delete(pTexture_comp); crnlib_delete(pTexture_comp);
@@ -95,7 +107,7 @@ namespace crnlib
{ {
if (params.m_flags & cCRNCompFlagDebugging) if (params.m_flags & cCRNCompFlagDebugging)
{ {
console::debug(L"Quality level bracket: [%u, %u]", low_quality, high_quality); console::debug("Quality level bracket: [%u, %u]", low_quality, high_quality);
} }
int trial_quality = (low_quality + high_quality) / 2; int trial_quality = (low_quality + high_quality) / 2;
@@ -137,7 +149,7 @@ namespace crnlib
} }
} }
console::info(L"Compressing to quality level %u", trial_quality); console::info("Compressing to quality level %u", trial_quality);
float bitrate = 0.0f; float bitrate = 0.0f;
@@ -153,7 +165,7 @@ namespace crnlib
highest_bitrate = math::maximum(highest_bitrate, bitrate); highest_bitrate = math::maximum(highest_bitrate, bitrate);
console::info(L"\nTried quality level %u, bpp: %3.3f", trial_quality, bitrate); console::info("\nTried quality level %u, bpp: %3.3f", trial_quality, bitrate);
if ( (best_quality_level < 0) || if ( (best_quality_level < 0) ||
((bitrate <= local_params.m_target_bitrate) && (best_bitrate > local_params.m_target_bitrate)) || ((bitrate <= local_params.m_target_bitrate) && (best_bitrate > local_params.m_target_bitrate)) ||
@@ -165,7 +177,7 @@ namespace crnlib
best_quality_level = trial_quality; best_quality_level = trial_quality;
if (params.m_flags & cCRNCompFlagDebugging) if (params.m_flags & cCRNCompFlagDebugging)
{ {
console::debug(L"Choose new best quality level"); console::debug("Choose new best quality level");
} }
if ((best_bitrate <= local_params.m_target_bitrate) && (fabs(best_bitrate - local_params.m_target_bitrate) < .005f)) if ((best_bitrate <= local_params.m_target_bitrate) && (fabs(best_bitrate - local_params.m_target_bitrate) < .005f))
@@ -188,7 +200,7 @@ namespace crnlib
(highest_bitrate < local_params.m_target_bitrate) && (highest_bitrate < local_params.m_target_bitrate) &&
(fabs(best_bitrate - local_params.m_target_bitrate) >= .005f)) (fabs(best_bitrate - local_params.m_target_bitrate) >= .005f))
{ {
console::info(L"Unable to achieve desired bitrate - disabling adaptive block sizes and retrying search."); console::info("Unable to achieve desired bitrate - disabling adaptive block sizes and retrying search.");
local_params.m_flags &= ~cCRNCompFlagHierarchical; local_params.m_flags &= ~cCRNCompFlagHierarchical;
@@ -214,7 +226,7 @@ namespace crnlib
if (pActual_quality_level) *pActual_quality_level = best_quality_level; if (pActual_quality_level) *pActual_quality_level = best_quality_level;
if (pActual_bitrate) *pActual_bitrate = best_bitrate; if (pActual_bitrate) *pActual_bitrate = best_bitrate;
console::printf(L"Selected quality level %u bpp: %f", best_quality_level, best_bitrate); console::printf("Selected quality level %u bpp: %f", best_quality_level, best_bitrate);
return true; return true;
} }
@@ -310,14 +322,14 @@ namespace crnlib
{ {
if (work_tex.get_num_faces() > 1) if (work_tex.get_num_faces() > 1)
{ {
console::warning(L"Can't crop cubemap textures"); console::warning("Can't crop cubemap textures");
} }
else else
{ {
console::info(L"Cropping input texture from window (%ux%u)-(%ux%u)", window_rect.get_left(), window_rect.get_top(), window_rect.get_right(), window_rect.get_bottom()); console::info("Cropping input texture from window (%ux%u)-(%ux%u)", window_rect.get_left(), window_rect.get_top(), window_rect.get_right(), window_rect.get_bottom());
if (!work_tex.crop(window_rect.get_left(), window_rect.get_top(), window_rect.get_width(), window_rect.get_height())) if (!work_tex.crop(window_rect.get_left(), window_rect.get_top(), window_rect.get_width(), window_rect.get_height()))
console::warning(L"Failed cropping window rect"); console::warning("Failed cropping window rect");
} }
} }
@@ -332,13 +344,13 @@ namespace crnlib
{ {
if (work_tex.get_num_faces() > 1) if (work_tex.get_num_faces() > 1)
{ {
console::warning(L"Can't crop cubemap textures"); console::warning("Can't crop cubemap textures");
} }
else else
{ {
new_width = math::minimum<uint>(mipmap_params.m_clamp_width, new_width); new_width = math::minimum<uint>(mipmap_params.m_clamp_width, new_width);
new_height = math::minimum<uint>(mipmap_params.m_clamp_height, new_height); new_height = math::minimum<uint>(mipmap_params.m_clamp_height, new_height);
console::info(L"Clamping input texture to %ux%u", new_width, new_height); console::info("Clamping input texture to %ux%u", new_width, new_height);
work_tex.crop(0, 0, new_width, new_height); work_tex.crop(0, 0, new_width, new_height);
} }
} }
@@ -420,7 +432,7 @@ namespace crnlib
if ((new_width != (int)work_tex.get_width()) || (new_height != (int)work_tex.get_height())) if ((new_width != (int)work_tex.get_width()) || (new_height != (int)work_tex.get_height()))
{ {
console::info(L"Resampling input texture to %ux%u", new_width, new_height); console::info("Resampling input texture to %ux%u", new_width, new_height);
const char* pFilter = crn_get_mip_filter_name(mipmap_params.m_filter); const char* pFilter = crn_get_mip_filter_name(mipmap_params.m_filter);
@@ -439,7 +451,7 @@ namespace crnlib
if (!work_tex.resize(new_width, new_height, res_params)) if (!work_tex.resize(new_width, new_height, res_params))
{ {
console::error(L"Failed resizing texture!"); console::error("Failed resizing texture!");
return false; return false;
} }
} }
@@ -461,18 +473,18 @@ namespace crnlib
gen_params.m_max_mips = mipmap_params.m_max_levels; gen_params.m_max_mips = mipmap_params.m_max_levels;
gen_params.m_min_mip_size = mipmap_params.m_min_mip_size; gen_params.m_min_mip_size = mipmap_params.m_min_mip_size;
console::info(L"Generating mipmaps using filter \"%S\"", pFilter); console::info("Generating mipmaps using filter \"%s\"", pFilter);
timer tm; timer tm;
tm.start(); tm.start();
if (!work_tex.generate_mipmaps(gen_params, true)) if (!work_tex.generate_mipmaps(gen_params, true))
{ {
console::error(L"Failed generating mipmaps!"); console::error("Failed generating mipmaps!");
return false; return false;
} }
double t = tm.get_elapsed_secs(); double t = tm.get_elapsed_secs();
console::info(L"Generated %u mipmap levels in %3.3fs", work_tex.get_num_levels() - 1, t); console::info("Generated %u mipmap levels in %3.3fs", work_tex.get_num_levels() - 1, t);
} }
return true; return true;
@@ -487,7 +499,7 @@ namespace crnlib
dds_texture work_tex; dds_texture work_tex;
if (!create_dds_tex(params, work_tex)) if (!create_dds_tex(params, work_tex))
{ {
console::error(L"Failed creating DDS texture from crn_comp_params!"); console::error("Failed creating DDS texture from crn_comp_params!");
return false; return false;
} }
+1 -1
View File
@@ -16,7 +16,7 @@ namespace crnlib
itexture_comp() { } itexture_comp() { }
virtual ~itexture_comp() { } virtual ~itexture_comp() { }
virtual const wchar_t *get_ext() const = 0; virtual const char *get_ext() const = 0;
virtual bool compress_init(const crn_comp_params& params) = 0; virtual bool compress_init(const crn_comp_params& params) = 0;
virtual bool compress_pass(const crn_comp_params& params, float *pEffective_bitrate) = 0; virtual bool compress_pass(const crn_comp_params& params, float *pEffective_bitrate) = 0;
+99 -91
View File
@@ -3,7 +3,7 @@
#include "crn_core.h" #include "crn_core.h"
#include "crn_texture_conversion.h" #include "crn_texture_conversion.h"
#include "crn_console.h" #include "crn_console.h"
#include "crn_win32_file_utils.h" #include "crn_file_utils.h"
#include "crn_cfile_stream.h" #include "crn_cfile_stream.h"
#include "crn_image_utils.h" #include "crn_image_utils.h"
#include "crn_texture_comp.h" #include "crn_texture_comp.h"
@@ -26,8 +26,8 @@ namespace crnlib
} }
bool convert_stats::init( bool convert_stats::init(
const wchar_t* pSrc_filename, const char* pSrc_filename,
const wchar_t* pDst_filename, const char* pDst_filename,
dds_texture& src_tex, dds_texture& src_tex,
texture_file_types::format dst_file_type, texture_file_types::format dst_file_type,
bool lzma_stats) bool lzma_stats)
@@ -38,8 +38,8 @@ namespace crnlib
m_pInput_tex = &src_tex; m_pInput_tex = &src_tex;
win32_file_utils::get_file_size(pSrc_filename, m_input_file_size); file_utils::get_file_size(pSrc_filename, m_input_file_size);
win32_file_utils::get_file_size(pDst_filename, m_output_file_size); file_utils::get_file_size(pDst_filename, m_output_file_size);
m_total_input_pixels = 0; m_total_input_pixels = 0;
for (uint i = 0; i < src_tex.get_num_levels(); i++) for (uint i = 0; i < src_tex.get_num_levels(); i++)
@@ -58,12 +58,12 @@ namespace crnlib
vector<uint8> dst_tex_bytes; vector<uint8> dst_tex_bytes;
if (!cfile_stream::read_file_into_array(pDst_filename, dst_tex_bytes)) if (!cfile_stream::read_file_into_array(pDst_filename, dst_tex_bytes))
{ {
console::error(L"Failed loading output file: %s", pDst_filename); console::error("Failed loading output file: %s", pDst_filename);
return false; return false;
} }
if (!dst_tex_bytes.size()) if (!dst_tex_bytes.size())
{ {
console::error(L"Output file is empty: %s", pDst_filename); console::error("Output file is empty: %s", pDst_filename);
return false; return false;
} }
vector<uint8> cmp_tex_bytes; vector<uint8> cmp_tex_bytes;
@@ -76,7 +76,7 @@ namespace crnlib
if (!m_output_tex.load_from_file(pDst_filename, m_dst_file_type)) if (!m_output_tex.load_from_file(pDst_filename, m_dst_file_type))
{ {
console::error(L"Failed loading output file: %s", pDst_filename); console::error("Failed loading output file: %s", pDst_filename);
return false; return false;
} }
@@ -91,12 +91,12 @@ namespace crnlib
return true; return true;
} }
bool convert_stats::print(bool psnr_metrics, bool mip_stats, bool grayscale_sampling, const wchar_t *pCSVStatsFile) const bool convert_stats::print(bool psnr_metrics, bool mip_stats, bool grayscale_sampling, const char *pCSVStatsFile) const
{ {
if (!m_pInput_tex) if (!m_pInput_tex)
return false; return false;
console::info(L"Input texture: %ux%u, Levels: %u, Faces: %u, Format: %s", console::info("Input texture: %ux%u, Levels: %u, Faces: %u, Format: %s",
m_pInput_tex->get_width(), m_pInput_tex->get_width(),
m_pInput_tex->get_height(), m_pInput_tex->get_height(),
m_pInput_tex->get_num_levels(), m_pInput_tex->get_num_levels(),
@@ -104,29 +104,29 @@ namespace crnlib
pixel_format_helpers::get_pixel_format_string(m_pInput_tex->get_format())); pixel_format_helpers::get_pixel_format_string(m_pInput_tex->get_format()));
// Just casting the uint64's filesizes to uint32 here to work around gcc issues - it's not even possible to have files that large anyway. // Just casting the uint64's filesizes to uint32 here to work around gcc issues - it's not even possible to have files that large anyway.
console::info(L"Input pixels: %u, Input file size: %u, Input bits/pixel: %1.3f", console::info("Input pixels: %u, Input file size: %u, Input bits/pixel: %1.3f",
m_total_input_pixels, (uint32)m_input_file_size, (m_input_file_size * 8.0f) / m_total_input_pixels); m_total_input_pixels, (uint32)m_input_file_size, (m_input_file_size * 8.0f) / m_total_input_pixels);
console::info(L"Output texture: %ux%u, Levels: %u, Faces: %u, Format: %s", console::info("Output texture: %ux%u, Levels: %u, Faces: %u, Format: %s",
m_output_tex.get_width(), m_output_tex.get_width(),
m_output_tex.get_height(), m_output_tex.get_height(),
m_output_tex.get_num_levels(), m_output_tex.get_num_levels(),
m_output_tex.get_num_faces(), m_output_tex.get_num_faces(),
pixel_format_helpers::get_pixel_format_string(m_output_tex.get_format())); pixel_format_helpers::get_pixel_format_string(m_output_tex.get_format()));
console::info(L"Output pixels: %u, Output file size: %u, Output bits/pixel: %1.3f", console::info("Output pixels: %u, Output file size: %u, Output bits/pixel: %1.3f",
m_total_output_pixels, (uint32)m_output_file_size, (m_output_file_size * 8.0f) / m_total_output_pixels); m_total_output_pixels, (uint32)m_output_file_size, (m_output_file_size * 8.0f) / m_total_output_pixels);
if (m_output_comp_file_size) if (m_output_comp_file_size)
{ {
console::info(L"LZMA compressed output file size: %u bytes, %1.3f bits/pixel", console::info("LZMA compressed output file size: %u bytes, %1.3f bits/pixel",
(uint32)m_output_comp_file_size, (m_output_comp_file_size * 8.0f) / m_total_output_pixels); (uint32)m_output_comp_file_size, (m_output_comp_file_size * 8.0f) / m_total_output_pixels);
} }
if (psnr_metrics) if (psnr_metrics)
{ {
if ( (m_pInput_tex->get_width() != m_output_tex.get_width()) || (m_pInput_tex->get_height() != m_output_tex.get_height()) || (m_pInput_tex->get_num_faces() != m_output_tex.get_num_faces()) ) if ( (m_pInput_tex->get_width() != m_output_tex.get_width()) || (m_pInput_tex->get_height() != m_output_tex.get_height()) || (m_pInput_tex->get_num_faces() != m_output_tex.get_num_faces()) )
{ {
console::warning(L"Unable to compute image statistics - input/output texture dimensions are different."); console::warning("Unable to compute image statistics - input/output texture dimensions are different.");
} }
else else
{ {
@@ -155,7 +155,7 @@ namespace crnlib
pB = &grayscale_b; pB = &grayscale_b;
} }
console::info(L"Mipmap level %u statistics:", level); console::info("Mipmap level %u statistics:", level);
image_utils::print_image_metrics(*pA, *pB); image_utils::print_image_metrics(*pA, *pB);
if ((pA->has_rgb()) || (pB->has_rgb())) if ((pA->has_rgb()) || (pB->has_rgb()))
@@ -187,23 +187,22 @@ namespace crnlib
image_utils::error_metrics luma_error; image_utils::error_metrics luma_error;
if (rgb_error.compute(*pA, *pB, 0, 3, false) && luma_error.compute(*pA, *pB, 0, 0, true)) if (rgb_error.compute(*pA, *pB, 0, 3, false) && luma_error.compute(*pA, *pB, 0, 0, true))
{ {
FILE *pFile = NULL; bool bCSVStatsFileExists = file_utils::does_file_exist(pCSVStatsFile);
#ifdef _MSC_VER FILE* pFile;
_wfopen_s(&pFile, pCSVStatsFile, L"a"); crn_fopen(&pFile, pCSVStatsFile, "a");
#else
pFile = _wfopen(pCSVStatsFile, L"a");
#endif
if (!pFile) if (!pFile)
console::warning(L"Unable to append to CSV stats file: %s\n", pCSVStatsFile); console::warning("Unable to append to CSV stats file: %s\n", pCSVStatsFile);
else else
{ {
dynamic_wstring filename; if (!bCSVStatsFileExists)
split_path(m_src_filename.get_ptr(), NULL, NULL, &filename, NULL); fprintf(pFile, "name,width,height,miplevels,rgb_rms,luma_rms,effective_output_size,effective_bitrate\n");
dynamic_string filenamea; dynamic_string filename;
file_utils::split_path(m_src_filename.get_ptr(), NULL, NULL, &filename, NULL);
uint64 effective_output_size = m_output_comp_file_size ? m_output_comp_file_size : m_output_file_size; uint64 effective_output_size = m_output_comp_file_size ? m_output_comp_file_size : m_output_file_size;
float bitrate = (effective_output_size * 8.0f) / m_total_output_pixels; float bitrate = (effective_output_size * 8.0f) / m_total_output_pixels;
fprintf(pFile, "%s,%u,%u,%u,%f,%f,%u,%f\n", fprintf(pFile, "%s,%u,%u,%u,%f,%f,%u,%f\n",
filename.as_ansi(filenamea).get_ptr(), filename.get_ptr(),
pB->get_width(), pB->get_height(), m_output_tex.get_num_levels(), pB->get_width(), pB->get_height(), m_output_tex.get_num_levels(),
rgb_error.mRootMeanSquared, luma_error.mRootMeanSquared, rgb_error.mRootMeanSquared, luma_error.mRootMeanSquared,
(uint32)effective_output_size, bitrate); (uint32)effective_output_size, bitrate);
@@ -283,12 +282,12 @@ namespace crnlib
return true; return true;
} }
static bool convert_error(const convert_params& params, const wchar_t* pError_msg) static bool convert_error(const convert_params& params, const char* pError_msg)
{ {
params.m_status = false; params.m_status = false;
params.m_error_message = pError_msg; params.m_error_message = pError_msg;
_wremove(params.m_dst_filename.get_ptr()); remove(params.m_dst_filename.get_ptr());
return false; return false;
} }
@@ -369,55 +368,55 @@ namespace crnlib
static void print_comp_params(const crn_comp_params &comp_params) static void print_comp_params(const crn_comp_params &comp_params)
{ {
console::debug(L"\nTexture conversion compression parameters:"); console::debug("\nTexture conversion compression parameters:");
console::debug(L" Desired bitrate: %3.3f", comp_params.m_target_bitrate); console::debug(" Desired bitrate: %3.3f", comp_params.m_target_bitrate);
console::debug(L" CRN Quality: %i", comp_params.m_quality_level); console::debug(" CRN Quality: %i", comp_params.m_quality_level);
console::debug(L"CRN C endpoints/selectors: %u %u", comp_params.m_crn_color_endpoint_palette_size, comp_params.m_crn_color_selector_palette_size); console::debug("CRN C endpoints/selectors: %u %u", comp_params.m_crn_color_endpoint_palette_size, comp_params.m_crn_color_selector_palette_size);
console::debug(L"CRN A endpoints/selectors: %u %u", comp_params.m_crn_alpha_endpoint_palette_size, comp_params.m_crn_alpha_selector_palette_size); console::debug("CRN A endpoints/selectors: %u %u", comp_params.m_crn_alpha_endpoint_palette_size, comp_params.m_crn_alpha_selector_palette_size);
console::debug(L" DXT both block types: %u, Alpha threshold: %u", comp_params.get_flag(cCRNCompFlagUseBothBlockTypes), comp_params.m_dxt1a_alpha_threshold); console::debug(" DXT both block types: %u, Alpha threshold: %u", comp_params.get_flag(cCRNCompFlagUseBothBlockTypes), comp_params.m_dxt1a_alpha_threshold);
console::debug(L" DXT compression quality: %s", crn_get_dxt_quality_string(comp_params.m_dxt_quality)); console::debug(" DXT compression quality: %s", crn_get_dxt_quality_string(comp_params.m_dxt_quality));
console::debug(L" Perceptual: %u, Large Blocks: %u", comp_params.get_flag(cCRNCompFlagPerceptual), comp_params.get_flag(cCRNCompFlagHierarchical)); console::debug(" Perceptual: %u, Large Blocks: %u", comp_params.get_flag(cCRNCompFlagPerceptual), comp_params.get_flag(cCRNCompFlagHierarchical));
console::debug(L" Compressor: %s", get_dxt_compressor_name(comp_params.m_dxt_compressor_type)); console::debug(" Compressor: %s", get_dxt_compressor_name(comp_params.m_dxt_compressor_type));
console::debug(L" Disable endpoint caching: %u", comp_params.get_flag(cCRNCompFlagDisableEndpointCaching)); console::debug(" Disable endpoint caching: %u", comp_params.get_flag(cCRNCompFlagDisableEndpointCaching));
console::debug(L" Grayscale sampling: %u", comp_params.get_flag(cCRNCompFlagGrayscaleSampling)); console::debug(" Grayscale sampling: %u", comp_params.get_flag(cCRNCompFlagGrayscaleSampling));
console::debug(L" Max helper threads: %u", comp_params.m_num_helper_threads); console::debug(" Max helper threads: %u", comp_params.m_num_helper_threads);
console::debug(L""); console::debug("");
} }
static void print_mipmap_params(const crn_mipmap_params &mipmap_params) static void print_mipmap_params(const crn_mipmap_params &mipmap_params)
{ {
console::debug(L"\nTexture conversion MIP-map parameters:"); console::debug("\nTexture conversion MIP-map parameters:");
console::debug(L" Mode: %s", crn_get_mip_mode_name(mipmap_params.m_mode)); console::debug(" Mode: %s", crn_get_mip_mode_name(mipmap_params.m_mode));
console::debug(L" Filter: %S", crn_get_mip_filter_name(mipmap_params.m_filter)); console::debug(" Filter: %s", crn_get_mip_filter_name(mipmap_params.m_filter));
console::debug(L"Gamma filtering: %u, Gamma: %2.2f", mipmap_params.m_gamma_filtering, mipmap_params.m_gamma); console::debug("Gamma filtering: %u, Gamma: %2.2f", mipmap_params.m_gamma_filtering, mipmap_params.m_gamma);
console::debug(L" Blurriness: %2.2f", mipmap_params.m_blurriness); console::debug(" Blurriness: %2.2f", mipmap_params.m_blurriness);
console::debug(L" Renormalize: %u", mipmap_params.m_renormalize); console::debug(" Renormalize: %u", mipmap_params.m_renormalize);
console::debug(L" Tiled: %u", mipmap_params.m_tiled); console::debug(" Tiled: %u", mipmap_params.m_tiled);
console::debug(L" Max Levels: %u", mipmap_params.m_max_levels); console::debug(" Max Levels: %u", mipmap_params.m_max_levels);
console::debug(L" Min level size: %u", mipmap_params.m_min_mip_size); console::debug(" Min level size: %u", mipmap_params.m_min_mip_size);
console::debug(L" window: %u %u %u %u", mipmap_params.m_window_left, mipmap_params.m_window_top, mipmap_params.m_window_right, mipmap_params.m_window_bottom); console::debug(" window: %u %u %u %u", mipmap_params.m_window_left, mipmap_params.m_window_top, mipmap_params.m_window_right, mipmap_params.m_window_bottom);
console::debug(L" scale mode: %s", crn_get_scale_mode_desc(mipmap_params.m_scale_mode)); console::debug(" scale mode: %s", crn_get_scale_mode_desc(mipmap_params.m_scale_mode));
console::debug(L" scale: %f %f", mipmap_params.m_scale_x, mipmap_params.m_scale_y); console::debug(" scale: %f %f", mipmap_params.m_scale_x, mipmap_params.m_scale_y);
console::debug(L" clamp: %u %u, clamp_scale: %u", mipmap_params.m_clamp_width, mipmap_params.m_clamp_height, mipmap_params.m_clamp_scale); console::debug(" clamp: %u %u, clamp_scale: %u", mipmap_params.m_clamp_width, mipmap_params.m_clamp_height, mipmap_params.m_clamp_scale);
console::debug(L""); console::debug("");
} }
void convert_params::print() void convert_params::print()
{ {
console::debug(L"\nTexture conversion parameters:"); console::debug("\nTexture conversion parameters:");
console::debug(L" Resolution: %ux%u, Faces: %u, Levels: %u, Format: %s", console::debug(" Resolution: %ux%u, Faces: %u, Levels: %u, Format: %s",
m_pInput_texture->get_width(), m_pInput_texture->get_width(),
m_pInput_texture->get_height(), m_pInput_texture->get_height(),
m_pInput_texture->get_num_faces(), m_pInput_texture->get_num_faces(),
m_pInput_texture->get_num_levels(), m_pInput_texture->get_num_levels(),
pixel_format_helpers::get_pixel_format_string(m_pInput_texture->get_format())); pixel_format_helpers::get_pixel_format_string(m_pInput_texture->get_format()));
console::debug(L" texture_type: %s", get_texture_type_desc(m_texture_type)); console::debug(" texture_type: %s", get_texture_type_desc(m_texture_type));
console::debug(L" dst_filename: %s", m_dst_filename.get_ptr()); console::debug(" dst_filename: %s", m_dst_filename.get_ptr());
console::debug(L" dst_file_type: %s", texture_file_types::get_extension(m_dst_file_type)); console::debug(" dst_file_type: %s", texture_file_types::get_extension(m_dst_file_type));
console::debug(L" dst_format: %s", pixel_format_helpers::get_pixel_format_string(m_dst_format)); console::debug(" dst_format: %s", pixel_format_helpers::get_pixel_format_string(m_dst_format));
console::debug(L" quick: %u", m_quick); console::debug(" quick: %u", m_quick);
console::debug(L" use_source_format: %u", m_use_source_format); console::debug(" use_source_format: %u", m_use_source_format);
} }
static bool write_compressed_texture( static bool write_compressed_texture(
@@ -432,19 +431,19 @@ namespace crnlib
crn_format crn_fmt = pixel_format_helpers::convert_pixel_format_to_best_crn_format(dst_format); crn_format crn_fmt = pixel_format_helpers::convert_pixel_format_to_best_crn_format(dst_format);
comp_params.m_format = crn_fmt; comp_params.m_format = crn_fmt;
console::message(L"Writing %s texture to file: \"%s\"", crn_get_format_string(crn_fmt), params.m_dst_filename.get_ptr()); console::message("Writing %s texture to file: \"%s\"", crn_get_format_string(crn_fmt), params.m_dst_filename.get_ptr());
uint32 actual_quality_level; uint32 actual_quality_level;
float actual_bitrate; float actual_bitrate;
bool status = work_tex.write_to_file(params.m_dst_filename.get_ptr(), params.m_dst_file_type, &comp_params, &actual_quality_level, &actual_bitrate); bool status = work_tex.write_to_file(params.m_dst_filename.get_ptr(), params.m_dst_file_type, &comp_params, &actual_quality_level, &actual_bitrate);
if (!status) if (!status)
return convert_error(params, L"Failed writing output file!"); return convert_error(params, "Failed writing output file!");
if (!params.m_no_stats) if (!params.m_no_stats)
{ {
if (!stats.init(params.m_pInput_texture->get_source_filename().get_ptr(), params.m_dst_filename.get_ptr(), *params.m_pIntermediate_texture, params.m_dst_file_type, params.m_lzma_stats)) if (!stats.init(params.m_pInput_texture->get_source_filename().get_ptr(), params.m_dst_filename.get_ptr(), *params.m_pIntermediate_texture, params.m_dst_file_type, params.m_lzma_stats))
{ {
console::warning(L"Unable to compute output statistics for file: %s", params.m_pInput_texture->get_source_filename().get_ptr()); console::warning("Unable to compute output statistics for file: %s", params.m_pInput_texture->get_source_filename().get_ptr());
} }
} }
@@ -471,7 +470,7 @@ namespace crnlib
pack_params.m_num_helper_threads = comp_params.m_num_helper_threads; pack_params.m_num_helper_threads = comp_params.m_num_helper_threads;
pack_params.m_use_transparent_indices_for_black = comp_params.get_flag(cCRNCompFlagUseTransparentIndicesForBlack); pack_params.m_use_transparent_indices_for_black = comp_params.get_flag(cCRNCompFlagUseTransparentIndicesForBlack);
console::info(L"Converting texture format from %s to %s", pixel_format_helpers::get_pixel_format_string(work_tex.get_format()), pixel_format_helpers::get_pixel_format_string(dst_format)); console::info("Converting texture format from %s to %s", pixel_format_helpers::get_pixel_format_string(work_tex.get_format()), pixel_format_helpers::get_pixel_format_string(dst_format));
timer tm; timer tm;
tm.start(); tm.start();
@@ -480,7 +479,7 @@ namespace crnlib
double t = tm.get_elapsed_secs(); double t = tm.get_elapsed_secs();
console::info(L""); console::info("");
if (!status) if (!status)
{ {
@@ -491,11 +490,11 @@ namespace crnlib
} }
else else
{ {
return convert_error(params, L"Failed converting texture to output format!"); return convert_error(params, "Failed converting texture to output format!");
} }
} }
console::info(L"Texture format conversion took %3.3fs", t); console::info("Texture format conversion took %3.3fs", t);
} }
if (params.m_write_mipmaps_to_multiple_files) if (params.m_write_mipmaps_to_multiple_files)
@@ -504,13 +503,13 @@ namespace crnlib
{ {
for (uint l = 0; l < work_tex.get_num_levels(); l++) for (uint l = 0; l < work_tex.get_num_levels(); l++)
{ {
dynamic_wstring filename(params.m_dst_filename.get_ptr()); dynamic_string filename(params.m_dst_filename.get_ptr());
dynamic_wstring drv, dir, fn, ext; dynamic_string drv, dir, fn, ext;
if (!split_path(params.m_dst_filename.get_ptr(), &drv, &dir, &fn, &ext)) if (!file_utils::split_path(params.m_dst_filename.get_ptr(), &drv, &dir, &fn, &ext))
return false; return false;
fn += dynamic_wstring(cVarArg, L"_face%u_mip%u", f, l).get_ptr(); fn += dynamic_string(cVarArg, "_face%u_mip%u", f, l).get_ptr();
filename = drv + dir + fn + ext; filename = drv + dir + fn + ext;
mip_level *pLevel = work_tex.get_level(f, l); mip_level *pLevel = work_tex.get_level(f, l);
@@ -521,25 +520,25 @@ namespace crnlib
dds_texture new_tex; dds_texture new_tex;
new_tex.assign(face); new_tex.assign(face);
console::info(L"Writing texture face %u mip level %u to file %s", f, l, filename.get_ptr()); console::info("Writing texture face %u mip level %u to file %s", f, l, filename.get_ptr());
if (!new_tex.write_to_file(filename.get_ptr(), params.m_dst_file_type, NULL, NULL, NULL)) if (!new_tex.write_to_file(filename.get_ptr(), params.m_dst_file_type, NULL, NULL, NULL))
return convert_error(params, L"Failed writing output file!"); return convert_error(params, "Failed writing output file!");
} }
} }
} }
else else
{ {
console::message(L"Writing texture to file: \"%s\"", params.m_dst_filename.get_ptr()); console::message("Writing texture to file: \"%s\"", params.m_dst_filename.get_ptr());
if (!work_tex.write_to_file(params.m_dst_filename.get_ptr(), params.m_dst_file_type, NULL, NULL, NULL)) if (!work_tex.write_to_file(params.m_dst_filename.get_ptr(), params.m_dst_file_type, NULL, NULL, NULL))
return convert_error(params, L"Failed writing output file!"); return convert_error(params, "Failed writing output file!");
if (!params.m_no_stats) if (!params.m_no_stats)
{ {
if (!stats.init(params.m_pInput_texture->get_source_filename().get_ptr(), params.m_dst_filename.get_ptr(), *params.m_pIntermediate_texture, params.m_dst_file_type, params.m_lzma_stats)) if (!stats.init(params.m_pInput_texture->get_source_filename().get_ptr(), params.m_dst_filename.get_ptr(), *params.m_pIntermediate_texture, params.m_dst_file_type, params.m_lzma_stats))
{ {
console::warning(L"Unable to compute output statistics for file: %s", params.m_pInput_texture->get_source_filename().get_ptr()); console::warning("Unable to compute output statistics for file: %s", params.m_pInput_texture->get_source_filename().get_ptr());
} }
} }
} }
@@ -576,7 +575,7 @@ namespace crnlib
{ {
if ((work_tex.get_comp_flags() & pixel_format_helpers::cCompFlagAValid) == 0) if ((work_tex.get_comp_flags() & pixel_format_helpers::cCompFlagAValid) == 0)
{ {
console::warning(L"Output format is alpha-only, but input doesn't have alpha, so setting alpha to luminance."); console::warning("Output format is alpha-only, but input doesn't have alpha, so setting alpha to luminance.");
work_tex.convert(PIXEL_FMT_A8, crnlib::dxt_image::pack_params()); work_tex.convert(PIXEL_FMT_A8, crnlib::dxt_image::pack_params());
@@ -586,6 +585,15 @@ namespace crnlib
} }
pixel_format dst_format = params.m_dst_format; pixel_format dst_format = params.m_dst_format;
if (pixel_format_helpers::is_dxt(dst_format))
{
if ((params.m_dst_file_type != texture_file_types::cFormatCRN) &&
(params.m_dst_file_type != texture_file_types::cFormatDDS))
{
console::warning("Output file format does not support DXT - automatically choosing pixel format.");
dst_format = PIXEL_FMT_INVALID;
}
}
if (dst_format == PIXEL_FMT_INVALID) if (dst_format == PIXEL_FMT_INVALID)
{ {
@@ -611,15 +619,15 @@ namespace crnlib
{ {
if (perceptual) if (perceptual)
{ {
//console::warning(L"Output pixel format is swizzled or not RGB, disabling perceptual color metrics"); console::message("Output pixel format is swizzled or not RGB, disabling perceptual color metrics");
perceptual = false; perceptual = false;
} }
} }
if (pixel_format_helpers::is_normal_map(dst_format)) if (pixel_format_helpers::is_normal_map(dst_format))
{ {
//if (perceptual) if (perceptual)
//console::warning(L"Output pixel format is intended for normal maps, disabling perceptual color metrics"); console::message("Output pixel format is intended for normal maps, disabling perceptual color metrics");
perceptual = false; perceptual = false;
} }
@@ -639,7 +647,7 @@ namespace crnlib
} }
if (!create_texture_mipmaps(work_tex, comp_params, mipmap_params, generate_mipmaps)) if (!create_texture_mipmaps(work_tex, comp_params, mipmap_params, generate_mipmaps))
return convert_error(params, L"Failed creating texture mipmaps!"); return convert_error(params, "Failed creating texture mipmaps!");
bool formats_differ = work_tex.get_format() != dst_format; bool formats_differ = work_tex.get_format() != dst_format;
if (formats_differ) if (formats_differ)
@@ -666,7 +674,7 @@ namespace crnlib
status = convert_and_write_normal_texture(work_tex, params, comp_params, dst_format, progress_state, formats_differ, perceptual, stats); status = convert_and_write_normal_texture(work_tex, params, comp_params, dst_format, progress_state, formats_differ, perceptual, stats);
} }
console::progress(L""); console::progress("");
if (progress_state.m_canceled) if (progress_state.m_canceled)
{ {
@@ -679,18 +687,18 @@ namespace crnlib
if (status) if (status)
{ {
if (params.m_param_debugging) if (params.m_param_debugging)
console::info(L"Work texture format: %s, desired destination format: %s", pixel_format_helpers::get_pixel_format_string(work_tex.get_format()), pixel_format_helpers::get_pixel_format_string(dst_format)); console::info("Work texture format: %s, desired destination format: %s", pixel_format_helpers::get_pixel_format_string(work_tex.get_format()), pixel_format_helpers::get_pixel_format_string(dst_format));
console::message(L"Texture successfully written in %3.3fs", total_write_time); console::message("Texture successfully written in %3.3fs", total_write_time);
} }
else else
{ {
dynamic_wstring str; dynamic_string str;
if (work_tex.get_last_error().is_empty()) if (work_tex.get_last_error().is_empty())
str.format(L"Failed writing texture to file \"%s\"", params.m_dst_filename.get_ptr()); str.format("Failed writing texture to file \"%s\"", params.m_dst_filename.get_ptr());
else else
str.format(L"Failed writing texture to file \"%s\", Reason: %s", params.m_dst_filename.get_ptr(), work_tex.get_last_error().get_ptr()); str.format("Failed writing texture to file \"%s\", Reason: %s", params.m_dst_filename.get_ptr(), work_tex.get_last_error().get_ptr());
return convert_error(params, str.get_ptr()); return convert_error(params, str.get_ptr());
} }
+10 -10
View File
@@ -16,18 +16,18 @@ namespace crnlib
convert_stats(); convert_stats();
bool init( bool init(
const wchar_t* pSrc_filename, const char* pSrc_filename,
const wchar_t* pDst_filename, const char* pDst_filename,
dds_texture& src_tex, dds_texture& src_tex,
texture_file_types::format dst_file_type, texture_file_types::format dst_file_type,
bool lzma_stats); bool lzma_stats);
bool print(bool psnr_metrics, bool mip_stats, bool grayscale_sampling, const wchar_t *pCSVStatsFile = NULL) const; bool print(bool psnr_metrics, bool mip_stats, bool grayscale_sampling, const char *pCSVStatsFile = NULL) const;
void clear(); void clear();
dynamic_wstring m_src_filename; dynamic_string m_src_filename;
dynamic_wstring m_dst_filename; dynamic_string m_dst_filename;
texture_file_types::format m_dst_file_type; texture_file_types::format m_dst_file_type;
dds_texture* m_pInput_tex; dds_texture* m_pInput_tex;
@@ -58,10 +58,10 @@ namespace crnlib
m_debugging(false), m_debugging(false),
m_param_debugging(false), m_param_debugging(false),
m_no_stats(false), m_no_stats(false),
m_use_source_format(false),
m_lzma_stats(false), m_lzma_stats(false),
m_status(false), m_status(false),
m_canceled(false), m_canceled(false)
m_use_source_format(false)
{ {
} }
@@ -77,7 +77,7 @@ namespace crnlib
texture_type m_texture_type; texture_type m_texture_type;
dynamic_wstring m_dst_filename; dynamic_string m_dst_filename;
texture_file_types::format m_dst_file_type; texture_file_types::format m_dst_file_type;
pixel_format m_dst_format; pixel_format m_dst_format;
@@ -90,7 +90,7 @@ namespace crnlib
// Return parameters // Return parameters
dds_texture* m_pIntermediate_texture; dds_texture* m_pIntermediate_texture;
mutable dynamic_wstring m_error_message; mutable dynamic_string m_error_message;
bool m_write_mipmaps_to_multiple_files; bool m_write_mipmaps_to_multiple_files;
bool m_quick; bool m_quick;
@@ -98,7 +98,7 @@ namespace crnlib
bool m_param_debugging; bool m_param_debugging;
bool m_no_stats; bool m_no_stats;
bool m_use_source_format; bool m_use_source_format;
bool m_lzma_stats; bool m_lzma_stats;
mutable bool m_status; mutable bool m_status;
mutable bool m_canceled; mutable bool m_canceled;
+30 -30
View File
@@ -2,48 +2,48 @@
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#include "crn_core.h" #include "crn_core.h"
#include "crn_texture_file_types.h" #include "crn_texture_file_types.h"
#include "crn_strutils.h" #include "crn_file_utils.h"
namespace crnlib namespace crnlib
{ {
const wchar_t* texture_file_types::get_extension(format fmt) const char* texture_file_types::get_extension(format fmt)
{ {
CRNLIB_ASSERT(fmt < cNumFileFormats); CRNLIB_ASSERT(fmt < cNumFileFormats);
if (fmt >= cNumFileFormats) if (fmt >= cNumFileFormats)
return NULL; return NULL;
static const wchar_t* extensions[cNumFileFormats] = static const char* extensions[cNumFileFormats] =
{ {
L"tga", "tga",
L"png", "png",
L"jpg", "jpg",
L"jpeg", "jpeg",
L"bmp", "bmp",
L"gif", "gif",
L"tif", "tif",
L"tiff", "tiff",
L"ppm", "ppm",
L"pgm", "pgm",
L"dds", "dds",
L"psd", "psd",
L"jp2", "jp2",
L"crn", "crn",
L"<clipboard>", "<clipboard>",
L"<dragdrop>" "<dragdrop>"
}; };
return extensions[fmt]; return extensions[fmt];
} }
texture_file_types::format texture_file_types::determine_file_format(const wchar_t* pFilename) texture_file_types::format texture_file_types::determine_file_format(const char* pFilename)
{ {
dynamic_wstring ext; dynamic_string ext;
if (!split_path(pFilename, NULL, NULL, NULL, &ext)) if (!file_utils::split_path(pFilename, NULL, NULL, NULL, &ext))
return cFormatInvalid; return cFormatInvalid;
if (ext.is_empty()) if (ext.is_empty())
return cFormatInvalid; return cFormatInvalid;
if (ext[0] == L'.') if (ext[0] == '.')
ext.right(1); ext.right(1);
for (uint i = 0; i < cNumFileFormats; i++) for (uint i = 0; i < cNumFileFormats; i++)
@@ -81,21 +81,21 @@ namespace crnlib
return true; return true;
} }
const wchar_t* get_texture_type_desc(texture_type t) const char* get_texture_type_desc(texture_type t)
{ {
switch (t) switch (t)
{ {
case cTextureTypeUnknown: return L"Unknown"; case cTextureTypeUnknown: return "Unknown";
case cTextureTypeRegularMap: return L"2D map"; case cTextureTypeRegularMap: return "2D map";
case cTextureTypeNormalMap: return L"Normal map"; case cTextureTypeNormalMap: return "Normal map";
case cTextureTypeVerticalCrossCubemap: return L"Vertical Cross Cubemap"; case cTextureTypeVerticalCrossCubemap: return "Vertical Cross Cubemap";
case cTextureTypeCubemap: return L"Cubemap"; case cTextureTypeCubemap: return "Cubemap";
default: break; default: break;
} }
CRNLIB_ASSERT(false); CRNLIB_ASSERT(false);
return L"?"; return "?";
} }
} // namespace crnlib } // namespace crnlib
+12 -12
View File
@@ -27,24 +27,24 @@ namespace crnlib
cFormatPSD, cFormatPSD,
cFormatJP2, cFormatJP2,
cFormatCRN, cFormatCRN,
cNumRegularFileFormats, cNumRegularFileFormats,
// Not really a file format // Not really a file format
cFormatClipboard = cNumRegularFileFormats, cFormatClipboard = cNumRegularFileFormats,
cFormatDragDrop, cFormatDragDrop,
cNumFileFormats cNumFileFormats
}; };
static const wchar_t* get_extension(format fmt); static const char* get_extension(format fmt);
static format determine_file_format(const char* pFilename);
static format determine_file_format(const wchar_t* pFilename);
static bool supports_mipmaps(format fmt); static bool supports_mipmaps(format fmt);
static bool supports_alpha(format fmt); static bool supports_alpha(format fmt);
}; };
enum texture_type enum texture_type
{ {
cTextureTypeUnknown = 0, cTextureTypeUnknown = 0,
@@ -55,8 +55,8 @@ namespace crnlib
cNumTextureTypes cNumTextureTypes
}; };
const wchar_t* get_texture_type_desc(texture_type t); const char* get_texture_type_desc(texture_type t);
} // namespace crnlib } // namespace crnlib
+4 -3
View File
@@ -2,6 +2,7 @@
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#pragma once #pragma once
#include "crn_clusterizer.h" #include "crn_clusterizer.h"
#include "crn_threading.h"
namespace crnlib namespace crnlib
{ {
@@ -43,7 +44,7 @@ namespace crnlib
progress_callback_func pProgress_callback, progress_callback_func pProgress_callback,
void* pProgress_callback_data) void* pProgress_callback_data)
{ {
m_main_thread_id = get_current_thread_id(); m_main_thread_id = crn_get_current_thread_id();
m_canceled = false; m_canceled = false;
m_pProgress_callback = pProgress_callback; m_pProgress_callback = pProgress_callback;
m_pProgress_callback_data = pProgress_callback_data; m_pProgress_callback_data = pProgress_callback_data;
@@ -136,7 +137,7 @@ namespace crnlib
private: private:
task_pool* m_pTask_pool; task_pool* m_pTask_pool;
uint32 m_main_thread_id; crn_thread_id_t m_main_thread_id;
struct create_clusters_task_state struct create_clusters_task_state
{ {
@@ -328,7 +329,7 @@ namespace crnlib
if (m_canceled) if (m_canceled)
return; return;
const bool is_main_thread = (get_current_thread_id() == m_main_thread_id); const bool is_main_thread = (crn_get_current_thread_id() == m_main_thread_id);
const bool quick = false; const bool quick = false;
m_clusterizers[partition_index].generate_codebook( m_clusterizers[partition_index].generate_codebook(
+1
View File
@@ -3,6 +3,7 @@
#include "crn_core.h" #include "crn_core.h"
#include "crn_threaded_resampler.h" #include "crn_threaded_resampler.h"
#include "crn_resample_filters.h" #include "crn_resample_filters.h"
#include "crn_threading.h"
namespace crnlib namespace crnlib
{ {
+20 -20
View File
@@ -3,34 +3,34 @@
#pragma once #pragma once
#include "crn_resampler.h" #include "crn_resampler.h"
#include "crn_vec.h" #include "crn_vec.h"
#include "crn_task_pool.h"
namespace crnlib namespace crnlib
{ {
class task_pool;
class threaded_resampler class threaded_resampler
{ {
CRNLIB_NO_COPY_OR_ASSIGNMENT_OP(threaded_resampler); CRNLIB_NO_COPY_OR_ASSIGNMENT_OP(threaded_resampler);
public: public:
threaded_resampler(task_pool& tp); threaded_resampler(task_pool& tp);
~threaded_resampler(); ~threaded_resampler();
enum pixel_format enum pixel_format
{ {
cPF_Y_F32, cPF_Y_F32,
cPF_RGBX_F32, cPF_RGBX_F32,
cPF_RGBA_F32, cPF_RGBA_F32,
cPF_Total cPF_Total
}; };
struct params struct params
{ {
params() params()
{ {
clear(); clear();
} }
void clear() void clear()
{ {
utils::zero_object(*this); utils::zero_object(*this);
@@ -42,44 +42,44 @@ namespace crnlib
m_filter_x_scale = 1.0f; m_filter_x_scale = 1.0f;
m_filter_y_scale = 1.0f; m_filter_y_scale = 1.0f;
} }
pixel_format m_fmt; pixel_format m_fmt;
const void* m_pSrc_pixels; const void* m_pSrc_pixels;
uint m_src_width; uint m_src_width;
uint m_src_height; uint m_src_height;
uint m_src_pitch; uint m_src_pitch;
void* m_pDst_pixels; void* m_pDst_pixels;
uint m_dst_width; uint m_dst_width;
uint m_dst_height; uint m_dst_height;
uint m_dst_pitch; uint m_dst_pitch;
Resampler::Boundary_Op m_boundary_op; Resampler::Boundary_Op m_boundary_op;
float m_sample_low; float m_sample_low;
float m_sample_high; float m_sample_high;
const char* m_Pfilter_name; const char* m_Pfilter_name;
float m_filter_x_scale; float m_filter_x_scale;
float m_filter_y_scale; float m_filter_y_scale;
}; };
bool resample(const params& p); bool resample(const params& p);
private: private:
task_pool* m_pTask_pool; task_pool* m_pTask_pool;
const params* m_pParams; const params* m_pParams;
Resampler::Contrib_List* m_pX_contribs; Resampler::Contrib_List* m_pX_contribs;
Resampler::Contrib_List* m_pY_contribs; Resampler::Contrib_List* m_pY_contribs;
uint m_bytes_per_pixel; uint m_bytes_per_pixel;
crnlib::vector<vec4F> m_tmp_img; crnlib::vector<vec4F> m_tmp_img;
void free_contrib_lists(); void free_contrib_lists();
void resample_x_task(uint64 data, void* pData_ptr); void resample_x_task(uint64 data, void* pData_ptr);
void resample_y_task(uint64 data, void* pData_ptr); void resample_y_task(uint64 data, void* pData_ptr);
}; };
+15 -1
View File
@@ -4,6 +4,15 @@
namespace crnlib namespace crnlib
{ {
template<typename T> struct int_traits { enum { cMin = crnlib::cINT32_MIN, cMax = crnlib::cINT32_MAX, cSigned = true }; };
template<> struct int_traits<int8> { enum { cMin = crnlib::cINT8_MIN, cMax = crnlib::cINT8_MAX, cSigned = true }; };
template<> struct int_traits<int16> { enum { cMin = crnlib::cINT16_MIN, cMax = crnlib::cINT16_MAX, cSigned = true }; };
template<> struct int_traits<int32> { enum { cMin = crnlib::cINT32_MIN, cMax = crnlib::cINT32_MAX, cSigned = true }; };
template<> struct int_traits<uint8> { enum { cMin = 0, cMax = crnlib::cUINT8_MAX, cSigned = false }; };
template<> struct int_traits<uint16> { enum { cMin = 0, cMax = crnlib::cUINT16_MAX, cSigned = false }; };
template<> struct int_traits<uint32> { enum { cMin = 0, cMax = crnlib::cUINT32_MAX, cSigned = false }; };
template<typename T> template<typename T>
struct scalar_type struct scalar_type
{ {
@@ -43,8 +52,13 @@ namespace crnlib
CRNLIB_DEFINE_BUILT_IN_TYPE(unsigned int) CRNLIB_DEFINE_BUILT_IN_TYPE(unsigned int)
CRNLIB_DEFINE_BUILT_IN_TYPE(long) CRNLIB_DEFINE_BUILT_IN_TYPE(long)
CRNLIB_DEFINE_BUILT_IN_TYPE(unsigned long) CRNLIB_DEFINE_BUILT_IN_TYPE(unsigned long)
#ifdef __GNUC__
CRNLIB_DEFINE_BUILT_IN_TYPE(long long)
CRNLIB_DEFINE_BUILT_IN_TYPE(unsigned long long)
#else
CRNLIB_DEFINE_BUILT_IN_TYPE(__int64) CRNLIB_DEFINE_BUILT_IN_TYPE(__int64)
CRNLIB_DEFINE_BUILT_IN_TYPE(unsigned __int64) CRNLIB_DEFINE_BUILT_IN_TYPE(unsigned __int64)
#endif
CRNLIB_DEFINE_BUILT_IN_TYPE(float) CRNLIB_DEFINE_BUILT_IN_TYPE(float)
CRNLIB_DEFINE_BUILT_IN_TYPE(double) CRNLIB_DEFINE_BUILT_IN_TYPE(double)
CRNLIB_DEFINE_BUILT_IN_TYPE(long double) CRNLIB_DEFINE_BUILT_IN_TYPE(long double)
@@ -69,7 +83,7 @@ namespace crnlib
#define CRNLIB_IS_SCALAR_TYPE(T) (scalar_type<T>::cFlag) #define CRNLIB_IS_SCALAR_TYPE(T) (scalar_type<T>::cFlag)
#define CRNLIB_IS_BITWISE_COPYABLE(T) ((scalar_type<T>::cFlag) || (bitwise_copyable<T>::cFlag) || CRNLIB_IS_POD(T)) #define CRNLIB_IS_BITWISE_COPYABLE(T) (CRNLIB_IS_SCALAR_TYPE(T) || CRNLIB_IS_POD(T) || (bitwise_copyable<T>::cFlag))
#define CRNLIB_IS_BITWISE_MOVABLE(T) (CRNLIB_IS_BITWISE_COPYABLE(T) || (bitwise_movable<T>::cFlag)) #define CRNLIB_IS_BITWISE_MOVABLE(T) (CRNLIB_IS_BITWISE_COPYABLE(T) || (bitwise_movable<T>::cFlag))
+10 -6
View File
@@ -137,7 +137,7 @@ namespace crnlib
return m_codebook; return m_codebook;
} }
const uint find_best_codebook_entry(const VectorType& v) const uint find_best_codebook_entry(const VectorType& v) const
{ {
uint cur_node_index = 0; uint cur_node_index = 0;
@@ -161,7 +161,7 @@ namespace crnlib
} }
} }
const uint find_best_codebook_entry_fs(const VectorType& v) const uint find_best_codebook_entry_fs(const VectorType& v) const
{ {
float best_dist = math::cNearlyInfinite; float best_dist = math::cNearlyInfinite;
uint best_index = 0; uint best_index = 0;
@@ -222,7 +222,7 @@ namespace crnlib
if (parent_node.m_vectors.size() == 1) if (parent_node.m_vectors.size() == 1)
return; return;
VectorType furthest; VectorType furthest(0);
double furthest_dist = -1.0f; double furthest_dist = -1.0f;
for (uint i = 0; i < parent_node.m_vectors.size(); i++) for (uint i = 0; i < parent_node.m_vectors.size(); i++)
@@ -272,9 +272,13 @@ namespace crnlib
covar[x][y] = covar[x][y] + v[x] * w[y]; covar[x][y] = covar[x][y] + v[x] * w[y];
} }
for (uint x = 0; x < N - 1; x++) if (N > 1)
for (uint y = x + 1; y < N; y++) {
covar[y][x] = covar[x][y]; //for (uint x = 0; x < (N - 1); x++)
for (uint x = 0; x != (N - 1); x++)
for (uint y = x + 1; y < N; y++)
covar[y][x] = covar[x][y];
}
covar /= float(parent_node.m_total_weight); covar /= float(parent_node.m_total_weight);
+27 -22
View File
@@ -12,31 +12,36 @@ namespace crnlib
typedef uint32 uint; typedef uint32 uint;
typedef signed int int32; typedef signed int int32;
typedef unsigned __int64 uint64; #ifdef __GNUC__
typedef signed __int64 int64; typedef unsigned long long uint64;
typedef long long int64;
#else
typedef unsigned __int64 uint64;
typedef signed __int64 int64;
#endif
const uint8 UINT8_MIN = 0; const uint8 cUINT8_MIN = 0;
const uint8 UINT8_MAX = 0xFFU; const uint8 cUINT8_MAX = 0xFFU;
const uint16 UINT16_MIN = 0; const uint16 cUINT16_MIN = 0;
const uint16 UINT16_MAX = 0xFFFFU; const uint16 cUINT16_MAX = 0xFFFFU;
const uint32 UINT32_MIN = 0; const uint32 cUINT32_MIN = 0;
const uint32 UINT32_MAX = 0xFFFFFFFFU; const uint32 cUINT32_MAX = 0xFFFFFFFFU;
const uint64 UINT64_MIN = 0; const uint64 cUINT64_MIN = 0;
const uint64 UINT64_MAX = 0xFFFFFFFFFFFFFFFFULL; //0xFFFFFFFFFFFFFFFFui64; const uint64 cUINT64_MAX = 0xFFFFFFFFFFFFFFFFULL; //0xFFFFFFFFFFFFFFFFui64;
const int8 INT8_MIN = -128; const int8 cINT8_MIN = -128;
const int8 INT8_MAX = 127; const int8 cINT8_MAX = 127;
const int16 INT16_MIN = -32768; const int16 cINT16_MIN = -32768;
const int16 INT16_MAX = 32767; const int16 cINT16_MAX = 32767;
const int32 INT32_MIN = (-2147483647 - 1); const int32 cINT32_MIN = (-2147483647 - 1);
const int32 INT32_MAX = 2147483647; const int32 cINT32_MAX = 2147483647;
const int64 INT64_MIN = (int64)0x8000000000000000ULL; //(-9223372036854775807i64 - 1); const int64 cINT64_MIN = (int64)0x8000000000000000ULL; //(-9223372036854775807i64 - 1);
const int64 INT64_MAX = (int64)0x7FFFFFFFFFFFFFFFULL; // 9223372036854775807i64; const int64 cINT64_MAX = (int64)0x7FFFFFFFFFFFFFFFULL; // 9223372036854775807i64;
#ifdef CRNLIB_PLATFORM_PC_X64 #if CRNLIB_64BIT_POINTERS
typedef unsigned __int64 uint_ptr; typedef uint64 uint_ptr;
typedef unsigned __int64 uint32_ptr; typedef uint64 uint32_ptr;
typedef signed __int64 signed_size_t; typedef int64 signed_size_t;
typedef uint64 ptr_bits_t; typedef uint64 ptr_bits_t;
#else #else
typedef unsigned int uint_ptr; typedef unsigned int uint_ptr;
+13 -1
View File
@@ -37,7 +37,19 @@ namespace crnlib
*pDst++ = swap16(*pSrc++); *pDst++ = swap16(*pSrc++);
} }
} }
void copy_dwords(uint32* pDst, const uint32* pSrc, uint num, bool endian_switch)
{
if (!endian_switch)
memcpy(pDst, pSrc, num << 2U);
else
{
uint32* pDst_end = pDst + num;
while (pDst != pDst_end)
*pDst++ = swap32(*pSrc++);
}
}
uint compute_max_mips(uint width, uint height) uint compute_max_mips(uint width, uint height)
{ {
if ((width | height) == 0) if ((width | height) == 0)
+16 -12
View File
@@ -8,18 +8,21 @@
#define CRNLIB_ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) #define CRNLIB_ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
#ifdef _MSC_VER #ifdef _MSC_VER
extern "C" unsigned long __cdecl _lrotl(unsigned long, int); // Need to explictly extern these with MSVC, but not MinGW.
#pragma intrinsic(_lrotl) extern "C" unsigned long __cdecl _lrotl(unsigned long, int);
#pragma intrinsic(_lrotl)
extern "C" unsigned long __cdecl _lrotr(unsigned long, int); extern "C" unsigned long __cdecl _lrotr(unsigned long, int);
#pragma intrinsic(_lrotr) #pragma intrinsic(_lrotr)
#endif #endif
//#define CRNLIB_ROTATE_LEFT(x, k) (((x) << (k)) | ((x) >> (32-(k)))) #ifdef WIN32
#define CRNLIB_ROTATE_LEFT(x, k) _lrotl(x, k) #define CRNLIB_ROTATE_LEFT(x, k) _lrotl(x, k)
#define CRNLIB_ROTATE_RIGHT(x, k) _lrotr(x, k)
//#define CRNLIB_ROTATE_RIGHT(x, k) (((x) >> (k)) | ((x) << (32-(k)))) #else
#define CRNLIB_ROTATE_RIGHT(x, k) _lrotr(x, k) #define CRNLIB_ROTATE_LEFT(x, k) (((x) << (k)) | ((x) >> (32-(k))))
#define CRNLIB_ROTATE_RIGHT(x, k) (((x) >> (k)) | ((x) << (32-(k))))
#endif
template<class T, size_t N> T decay_array_to_subtype(T (&a)[N]); template<class T, size_t N> T decay_array_to_subtype(T (&a)[N]);
#define CRNLIB_ARRAY_SIZE(X) (sizeof(X) / sizeof(decay_array_to_subtype(X))) #define CRNLIB_ARRAY_SIZE(X) (sizeof(X) / sizeof(decay_array_to_subtype(X)))
@@ -39,12 +42,12 @@ namespace crnlib
template<typename T> inline void zero_object(T& obj) template<typename T> inline void zero_object(T& obj)
{ {
memset(&obj, 0, sizeof(obj)); memset((void*)&obj, 0, sizeof(obj));
} }
template<typename T> inline void zero_this(T* pObj) template<typename T> inline void zero_this(T* pObj)
{ {
memset(pObj, 0, sizeof(*pObj)); memset((void*)pObj, 0, sizeof(*pObj));
} }
inline bool is_bit_set(uint bits, uint mask) inline bool is_bit_set(uint bits, uint mask)
@@ -225,7 +228,8 @@ namespace crnlib
void endian_switch_words(uint16* p, uint num); void endian_switch_words(uint16* p, uint num);
void endian_switch_dwords(uint32* p, uint num); void endian_switch_dwords(uint32* p, uint num);
void copy_words(uint16* pDst, const uint16* pSrc, uint num, bool endian_switch); void copy_words(uint16* pDst, const uint16* pSrc, uint num, bool endian_switch);
void copy_dwords(uint32* pDst, const uint32* pSrc, uint num, bool endian_switch);
uint compute_max_mips(uint width, uint height); uint compute_max_mips(uint width, uint height);
} // namespace utils } // namespace utils
+10 -10
View File
@@ -5,17 +5,17 @@
namespace crnlib namespace crnlib
{ {
const wchar_t* gValueDataTypeStrings[cDTTotal + 1] = const char* gValueDataTypeStrings[cDTTotal + 1] =
{ {
L"invalid", "invalid",
L"string", "string",
L"bool", "bool",
L"int", "int",
L"uint", "uint",
L"float", "float",
L"vec3f", "vec3f",
L"vec3i", "vec3i",
NULL, NULL,
}; };
+40 -40
View File
@@ -2,7 +2,7 @@
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#pragma once #pragma once
#include "crn_strutils.h" #include "crn_strutils.h"
#include "crn_dynamic_wstring.h" #include "crn_dynamic_string.h"
#include "crn_vec.h" #include "crn_vec.h"
namespace crnlib namespace crnlib
@@ -21,7 +21,7 @@ namespace crnlib
cDTTotal cDTTotal
}; };
extern const wchar_t* gValueDataTypeStrings[cDTTotal + 1]; extern const char* gValueDataTypeStrings[cDTTotal + 1];
class value class value
{ {
@@ -31,13 +31,13 @@ namespace crnlib
{ {
} }
value(const wchar_t* pStr) : value(const char* pStr) :
m_pStr(crnlib_new<dynamic_wstring>(pStr)), m_type(cDTString) m_pStr(crnlib_new<dynamic_string>(pStr)), m_type(cDTString)
{ {
} }
value(const dynamic_wstring& str) : value(const dynamic_string& str) :
m_pStr(crnlib_new<dynamic_wstring>(str)), m_type(cDTString) m_pStr(crnlib_new<dynamic_string>(str)), m_type(cDTString)
{ {
} }
@@ -125,7 +125,7 @@ namespace crnlib
m_type = cDTInvalid; m_type = cDTInvalid;
} }
void set_string(const wchar_t* pStr) void set_string(const char* pStr)
{ {
set_str(pStr); set_str(pStr);
} }
@@ -170,7 +170,7 @@ namespace crnlib
m_pVec3I->set(v); m_pVec3I->set(v);
} }
bool parse(const wchar_t* p) bool parse(const char* p)
{ {
if ((!p) || (!p[0])) if ((!p) || (!p[0]))
{ {
@@ -178,12 +178,12 @@ namespace crnlib
return false; return false;
} }
if (_wcsicmp(p, L"false") == 0) if (_stricmp(p, "false") == 0)
{ {
set_bool(false); set_bool(false);
return true; return true;
} }
else if (_wcsicmp(p, L"true") == 0) else if (_stricmp(p, "true") == 0)
{ {
set_bool(true); set_bool(true);
return true; return true;
@@ -191,7 +191,7 @@ namespace crnlib
if (p[0] == '\"') if (p[0] == '\"')
{ {
dynamic_wstring str; dynamic_string str;
str = p + 1; str = p + 1;
if (!str.is_empty()) if (!str.is_empty())
{ {
@@ -205,21 +205,21 @@ namespace crnlib
} }
} }
if (wcschr(p, L',') != NULL) if (strchr(p, ',') != NULL)
{ {
float fx = 0, fy = 0, fz = 0; float fx = 0, fy = 0, fz = 0;
#ifdef _MSC_VER #ifdef _MSC_VER
if (swscanf_s(p, L"%f,%f,%f", &fx, &fy, &fz) == 3) if (sscanf_s(p, "%f,%f,%f", &fx, &fy, &fz) == 3)
#else #else
if (swscanf(p, L"%f,%f,%f", &fx, &fy, &fz) == 3) if (sscanf(p, "%f,%f,%f", &fx, &fy, &fz) == 3)
#endif #endif
{ {
bool as_float = true; bool as_float = true;
int ix = 0, iy = 0, iz = 0; int ix = 0, iy = 0, iz = 0;
#ifdef _MSC_VER #ifdef _MSC_VER
if (swscanf_s(p, L"%i,%i,%i", &ix, &iy, &iz) == 3) if (sscanf_s(p, "%i,%i,%i", &ix, &iy, &iz) == 3)
#else #else
if (swscanf(p, L"%i,%i,%i", &ix, &iy, &iz) == 3) if (sscanf(p, "%i,%i,%i", &ix, &iy, &iz) == 3)
#endif #endif
{ {
if ((ix == fx) && (iy == fy) && (iz == fz)) if ((ix == fx) && (iy == fy) && (iz == fz))
@@ -235,7 +235,7 @@ namespace crnlib
} }
} }
const wchar_t* q = p; const char* q = p;
bool success = string_to_uint(q, m_uint); bool success = string_to_uint(q, m_uint);
if ((success) && (*q == 0)) if ((success) && (*q == 0))
{ {
@@ -264,18 +264,18 @@ namespace crnlib
return true; return true;
} }
dynamic_wstring& get_as_string(dynamic_wstring& dst) const dynamic_string& get_as_string(dynamic_string& dst) const
{ {
switch (m_type) switch (m_type)
{ {
case cDTInvalid: dst.clear(); break; case cDTInvalid: dst.clear(); break;
case cDTString: dst = *m_pStr; break; case cDTString: dst = *m_pStr; break;
case cDTBool: dst = m_bool ? L"TRUE" : L"FALSE"; break; case cDTBool: dst = m_bool ? "TRUE" : "FALSE"; break;
case cDTInt: dst.format(L"%i", m_int); break; case cDTInt: dst.format("%i", m_int); break;
case cDTUInt: dst.format(L"%u", m_uint); break; case cDTUInt: dst.format("%u", m_uint); break;
case cDTFloat: dst.format(L"%f", m_float); break; case cDTFloat: dst.format("%f", m_float); break;
case cDTVec3F: dst.format(L"%f,%f,%f", (*m_pVec3F)[0], (*m_pVec3F)[1], (*m_pVec3F)[2]); break; case cDTVec3F: dst.format("%f,%f,%f", (*m_pVec3F)[0], (*m_pVec3F)[1], (*m_pVec3F)[2]); break;
case cDTVec3I: dst.format(L"%i,%i,%i", (*m_pVec3I)[0], (*m_pVec3I)[1], (*m_pVec3I)[2]); break; case cDTVec3I: dst.format("%i,%i,%i", (*m_pVec3I)[0], (*m_pVec3I)[1], (*m_pVec3I)[2]); break;
default: break; default: break;
} }
@@ -293,7 +293,7 @@ namespace crnlib
} }
case cDTString: case cDTString:
{ {
const wchar_t* p = m_pStr->get_ptr(); const char* p = m_pStr->get_ptr();
return string_to_int(p, val); return string_to_int(p, val);
} }
case cDTBool: val = m_bool; break; case cDTBool: val = m_bool; break;
@@ -359,7 +359,7 @@ namespace crnlib
} }
case cDTString: case cDTString:
{ {
const wchar_t* p = m_pStr->get_ptr(); const char* p = m_pStr->get_ptr();
return string_to_uint(p, val); return string_to_uint(p, val);
} }
case cDTBool: case cDTBool:
@@ -438,7 +438,7 @@ namespace crnlib
} }
case cDTString: case cDTString:
{ {
const wchar_t* p = m_pStr->get_ptr(); const char* p = m_pStr->get_ptr();
return string_to_bool(p, val); return string_to_bool(p, val);
} }
case cDTBool: case cDTBool:
@@ -497,7 +497,7 @@ namespace crnlib
} }
case cDTString: case cDTString:
{ {
const wchar_t* p = m_pStr->get_ptr(); const char* p = m_pStr->get_ptr();
return string_to_float(p, val); return string_to_float(p, val);
} }
case cDTBool: case cDTBool:
@@ -556,12 +556,12 @@ namespace crnlib
} }
case cDTString: case cDTString:
{ {
const wchar_t* p = m_pStr->get_ptr(); const char* p = m_pStr->get_ptr();
float x = 0, y = 0, z = 0; float x = 0, y = 0, z = 0;
#ifdef _MSC_VER #ifdef _MSC_VER
if (wscanf_s(p, L"%f,%f,%f", &x, &y, &z) == 3) if (sscanf_s(p, "%f,%f,%f", &x, &y, &z) == 3)
#else #else
if (wscanf(p, L"%f,%f,%f", &x, &y, &z) == 3) if (sscanf(p, "%f,%f,%f", &x, &y, &z) == 3)
#endif #endif
{ {
val.set(x, y, z); val.set(x, y, z);
@@ -619,12 +619,12 @@ namespace crnlib
} }
case cDTString: case cDTString:
{ {
const wchar_t* p = m_pStr->get_ptr(); const char* p = m_pStr->get_ptr();
float x = 0, y = 0, z = 0; float x = 0, y = 0, z = 0;
#ifdef _MSC_VER #ifdef _MSC_VER
if (wscanf_s(p, L"%f,%f,%f", &x, &y, &z) == 3) if (sscanf_s(p, "%f,%f,%f", &x, &y, &z) == 3)
#else #else
if (wscanf(p, L"%f,%f,%f", &x, &y, &z) == 3) if (sscanf(p, "%f,%f,%f", &x, &y, &z) == 3)
#endif #endif
{ {
if ((x < INT_MIN) || (x > INT_MAX) || (y < INT_MIN) || (y > INT_MAX) || (z < INT_MIN) || (z > INT_MAX)) if ((x < INT_MIN) || (x > INT_MAX) || (y < INT_MIN) || (y > INT_MAX) || (z < INT_MIN) || (z > INT_MAX))
@@ -963,7 +963,7 @@ namespace crnlib
switch (m_type) switch (m_type)
{ {
case cDTString: case cDTString:
m_pStr = crnlib_new<dynamic_wstring>(); m_pStr = crnlib_new<dynamic_string>();
break; break;
case cDTVec3F: case cDTVec3F:
m_pVec3F = crnlib_new<vec3F>(); m_pVec3F = crnlib_new<vec3F>();
@@ -976,7 +976,7 @@ namespace crnlib
} }
} }
void set_str(const dynamic_wstring& s) void set_str(const dynamic_string& s)
{ {
if (m_type == cDTString) if (m_type == cDTString)
m_pStr->set(s); m_pStr->set(s);
@@ -985,11 +985,11 @@ namespace crnlib
clear_dynamic(); clear_dynamic();
m_type = cDTString; m_type = cDTString;
m_pStr = crnlib_new<dynamic_wstring>(s); m_pStr = crnlib_new<dynamic_string>(s);
} }
} }
void set_str(const wchar_t* p) void set_str(const char* p)
{ {
if (m_type == cDTString) if (m_type == cDTString)
m_pStr->set(p); m_pStr->set(p);
@@ -998,7 +998,7 @@ namespace crnlib
clear_dynamic(); clear_dynamic();
m_type = cDTString; m_type = cDTString;
m_pStr = crnlib_new<dynamic_wstring>(p); m_pStr = crnlib_new<dynamic_string>(p);
} }
} }
@@ -1013,7 +1013,7 @@ namespace crnlib
vec3F* m_pVec3F; vec3F* m_pVec3F;
vec3I* m_pVec3I; vec3I* m_pVec3I;
dynamic_wstring* m_pStr; dynamic_string* m_pStr;
uint m_union[cUnionSize]; uint m_union[cUnionSize];
}; };
+1 -2
View File
@@ -6,14 +6,13 @@
#include "crn_color.h" #include "crn_color.h"
#include "crn_vec.h" #include "crn_vec.h"
#include <stdio.h>
namespace crnlib namespace crnlib
{ {
bool elemental_vector::increase_capacity(uint min_new_capacity, bool grow_hint, uint element_size, object_mover pMover, bool nofail) bool elemental_vector::increase_capacity(uint min_new_capacity, bool grow_hint, uint element_size, object_mover pMover, bool nofail)
{ {
CRNLIB_ASSERT(m_size <= m_capacity); CRNLIB_ASSERT(m_size <= m_capacity);
#ifdef CRNLIB_PLATFORM_PC_X64 #ifdef CRNLIB_64BIT_POINTERS
CRNLIB_ASSERT(min_new_capacity < (0x400000000ULL / element_size)); CRNLIB_ASSERT(min_new_capacity < (0x400000000ULL / element_size));
#else #else
CRNLIB_ASSERT(min_new_capacity < (0x7FFF0000U / element_size)); CRNLIB_ASSERT(min_new_capacity < (0x7FFF0000U / element_size));
+26 -6
View File
@@ -296,7 +296,10 @@ namespace crnlib
const uint num_to_move = orig_size - index; const uint num_to_move = orig_size - index;
if (CRNLIB_IS_BITWISE_COPYABLE(T)) if (CRNLIB_IS_BITWISE_COPYABLE(T))
{
// This overwrites the destination object bits, but bitwise copyable means we don't need to worry about destruction.
memmove(m_p + index + n, m_p + index, sizeof(T) * num_to_move); memmove(m_p + index + n, m_p + index, sizeof(T) * num_to_move);
}
else else
{ {
const T* pSrc = m_p + orig_size - 1; const T* pSrc = m_p + orig_size - 1;
@@ -312,7 +315,10 @@ namespace crnlib
T* pDst = m_p + index; T* pDst = m_p + index;
if (CRNLIB_IS_BITWISE_COPYABLE(T)) if (CRNLIB_IS_BITWISE_COPYABLE(T))
{
// This copies in the new bits, overwriting the existing objects, which is OK for copyable types that don't need destruction.
memcpy(pDst, p, sizeof(T) * n); memcpy(pDst, p, sizeof(T) * n);
}
else else
{ {
for (uint i = 0; i < n; i++) for (uint i = 0; i < n; i++)
@@ -355,15 +361,29 @@ namespace crnlib
const uint num_to_move = m_size - (start + n); const uint num_to_move = m_size - (start + n);
T* pDst = m_p + start; T* pDst = m_p + start;
const T* pSrc = m_p + start + n; const T* pSrc = m_p + start + n;
if (CRNLIB_IS_BITWISE_COPYABLE(T)) if ((CRNLIB_IS_BITWISE_COPYABLE(T)) && (!CRNLIB_IS_BITWISE_MOVABLE(T)))
{
// Type is bitwise copyable, so there's no need to destruct the overwritten objects.
// Copy "down" the objects to preserve, filling in the empty slots.
memmove(pDst, pSrc, num_to_move * sizeof(T)); memmove(pDst, pSrc, num_to_move * sizeof(T));
}
else if (CRNLIB_IS_BITWISE_MOVABLE(T))
{
// Type is bitwise movable, which means we can move them around but they still may need to be destructed.
// First destroy the erased objects.
scalar_type<T>::destruct_array(pDst, n);
// Copy "down" the objects to preserve, filling in the empty slots.
memmove(pDst, pSrc, num_to_move * sizeof(T));
}
else else
{ {
// Type is not bitwise copyable or movable.
// Move them down one at a time by using the equals operator, and destroying anything that's left over at the end.
T* pDst_end = pDst + num_to_move; T* pDst_end = pDst + num_to_move;
while (pDst != pDst_end) while (pDst != pDst_end)
*pDst++ = *pSrc++; *pDst++ = *pSrc++;
@@ -609,11 +629,11 @@ namespace crnlib
// placement new // placement new
new (static_cast<void*>(pDst)) T(*pSrc); new (static_cast<void*>(pDst)) T(*pSrc);
pSrc->~T(); pSrc->~T();
pSrc++; ++pSrc;
pDst++; ++pDst;
} }
} }
inline bool increase_capacity(uint min_new_capacity, bool grow_hint, bool nofail = false) inline bool increase_capacity(uint min_new_capacity, bool grow_hint, bool nofail = false)
{ {
return reinterpret_cast<elemental_vector*>(this)->increase_capacity( return reinterpret_cast<elemental_vector*>(this)->increase_capacity(
+5 -1
View File
@@ -1,8 +1,12 @@
#pragma once #pragma once
#ifndef WIN32
#error Should not get here
#endif
#ifndef _WIN32_WINNT #ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x500 #define _WIN32_WINNT 0x500
#endif #endif
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
+51 -79
View File
@@ -586,6 +586,10 @@
RelativePath=".\crn_assert.h" RelativePath=".\crn_assert.h"
> >
</File> </File>
<File
RelativePath=".\crn_atomics.h"
>
</File>
<File <File
RelativePath=".\crn_core.cpp" RelativePath=".\crn_core.cpp"
> >
@@ -978,13 +982,6 @@
<File <File
RelativePath=".\crn_lzma_codec.cpp" RelativePath=".\crn_lzma_codec.cpp"
> >
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\crn_lzma_codec.h" RelativePath=".\crn_lzma_codec.h"
@@ -1062,14 +1059,6 @@
RelativePath=".\crn_dynamic_string.h" RelativePath=".\crn_dynamic_string.h"
> >
</File> </File>
<File
RelativePath=".\crn_dynamic_wstring.cpp"
>
</File>
<File
RelativePath=".\crn_dynamic_wstring.h"
>
</File>
<File <File
RelativePath=".\crn_strutils.cpp" RelativePath=".\crn_strutils.cpp"
> >
@@ -1079,50 +1068,6 @@
> >
</File> </File>
</Filter> </Filter>
<Filter
Name="win32"
>
<File
RelativePath=".\crn_win32_console.cpp"
>
</File>
<File
RelativePath=".\crn_win32_console.h"
>
</File>
<File
RelativePath=".\crn_win32_file_utils.cpp"
>
</File>
<File
RelativePath=".\crn_win32_file_utils.h"
>
</File>
<File
RelativePath=".\crn_win32_find_files.cpp"
>
</File>
<File
RelativePath=".\crn_win32_find_files.h"
>
</File>
<File
RelativePath=".\crn_win32_threading.cpp"
>
</File>
<File
RelativePath=".\crn_win32_threading.h"
>
</File>
<File
RelativePath=".\crn_win32_timer.cpp"
>
</File>
<File
RelativePath=".\crn_win32_timer.h"
>
</File>
</Filter>
<Filter <Filter
Name="utils" Name="utils"
> >
@@ -1166,6 +1111,14 @@
RelativePath=".\crn_packed_uint.h" RelativePath=".\crn_packed_uint.h"
> >
</File> </File>
<File
RelativePath=".\crn_timer.cpp"
>
</File>
<File
RelativePath=".\crn_timer.h"
>
</File>
<File <File
RelativePath=".\crn_traits.h" RelativePath=".\crn_traits.h"
> >
@@ -1210,6 +1163,14 @@
<Filter <Filter
Name="console" Name="console"
> >
<File
RelativePath=".\crn_colorized_console.cpp"
>
</File>
<File
RelativePath=".\crn_colorized_console.h"
>
</File>
<File <File
RelativePath=".\crn_console.cpp" RelativePath=".\crn_console.cpp"
> >
@@ -1223,35 +1184,26 @@
Name="threading" Name="threading"
> >
<File <File
RelativePath=".\crn_condition_var.cpp" RelativePath=".\crn_threading.h"
> >
</File> </File>
<File <File
RelativePath=".\crn_condition_var.h" RelativePath=".\crn_threading_null.h"
> >
</File> </File>
<File <File
RelativePath=".\crn_event.h" RelativePath=".\crn_threading_win32.cpp"
> >
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath=".\crn_mutex.h" RelativePath=".\crn_threading_win32.h"
>
</File>
<File
RelativePath=".\crn_semaphore.h"
>
</File>
<File
RelativePath=".\crn_spinlock.h"
>
</File>
<File
RelativePath=".\crn_task_pool.cpp"
>
</File>
<File
RelativePath=".\crn_task_pool.h"
> >
</File> </File>
</Filter> </Filter>
@@ -1475,6 +1427,26 @@
> >
</File> </File>
</Filter> </Filter>
<Filter
Name="file"
>
<File
RelativePath=".\crn_file_utils.cpp"
>
</File>
<File
RelativePath=".\crn_file_utils.h"
>
</File>
<File
RelativePath=".\crn_find_files.cpp"
>
</File>
<File
RelativePath=".\crn_find_files.h"
>
</File>
</Filter>
</Filter> </Filter>
</Files> </Files>
<Globals> <Globals>
+24 -20
View File
@@ -14,6 +14,7 @@
<Option compiler="gcc" /> <Option compiler="gcc" />
<Option createDefFile="1" /> <Option createDefFile="1" />
<Compiler> <Compiler>
<Add option="-Wextra" />
<Add option="-Wall" /> <Add option="-Wall" />
<Add option="-g" /> <Add option="-g" />
</Compiler> </Compiler>
@@ -26,8 +27,11 @@
<Option compiler="gcc" /> <Option compiler="gcc" />
<Option createDefFile="1" /> <Option createDefFile="1" />
<Compiler> <Compiler>
<Add option="-fomit-frame-pointer" />
<Add option="-fexpensive-optimizations" />
<Add option="-O3" />
<Add option="-Wextra" />
<Add option="-Wall" /> <Add option="-Wall" />
<Add option="-O2" />
</Compiler> </Compiler>
<Linker> <Linker>
<Add option="-s" /> <Add option="-s" />
@@ -35,6 +39,8 @@
</Target> </Target>
</Build> </Build>
<Compiler> <Compiler>
<Add option="-Wextra" />
<Add option="-Wall" />
<Add option="-Wno-unused-value" /> <Add option="-Wno-unused-value" />
<Add option="-Wno-unused" /> <Add option="-Wno-unused" />
</Compiler> </Compiler>
@@ -48,11 +54,12 @@
<Unit filename="crn_checksum.h" /> <Unit filename="crn_checksum.h" />
<Unit filename="crn_clusterizer.h" /> <Unit filename="crn_clusterizer.h" />
<Unit filename="crn_color.h" /> <Unit filename="crn_color.h" />
<Unit filename="crn_colorized_console.cpp" />
<Unit filename="crn_colorized_console.h" />
<Unit filename="crn_command_line_params.cpp" /> <Unit filename="crn_command_line_params.cpp" />
<Unit filename="crn_command_line_params.h" /> <Unit filename="crn_command_line_params.h" />
<Unit filename="crn_comp.cpp" /> <Unit filename="crn_comp.cpp" />
<Unit filename="crn_comp.h" /> <Unit filename="crn_comp.h" />
<Unit filename="crn_condition_var.cpp" />
<Unit filename="crn_condition_var.h" /> <Unit filename="crn_condition_var.h" />
<Unit filename="crn_console.cpp" /> <Unit filename="crn_console.cpp" />
<Unit filename="crn_console.h" /> <Unit filename="crn_console.h" />
@@ -85,9 +92,10 @@
<Unit filename="crn_dynamic_stream.h" /> <Unit filename="crn_dynamic_stream.h" />
<Unit filename="crn_dynamic_string.cpp" /> <Unit filename="crn_dynamic_string.cpp" />
<Unit filename="crn_dynamic_string.h" /> <Unit filename="crn_dynamic_string.h" />
<Unit filename="crn_dynamic_wstring.cpp" /> <Unit filename="crn_file_utils.cpp" />
<Unit filename="crn_dynamic_wstring.h" /> <Unit filename="crn_file_utils.h" />
<Unit filename="crn_event.h" /> <Unit filename="crn_find_files.cpp" />
<Unit filename="crn_find_files.h" />
<Unit filename="crn_fixed_array.h" /> <Unit filename="crn_fixed_array.h" />
<Unit filename="crn_hash.cpp" /> <Unit filename="crn_hash.cpp" />
<Unit filename="crn_hash.h" /> <Unit filename="crn_hash.h" />
@@ -130,18 +138,14 @@
<Unit filename="crn_ryg_dxt.cpp" /> <Unit filename="crn_ryg_dxt.cpp" />
<Unit filename="crn_ryg_dxt.hpp" /> <Unit filename="crn_ryg_dxt.hpp" />
<Unit filename="crn_ryg_types.hpp" /> <Unit filename="crn_ryg_types.hpp" />
<Unit filename="crn_semaphore.h" />
<Unit filename="crn_sparse_array.h" /> <Unit filename="crn_sparse_array.h" />
<Unit filename="crn_sparse_bit_array.cpp" /> <Unit filename="crn_sparse_bit_array.cpp" />
<Unit filename="crn_sparse_bit_array.h" /> <Unit filename="crn_sparse_bit_array.h" />
<Unit filename="crn_spinlock.h" />
<Unit filename="crn_stb_image.cpp" /> <Unit filename="crn_stb_image.cpp" />
<Unit filename="crn_strutils.cpp" /> <Unit filename="crn_strutils.cpp" />
<Unit filename="crn_strutils.h" /> <Unit filename="crn_strutils.h" />
<Unit filename="crn_symbol_codec.cpp" /> <Unit filename="crn_symbol_codec.cpp" />
<Unit filename="crn_symbol_codec.h" /> <Unit filename="crn_symbol_codec.h" />
<Unit filename="crn_task_pool.cpp" />
<Unit filename="crn_task_pool.h" />
<Unit filename="crn_texture_comp.cpp" /> <Unit filename="crn_texture_comp.cpp" />
<Unit filename="crn_texture_comp.h" /> <Unit filename="crn_texture_comp.h" />
<Unit filename="crn_texture_conversion.cpp" /> <Unit filename="crn_texture_conversion.cpp" />
@@ -151,6 +155,13 @@
<Unit filename="crn_threaded_clusterizer.h" /> <Unit filename="crn_threaded_clusterizer.h" />
<Unit filename="crn_threaded_resampler.cpp" /> <Unit filename="crn_threaded_resampler.cpp" />
<Unit filename="crn_threaded_resampler.h" /> <Unit filename="crn_threaded_resampler.h" />
<Unit filename="crn_threading.h" />
<Unit filename="crn_threading_null.h" />
<Unit filename="crn_threading_pthreads.h" />
<Unit filename="crn_threading_win32.cpp" />
<Unit filename="crn_threading_win32.h" />
<Unit filename="crn_timer.cpp" />
<Unit filename="crn_timer.h" />
<Unit filename="crn_traits.h" /> <Unit filename="crn_traits.h" />
<Unit filename="crn_tree_clusterizer.h" /> <Unit filename="crn_tree_clusterizer.h" />
<Unit filename="crn_types.h" /> <Unit filename="crn_types.h" />
@@ -162,16 +173,6 @@
<Unit filename="crn_vec_interval.h" /> <Unit filename="crn_vec_interval.h" />
<Unit filename="crn_vector.cpp" /> <Unit filename="crn_vector.cpp" />
<Unit filename="crn_vector.h" /> <Unit filename="crn_vector.h" />
<Unit filename="crn_win32_console.cpp" />
<Unit filename="crn_win32_console.h" />
<Unit filename="crn_win32_file_utils.cpp" />
<Unit filename="crn_win32_file_utils.h" />
<Unit filename="crn_win32_find_files.cpp" />
<Unit filename="crn_win32_find_files.h" />
<Unit filename="crn_win32_threading.cpp" />
<Unit filename="crn_win32_threading.h" />
<Unit filename="crn_win32_timer.cpp" />
<Unit filename="crn_win32_timer.h" />
<Unit filename="crn_winhdr.h" /> <Unit filename="crn_winhdr.h" />
<Unit filename="crn_zeng.cpp" /> <Unit filename="crn_zeng.cpp" />
<Unit filename="crn_zeng.h" /> <Unit filename="crn_zeng.h" />
@@ -180,7 +181,6 @@
<Unit filename="lzma_7zBuf.cpp" /> <Unit filename="lzma_7zBuf.cpp" />
<Unit filename="lzma_7zBuf.h" /> <Unit filename="lzma_7zBuf.h" />
<Unit filename="lzma_7zBuf2.cpp" /> <Unit filename="lzma_7zBuf2.cpp" />
<Unit filename="lzma_7zCrc.cpp" />
<Unit filename="lzma_7zCrc.h" /> <Unit filename="lzma_7zCrc.h" />
<Unit filename="lzma_7zFile.cpp" /> <Unit filename="lzma_7zFile.cpp" />
<Unit filename="lzma_7zFile.h" /> <Unit filename="lzma_7zFile.h" />
@@ -210,9 +210,13 @@
<Unit filename="lzma_Threads.cpp" /> <Unit filename="lzma_Threads.cpp" />
<Unit filename="lzma_Threads.h" /> <Unit filename="lzma_Threads.h" />
<Unit filename="lzma_Types.h" /> <Unit filename="lzma_Types.h" />
<Unit filename="..\inc\crn_decomp.h" />
<Unit filename="..\inc\crnlib.h" />
<Unit filename="..\inc\dds_defs.h" />
<Extensions> <Extensions>
<code_completion /> <code_completion />
<debugger /> <debugger />
<envvars />
</Extensions> </Extensions>
</Project> </Project>
</CodeBlocks_project_file> </CodeBlocks_project_file>
+32 -70
View File
@@ -1,4 +1,4 @@
// File: crnlib.cpp // File: crnlib.cpp
// See Copyright Notice and license at the end of inc/crnlib.h // See Copyright Notice and license at the end of inc/crnlib.h
#include "crn_core.h" #include "crn_core.h"
#include "../inc/crnlib.h" #include "../inc/crnlib.h"
@@ -8,8 +8,6 @@
#include "crn_buffer_stream.h" #include "crn_buffer_stream.h"
#include "crn_ryg_dxt.hpp" #include "crn_ryg_dxt.hpp"
#include "crn_winhdr.h"
#define CRND_HEADER_FILE_ONLY #define CRND_HEADER_FILE_ONLY
#include "../inc/crn_decomp.h" #include "../inc/crn_decomp.h"
@@ -32,15 +30,10 @@ namespace crnlib
public: public:
crnlib_global_initializer() crnlib_global_initializer()
{ {
crn_threading_init();
ryg_dxt::sInitDXT(); ryg_dxt::sInitDXT();
#ifdef CRNLIB_PLATFORM_PC
SYSTEM_INFO g_system_info;
GetSystemInfo(&g_system_info);
g_number_of_processors = math::maximum<uint>(1U, g_system_info.dwNumberOfProcessors);
#endif
crnlib_enable_fail_exceptions(true); crnlib_enable_fail_exceptions(true);
// Redirect crn_decomp.h's memory allocations into crnlib, which may be further redirected by the outside caller. // Redirect crn_decomp.h's memory allocations into crnlib, which may be further redirected by the outside caller.
@@ -49,16 +42,11 @@ namespace crnlib
}; };
crnlib_global_initializer g_crnlib_initializer; crnlib_global_initializer g_crnlib_initializer;
} } // namespace crnlib
using namespace crnlib; using namespace crnlib;
const char* crn_get_format_stringa(crn_format fmt) const char* crn_get_format_string(crn_format fmt)
{
return pixel_format_helpers::get_crn_format_stringa(fmt);
}
const wchar_t* crn_get_format_string(crn_format fmt)
{ {
return pixel_format_helpers::get_crn_format_string(fmt); return pixel_format_helpers::get_crn_format_string(fmt);
} }
@@ -83,18 +71,7 @@ crn_format crn_get_fundamental_dxt_format(crn_format fmt)
return crnd::crnd_get_fundamental_dxt_format(fmt); return crnd::crnd_get_fundamental_dxt_format(fmt);
} }
const wchar_t* crn_get_file_type_ext(crn_file_type file_type) const char* crn_get_file_type_ext(crn_file_type file_type)
{
switch (file_type)
{
case cCRNFileTypeDDS: return L"dds";
case cCRNFileTypeCRN: return L"crn";
default: break;
}
return L"?";
}
const char* crn_get_file_type_exta(crn_file_type file_type)
{ {
switch (file_type) switch (file_type)
{ {
@@ -105,30 +82,30 @@ const char* crn_get_file_type_exta(crn_file_type file_type)
return "?"; return "?";
} }
const wchar_t* crn_get_mip_mode_desc(crn_mip_mode m) const char* crn_get_mip_mode_desc(crn_mip_mode m)
{ {
switch (m) switch (m)
{ {
case cCRNMipModeUseSourceOrGenerateMips: return L"Use source/generate if none"; case cCRNMipModeUseSourceOrGenerateMips: return "Use source/generate if none";
case cCRNMipModeUseSourceMips: return L"Only use source MIP maps (if any)"; case cCRNMipModeUseSourceMips: return "Only use source MIP maps (if any)";
case cCRNMipModeGenerateMips: return L"Always generate new MIP maps"; case cCRNMipModeGenerateMips: return "Always generate new MIP maps";
case cCRNMipModeNoMips: return L"No MIP maps"; case cCRNMipModeNoMips: return "No MIP maps";
default: break; default: break;
} }
return L"?"; return "?";
} }
const wchar_t* crn_get_mip_mode_name(crn_mip_mode m) const char* crn_get_mip_mode_name(crn_mip_mode m)
{ {
switch (m) switch (m)
{ {
case cCRNMipModeUseSourceOrGenerateMips: return L"UseSourceOrGenerate"; case cCRNMipModeUseSourceOrGenerateMips: return "UseSourceOrGenerate";
case cCRNMipModeUseSourceMips: return L"UseSource"; case cCRNMipModeUseSourceMips: return "UseSource";
case cCRNMipModeGenerateMips: return L"Generate"; case cCRNMipModeGenerateMips: return "Generate";
case cCRNMipModeNoMips: return L"None"; case cCRNMipModeNoMips: return "None";
default: break; default: break;
} }
return L"?"; return "?";
} }
const char* crn_get_mip_filter_name(crn_mip_filter f) const char* crn_get_mip_filter_name(crn_mip_filter f)
@@ -145,37 +122,22 @@ const char* crn_get_mip_filter_name(crn_mip_filter f)
return "?"; return "?";
} }
const wchar_t* crn_get_scale_mode_desc(crn_scale_mode sm) const char* crn_get_scale_mode_desc(crn_scale_mode sm)
{ {
switch (sm) switch (sm)
{ {
case cCRNSMDisabled: return L"disabled"; case cCRNSMDisabled: return "disabled";
case cCRNSMAbsolute: return L"absolute"; case cCRNSMAbsolute: return "absolute";
case cCRNSMRelative: return L"relative"; case cCRNSMRelative: return "relative";
case cCRNSMLowerPow2: return L"lowerpow2"; case cCRNSMLowerPow2: return "lowerpow2";
case cCRNSMNearestPow2: return L"nearestpow2"; case cCRNSMNearestPow2: return "nearestpow2";
case cCRNSMNextPow2: return L"nextpow2"; case cCRNSMNextPow2: return "nextpow2";
default: break; default: break;
} }
return L"?"; return "?";
} }
const wchar_t* crn_get_dxt_quality_string(crn_dxt_quality q) const char* crn_get_dxt_quality_string(crn_dxt_quality q)
{
switch (q)
{
case cCRNDXTQualitySuperFast: return L"SuperFast";
case cCRNDXTQualityFast: return L"Fast";
case cCRNDXTQualityNormal: return L"Normal";
case cCRNDXTQualityBetter: return L"Better";
case cCRNDXTQualityUber: return L"Uber";
default: break;
}
CRNLIB_ASSERT(false);
return L"?";
}
const char* crn_get_dxt_quality_stringa(crn_dxt_quality q)
{ {
switch (q) switch (q)
{ {
@@ -233,7 +195,7 @@ 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) void *crn_decompress_crn_to_dds(const void *pCRN_file_data, crn_uint32 &file_size)
{ {
dds_texture tex; dds_texture tex;
if (!tex.load_crn_from_memory(L"from_memory.crn", pCRN_file_data, file_size)) if (!tex.load_crn_from_memory("from_memory.crn", pCRN_file_data, file_size))
{ {
file_size = 0; file_size = 0;
return NULL; return NULL;
@@ -277,9 +239,9 @@ bool crn_decompress_dds_to_images(const void *pDDS_file_data, crn_uint32 dds_fil
tex_desc.m_levels = tex.get_num_levels(); tex_desc.m_levels = tex.get_num_levels();
tex_desc.m_fmt_fourcc = (crn_uint32)tex.get_format(); tex_desc.m_fmt_fourcc = (crn_uint32)tex.get_format();
for (uint f = 0; f < tex.get_num_faces(); f++) for (uint32 f = 0; f < tex.get_num_faces(); f++)
{ {
for (uint l = 0; l < tex.get_num_levels(); l++) for (uint32 l = 0; l < tex.get_num_levels(); l++)
{ {
mip_level *pLevel = tex.get_level(f, l); mip_level *pLevel = tex.get_level(f, l);
image_u8 *pImg = pLevel->get_image(); image_u8 *pImg = pLevel->get_image();
@@ -292,8 +254,8 @@ bool crn_decompress_dds_to_images(const void *pDDS_file_data, crn_uint32 dds_fil
void crn_free_all_images(crn_uint32 **ppImages, const crn_texture_desc &desc) void crn_free_all_images(crn_uint32 **ppImages, const crn_texture_desc &desc)
{ {
for (uint f = 0; f < desc.m_faces; f++) for (uint32 f = 0; f < desc.m_faces; f++)
for (uint l = 0; l < desc.m_levels; l++) for (uint32 l = 0; l < desc.m_levels; l++)
crn_free_block(ppImages[l + desc.m_levels * f]); crn_free_block(ppImages[l + desc.m_levels * f]);
} }
+2 -2
View File
@@ -106,8 +106,8 @@ SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
size -= 4; size -= 4;
for (i = 0; i <= size; i += 4) for (i = 0; i <= size; i += 4)
{ {
if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 || if ( ((data[i] == 0x40) && ((data[i + 1] & 0xC0) == 0x00)) ||
data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0) ((data[i] == 0x7F) && ((data[i + 1] & 0xC0) == 0xC0)) )
{ {
UInt32 src = UInt32 src =
((UInt32)data[i + 0] << 24) | ((UInt32)data[i + 0] << 24) |
+25 -22
View File
@@ -105,7 +105,7 @@ void LzmaEnc_FastPosInit(Byte *g_FastPos)
int c = 2, slotFast; int c = 2, slotFast;
g_FastPos[0] = 0; g_FastPos[0] = 0;
g_FastPos[1] = 1; g_FastPos[1] = 1;
for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
{ {
UInt32 k = (1 << ((slotFast >> 1) - 1)); UInt32 k = (1 << ((slotFast >> 1) - 1));
@@ -262,7 +262,7 @@ typedef struct
CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
CLzmaProb posAlignEncoder[1 << kNumAlignBits]; CLzmaProb posAlignEncoder[1 << kNumAlignBits];
CLenPriceEnc lenEnc; CLenPriceEnc lenEnc;
CLenPriceEnc repLenEnc; CLenPriceEnc repLenEnc;
@@ -285,7 +285,7 @@ typedef struct _CLzmaEnc
#ifdef COMPRESS_MF_MT #ifdef COMPRESS_MF_MT
Byte pad[128]; Byte pad[128];
#endif #endif
UInt32 optimumEndIndex; UInt32 optimumEndIndex;
UInt32 optimumCurrentIndex; UInt32 optimumCurrentIndex;
@@ -293,7 +293,7 @@ typedef struct _CLzmaEnc
UInt32 numPairs; UInt32 numPairs;
UInt32 numAvail; UInt32 numAvail;
COptimal opt[kNumOpts]; COptimal opt[kNumOpts];
#ifndef LZMA_LOG_BSR #ifndef LZMA_LOG_BSR
Byte g_FastPos[1 << kNumLogBits]; Byte g_FastPos[1 << kNumLogBits];
#endif #endif
@@ -327,14 +327,14 @@ typedef struct _CLzmaEnc
CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
CLzmaProb posAlignEncoder[1 << kNumAlignBits]; CLzmaProb posAlignEncoder[1 << kNumAlignBits];
CLenPriceEnc lenEnc; CLenPriceEnc lenEnc;
CLenPriceEnc repLenEnc; CLenPriceEnc repLenEnc;
unsigned lclp; unsigned lclp;
Bool fastMode; Bool fastMode;
CRangeEnc rc; CRangeEnc rc;
Bool writeEndMark; Bool writeEndMark;
@@ -411,8 +411,11 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
CLzmaEncProps props = *props2; CLzmaEncProps props = *props2;
LzmaEncProps_Normalize(&props); LzmaEncProps_Normalize(&props);
if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || if (props.lc > LZMA_LC_MAX ||
props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30)) props.lp > LZMA_LP_MAX ||
props.pb > LZMA_PB_MAX ||
props.dictSize > (1U << kDicLogSizeMaxCompress) ||
props.dictSize > (1 << 30))
return SZ_ERROR_PARAM; return SZ_ERROR_PARAM;
p->dictSize = props.dictSize; p->dictSize = props.dictSize;
p->matchFinderCycles = props.mc; p->matchFinderCycles = props.mc;
@@ -926,10 +929,10 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
{ {
UInt32 posPrev = posMem; UInt32 posPrev = posMem;
UInt32 backCur = backMem; UInt32 backCur = backMem;
backMem = p->opt[posPrev].backPrev; backMem = p->opt[posPrev].backPrev;
posMem = p->opt[posPrev].posPrev; posMem = p->opt[posPrev].posPrev;
p->opt[posPrev].backPrev = backCur; p->opt[posPrev].backPrev = backCur;
p->opt[posPrev].posPrev = cur; p->opt[posPrev].posPrev = cur;
cur = posPrev; cur = posPrev;
@@ -960,7 +963,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
return lenRes; return lenRes;
} }
p->optimumCurrentIndex = p->optimumEndIndex = 0; p->optimumCurrentIndex = p->optimumEndIndex = 0;
if (p->additionalOffset == 0) if (p->additionalOffset == 0)
mainLen = ReadMatchDistances(p, &numPairs); mainLen = ReadMatchDistances(p, &numPairs);
else else
@@ -1258,7 +1261,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
{ {
UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
@@ -1320,7 +1323,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
} }
} }
} }
startLen = 2; /* speed optimization */ startLen = 2; /* speed optimization */
{ {
UInt32 repIndex; UInt32 repIndex;
@@ -1351,10 +1354,10 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
} }
while (--lenTest >= 2); while (--lenTest >= 2);
lenTest = lenTestTemp; lenTest = lenTestTemp;
if (repIndex == 0) if (repIndex == 0)
startLen = lenTest + 1; startLen = lenTest + 1;
/* if (_maxMode) */ /* if (_maxMode) */
{ {
UInt32 lenTest2 = lenTest + 1; UInt32 lenTest2 = lenTest + 1;
@@ -1378,7 +1381,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
nextRepMatchPrice = curAndLenCharPrice + nextRepMatchPrice = curAndLenCharPrice +
GET_PRICE_1(p->isMatch[state2][posStateNext]) + GET_PRICE_1(p->isMatch[state2][posStateNext]) +
GET_PRICE_1(p->isRep[state2]); GET_PRICE_1(p->isRep[state2]);
/* for (; lenTest2 >= 2; lenTest2--) */ /* for (; lenTest2 >= 2; lenTest2--) */
{ {
UInt32 curAndLenPrice; UInt32 curAndLenPrice;
@@ -1433,7 +1436,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
else else
curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
opt = &p->opt[cur + lenTest]; opt = &p->opt[cur + lenTest];
if (curAndLenPrice < opt->price) if (curAndLenPrice < opt->price)
{ {
@@ -1467,7 +1470,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
nextRepMatchPrice = curAndLenCharPrice + nextRepMatchPrice = curAndLenCharPrice +
GET_PRICE_1(p->isMatch[state2][posStateNext]) + GET_PRICE_1(p->isMatch[state2][posStateNext]) +
GET_PRICE_1(p->isRep[state2]); GET_PRICE_1(p->isRep[state2]);
/* for (; lenTest2 >= 2; lenTest2--) */ /* for (; lenTest2 >= 2; lenTest2--) */
{ {
UInt32 offset = cur + lenTest + 1 + lenTest2; UInt32 offset = cur + lenTest + 1 + lenTest2;
@@ -1579,7 +1582,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
MovePos(p, repLen - 1); MovePos(p, repLen - 1);
return repLen; return repLen;
} }
if (mainLen < 2 || numAvail <= 2) if (mainLen < 2 || numAvail <= 2)
return 1; return 1;
@@ -1593,7 +1596,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
(p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))
return 1; return 1;
} }
data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
for (i = 0; i < LZMA_NUM_REPS; i++) for (i = 0; i < LZMA_NUM_REPS; i++)
{ {
@@ -1855,7 +1858,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
pos -= LZMA_NUM_REPS; pos -= LZMA_NUM_REPS;
GetPosSlot(pos, posSlot); GetPosSlot(pos, posSlot);
RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex) if (posSlot >= kStartPosModelIndex)
{ {
UInt32 footerBits = ((posSlot >> 1) - 1); UInt32 footerBits = ((posSlot >> 1) - 1);
@@ -2157,7 +2160,7 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
p->rc.outStream = &outStream.funcTable; p->rc.outStream = &outStream.funcTable;
res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
*unpackSize = (UInt32)(p->nowPos64 - nowPos64); *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
*destLen -= outStream.rem; *destLen -= outStream.rem;
if (outStream.overflow) if (outStream.overflow)
+2 -7
View File
@@ -4,16 +4,11 @@
#ifndef __7Z_TYPES_H #ifndef __7Z_TYPES_H
#define __7Z_TYPES_H #define __7Z_TYPES_H
#define COMPRESS_MF_MT
#include <stddef.h> #include <stddef.h>
#ifdef _XBOX #if defined( _WIN32 )
#include <xtl.h>
#elif defined( _WIN32 )
#include <windows.h> #include <windows.h>
#else #define COMPRESS_MF_MT
#error Unknown platform
#endif #endif
namespace crnlib { namespace crnlib {
+4 -1
View File
@@ -24,7 +24,9 @@
<Option type="1" /> <Option type="1" />
<Option compiler="gcc" /> <Option compiler="gcc" />
<Compiler> <Compiler>
<Add option="-O2" /> <Add option="-fomit-frame-pointer" />
<Add option="-fexpensive-optimizations" />
<Add option="-O3" />
</Compiler> </Compiler>
<Linker> <Linker>
<Add option="-s" /> <Add option="-s" />
@@ -33,6 +35,7 @@
</Target> </Target>
</Build> </Build>
<Compiler> <Compiler>
<Add option="-Wextra" />
<Add option="-Wall" /> <Add option="-Wall" />
<Add option="-fexceptions" /> <Add option="-fexceptions" />
<Add option="-Wno-unused-value" /> <Add option="-Wno-unused-value" />
+452 -460
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -275,7 +275,7 @@ int main(int argc, char *argv[])
uint f; uint f;
for (f = 0; f < cCRNFmtTotal; f++) for (f = 0; f < cCRNFmtTotal; f++)
{ {
if (!_stricmp(argv[i], crn_get_format_stringa(static_cast<crn_format>(f)))) if (!_stricmp(argv[i], crn_get_format_string(static_cast<crn_format>(f))))
{ {
fmt = static_cast<crn_format>(f); fmt = static_cast<crn_format>(f);
break; break;
@@ -456,7 +456,7 @@ int main(int argc, char *argv[])
float actual_bitrate; float actual_bitrate;
crn_uint32 output_file_size; crn_uint32 output_file_size;
printf("Compressing to %s\n", crn_get_format_stringa(comp_params.m_format)); printf("Compressing to %s\n", crn_get_format_string(comp_params.m_format));
// Now compress to DDS or CRN. // Now compress to DDS or CRN.
void *pOutput_file_data = crn_compress(comp_params, mip_params, output_file_size, &actual_quality_level, &actual_bitrate); void *pOutput_file_data = crn_compress(comp_params, mip_params, output_file_size, &actual_quality_level, &actual_bitrate);
+3 -3
View File
@@ -99,7 +99,7 @@ int main(int argc, char *argv[])
for (f = 0; f < cCRNFmtTotal; f++) for (f = 0; f < cCRNFmtTotal; f++)
{ {
crn_format actual_fmt = crn_get_fundamental_dxt_format(static_cast<crn_format>(f)); crn_format actual_fmt = crn_get_fundamental_dxt_format(static_cast<crn_format>(f));
if (!_stricmp(argv[i], crn_get_format_stringa(actual_fmt))) if (!_stricmp(argv[i], crn_get_format_string(actual_fmt)))
{ {
fmt = actual_fmt; fmt = actual_fmt;
break; break;
@@ -116,7 +116,7 @@ int main(int argc, char *argv[])
uint q; uint q;
for (q = 0; q < cCRNDXTQualityTotal; q++) for (q = 0; q < cCRNDXTQualityTotal; q++)
{ {
if (!_stricmp(argv[i], crn_get_dxt_quality_stringa(static_cast<crn_dxt_quality>(q)))) if (!_stricmp(argv[i], crn_get_dxt_quality_string(static_cast<crn_dxt_quality>(q))))
{ {
dxt_quality = static_cast<crn_dxt_quality>(q); dxt_quality = static_cast<crn_dxt_quality>(q);
break; break;
@@ -192,7 +192,7 @@ int main(int argc, char *argv[])
crn_block_compressor_context_t pContext = crn_create_block_compressor(comp_params); crn_block_compressor_context_t pContext = crn_create_block_compressor(comp_params);
printf("Compressing to %s: ", crn_get_format_stringa(fmt)); printf("Compressing to %s: ", crn_get_format_string(fmt));
int prev_percentage_complete = -1; int prev_percentage_complete = -1;
for (crn_uint32 block_y = 0; block_y < num_blocks_y; block_y++) for (crn_uint32 block_y = 0; block_y < num_blocks_y; block_y++)
+103 -121
View File
@@ -1,5 +1,6 @@
// File: crn_decomp.h - CRN texture decompressor v1.01 // File: crn_decomp.h - Fast CRN->DXTc texture transcoder header file library
// Copyright (c) 2010-2012 Rich Geldreich and Tenacious Software LLC // Copyright (c) 2010-2012 Rich Geldreich and Tenacious Software LLC
// See Copyright Notice and license at the end of this file.
// //
// This single header file contains *all* of the code necessary to unpack .CRN files to raw DXTn bits. // This single header file contains *all* of the code necessary to unpack .CRN files to raw DXTn bits.
// It does NOT depend on the crn compression library. // It does NOT depend on the crn compression library.
@@ -8,17 +9,14 @@
// If CRND_INCLUDE_CRND_H is NOT defined, the header is included. // If CRND_INCLUDE_CRND_H is NOT defined, the header is included.
// If CRND_HEADER_FILE_ONLY is NOT defined, the implementation is included. // If CRND_HEADER_FILE_ONLY is NOT defined, the implementation is included.
// Define PLATFORM_NACL if compiling under native client.
//#define PLATFORM_NACL
#ifndef CRND_INCLUDE_CRND_H #ifndef CRND_INCLUDE_CRND_H
#define CRND_INCLUDE_CRND_H #define CRND_INCLUDE_CRND_H
// Include crnlib header - only to bring in some basic some CRN-related types. // Include crnlib.h (only to bring in some basic CRN-related types).
#include "crnlib.h" #include "crnlib.h"
#define CRND_LIB_VERSION 101 #define CRND_LIB_VERSION 103
#define CRND_VERSION_STRING "01.01" #define CRND_VERSION_STRING "01.03"
#ifdef _DEBUG #ifdef _DEBUG
#define CRND_BUILD_DEBUG #define CRND_BUILD_DEBUG
@@ -37,10 +35,13 @@ namespace crnd
typedef uint32 uint32; typedef uint32 uint32;
typedef unsigned int uint; typedef unsigned int uint;
typedef signed int int32; typedef signed int int32;
#ifndef PLATFORM_NACL #ifdef __GNUC__
typedef unsigned __int64 uint64; typedef unsigned long long uint64;
typedef signed __int64 int64; typedef long long int64;
#endif #else
typedef unsigned __int64 uint64;
typedef signed __int64 int64;
#endif
// The crnd library assumes all allocation blocks have at least CRND_MIN_ALLOC_ALIGNMENT alignment. // The crnd library assumes all allocation blocks have at least CRND_MIN_ALLOC_ALIGNMENT alignment.
const uint32 CRND_MIN_ALLOC_ALIGNMENT = sizeof(uint32) * 2U; const uint32 CRND_MIN_ALLOC_ALIGNMENT = sizeof(uint32) * 2U;
@@ -129,29 +130,32 @@ namespace crnd
// The crn_file_info.m_struct_size field must be set before calling this function. // The crn_file_info.m_struct_size field must be set before calling this function.
bool crnd_validate_file(const void* pData, uint32 data_size, crn_file_info* pFile_info); bool crnd_validate_file(const void* pData, uint32 data_size, crn_file_info* pFile_info);
// Retrieves texture information from the CRN file.
// The crn_texture_info.m_struct_size field must be set before calling this function. // The crn_texture_info.m_struct_size field must be set before calling this function.
bool crnd_get_texture_info(const void* pData, uint32 data_size, crn_texture_info* pTexture_info); bool crnd_get_texture_info(const void* pData, uint32 data_size, crn_texture_info* pTexture_info);
// Retrieves mipmap level specific information from the CRN file.
// The crn_level_info.m_struct_size field must be set before calling this function. // The crn_level_info.m_struct_size field must be set before calling this function.
bool crnd_get_level_info(const void* pData, uint32 data_size, uint32 level_index, crn_level_info* pLevel_info); bool crnd_get_level_info(const void* pData, uint32 data_size, uint32 level_index, crn_level_info* pLevel_info);
// Transcode/unpack context handle.
typedef void* crnd_unpack_context; typedef void* crnd_unpack_context;
// crnd_unpack_begin() - Decompresses the texture's decoder tables and endpoint/selector palettes. // crnd_unpack_begin() - Decompresses the texture's decoder tables and endpoint/selector palettes.
// Once you call this function, you may call crnd_unpack_level() to unpack one or more mip levels. // Once you call this function, you may call crnd_unpack_level() to unpack one or more mip levels.
// Don't call this once per mip level (unless you absolutely must)! // Don't call this once per mip level (unless you absolutely must)!
// This function allocated enough memory to hold: Huffman decompression tables, and the endpoint/selector palettes (color and/or alpha). // This function allocates enough memory to hold: Huffman decompression tables, and the endpoint/selector palettes (color and/or alpha).
// Worst case allocation is approx. 200k, assuming all palettes contain 8192 entries. // Worst case allocation is approx. 200k, assuming all palettes contain 8192 entries.
// pData must point to a buffer holding all of the compressed data. // pData must point to a buffer holding all of the compressed .CRN file data.
// This buffer must be stable until crnd_unpack_end() is called. // This buffer must be stable until crnd_unpack_end() is called.
// Returns NULL on out of memory or if any of the input parameters are invalid. // Returns NULL if out of memory, or if any of the input parameters are invalid.
crnd_unpack_context crnd_unpack_begin(const void* pData, uint32 data_size); crnd_unpack_context crnd_unpack_begin(const void* pData, uint32 data_size);
// Returns the compressed data associated with a context. // Returns a pointer to the compressed .CRN data associated with a crnd_unpack_context.
// Returns false if any of the input parameters are invalid. // Returns false if any of the input parameters are invalid.
bool crnd_get_data(crnd_unpack_context pContext, const void** ppData, uint32* pData_size); bool crnd_get_data(crnd_unpack_context pContext, const void** ppData, uint32* pData_size);
// crnd_unpack_level() - Unpacks the specified mipmap level to a destination buffer in cached or write combined memory. // crnd_unpack_level() - Transcodes the specified mipmap level to a destination buffer in cached or write combined memory.
// pContext - Context created by a call to crnd_unpack_begin(). // pContext - Context created by a call to crnd_unpack_begin().
// ppDst - A pointer to an array of 1 or 6 destination buffer pointers. Cubemaps require an array of 6 pointers, 2D textures require an array of 1 pointer. // ppDst - A pointer to an array of 1 or 6 destination buffer pointers. Cubemaps require an array of 6 pointers, 2D textures require an array of 1 pointer.
// dst_size_in_bytes - Optional size of each destination buffer. Only used for debugging - OK to set to UINT32_MAX. // dst_size_in_bytes - Optional size of each destination buffer. Only used for debugging - OK to set to UINT32_MAX.
@@ -166,14 +170,14 @@ namespace crnd
// crnd_unpack_level_segmented() - Unpacks the specified mipmap level from a "segmented" CRN file. // crnd_unpack_level_segmented() - Unpacks the specified mipmap level from a "segmented" CRN file.
// See the crnd_create_segmented_file() API below. // See the crnd_create_segmented_file() API below.
// Segmented files allow the user to control where the compressed mipmaps are stored. // Segmented files allow the user to control where the compressed mipmap data is stored.
bool crnd_unpack_level_segmented( bool crnd_unpack_level_segmented(
crnd_unpack_context pContext, crnd_unpack_context pContext,
const void* pSrc, uint32 src_size_in_bytes, const void* pSrc, uint32 src_size_in_bytes,
void** ppDst, uint32 dst_size_in_bytes, uint32 row_pitch_in_bytes, void** ppDst, uint32 dst_size_in_bytes, uint32 row_pitch_in_bytes,
uint32 level_index); uint32 level_index);
// crnd_unpack_end() - Frees the decompress tables and unpacked palettes associated with the specified context. // crnd_unpack_end() - Frees the decompress tables and unpacked palettes associated with the specified unpack context.
// Returns false if the context is NULL, or if it points to an invalid context. // Returns false if the context is NULL, or if it points to an invalid context.
// This function frees all memory associated with the context. // This function frees all memory associated with the context.
bool crnd_unpack_end(crnd_unpack_context pContext); bool crnd_unpack_end(crnd_unpack_context pContext);
@@ -189,7 +193,7 @@ namespace crnd
// Returns the compressed size of the texture's header and compression tables (but no levels). // Returns the compressed size of the texture's header and compression tables (but no levels).
uint32 crnd_get_segmented_file_size(const void* pData, uint32 data_size); uint32 crnd_get_segmented_file_size(const void* pData, uint32 data_size);
// Creates a "segmented" CRN texture. The new texture will be created at pBase_data, and will be crnd_get_base_data_size() bytes long. // Creates a "segmented" CRN texture from a normal CRN texture. The new texture will be created at pBase_data, and will be crnd_get_base_data_size() bytes long.
// base_data_size must be >= crnd_get_base_data_size(). // base_data_size must be >= crnd_get_base_data_size().
// The base data will contain the CRN header and compression tables, but no mipmap data. // The base data will contain the CRN header and compression tables, but no mipmap data.
bool crnd_create_segmented_file(const void* pData, uint32 data_size, void* pBase_data, uint base_data_size); bool crnd_create_segmented_file(const void* pData, uint32 data_size, void* pBase_data, uint base_data_size);
@@ -310,12 +314,11 @@ namespace crnd
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#ifndef PLATFORM_NACL #ifdef WIN32
#include <memory.h> #include <memory.h>
#else #else
#include <malloc.h> #include <malloc.h>
#include <process.h> #endif
#endif
#include <stdarg.h> #include <stdarg.h>
#include <new> // needed for placement new, _msize, _expand #include <new> // needed for placement new, _msize, _expand
@@ -343,7 +346,7 @@ namespace crnd
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#endif #endif
#ifndef #ifndef
#define NOMINMAX #define NOMINMAX
#endif #endif
#include "windows.h" // only for IsDebuggerPresent(), DebugBreak(), and OutputDebugStringA() #include "windows.h" // only for IsDebuggerPresent(), DebugBreak(), and OutputDebugStringA()
@@ -531,10 +534,8 @@ namespace crnd
CRND_DEFINE_BUILT_IN_TYPE(unsigned int) CRND_DEFINE_BUILT_IN_TYPE(unsigned int)
CRND_DEFINE_BUILT_IN_TYPE(long) CRND_DEFINE_BUILT_IN_TYPE(long)
CRND_DEFINE_BUILT_IN_TYPE(unsigned long) CRND_DEFINE_BUILT_IN_TYPE(unsigned long)
#ifndef PLATFORM_NACL CRND_DEFINE_BUILT_IN_TYPE(int64)
CRND_DEFINE_BUILT_IN_TYPE(__int64) CRND_DEFINE_BUILT_IN_TYPE(uint64)
CRND_DEFINE_BUILT_IN_TYPE(unsigned __int64)
#endif
CRND_DEFINE_BUILT_IN_TYPE(float) CRND_DEFINE_BUILT_IN_TYPE(float)
CRND_DEFINE_BUILT_IN_TYPE(double) CRND_DEFINE_BUILT_IN_TYPE(double)
CRND_DEFINE_BUILT_IN_TYPE(long double) CRND_DEFINE_BUILT_IN_TYPE(long double)
@@ -658,7 +659,7 @@ namespace crnd
namespace math namespace math
{ {
const float cNearlyInfinite = 1.0e+37f; const float cNearlyInfinite = 1.0e+37f;
const float cDegToRad = 0.01745329252f; const float cDegToRad = 0.01745329252f;
const float cRadToDeg = 57.29577951f; const float cRadToDeg = 57.29577951f;
@@ -1275,33 +1276,33 @@ namespace crnd
component_type c[cNumComps]; component_type c[cNumComps];
}; };
color_quad() inline color_quad()
{ {
} }
color_quad(eClear) : inline color_quad(eClear) :
r(0), g(0), b(0), a(0) r(0), g(0), b(0), a(0)
{ {
} }
color_quad(const color_quad& other) : inline color_quad(const color_quad& other) :
r(other.r), g(other.g), b(other.b), a(other.a) r(other.r), g(other.g), b(other.b), a(other.a)
{ {
} }
color_quad(parameter_type y, parameter_type alpha = component_traits::cMax) inline color_quad(parameter_type y, parameter_type alpha = component_traits::cMax)
{ {
set(y, alpha); set(y, alpha);
} }
color_quad(parameter_type red, parameter_type green, parameter_type blue, parameter_type alpha = component_traits::cMax) inline color_quad(parameter_type red, parameter_type green, parameter_type blue, parameter_type alpha = component_traits::cMax)
{ {
set(red, green, blue, alpha); set(red, green, blue, alpha);
} }
template<typename other_component_type, typename other_parameter_type> template<typename other_component_type, typename other_parameter_type>
color_quad(const color_quad<other_component_type, other_parameter_type>& other) : inline color_quad(const color_quad<other_component_type, other_parameter_type>& other) :
r(clamp(other.r)), g(clamp(other.g)), b(clamp(other.b)), a(clamp(other.a)) r(clamp(other.r)), g(clamp(other.g)), b(clamp(other.b)), a(clamp(other.a))
{ {
} }
@@ -1313,7 +1314,7 @@ namespace crnd
a = 0; a = 0;
} }
color_quad& operator= (const color_quad& other) inline color_quad& operator= (const color_quad& other)
{ {
r = other.r; r = other.r;
g = other.g; g = other.g;
@@ -1323,7 +1324,7 @@ namespace crnd
} }
template<typename other_component_type, typename other_parameter_type> template<typename other_component_type, typename other_parameter_type>
color_quad& operator=(const color_quad<other_component_type, other_parameter_type>& other) inline color_quad& operator=(const color_quad<other_component_type, other_parameter_type>& other)
{ {
r = clamp(other.r); r = clamp(other.r);
g = clamp(other.g); g = clamp(other.g);
@@ -1332,7 +1333,7 @@ namespace crnd
return *this; return *this;
} }
color_quad& set(parameter_type y, parameter_type alpha = component_traits::cMax) inline color_quad& set(parameter_type y, parameter_type alpha = component_traits::cMax)
{ {
y = clamp(y); y = clamp(y);
r = static_cast<component_type>(y); r = static_cast<component_type>(y);
@@ -1342,7 +1343,7 @@ namespace crnd
return *this; return *this;
} }
color_quad& set(parameter_type red, parameter_type green, parameter_type blue, parameter_type alpha = component_traits::cMax) inline color_quad& set(parameter_type red, parameter_type green, parameter_type blue, parameter_type alpha = component_traits::cMax)
{ {
r = static_cast<component_type>(clamp(red)); r = static_cast<component_type>(clamp(red));
g = static_cast<component_type>(clamp(green)); g = static_cast<component_type>(clamp(green));
@@ -1351,7 +1352,7 @@ namespace crnd
return *this; return *this;
} }
color_quad& set_noclamp_rgba(parameter_type red, parameter_type green, parameter_type blue, parameter_type alpha) inline color_quad& set_noclamp_rgba(parameter_type red, parameter_type green, parameter_type blue, parameter_type alpha)
{ {
r = static_cast<component_type>(red); r = static_cast<component_type>(red);
g = static_cast<component_type>(green); g = static_cast<component_type>(green);
@@ -1360,7 +1361,7 @@ namespace crnd
return *this; return *this;
} }
color_quad& set_noclamp_rgb(parameter_type red, parameter_type green, parameter_type blue) inline color_quad& set_noclamp_rgb(parameter_type red, parameter_type green, parameter_type blue)
{ {
r = static_cast<component_type>(red); r = static_cast<component_type>(red);
g = static_cast<component_type>(green); g = static_cast<component_type>(green);
@@ -1368,14 +1369,14 @@ namespace crnd
return *this; return *this;
} }
static parameter_type get_min_comp() { return component_traits::cMin; } static inline parameter_type get_min_comp() { return component_traits::cMin; }
static parameter_type get_max_comp() { return component_traits::cMax; } static inline parameter_type get_max_comp() { return component_traits::cMax; }
static bool get_comps_are_signed() { return component_traits::cSigned; } static inline bool get_comps_are_signed() { return component_traits::cSigned; }
component_type operator[] (uint32 i) const { CRND_ASSERT(i < cNumComps); return c[i]; } inline component_type operator[] (uint32 i) const { CRND_ASSERT(i < cNumComps); return c[i]; }
component_type& operator[] (uint32 i) { CRND_ASSERT(i < cNumComps); return c[i]; } inline component_type& operator[] (uint32 i) { CRND_ASSERT(i < cNumComps); return c[i]; }
color_quad& set_component(uint32 i, parameter_type f) inline color_quad& set_component(uint32 i, parameter_type f)
{ {
CRND_ASSERT(i < cNumComps); CRND_ASSERT(i < cNumComps);
@@ -1384,14 +1385,14 @@ namespace crnd
return *this; return *this;
} }
color_quad& clamp(const color_quad& l, const color_quad& h) inline color_quad& clamp(const color_quad& l, const color_quad& h)
{ {
for (uint32 i = 0; i < cNumComps; i++) for (uint32 i = 0; i < cNumComps; i++)
c[i] = static_cast<component_type>(math::clamp<parameter_type>(c[i], l[i], h[i])); c[i] = static_cast<component_type>(math::clamp<parameter_type>(c[i], l[i], h[i]));
return *this; return *this;
} }
color_quad& clamp(parameter_type l, parameter_type h) inline color_quad& clamp(parameter_type l, parameter_type h)
{ {
for (uint32 i = 0; i < cNumComps; i++) for (uint32 i = 0; i < cNumComps; i++)
c[i] = static_cast<component_type>(math::clamp<parameter_type>(c[i], l, h)); c[i] = static_cast<component_type>(math::clamp<parameter_type>(c[i], l, h));
@@ -1409,23 +1410,23 @@ namespace crnd
{ {
return static_cast<parameter_type>((13938U * r + 46869U * g + 4729U * b + 32768U) >> 16U); return static_cast<parameter_type>((13938U * r + 46869U * g + 4729U * b + 32768U) >> 16U);
} }
uint32 squared_distance(const color_quad& c, bool alpha = true) const inline uint32 squared_distance(const color_quad& c, bool alpha = true) const
{ {
return math::square(r - c.r) + math::square(g - c.g) + math::square(b - c.b) + (alpha ? math::square(a - c.a) : 0); return math::square(r - c.r) + math::square(g - c.g) + math::square(b - c.b) + (alpha ? math::square(a - c.a) : 0);
} }
bool rgb_equals(const color_quad& rhs) const inline bool rgb_equals(const color_quad& rhs) const
{ {
return (r == rhs.r) && (g == rhs.g) && (b == rhs.b); return (r == rhs.r) && (g == rhs.g) && (b == rhs.b);
} }
bool operator== (const color_quad& rhs) const inline bool operator== (const color_quad& rhs) const
{ {
return (r == rhs.r) && (g == rhs.g) && (b == rhs.b) && (a == rhs.a); return (r == rhs.r) && (g == rhs.g) && (b == rhs.b) && (a == rhs.a);
} }
bool operator< (const color_quad& rhs) const inline bool operator< (const color_quad& rhs) const
{ {
for (uint32 i = 0; i < cNumComps; i++) for (uint32 i = 0; i < cNumComps; i++)
{ {
@@ -1437,76 +1438,76 @@ namespace crnd
return false; return false;
} }
color_quad& operator+= (const color_quad& other) inline color_quad& operator+= (const color_quad& other)
{ {
for (uint32 i = 0; i < 4; i++) for (uint32 i = 0; i < 4; i++)
c[i] = static_cast<component_type>(clamp(c[i] + other.c[i])); c[i] = static_cast<component_type>(clamp(c[i] + other.c[i]));
return *this; return *this;
} }
color_quad& operator-= (const color_quad& other) inline color_quad& operator-= (const color_quad& other)
{ {
for (uint32 i = 0; i < 4; i++) for (uint32 i = 0; i < 4; i++)
c[i] = static_cast<component_type>(clamp(c[i] - other.c[i])); c[i] = static_cast<component_type>(clamp(c[i] - other.c[i]));
return *this; return *this;
} }
color_quad& operator*= (parameter_type v) inline color_quad& operator*= (parameter_type v)
{ {
for (uint32 i = 0; i < 4; i++) for (uint32 i = 0; i < 4; i++)
c[i] = static_cast<component_type>(clamp(c[i] * v)); c[i] = static_cast<component_type>(clamp(c[i] * v));
return *this; return *this;
} }
color_quad& operator/= (parameter_type v) inline color_quad& operator/= (parameter_type v)
{ {
for (uint32 i = 0; i < 4; i++) for (uint32 i = 0; i < 4; i++)
c[i] = static_cast<component_type>(c[i] / v); c[i] = static_cast<component_type>(c[i] / v);
return *this; return *this;
} }
color_quad get_swizzled(uint32 x, uint32 y, uint32 z, uint32 w) const inline color_quad get_swizzled(uint32 x, uint32 y, uint32 z, uint32 w) const
{ {
CRND_ASSERT((x | y | z | w) < 4); CRND_ASSERT((x | y | z | w) < 4);
return color_quad(c[x], c[y], c[z], c[w]); return color_quad(c[x], c[y], c[z], c[w]);
} }
friend color_quad operator+ (const color_quad& lhs, const color_quad& rhs) inline friend color_quad operator+ (const color_quad& lhs, const color_quad& rhs)
{ {
color_quad result(lhs); color_quad result(lhs);
result += rhs; result += rhs;
return result; return result;
} }
friend color_quad operator- (const color_quad& lhs, const color_quad& rhs) inline friend color_quad operator- (const color_quad& lhs, const color_quad& rhs)
{ {
color_quad result(lhs); color_quad result(lhs);
result -= rhs; result -= rhs;
return result; return result;
} }
friend color_quad operator* (const color_quad& lhs, parameter_type v) inline friend color_quad operator* (const color_quad& lhs, parameter_type v)
{ {
color_quad result(lhs); color_quad result(lhs);
result *= v; result *= v;
return result; return result;
} }
friend color_quad operator/ (const color_quad& lhs, parameter_type v) friend inline color_quad operator/ (const color_quad& lhs, parameter_type v)
{ {
color_quad result(lhs); color_quad result(lhs);
result /= v; result /= v;
return result; return result;
} }
friend color_quad operator* (parameter_type v, const color_quad& rhs) friend inline color_quad operator* (parameter_type v, const color_quad& rhs)
{ {
color_quad result(rhs); color_quad result(rhs);
result *= v; result *= v;
return result; return result;
} }
uint32 get_min_component_index(bool alpha = true) const inline uint32 get_min_component_index(bool alpha = true) const
{ {
uint32 index = 0; uint32 index = 0;
uint32 limit = alpha ? cNumComps : (cNumComps - 1); uint32 limit = alpha ? cNumComps : (cNumComps - 1);
@@ -1516,7 +1517,7 @@ namespace crnd
return index; return index;
} }
uint32 get_max_component_index(bool alpha = true) const inline uint32 get_max_component_index(bool alpha = true) const
{ {
uint32 index = 0; uint32 index = 0;
uint32 limit = alpha ? cNumComps : (cNumComps - 1); uint32 limit = alpha ? cNumComps : (cNumComps - 1);
@@ -1526,24 +1527,24 @@ namespace crnd
return index; return index;
} }
void get_float4(float* pDst) inline void get_float4(float* pDst)
{ {
for (uint32 i = 0; i < 4; i++) for (uint32 i = 0; i < 4; i++)
pDst[i] = ((*this)[i] - component_traits::cMin) / float(component_traits::cMax - component_traits::cMin); pDst[i] = ((*this)[i] - component_traits::cMin) / float(component_traits::cMax - component_traits::cMin);
} }
void get_float3(float* pDst) inline void get_float3(float* pDst)
{ {
for (uint32 i = 0; i < 3; i++) for (uint32 i = 0; i < 3; i++)
pDst[i] = ((*this)[i] - component_traits::cMin) / float(component_traits::cMax - component_traits::cMin); pDst[i] = ((*this)[i] - component_traits::cMin) / float(component_traits::cMax - component_traits::cMin);
} }
static color_quad make_black() static inline color_quad make_black()
{ {
return color_quad(0, 0, 0, component_traits::cMax); return color_quad(0, 0, 0, component_traits::cMax);
} }
static color_quad make_white() static inline color_quad make_white()
{ {
return color_quad(component_traits::cMax, component_traits::cMax, component_traits::cMax, component_traits::cMax); return color_quad(component_traits::cMax, component_traits::cMax, component_traits::cMax, component_traits::cMax);
} }
@@ -1988,7 +1989,7 @@ namespace crnd
public: public:
uint32 m_total_syms; uint32 m_total_syms;
crnd::vector<uint8> m_code_sizes; crnd::vector<uint8> m_code_sizes;
prefix_coding::decoder_tables* m_pDecode_tables; prefix_coding::decoder_tables* m_pDecode_tables;
private: private:
@@ -2009,11 +2010,7 @@ namespace crnd
uint32 decode_bits(uint32 num_bits); uint32 decode_bits(uint32 num_bits);
uint32 decode(const static_huffman_data_model& model); uint32 decode(const static_huffman_data_model& model);
#ifdef PLATFORM_NACL
uint32 stop_decoding();
#else
uint64 stop_decoding(); uint64 stop_decoding();
#endif
public: public:
const uint8* m_pDecode_buf; const uint8* m_pDecode_buf;
@@ -2052,7 +2049,7 @@ namespace crnd
crnd_output_debug_string(buf); crnd_output_debug_string(buf);
printf(buf); puts(buf);
if (crnd_is_debugger_present()) if (crnd_is_debugger_present())
crnd_debug_break(); crnd_debug_break();
@@ -2421,11 +2418,13 @@ namespace crnd
p_new = ::malloc(size); p_new = ::malloc(size);
if (pActual_size) if (pActual_size)
#ifdef PLATFORM_NACL {
*pActual_size = p_new ? malloc_usable_size(p_new) : 0; #ifdef WIN32
*pActual_size = p_new ? ::_msize(p_new) : 0;
#else #else
*pActual_size = p_new ? ::_msize(p_new) : 0; *pActual_size = p_new ? malloc_usable_size(p_new) : 0;
#endif #endif
}
} }
else if (!size) else if (!size)
{ {
@@ -2438,10 +2437,10 @@ namespace crnd
else else
{ {
void* p_final_block = p; void* p_final_block = p;
#ifdef PLATFORM_NACL #ifdef WIN32
p_new = ::realloc(p, size);
#else
p_new = ::_expand(p, size); p_new = ::_expand(p, size);
#else
p_new = NULL;
#endif #endif
if (p_new) if (p_new)
@@ -2455,11 +2454,13 @@ namespace crnd
} }
if (pActual_size) if (pActual_size)
#ifdef PLATFORM_NACL {
*pActual_size = ::malloc_usable_size(p_final_block); #ifdef WIN32
#else
*pActual_size = ::_msize(p_final_block); *pActual_size = ::_msize(p_final_block);
#else
*pActual_size = ::malloc_usable_size(p_final_block);
#endif #endif
}
} }
return p_new; return p_new;
@@ -2468,10 +2469,10 @@ namespace crnd
static size_t crnd_default_msize(void* p, void* pUser_data) static size_t crnd_default_msize(void* p, void* pUser_data)
{ {
pUser_data; pUser_data;
#ifdef PLATFORM_NACL #ifdef WIN32
return p ? malloc_usable_size(p) : 0;
#else
return p ? _msize(p) : 0; return p ? _msize(p) : 0;
#else
return p ? malloc_usable_size(p) : 0;
#endif #endif
} }
@@ -2722,7 +2723,7 @@ namespace crnd
return false; return false;
if ((pHeader->m_levels < 1) || (pHeader->m_levels > utils::compute_max_mips(pHeader->m_width, pHeader->m_height))) if ((pHeader->m_levels < 1) || (pHeader->m_levels > utils::compute_max_mips(pHeader->m_width, pHeader->m_height)))
return false; return false;
if ((pHeader->m_format < cCRNFmtDXT1) || (pHeader->m_format >= cCRNFmtTotal)) if (((int)pHeader->m_format < cCRNFmtDXT1) || ((int)pHeader->m_format >= cCRNFmtTotal))
return false; return false;
if (pFile_info) if (pFile_info)
@@ -3277,38 +3278,20 @@ uint32 symbol_codec::decode(const static_huffman_data_model& model)
return sym; return sym;
} }
#ifdef PLATFORM_NACL
uint32 symbol_codec::stop_decoding()
{
#if 0
uint32 i = get_bits(4);
uint32 k = get_bits(3);
i, k;
CRND_ASSERT((i == 15) && (k == 3));
#endif
uint32 n = m_pDecode_buf_next - m_pDecode_buf;
return n;
}
#else
uint64 symbol_codec::stop_decoding() uint64 symbol_codec::stop_decoding()
{ {
#if 0 #if 0
uint32 i = get_bits(4); uint32 i = get_bits(4);
uint32 k = get_bits(3); uint32 k = get_bits(3);
i, k; i, k;
CRND_ASSERT((i == 15) && (k == 3)); CRND_ASSERT((i == 15) && (k == 3));
#endif #endif
uint64 n = m_pDecode_buf_next - m_pDecode_buf; uint64 n = static_cast<uint64>(m_pDecode_buf_next - m_pDecode_buf);
return n; return n;
} }
#endif
} // namespace crnd } // namespace crnd
// File: crnd_dxt_hc_common.cpp // File: crnd_dxt_hc_common.cpp
@@ -3591,10 +3574,9 @@ namespace crnd
namespace crnd namespace crnd
{ {
#if CRND_CREATE_BYTE_STREAMS #if CRND_CREATE_BYTE_STREAMS
static void write_array_to_file(const wchar_t* pFilename, const vector<uint8>& buf) static void write_array_to_file(const char* pFilename, const vector<uint8>& buf)
{ {
FILE* pFile; FILE* pFile = fopen(pFilename, "wb");
_wfopen_s(&pFile, pFilename, L"wb");
fwrite(&buf[0], buf.size(), 1, pFile); fwrite(&buf[0], buf.size(), 1, pFile);
fclose(pFile); fclose(pFile);
} }
@@ -3659,7 +3641,7 @@ namespace crnd
class crn_unpacker class crn_unpacker
{ {
public: public:
crn_unpacker() : inline crn_unpacker() :
m_magic(cMagicValue), m_magic(cMagicValue),
m_pData(NULL), m_pData(NULL),
m_data_size(0), m_data_size(0),
@@ -3667,7 +3649,7 @@ namespace crnd
{ {
} }
~crn_unpacker() inline ~crn_unpacker()
{ {
m_magic = 0; m_magic = 0;
} }
@@ -4828,15 +4810,15 @@ namespace crnd
// http://opensource.org/licenses/Zlib // http://opensource.org/licenses/Zlib
// //
// Copyright (c) 2010-2012 Rich Geldreich and Tenacious Software LLC // Copyright (c) 2010-2012 Rich Geldreich and Tenacious Software LLC
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
// arising from the use of this software. // arising from the use of this software.
// //
// Permission is granted to anyone to use this software for any purpose, // Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it // including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions: // freely, subject to the following restrictions:
// //
// 1. The origin of this software must not be misrepresented; you must not // 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software // claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be // in a product, an acknowledgment in the product documentation would be
+143 -66
View File
@@ -2,18 +2,25 @@
// Copyright (c) 2010-2012 Rich Geldreich and Tenacious Software LLC // Copyright (c) 2010-2012 Rich Geldreich and Tenacious Software LLC
// See copyright notice and license at the end of this file. // See copyright notice and license at the end of this file.
// //
// This header file contains the public crnlib declarations for DXTn and // This header file contains the public crnlib declarations for DXTn,
// clustered DXTn compression/decompression. // clustered DXTn, and CRN compression/decompression.
// //
// Note: This library does NOT need to be linked into your game executable if // Note: This library does NOT need to be linked into your game executable if
// all you want to do is transcode .CRN files to raw DXTn bits at run-time. // all you want to do is transcode .CRN files to raw DXTn bits at run-time.
// The crn_decomp.h header file library contains all the code necessary for // The crn_decomp.h header file library contains all the code necessary for
// decompression. // decompression.
// //
#ifndef CRNLIB_H #ifndef CRNLIB_H
#define CRNLIB_H #define CRNLIB_H
#define CRNLIB_VERSION 101 #ifdef _MSC_VER
#pragma warning (disable: 4127) // conditional expression is constant
#endif
#define CRNLIB_VERSION 103
#define CRNLIB_SUPPORT_ATI_COMPRESS 0
#define CRNLIB_SUPPORT_SQUISH 0
typedef unsigned char crn_uint8; typedef unsigned char crn_uint8;
typedef unsigned short crn_uint16; typedef unsigned short crn_uint16;
@@ -28,7 +35,7 @@ enum crn_file_type
{ {
// .CRN // .CRN
cCRNFileTypeCRN = 0, cCRNFileTypeCRN = 0,
// .DDS using regular DXT or clustered DXT // .DDS using regular DXT or clustered DXT
cCRNFileTypeDDS, cCRNFileTypeDDS,
@@ -36,21 +43,21 @@ enum crn_file_type
}; };
// Supported compressed pixel formats. // Supported compressed pixel formats.
// Basically all the standard DX9 formats, with some swizzled DXT5 formats // Basically all the standard DX9 formats, with some swizzled DXT5 formats
// (most of them supported by ATI's Compressonator), along with some ATI/X360 GPU specific formats. // (most of them supported by ATI's Compressonator), along with some ATI/X360 GPU specific formats.
enum crn_format enum crn_format
{ {
cCRNFmtInvalid = -1, cCRNFmtInvalid = -1,
cCRNFmtDXT1 = 0, cCRNFmtDXT1 = 0,
cCRNFmtFirstValid = cCRNFmtDXT1, cCRNFmtFirstValid = cCRNFmtDXT1,
// cCRNFmtDXT3 is not currently supported when writing to CRN - only DDS. // cCRNFmtDXT3 is not currently supported when writing to CRN - only DDS.
cCRNFmtDXT3, cCRNFmtDXT3,
cCRNFmtDXT5, cCRNFmtDXT5,
// Various DXT5 derivatives // Various DXT5 derivatives
cCRNFmtDXT5_CCxY, // Luma-chroma cCRNFmtDXT5_CCxY, // Luma-chroma
cCRNFmtDXT5_xGxR, // Swizzled 2-component cCRNFmtDXT5_xGxR, // Swizzled 2-component
@@ -58,7 +65,7 @@ enum crn_format
cCRNFmtDXT5_AGBR, // Swizzled 4-component cCRNFmtDXT5_AGBR, // Swizzled 4-component
// ATI 3DC and X360 DXN // ATI 3DC and X360 DXN
cCRNFmtDXN_XY, cCRNFmtDXN_XY,
cCRNFmtDXN_YX, cCRNFmtDXN_YX,
// DXT5 alpha blocks only // DXT5 alpha blocks only
@@ -72,7 +79,7 @@ enum crn_format
// Various library/file format limits. // Various library/file format limits.
enum crn_limits enum crn_limits
{ {
// Max. mipmap level resolution on any axis (will be doubled to 8k in next release). // Max. mipmap level resolution on any axis.
cCRNMaxLevelResolution = 4096, cCRNMaxLevelResolution = 4096,
cCRNMinPaletteSize = 8, cCRNMinPaletteSize = 8,
@@ -91,27 +98,27 @@ enum crn_limits
// See the m_flags member in the crn_comp_params struct, below. // See the m_flags member in the crn_comp_params struct, below.
enum crn_comp_flags enum crn_comp_flags
{ {
// Enables perceptual colorspace distance metrics if set. // Enables perceptual colorspace distance metrics if set.
// Important: Be sure to disable this when compressing non-sRGB colorspace images, like normal maps! // Important: Be sure to disable this when compressing non-sRGB colorspace images, like normal maps!
// Default: Set // Default: Set
cCRNCompFlagPerceptual = 1, cCRNCompFlagPerceptual = 1,
// Enables (up to) 8x8 macroblock usage if set. If disabled, only 4x4 blocks are allowed. // Enables (up to) 8x8 macroblock usage if set. If disabled, only 4x4 blocks are allowed.
// Compression ratio will be lower when disabled, but may cut down on blocky artifacts because the process used to determine // Compression ratio will be lower when disabled, but may cut down on blocky artifacts because the process used to determine
// where large macroblocks can be used without artifacts isn't perfect. // where large macroblocks can be used without artifacts isn't perfect.
// Default: Set. // Default: Set.
cCRNCompFlagHierarchical = 2, cCRNCompFlagHierarchical = 2,
// cCRNCompFlagQuick disables several output file optimizations - intended for things like quicker previews. // cCRNCompFlagQuick disables several output file optimizations - intended for things like quicker previews.
// Default: Not set. // Default: Not set.
cCRNCompFlagQuick = 4, cCRNCompFlagQuick = 4,
// DXT1: OK to use DXT1 alpha blocks for better quality or DXT1A transparency. // DXT1: OK to use DXT1 alpha blocks for better quality or DXT1A transparency.
// DXT5: OK to use both DXT5 block types. // DXT5: OK to use both DXT5 block types.
// Currently only used when writing to .DDS files, as .CRN uses only a subset of the possible DXTn block types. // Currently only used when writing to .DDS files, as .CRN uses only a subset of the possible DXTn block types.
// Default: Set. // Default: Set.
cCRNCompFlagUseBothBlockTypes = 8, cCRNCompFlagUseBothBlockTypes = 8,
// OK to use DXT1A transparent indices to encode black (assumes pixel shader ignores fetched alpha). // OK to use DXT1A transparent indices to encode black (assumes pixel shader ignores fetched alpha).
// Currently only used when writing to .DDS files, .CRN never uses alpha blocks. // Currently only used when writing to .DDS files, .CRN never uses alpha blocks.
// Default: Not set. // Default: Not set.
@@ -120,12 +127,12 @@ enum crn_comp_flags
// Disables endpoint caching, for more deterministic output. // Disables endpoint caching, for more deterministic output.
// Currently only used when writing to .DDS files. // Currently only used when writing to .DDS files.
// Default: Not set. // Default: Not set.
cCRNCompFlagDisableEndpointCaching = 32, cCRNCompFlagDisableEndpointCaching = 32,
// If enabled, use the cCRNColorEndpointPaletteSize, etc. params to control the CRN palette sizes. Only useful when writing to .CRN files. // If enabled, use the cCRNColorEndpointPaletteSize, etc. params to control the CRN palette sizes. Only useful when writing to .CRN files.
// Default: Not set. // Default: Not set.
cCRNCompFlagManualPaletteSizes = 64, cCRNCompFlagManualPaletteSizes = 64,
// If enabled, DXT1A alpha blocks are used to encode single bit transparency. // If enabled, DXT1A alpha blocks are used to encode single bit transparency.
// Default: Not set. // Default: Not set.
cCRNCompFlagDXT1AForTransparency = 128, cCRNCompFlagDXT1AForTransparency = 128,
@@ -136,7 +143,7 @@ enum crn_comp_flags
// Only enable on grayscale source images. // Only enable on grayscale source images.
// Default: Not set. // Default: Not set.
cCRNCompFlagGrayscaleSampling = 256, cCRNCompFlagGrayscaleSampling = 256,
// If enabled, debug information will be output during compression. // If enabled, debug information will be output during compression.
// Default: Not set. // Default: Not set.
cCRNCompFlagDebugging = 0x80000000, cCRNCompFlagDebugging = 0x80000000,
@@ -158,19 +165,27 @@ enum crn_dxt_quality
cCRNDXTQualityForceDWORD = 0xFFFFFFFF cCRNDXTQualityForceDWORD = 0xFFFFFFFF
}; };
// Which DXTn compressor to use when compressing to .DDS. // Which DXTn compressor to use when compressing to plain (non-clustered) .DDS.
enum crn_dxt_compressor_type enum crn_dxt_compressor_type
{ {
cCRNDXTCompressorCRN, cCRNDXTCompressorCRN, // Use crnlib's DXTc block compressor (default, highest quality, comparable or better than ati_compress or squish)
cCRNDXTCompressorCRNF, cCRNDXTCompressorCRNF, // Use crnlib's "fast" DXTc block compressor
cCRNDXTCompressorRYG, cCRNDXTCompressorRYG, // Use RYG's DXTc block compressor (low quality, but very fast)
#if CRNLIB_SUPPORT_ATI_COMPRESS
cCRNDXTCompressorATI,
#endif
#if CRNLIB_SUPPORT_SQUISH
cCRNDXTCompressorSquish,
#endif
cCRNTotalDXTCompressors, cCRNTotalDXTCompressors,
cCRNDXTCompressorForceDWORD = 0xFFFFFFFF cCRNDXTCompressorForceDWORD = 0xFFFFFFFF
}; };
// Compression will stop prematurely (and fail) if the callback returns false. // Progress callback function.
// Processing will stop prematurely (and fail) if the callback returns false.
// phase_index, total_phases - high level progress // phase_index, total_phases - high level progress
// subphase_index, total_subphases - progress within current phase // subphase_index, total_subphases - progress within current phase
typedef crn_bool (*crn_progress_callback_func)(crn_uint32 phase_index, crn_uint32 total_phases, crn_uint32 subphase_index, crn_uint32 total_subphases, void* pUser_data_ptr); typedef crn_bool (*crn_progress_callback_func)(crn_uint32 phase_index, crn_uint32 total_phases, crn_uint32 subphase_index, crn_uint32 total_subphases, void* pUser_data_ptr);
@@ -180,6 +195,7 @@ struct crn_comp_params
{ {
inline crn_comp_params() { clear(); } inline crn_comp_params() { clear(); }
// Clear struct to default parameters.
inline void clear() inline void clear()
{ {
m_size_of_obj = sizeof(*this); m_size_of_obj = sizeof(*this);
@@ -216,6 +232,43 @@ struct crn_comp_params
m_pProgress_func_data = NULL; m_pProgress_func_data = NULL;
} }
inline bool operator== (const crn_comp_params& rhs) const
{
#define CRNLIB_COMP(x) do { if ((x) != (rhs.x)) return false; } while(0)
CRNLIB_COMP(m_size_of_obj);
CRNLIB_COMP(m_file_type);
CRNLIB_COMP(m_faces);
CRNLIB_COMP(m_width);
CRNLIB_COMP(m_height);
CRNLIB_COMP(m_levels);
CRNLIB_COMP(m_format);
CRNLIB_COMP(m_flags);
CRNLIB_COMP(m_target_bitrate);
CRNLIB_COMP(m_quality_level);
CRNLIB_COMP(m_dxt1a_alpha_threshold);
CRNLIB_COMP(m_dxt_quality);
CRNLIB_COMP(m_dxt_compressor_type);
CRNLIB_COMP(m_alpha_component);
CRNLIB_COMP(m_crn_adaptive_tile_color_psnr_derating);
CRNLIB_COMP(m_crn_adaptive_tile_alpha_psnr_derating);
CRNLIB_COMP(m_crn_color_endpoint_palette_size);
CRNLIB_COMP(m_crn_color_selector_palette_size);
CRNLIB_COMP(m_crn_alpha_endpoint_palette_size);
CRNLIB_COMP(m_crn_alpha_selector_palette_size);
CRNLIB_COMP(m_num_helper_threads);
CRNLIB_COMP(m_userdata0);
CRNLIB_COMP(m_userdata1);
CRNLIB_COMP(m_pProgress_func);
CRNLIB_COMP(m_pProgress_func_data);
for (crn_uint32 f = 0; f < cCRNMaxFaces; f++)
for (crn_uint32 l = 0; l < cCRNMaxLevels; l++)
CRNLIB_COMP(m_pImages[f][l]);
#undef CRNLIB_COMP
return true;
}
// Returns true if the input parameters are reasonable. // Returns true if the input parameters are reasonable.
inline bool check() const inline bool check() const
{ {
@@ -244,16 +297,16 @@ struct crn_comp_params
// Helper to set/get flags from m_flags member. // Helper to set/get flags from m_flags member.
inline bool get_flag(crn_comp_flags flag) const { return (m_flags & flag) != 0; } inline bool get_flag(crn_comp_flags flag) const { return (m_flags & flag) != 0; }
inline void set_flag(crn_comp_flags flag, bool val) { m_flags &= ~flag; if (val) m_flags |= flag; } inline void set_flag(crn_comp_flags flag, bool val) { m_flags &= ~flag; if (val) m_flags |= flag; }
crn_uint32 m_size_of_obj; crn_uint32 m_size_of_obj;
crn_file_type m_file_type; // Output file type: cCRNFileTypeCRN or cCRNFileTypeDDS. crn_file_type m_file_type; // Output file type: cCRNFileTypeCRN or cCRNFileTypeDDS.
crn_uint32 m_faces; // 1 (2D map) or 6 (cubemap) crn_uint32 m_faces; // 1 (2D map) or 6 (cubemap)
crn_uint32 m_width; // [1,cCRNMaxLevelResolution], non-power of 2 OK, non-square OK crn_uint32 m_width; // [1,cCRNMaxLevelResolution], non-power of 2 OK, non-square OK
crn_uint32 m_height; // [1,cCRNMaxLevelResolution], non-power of 2 OK, non-square OK crn_uint32 m_height; // [1,cCRNMaxLevelResolution], non-power of 2 OK, non-square OK
crn_uint32 m_levels; // [1,cCRNMaxLevelResolution], non-power of 2 OK, non-square OK crn_uint32 m_levels; // [1,cCRNMaxLevelResolution], non-power of 2 OK, non-square OK
crn_format m_format; // Output pixel format. crn_format m_format; // Output pixel format.
crn_uint32 m_flags; // see crn_comp_flags enum crn_uint32 m_flags; // see crn_comp_flags enum
@@ -261,20 +314,20 @@ struct crn_comp_params
// Array of pointers to 32bpp input images. // Array of pointers to 32bpp input images.
const crn_uint32* m_pImages[cCRNMaxFaces][cCRNMaxLevels]; const crn_uint32* m_pImages[cCRNMaxFaces][cCRNMaxLevels];
// Target bitrate - if non-zero, the compressor will use an interpolative search to find the // Target bitrate - if non-zero, the compressor will use an interpolative search to find the
// highest quality level that is <= the target bitrate. If it fails to find a bitrate high enough, it'll // highest quality level that is <= the target bitrate. If it fails to find a bitrate high enough, it'll
// disabling adaptive block sizes (cCRNCompFlagHierarchical flag) and try again. This process can be pretty slow. // try disabling adaptive block sizes (cCRNCompFlagHierarchical flag) and redo the search. This process can be pretty slow.
float m_target_bitrate; float m_target_bitrate;
// Desired quality level. // Desired quality level.
// Currently, CRN and DDS quality levels are not compatible with eachother from an image quality standpoint. // Currently, CRN and DDS quality levels are not compatible with eachother from an image quality standpoint.
crn_uint32 m_quality_level; // [cCRNMinQualityLevel, cCRNMaxQualityLevel] crn_uint32 m_quality_level; // [cCRNMinQualityLevel, cCRNMaxQualityLevel]
// DXTn compression parameters. // DXTn compression parameters.
crn_uint32 m_dxt1a_alpha_threshold; crn_uint32 m_dxt1a_alpha_threshold;
crn_dxt_quality m_dxt_quality; crn_dxt_quality m_dxt_quality;
crn_dxt_compressor_type m_dxt_compressor_type; crn_dxt_compressor_type m_dxt_compressor_type;
// Alpha channel's component. Defaults to 3. // Alpha channel's component. Defaults to 3.
crn_uint32 m_alpha_component; crn_uint32 m_alpha_component;
@@ -288,7 +341,7 @@ struct crn_comp_params
crn_uint32 m_crn_alpha_endpoint_palette_size; // [cCRNMinPaletteSize,cCRNMaxPaletteSize] crn_uint32 m_crn_alpha_endpoint_palette_size; // [cCRNMinPaletteSize,cCRNMaxPaletteSize]
crn_uint32 m_crn_alpha_selector_palette_size; // [cCRNMinPaletteSize,cCRNMaxPaletteSize] crn_uint32 m_crn_alpha_selector_palette_size; // [cCRNMinPaletteSize,cCRNMaxPaletteSize]
// Number of helper threads to create to assist the compressor. 0=no threading. // Number of helper threads to create during compression. 0=no threading.
crn_uint32 m_num_helper_threads; crn_uint32 m_num_helper_threads;
// CRN userdata0 and userdata1 members, which are written directly to the header of the output file. // CRN userdata0 and userdata1 members, which are written directly to the header of the output file.
@@ -303,18 +356,18 @@ struct crn_comp_params
// Mipmap generator's mode. // Mipmap generator's mode.
enum crn_mip_mode enum crn_mip_mode
{ {
cCRNMipModeUseSourceOrGenerateMips, cCRNMipModeUseSourceOrGenerateMips, // Use source texture's mipmaps if it has any, otherwise generate new mipmaps
cCRNMipModeUseSourceMips, cCRNMipModeUseSourceMips, // Use source texture's mipmaps if it has any, otherwise the output has no mipmaps
cCRNMipModeGenerateMips, cCRNMipModeGenerateMips, // Always generate new mipmaps
cCRNMipModeNoMips, cCRNMipModeNoMips, // Output texture has no mipmaps
cCRNMipModeTotal, cCRNMipModeTotal,
cCRNModeForceDWORD = 0xFFFFFFFF cCRNModeForceDWORD = 0xFFFFFFFF
}; };
const wchar_t* crn_get_mip_mode_desc(crn_mip_mode m); const char* crn_get_mip_mode_desc(crn_mip_mode m);
const wchar_t* crn_get_mip_mode_name(crn_mip_mode m); const char* crn_get_mip_mode_name(crn_mip_mode m);
// Mipmap generator's filter kernel. // Mipmap generator's filter kernel.
enum crn_mip_filter enum crn_mip_filter
@@ -323,7 +376,7 @@ enum crn_mip_filter
cCRNMipFilterTent, cCRNMipFilterTent,
cCRNMipFilterLanczos4, cCRNMipFilterLanczos4,
cCRNMipFilterMitchell, cCRNMipFilterMitchell,
cCRNMipFilterKaiser, cCRNMipFilterKaiser, // Kaiser=default mipmap filter
cCRNMipFilterTotal, cCRNMipFilterTotal,
@@ -347,8 +400,8 @@ enum crn_scale_mode
cCRNSMForceDWORD = 0xFFFFFFFF cCRNSMForceDWORD = 0xFFFFFFFF
}; };
const wchar_t* crn_get_scale_mode_desc(crn_scale_mode sm); const char* crn_get_scale_mode_desc(crn_scale_mode sm);
// Mipmap generator parameters. // Mipmap generator parameters.
struct crn_mipmap_params struct crn_mipmap_params
{ {
@@ -361,6 +414,7 @@ struct crn_mipmap_params
m_filter = cCRNMipFilterKaiser; m_filter = cCRNMipFilterKaiser;
m_gamma_filtering = true; m_gamma_filtering = true;
m_gamma = 2.2f; m_gamma = 2.2f;
// Default "blurriness" factor of .9 actually sharpens the output a little.
m_blurriness = .9f; m_blurriness = .9f;
m_renormalize = false; m_renormalize = false;
m_tiled = false; m_tiled = false;
@@ -383,19 +437,45 @@ struct crn_mipmap_params
inline bool check() const { return true; } inline bool check() const { return true; }
inline bool operator== (const crn_mipmap_params& rhs) const
{
#define CRNLIB_COMP(x) do { if ((x) != (rhs.x)) return false; } while(0)
CRNLIB_COMP(m_size_of_obj);
CRNLIB_COMP(m_mode);
CRNLIB_COMP(m_filter);
CRNLIB_COMP(m_gamma_filtering);
CRNLIB_COMP(m_gamma);
CRNLIB_COMP(m_blurriness);
CRNLIB_COMP(m_renormalize);
CRNLIB_COMP(m_tiled);
CRNLIB_COMP(m_max_levels);
CRNLIB_COMP(m_min_mip_size);
CRNLIB_COMP(m_scale_mode);
CRNLIB_COMP(m_scale_x);
CRNLIB_COMP(m_scale_y);
CRNLIB_COMP(m_window_left);
CRNLIB_COMP(m_window_top);
CRNLIB_COMP(m_window_right);
CRNLIB_COMP(m_window_bottom);
CRNLIB_COMP(m_clamp_scale);
CRNLIB_COMP(m_clamp_width);
CRNLIB_COMP(m_clamp_height);
return true;
#undef CRNLIB_COMP
}
crn_uint32 m_size_of_obj; crn_uint32 m_size_of_obj;
crn_mip_mode m_mode; crn_mip_mode m_mode;
crn_mip_filter m_filter; crn_mip_filter m_filter;
crn_bool m_gamma_filtering; crn_bool m_gamma_filtering;
float m_gamma; float m_gamma;
float m_blurriness; float m_blurriness;
crn_uint32 m_max_levels; crn_uint32 m_max_levels;
crn_uint32 m_min_mip_size; crn_uint32 m_min_mip_size;
crn_bool m_renormalize; crn_bool m_renormalize;
crn_bool m_tiled; crn_bool m_tiled;
@@ -440,11 +520,11 @@ void crn_free_block(void *pBlock);
// compressed_size will be set to the size of the returned memory buffer. // compressed_size will be set to the size of the returned memory buffer.
// Notes: // Notes:
// A "regular" DDS file is compressed using normal DXTn compression at the specified DXT quality level. // A "regular" DDS file is compressed using normal DXTn compression at the specified DXT quality level.
// A "clustered" DDS file is compressed using clustered DXTn compression to either the target bitrate or the specified integer quality factor. // A "clustered" DDS file is compressed using clustered DXTn compression to either the target bitrate or the specified integer quality factor.
// The output file is a standard DX9 format DDS file, except the compressor assumes you will be later losslessly compressing the DDS output file using the LZMA algorithm. // The output file is a standard DX9 format DDS file, except the compressor assumes you will be later losslessly compressing the DDS output file using the LZMA algorithm.
// A texture is defined as an array of 1 or 6 "faces" (6 faces=cubemap), where each "face" consists of between [1,cCRNMaxLevels] mipmap levels. // A texture is defined as an array of 1 or 6 "faces" (6 faces=cubemap), where each "face" consists of between [1,cCRNMaxLevels] mipmap levels.
// Mipmap levels are simple 32-bit 2D images with a pitch of width*sizeof(uint32), arranged in the usual raster order (top scanline first). // Mipmap levels are simple 32-bit 2D images with a pitch of width*sizeof(uint32), arranged in the usual raster order (top scanline first).
// The image pixels may be grayscale (YYYX), grayscale/alpha (YYYA), 24-bit RGBX, or 32-bit RGBA colors (where "X"=don't care). // The image pixels may be grayscale (YYYX bytes in memory), grayscale/alpha (YYYA in memory), 24-bit (RGBX in memory), or 32-bit (RGBA) colors (where "X"=don't care).
// RGB color data is generally assumed to be in the sRGB colorspace. If not, be sure to clear the "cCRNCompFlagPerceptual" in the crn_comp_params struct! // RGB color data is generally assumed to be in the sRGB colorspace. If not, be sure to clear the "cCRNCompFlagPerceptual" in the crn_comp_params struct!
void *crn_compress(const crn_comp_params &comp_params, crn_uint32 &compressed_size, crn_uint32 *pActual_quality_level = NULL, float *pActual_bitrate = NULL); void *crn_compress(const crn_comp_params &comp_params, crn_uint32 &compressed_size, crn_uint32 *pActual_quality_level = NULL, float *pActual_bitrate = NULL);
@@ -453,15 +533,15 @@ void *crn_compress(const crn_comp_params &comp_params, crn_uint32 &compressed_si
// Be sure to set the "m_gamma_filtering" member of crn_mipmap_params to false if the input texture is not sRGB. // Be sure to set the "m_gamma_filtering" member of crn_mipmap_params to false if the input texture is not sRGB.
void *crn_compress(const crn_comp_params &comp_params, const crn_mipmap_params &mip_params, crn_uint32 &compressed_size, crn_uint32 *pActual_quality_level = NULL, float *pActual_bitrate = NULL); void *crn_compress(const crn_comp_params &comp_params, const crn_mipmap_params &mip_params, crn_uint32 &compressed_size, crn_uint32 *pActual_quality_level = NULL, float *pActual_bitrate = NULL);
// Transcodes an entire CRN file to DDS using the crn_decomp.h header file library to do most of the heavy lifting. // Transcodes an entire CRN file to DDS using the crn_decomp.h header file library to do most of the heavy lifting.
// The output DDS file's format is guaranteed to be one of the DXTn formats in the crn_format enum. // The output DDS file's format is guaranteed to be one of the DXTn formats in the crn_format enum.
// This is a fast operation, because the CRN format is explicitly designed to be efficiently transcodable to DXTn. // This is a fast operation, because the CRN format is explicitly designed to be efficiently transcodable to DXTn.
// For more control over decompression, see the lower-level helper functions in crn_decomp.h, which do not depend at all on crnlib. // For more control over decompression, see the lower-level helper functions in crn_decomp.h, which do not depend at all on crnlib.
void *crn_decompress_crn_to_dds(const void *pCRN_file_data, crn_uint32 &file_size); void *crn_decompress_crn_to_dds(const void *pCRN_file_data, crn_uint32 &file_size);
// Decompresses an entire DDS file in any supported format to uncompressed 32-bit/pixel image(s). // Decompresses an entire DDS file in any supported format to uncompressed 32-bit/pixel image(s).
// See the crnlib::pixel_format in inc/dds_defs.h for a list of the supported DDS formats. // See the crnlib::pixel_format enum in inc/dds_defs.h for a list of the supported DDS formats.
// You are responsible for freeing each image, either by calling crn_free_all_images() or manually calling crn_free_block() on each image pointer. // You are responsible for freeing each image block, either by calling crn_free_all_images() or manually calling crn_free_block() on each image pointer.
struct crn_texture_desc struct crn_texture_desc
{ {
crn_uint32 m_faces; crn_uint32 m_faces;
@@ -493,16 +573,13 @@ crn_format crn_get_fundamental_dxt_format(crn_format fmt);
// -------- String helpers. // -------- String helpers.
// Converts a crn_file_type to a string. // Converts a crn_file_type to a string.
const wchar_t* crn_get_file_type_ext(crn_file_type file_type); const char* crn_get_file_type_ext(crn_file_type file_type);
const char* crn_get_file_type_exta(crn_file_type file_type);
// Converts a crn_format to a string. // Converts a crn_format to a string.
const char* crn_get_format_stringa(crn_format fmt); const char* crn_get_format_string(crn_format fmt);
const wchar_t* crn_get_format_string(crn_format fmt);
// Converts a crn_dxt_quality to a string. // Converts a crn_dxt_quality to a string.
const wchar_t* crn_get_dxt_quality_string(crn_dxt_quality q); const char* crn_get_dxt_quality_string(crn_dxt_quality q);
const char* crn_get_dxt_quality_stringa(crn_dxt_quality q);
// -------- Low-level DXTn 4x4 block compressor API // -------- Low-level DXTn 4x4 block compressor API
@@ -530,15 +607,15 @@ void crn_free_block_compressor(crn_block_compressor_context_t pContext);
// http://opensource.org/licenses/Zlib // http://opensource.org/licenses/Zlib
// //
// Copyright (c) 2010-2012 Rich Geldreich and Tenacious Software LLC // Copyright (c) 2010-2012 Rich Geldreich and Tenacious Software LLC
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
// arising from the use of this software. // arising from the use of this software.
// //
// Permission is granted to anyone to use this software for any purpose, // Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it // including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions: // freely, subject to the following restrictions:
// //
// 1. The origin of this software must not be misrepresented; you must not // 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software // claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would be // in a product, an acknowledgment in the product documentation would be
+9 -1
View File
@@ -1,4 +1,4 @@
crunch/crnlib v1.01 - Advanced DXTn texture compression library crunch/crnlib v1.03 PRERELEASE - Advanced DXTn texture compression library
Copyright (C) 2010-2012 Rich Geldreich and Tenacious Software LLC Copyright (C) 2010-2012 Rich Geldreich and Tenacious Software LLC
For bugs or support contact Rich Geldreich <richgel99@gmail.com>. For bugs or support contact Rich Geldreich <richgel99@gmail.com>.
@@ -12,6 +12,14 @@ originally written by Igor Pavlov (LZMA) and RYG (crn_ryg_dxt*).
If you use this software in a product, an acknowledgment in the product If you use this software in a product, an acknowledgment in the product
documentation would be highly appreciated but is not required. documentation would be highly appreciated but is not required.
New for v1.03 [4/26/12]: crnlib more portable, Linux Port
------------------------------------------------
v1.03 has been ported to Linux. It's still a work in progress. A few features
of the command line tool don't work under Linux yet (such as -timestamp),
but the core functionality (compression/decompression/transcoding) should work
OK. I'm currently testing crnlib/crunch with Codeblocks 10.05 under Ubuntu x86.
Overview Overview
-------- --------