1 Commits

Author SHA1 Message Date
richgel99@gmail.com 02646ebc08 2012-12-03 22:16:54 +00:00
20 changed files with 347 additions and 480 deletions
-2
View File
@@ -1,2 +0,0 @@
*.o
crnlib/crunch
-17
View File
@@ -1,17 +0,0 @@
# Change Log
## [0.1.4] - 2012-11-24
### Added
* KTX file format
* Basic ETC1 support
* Simple makefile
### Fixed
* Various DDS format fixes
## [0.1.3] - 2012-04-26
### Added
* Ported to Linux (tested on Ubuntu x86 w/Codeblocks). Note that a few features of the cmd line tool don't work yet (eg. -timestamp)
[0.1.4]: https://github.com/BinomialLLC/crunch
[0.1.3]: https://github.com/BinomialLLC/crunch
BIN
View File
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -8,7 +8,7 @@
namespace crnlib namespace crnlib
{ {
const char *g_copyright_str = "Copyright (c) 2010-2016 Richard Geldreich, Jr. and Binomial LLC"; const char *g_copyright_str = "Copyright (c) 2010-2012 Rich Geldreich and Tenacious Software LLC";
const char *g_sig_str = "C8cfRlaorj0wLtnMSxrBJxTC85rho2L9hUZKHcBL"; const char *g_sig_str = "C8cfRlaorj0wLtnMSxrBJxTC85rho2L9hUZKHcBL";
} // namespace crnlib } // namespace crnlib
+14 -14
View File
@@ -112,9 +112,9 @@ namespace crnlib
uint weight = m_unique_colors[i].m_weight; uint weight = m_unique_colors[i].m_weight;
total_weight += weight; total_weight += weight;
tot_r += m_unique_colors[i].m_color.r * static_cast<uint64>(weight); tot_r += m_unique_colors[i].m_color.r * weight;
tot_g += m_unique_colors[i].m_color.g * static_cast<uint64>(weight); tot_g += m_unique_colors[i].m_color.g * weight;
tot_b += m_unique_colors[i].m_color.b * static_cast<uint64>(weight); tot_b += m_unique_colors[i].m_color.b * weight;
} }
const uint half_total_weight = total_weight >> 1; const uint half_total_weight = total_weight >> 1;
@@ -494,7 +494,7 @@ namespace crnlib
ll[2] = (ll[0]*2+ll[1])/3; ll[2] = (ll[0]*2+ll[1])/3;
ll[3] = (ll[0]+ll[1]*2)/3; ll[3] = (ll[0]+ll[1]*2)/3;
uint64 error_to_beat = 0; uint error_to_beat = 0;
uint min_color_weight = 0; uint min_color_weight = 0;
uint max_color_weight = 0; uint max_color_weight = 0;
for (uint i = 0; i < m_unique_colors.size(); i++) for (uint i = 0; i < m_unique_colors.size(); i++)
@@ -503,7 +503,7 @@ namespace crnlib
uint w = m_unique_colors[i].m_weight; uint w = m_unique_colors[i].m_weight;
int delta = ll[m_best_solution.m_selectors[i]] - c; int delta = ll[m_best_solution.m_selectors[i]] - c;
error_to_beat += static_cast<int64>(w) * (delta * delta); error_to_beat += (int)w * (delta * delta);
if (c == min_color[comp_index]) if (c == min_color[comp_index])
min_color_weight += w; min_color_weight += w;
@@ -561,11 +561,11 @@ namespace crnlib
tl[2] = (tl[0]*2+tl[1])/3; tl[2] = (tl[0]*2+tl[1])/3;
tl[3] = (tl[0]+tl[1]*2)/3; tl[3] = (tl[0]+tl[1]*2)/3;
uint64 trial_error = 0; uint trial_error = 0;
for (uint i = 0; i < m_unique_colors.size(); i++) for (uint i = 0; i < m_unique_colors.size(); i++)
{ {
int delta = tl[m_best_solution.m_selectors[i]] - m_unique_colors[i].m_color[comp_index]; int delta = tl[m_best_solution.m_selectors[i]] - m_unique_colors[i].m_color[comp_index];
trial_error += static_cast<int64>(m_unique_colors[i].m_weight) * (delta * delta); trial_error += m_unique_colors[i].m_weight * (delta * delta);
if (trial_error >= error_to_beat) if (trial_error >= error_to_beat)
break; break;
} }
@@ -599,7 +599,7 @@ namespace crnlib
for (uint i = 0; i < m_unique_colors.size(); i++) for (uint i = 0; i < m_unique_colors.size(); i++)
{ {
int delta = tl[m_best_solution.m_selectors[i]] - m_unique_colors[i].m_color[comp_index]; int delta = tl[m_best_solution.m_selectors[i]] - m_unique_colors[i].m_color[comp_index];
error_to_beat += static_cast<int64>(m_unique_colors[i].m_weight) * (delta * delta); error_to_beat += m_unique_colors[i].m_weight * (delta * delta);
} }
} // better } // better
@@ -1582,7 +1582,7 @@ namespace crnlib
err = color_distance(true, c, colors[3], false); err = color_distance(true, c, colors[3], false);
if (err < best_error) { best_error = err; best_color_index = 3; } if (err < best_error) { best_error = err; best_color_index = 3; }
trial_error += best_error * static_cast<uint64>(m_unique_colors[unique_color_index].m_weight); trial_error += best_error * m_unique_colors[unique_color_index].m_weight;
if (trial_error >= solution.m_error) if (trial_error >= solution.m_error)
break; break;
@@ -1607,7 +1607,7 @@ namespace crnlib
err = color_distance(false, c, colors[3], false); err = color_distance(false, c, colors[3], false);
if (err < best_error) { best_error = err; best_color_index = 3; } if (err < best_error) { best_error = err; best_color_index = 3; }
trial_error += best_error * static_cast<uint64>(m_unique_colors[unique_color_index].m_weight); trial_error += best_error * m_unique_colors[unique_color_index].m_weight;
if (trial_error >= solution.m_error) if (trial_error >= solution.m_error)
break; break;
@@ -1634,7 +1634,7 @@ namespace crnlib
err = color_distance(true, c, colors[2], false); err = color_distance(true, c, colors[2], false);
if (err < best_error) { best_error = err; best_color_index = 2; } if (err < best_error) { best_error = err; best_color_index = 2; }
trial_error += best_error * static_cast<uint64>(m_unique_colors[unique_color_index].m_weight); trial_error += best_error * m_unique_colors[unique_color_index].m_weight;
if (trial_error >= solution.m_error) if (trial_error >= solution.m_error)
break; break;
@@ -1656,7 +1656,7 @@ namespace crnlib
err = color_distance(false, c, colors[2], false); err = color_distance(false, c, colors[2], false);
if (err < best_error) { best_error = err; best_color_index = 2; } if (err < best_error) { best_error = err; best_color_index = 2; }
trial_error += best_error * static_cast<uint64>(m_unique_colors[unique_color_index].m_weight); trial_error += best_error * m_unique_colors[unique_color_index].m_weight;
if (trial_error >= solution.m_error) if (trial_error >= solution.m_error)
break; break;
@@ -1781,7 +1781,7 @@ namespace crnlib
uint best_error = color_distance(m_perceptual, c, colors[best_color_index], false); uint best_error = color_distance(m_perceptual, c, colors[best_color_index], false);
trial_error += best_error * static_cast<uint64>(m_unique_colors[unique_color_index].m_weight); trial_error += best_error * m_unique_colors[unique_color_index].m_weight;
if (trial_error >= solution.m_error) if (trial_error >= solution.m_error)
break; break;
@@ -1814,7 +1814,7 @@ namespace crnlib
uint best_error = color_distance(m_perceptual, c, colors[best_color_index], false); uint best_error = color_distance(m_perceptual, c, colors[best_color_index], false);
trial_error += best_error * static_cast<uint64>(m_unique_colors[unique_color_index].m_weight); trial_error += best_error * m_unique_colors[unique_color_index].m_weight;
if (trial_error >= solution.m_error) if (trial_error >= solution.m_error)
break; break;
+1 -1
View File
@@ -1305,7 +1305,7 @@ namespace crnlib
*pActualComps = 0; *pActualComps = 0;
if ((req_comps < 1) || (req_comps > 4)) if ((req_comps < 1) || (req_comps > 4))
return NULL; return false;
mipmapped_texture tex; mipmapped_texture tex;
+6 -6
View File
@@ -355,7 +355,7 @@ namespace crnlib
inline T* alloc_group(bool nofail = false) inline T* alloc_group(bool nofail = false)
{ {
T* p = static_cast<T*>(sparse_array_traits<T, Log2N>::alloc_space(N * sizeof(T))); T* p = static_cast<T*>(alloc_space(N * sizeof(T)));
if (!p) if (!p)
{ {
@@ -365,7 +365,7 @@ namespace crnlib
CRNLIB_FAIL("Out of memory"); CRNLIB_FAIL("Out of memory");
} }
sparse_array_traits<T, Log2N>::construct_group(p); construct_group(p);
m_num_active_groups++; m_num_active_groups++;
@@ -379,20 +379,20 @@ namespace crnlib
CRNLIB_ASSERT(m_num_active_groups); CRNLIB_ASSERT(m_num_active_groups);
m_num_active_groups--; m_num_active_groups--;
sparse_array_traits<T, Log2N>::destruct_group(p); destruct_group(p);
sparse_array_traits<T, Log2N>::free_space(p); free_space(p);
} }
} }
inline void init_default() inline void init_default()
{ {
sparse_array_traits<T, Log2N>::construct_element(reinterpret_cast<T*>(m_default)); construct_element(reinterpret_cast<T*>(m_default));
} }
inline void deinit_default() inline void deinit_default()
{ {
sparse_array_traits<T, Log2N>::destruct_element(reinterpret_cast<T*>(m_default)); destruct_element(reinterpret_cast<T*>(m_default));
} }
}; };
+3 -3
View File
@@ -172,7 +172,7 @@ void *crn_compress(const crn_comp_params &comp_params, crn_uint32 &compressed_si
if (pActual_bitrate) *pActual_bitrate = 0.0f; if (pActual_bitrate) *pActual_bitrate = 0.0f;
if (!comp_params.check()) if (!comp_params.check())
return NULL; return false;
crnlib::vector<uint8> crn_file_data; crnlib::vector<uint8> crn_file_data;
if (!create_compressed_texture(comp_params, crn_file_data, pActual_quality_level, pActual_bitrate)) if (!create_compressed_texture(comp_params, crn_file_data, pActual_quality_level, pActual_bitrate))
@@ -189,7 +189,7 @@ void *crn_compress(const crn_comp_params &comp_params, const crn_mipmap_params &
if (pActual_bitrate) *pActual_bitrate = 0.0f; if (pActual_bitrate) *pActual_bitrate = 0.0f;
if ((!comp_params.check()) || (!mip_params.check())) if ((!comp_params.check()) || (!mip_params.check()))
return NULL; return false;
crnlib::vector<uint8> crn_file_data; crnlib::vector<uint8> crn_file_data;
if (!create_compressed_texture(comp_params, mip_params, crn_file_data, pActual_quality_level, pActual_bitrate)) if (!create_compressed_texture(comp_params, mip_params, crn_file_data, pActual_quality_level, pActual_bitrate))
@@ -456,4 +456,4 @@ bool crn_decompress_block(const void *pSrc_block, crn_uint32 *pDst_pixels_u32, c
} }
return true; return true;
} }
+3 -3
View File
@@ -176,7 +176,7 @@ public:
console::printf("-%s", pixel_format_helpers::get_pixel_format_string(fmt)); console::printf("-%s", pixel_format_helpers::get_pixel_format_string(fmt));
} }
console::printf("\nFor bugs, support, or feedback: info@binomial.info"); console::printf("\nFor bugs, support, or feedback: richgel99@gmail.com");
} }
bool convert(const char* pCommand_line) bool convert(const char* pCommand_line)
@@ -1253,8 +1253,8 @@ static bool check_for_option(int argc, char *argv[], const char *pOption)
static void print_title() static void print_title()
{ {
console::printf("crunch: Advanced DXTn Texture Compressor - https://github.com/BinomialLLC/crunch"); console::printf("crunch: Advanced DXTn Texture Compressor - http://code.google.com/p/crunch");
console::printf("Copyright (c) 2010-2016 Richard Geldreich, Jr. and Binomial LLC"); console::printf("Copyright (c) 2010-2012 Rich Geldreich and Tenacious Software LLC");
console::printf("crnlib version v%u.%02u %s Built %s, %s", CRNLIB_VERSION / 100U, CRNLIB_VERSION % 100U, crnlib_is_x64() ? "x64" : "x86", __DATE__, __TIME__); console::printf("crnlib version v%u.%02u %s Built %s, %s", CRNLIB_VERSION / 100U, CRNLIB_VERSION % 100U, crnlib_is_x64() ? "x64" : "x86", __DATE__, __TIME__);
console::printf(""); console::printf("");
} }
-110
View File
@@ -1,110 +0,0 @@
/* Copyright (c) 2013, Evan Parker, Brandon Jones. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#define PLATFORM_NACL // This disables use of 64 bit integers, among other things.
#include <stddef.h> // For NULL, size_t
#include <cstring> // for malloc etc
#include "crn_decomp.h"
extern "C" {
unsigned int crn_get_width(void *src, unsigned int src_size);
unsigned int crn_get_height(void *src, unsigned int src_size);
unsigned int crn_get_levels(void *src, unsigned int src_size);
unsigned int crn_get_dxt_format(void *src, unsigned int src_size);
unsigned int crn_get_bytes_per_block(void *src, unsigned int src_size);
unsigned int crn_get_uncompressed_size(void *p, unsigned int size, unsigned int level);
void crn_decompress(void *src, unsigned int src_size, void *dst, unsigned int dst_size, unsigned int firstLevel, unsigned int levelCount);
}
unsigned int crn_get_width(void *src, unsigned int src_size) {
crnd::crn_texture_info tex_info;
crnd::crnd_get_texture_info(static_cast<crn_uint8*>(src), src_size, &tex_info);
return tex_info.m_width;
}
unsigned int crn_get_height(void *src, unsigned int src_size) {
crnd::crn_texture_info tex_info;
crnd::crnd_get_texture_info(static_cast<crn_uint8*>(src), src_size, &tex_info);
return tex_info.m_height;
}
unsigned int crn_get_levels(void *src, unsigned int src_size) {
crnd::crn_texture_info tex_info;
crnd::crnd_get_texture_info(static_cast<crn_uint8*>(src), src_size, &tex_info);
return tex_info.m_levels;
}
unsigned int crn_get_dxt_format(void *src, unsigned int src_size) {
crnd::crn_texture_info tex_info;
crnd::crnd_get_texture_info(static_cast<crn_uint8*>(src), src_size, &tex_info);
return tex_info.m_format;
}
unsigned int crn_get_bytes_per_block(void *src, unsigned int src_size) {
crnd::crn_texture_info tex_info;
crnd::crnd_get_texture_info(static_cast<crn_uint8*>(src), src_size, &tex_info);
return crnd::crnd_get_bytes_per_dxt_block(tex_info.m_format);
}
unsigned int crn_get_uncompressed_size(void *src, unsigned int src_size, unsigned int level) {
crnd::crn_texture_info tex_info;
crnd::crnd_get_texture_info(static_cast<crn_uint8*>(src), src_size, &tex_info);
const crn_uint32 width = tex_info.m_width >> level;
const crn_uint32 height = tex_info.m_height >> level;
const crn_uint32 blocks_x = (width + 3) >> 2;
const crn_uint32 blocks_y = (height + 3) >> 2;
const crn_uint32 row_pitch = blocks_x * crnd::crnd_get_bytes_per_dxt_block(tex_info.m_format);
const crn_uint32 total_face_size = row_pitch * blocks_y;
return total_face_size;
}
void crn_decompress(void *src, unsigned int src_size, void *dst, unsigned int dst_size, unsigned int firstLevel, unsigned int levelCount) {
crnd::crn_texture_info tex_info;
crnd::crnd_get_texture_info(static_cast<crn_uint8*>(src), src_size, &tex_info);
crn_uint32 width = tex_info.m_width >> firstLevel;
crn_uint32 height = tex_info.m_height >> firstLevel;
crn_uint32 bytes_per_block = crnd::crnd_get_bytes_per_dxt_block(tex_info.m_format);
void *pDecomp_images[1];
pDecomp_images[0] = dst;
crnd::crnd_unpack_context pContext =
crnd::crnd_unpack_begin(static_cast<crn_uint8*>(src), src_size);
for (int i = firstLevel; i < firstLevel + levelCount; ++i) {
crn_uint32 blocks_x = (width + 3) >> 2;
crn_uint32 blocks_y = (height + 3) >> 2;
crn_uint32 row_pitch = blocks_x * bytes_per_block;
crn_uint32 total_level_size = row_pitch * blocks_y;
crnd::crnd_unpack_level(pContext, pDecomp_images, total_level_size, row_pitch, i);
pDecomp_images[0] = (char*)pDecomp_images[0] + total_level_size;
width = width >> 1;
height = height >> 1;
}
crnd::crnd_unpack_end(pContext);
}
+1 -1
View File
@@ -33,7 +33,7 @@ const int cDefaultCRNQualityLevel = 128;
static int print_usage() static int print_usage()
{ {
printf("Description: Simple crnlib API example program.\n"); printf("Description: Simple crnlib API example program.\n");
printf("Copyright (c) 2010-2016 Richard Geldreich, Jr. and Binomial LLC\n"); printf("Copyright (c) 2010-2011 Tenacious Software LLC\n");
printf("Usage: example1 [mode: i/c/d] [source_file] [options]\n"); printf("Usage: example1 [mode: i/c/d] [source_file] [options]\n");
printf("\nModes:\n"); printf("\nModes:\n");
printf("c: Compress to .DDS or .CRN using the crn_compress() func. in crnlib.h\n"); printf("c: Compress to .DDS or .CRN using the crn_compress() func. in crnlib.h\n");
+1 -1
View File
@@ -24,7 +24,7 @@ using namespace crnlib;
static int print_usage() static int print_usage()
{ {
printf("Description: Transcodes .CRN to .DDS files using crn_decomp.h.\n"); printf("Description: Transcodes .CRN to .DDS files using crn_decomp.h.\n");
printf("Copyright (c) 2010-2016 Richard Geldreich, Jr. and Binomial LLC\n"); printf("Copyright (c) 2010-2011 Tenacious Software LLC\n");
printf("Usage: example2 [source_file] [options]\n"); printf("Usage: example2 [source_file] [options]\n");
printf("\nOptions:\n"); printf("\nOptions:\n");
printf("-out filename - Force output filename.\n"); printf("-out filename - Force output filename.\n");
+1 -1
View File
@@ -29,7 +29,7 @@ const uint cDXTBlockSize = 4;
static int print_usage() static int print_usage()
{ {
printf("Description: Simple .DDS DXTn block compression using crnlib.\n"); printf("Description: Simple .DDS DXTn block compression using crnlib.\n");
printf("Copyright (c) 2010-2016 Binomial LLC\n"); printf("Copyright (c) 2010-2011 Tenacious Software LLC\n");
printf("Usage: example3 [source_file] [options]\n"); printf("Usage: example3 [source_file] [options]\n");
printf("\n"); printf("\n");
printf("Note: This simple example is not multithreaded, so it's not going to be\n"); printf("Note: This simple example is not multithreaded, so it's not going to be\n");
+6 -10
View File
@@ -1,5 +1,5 @@
// File: crn_decomp.h - Fast CRN->DXTc texture transcoder header file library // File: crn_decomp.h - Fast CRN->DXTc texture transcoder header file library
// Copyright (c) 2010-2016 Richard Geldreich, Jr. and Binomial 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 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.
@@ -377,11 +377,7 @@ namespace crnd
#ifdef _WIN64 #ifdef _WIN64
typedef uint64 ptr_bits; typedef uint64 ptr_bits;
#else #else
#ifdef __x86_64__ typedef uint32 ptr_bits;
typedef uint64 ptr_bits;
#else
typedef uint32 ptr_bits;
#endif
#endif #endif
template<typename T> struct int_traits { enum { cMin = crnd::cINT32_MIN, cMax = crnd::cINT32_MAX, cSigned = true }; }; template<typename T> struct int_traits { enum { cMin = crnd::cINT32_MIN, cMax = crnd::cINT32_MAX, cSigned = true }; };
@@ -2823,15 +2819,15 @@ namespace crnd
*pSize = 0; *pSize = 0;
if ((!pData) || (data_size < cCRNHeaderMinSize)) if ((!pData) || (data_size < cCRNHeaderMinSize))
return NULL; return false;
crn_header tmp_header; crn_header tmp_header;
const crn_header* pHeader = crnd_get_header(tmp_header, pData, data_size); const crn_header* pHeader = crnd_get_header(tmp_header, pData, data_size);
if (!pHeader) if (!pHeader)
return NULL; return false;
if (level_index >= pHeader->m_levels) if (level_index >= pHeader->m_levels)
return NULL; return false;
uint32 cur_level_ofs = pHeader->m_level_ofs[level_index]; uint32 cur_level_ofs = pHeader->m_level_ofs[level_index];
@@ -4816,7 +4812,7 @@ namespace crnd
// crn_decomp.h uses the ZLIB license: // crn_decomp.h uses the ZLIB license:
// http://opensource.org/licenses/Zlib // http://opensource.org/licenses/Zlib
// //
// Copyright (c) 2010-2016 Richard Geldreich, Jr. and Binomial 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
+2 -2
View File
@@ -1,5 +1,5 @@
// File: crnlib.h - Advanced DXTn texture compression library. // File: crnlib.h - Advanced DXTn texture compression library.
// Copyright (c) 2010-2016 Richard Geldreich, Jr. and Binomial 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, // This header file contains the public crnlib declarations for DXTn,
@@ -619,7 +619,7 @@ bool crn_decompress_block(const void *pSrc_block, crn_uint32 *pDst_pixels, crn_f
// crnlib uses the ZLIB license: // crnlib uses the ZLIB license:
// http://opensource.org/licenses/Zlib // http://opensource.org/licenses/Zlib
// //
// Copyright (c) 2010-2016 Richard Geldreich, Jr. and Binomial 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
+1 -1
View File
@@ -1,7 +1,7 @@
crunch/crnlib uses the ZLIB license: crunch/crnlib uses the ZLIB license:
http://opensource.org/licenses/Zlib http://opensource.org/licenses/Zlib
Copyright (c) 2010-2016 Richard Geldreich, Jr. and Binomial 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
+307 -307
View File
@@ -1,307 +1,307 @@
crunch/crnlib v1.04 - Advanced DXTn texture compression library crunch/crnlib v1.04 - Advanced DXTn texture compression library
Copyright (C) 2010-2017 Richard Geldreich, Jr. and Binomial LLC http://binomial.info Copyright (C) 2010-2012 Rich Geldreich and Tenacious Software LLC
For bugs or support contact Binomial <info@binomial.info>. For bugs or support contact Rich Geldreich <richgel99@gmail.com>.
This software uses the ZLIB license, which is located in license.txt. This software uses the ZLIB license, which is located in license.txt.
http://opensource.org/licenses/Zlib http://opensource.org/licenses/Zlib
Portions of this software make use of public domain code originally Portions of this software make use of public domain code originally
written by Igor Pavlov (LZMA), RYG (crn_ryg_dxt*), and Sean Barrett (stb_image.c). written by Igor Pavlov (LZMA), RYG (crn_ryg_dxt*), and Sean Barrett (stb_image.c).
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.
Note: crunch originally used to live on Google Code: https://code.google.com/p/crunch/ New for v1.04 [11/24/12]: KTX file format, basic ETC1 support, DDS format fixes, simple makefile
------------------------------------------------
## Overview
Lots of higher level changes to get crnlib into a state where I can carry it forward to
crnlib is a lossy texture compression library for developers that ship support other file and texture compression formats. No major codec-level changes.
content using the DXT1/5/N or 3DC compressed color/normal map/cubemap I've regression tested the codec writing .CRN and RDO .DDS files at various bitrates.
mipmapped texture formats. It was written by the same author as the open Everything seems OK, but with all the changes I made to support KTX and other formats like ETC1
source [LZHAM compression library](http://code.google.com/p/lzham/). I'm still worried about bugs.
It can compress mipmapped 2D textures, normal maps, and cubemaps to New for v1.03 [4/26/12]: crnlib more portable, Linux Port
approx. 1-1.25 bits/texel, and normal maps to 1.75-2 bits/texel. The ------------------------------------------------
actual bitrate depends on the complexity of the texture itself, the
specified quality factor/target bitrate, and ultimately on the desired v1.03 has been ported to Linux. It's still a work in progress. A few features
quality needed for a particular texture. of the command line tool don't work under Linux yet (such as -timestamp),
but the core functionality (compression/decompression/transcoding) should work
crnlib's differs significantly from other approaches because its OK. I'm currently testing crnlib/crunch with Codeblocks 10.05 under Ubuntu x86.
compressed texture data format was carefully designed to be quickly
transcodable directly to DXTn with no intermediate recompression step. Overview
The typical (single threaded) transcode to DXTn rate is generally --------
between 100-250 megatexels/sec. The current library supports PC
(Win32/x64) and Xbox 360. Fast random access to individual mipmap levels crnlib is a lossy texture compression library for developers that ship
is supported. content using the DXT1/5/N or 3DC compressed color/normal map/cubemap
mipmapped texture formats. It was written by the same author as the open
crnlib can also generates standard .DDS files at specified quality source LZHAM lossless data compression library:
setting, which results in files that are much more compressible by http://code.google.com/p/lzham/
LZMA/Deflate/etc. compared to files generated by standard DXTn texture
tools (see below). This feature allows easy integration into any engine It can compress mipmapped 2D textures, normal maps, and cubemaps to
or graphics library that already supports .DDS files. approx. 1-1.25 bits/texel, and normal maps to 1.75-2 bits/texel. The
actual bitrate depends on the complexity of the texture itself, the
The .CRN file format supports the following core DXTn texture formats: specified quality factor/target bitrate, and ultimately on the desired
DXT1 (but not DXT1A), DXT5, DXT5A, and DXN/3DC quality needed for a particular texture.
It also supports several popular swizzled variants (several are crnlib's differs significantly from other approaches because its
also supported by AMD's Compressonator): compressed texture data format was carefully designed to be quickly
DXT5_XGBR, DXT5_xGxR, DXT5_AGBR, and DXT5_CCxY (experimental luma-chroma YCoCg). transcodable directly to DXTn with no intermediate recompression step.
The typical (single threaded) transcode to DXTn rate is generally
## Recommended Software between 100-250 megatexels/sec. The current library supports PC
(Win32/x64) and Xbox 360. Fast random access to individual mipmap levels
AMD's [Compressonator tool](https://github.com/GPUOpen-Tools/Compressonator) is supported.
is recommended to view the .DDS files created by the crunch tool and the included example projects.
crnlib can also generates standard .DDS files at specified quality
Note: Some of the swizzled DXTn .DDS output formats (such as DXT5_xGBR) setting, which results in files that are much more compressible by
read/written by the crunch tool or examples deviate from the DX9 DDS LZMA/Deflate/etc. compared to files generated by standard DXTn texture
standard, so DXSDK tools such as DXTEX.EXE won't load them at all or tools (see below). This feature allows easy integration into any engine
they won't be properly displayed. or graphics library that already supports .DDS files.
## Compression Algorithm Details The .CRN file format supports the following core DXTn texture formats:
DXT1 (but not DXT1A), DXT5, DXT5A, and DXN/3DC
The compression process employed in creating both .CRN and
clustered .DDS files utilizes a very high quality, scalable DXTn It also supports several popular swizzled variants (several are
endpoint optimizer capable of processing any number of pixels (instead also supported by AMD's Compressonator):
of the typical hard coded 16), optional adaptive switching between DXT5_XGBR, DXT5_xGxR, DXT5_AGBR, and DXT5_CCxY (experimental luma-chroma YCoCg).
several macroblock sizes/configurations (currently any combination of
4x4, 8x4, 4x8, and 8x8 pixel blocks), endpoint clusterization using Recommended Software
top-down cluster analysis, vector quantization (VQ) of the selector --------------------
indices, and several custom algorithms for compressing the resulting
endpoint/selector codebooks and macroblock indices. Multiple feedback AMD's Compressonator tool is recommended to view the .DDS files created by
passes are performed between the clusterization and VQ steps to optimize the crunch tool and the included example projects:
quality, and several steps use a brute force refinement approach to improve
quality. The majority of compression steps are multithreaded. http://developer.amd.com/gpu/compressonator/pages/default.aspx
The .CRN format currently utilizes canonical Huffman coding for speed Note: Some of the swizzled DXTn .DDS output formats (such as DXT5_xGBR)
(similar to Deflate but with much larger tables), but the next major read/written by the crunch tool or examples deviate from the DX9 DDS
version will also utilize adaptive binary arithmetic coding and higher standard, so DXSDK tools such as DXTEX.EXE won't load them at all or
order context modeling using already developed tech from the my LZHAM they won't be properly displayed.
compression library.
Compression Algorithm Details
## Supported File Formats -----------------------------
crnlib supports two compressed texture file formats. The first The compression process employed in creating both .CRN and
format (clustered .DDS) is simple to integrate into an existing project clustered .DDS files utilizes a very high quality, scalable DXTn
(typically, no code changes are required), but it doesn't offer the endpoint optimizer capable of processing any number of pixels (instead
highest quality/compression ratio that crnlib is capable of. Integrating of the typical hard coded 16), optional adaptive switching between
the second, higher quality custom format (.CRN) requires a few several macroblock sizes/configurations (currently any combination of
typically straightforward engine modifications to integrate the 4x4, 8x4, 4x8, and 8x8 pixel blocks), endpoint clusterization using
.CRN->DXTn transcoder header file library into your tools/engine. top-down cluster analysis, vector quantization (VQ) of the selector
indices, and several custom algorithms for compressing the resulting
### .DDS endpoint/selector codebooks and macroblock indices. Multiple feedback
passes are performed between the clusterization and VQ steps to optimize
crnlib can compress textures to standard DX9-style .DDS files using quality, and several steps use a brute force refinement approach to improve
clustered DXTn compression, which is a subset of the approach used to quality. The majority of compression steps are multithreaded.
create .CRN files.(For completeness, crnlib also supports vanilla, block
by block DXTn compression too, but that's not very interesting.) The .CRN format currently utilizes canonical Huffman coding for speed
Clustered DXTn compressed .DDS files are much more compressible than (similar to Deflate but with much larger tables), but the next major
files created by other libraries/tools. Apart from increased version will also utilize adaptive binary arithmetic coding and higher
compressibility, the .DDS files generated by this process are completely order context modeling using already developed tech from the my LZHAM
standard so they should be fairly easy to add to a project with little compression library.
to no code changes.
Supported File Formats
To actually benefit from clustered DXTn .DDS files, your engine needs to ----------------------
further losslessly compress the .DDS data generated by crnlib using a
lossless codec such as zlib, lzo, LZMA, LZHAM, etc. Most likely, your crnlib supports two compressed texture file formats. The first
engine does this already. (If not, you definitely should because DXTn format (clustered .DDS) is simple to integrate into an existing project
compressed textures generally contain a large amount of highly redundant (typically, no code changes are required), but it doesn't offer the
data.) highest quality/compression ratio that crnlib is capable of. Integrating
the second, higher quality custom format (.CRN) requires a few
Clustered .DDS files are intended to be the simplest/fastest way to typically straightforward engine modifications to integrate the
integrate crnlib's tech into a project. .CRN->DXTn transcoder header file library into your tools/engine.
### .CRN .DDS
crnlib can compress textures to standard DX9-style .DDS files using
The second, better, option is to compress your textures to .CRN files clustered DXTn compression, which is a subset of the approach used to
using crnlib. To read the resulting .CRN data, you must add the .CRN create .CRN files.(For completeness, crnlib also supports vanilla, block
transcoder library (located in the included single file, stand-alone by block DXTn compression too, but that's not very interesting.)
header file library inc/crn_decomp.h) into your application. .CRN files Clustered DXTn compressed .DDS files are much more compressible than
provide noticeably higher quality at the same effective bitrate compared files created by other libraries/tools. Apart from increased
to clustered DXTn compressed .DDS files. Also, .CRN files don't require compressibility, the .DDS files generated by this process are completely
further lossless compression because they're already highly compressed. standard so they should be fairly easy to add to a project with little
to no code changes.
.CRN files are a bit more difficult/risky to integrate into a project, but
the resulting compression ratio and quality is superior vs. clustered .DDS files. To actually benefit from clustered DXTn .DDS files, your engine needs to
further losslessly compress the .DDS data generated by crnlib using a
### .KTX lossless codec such as zlib, lzo, LZMA, LZHAM, etc. Most likely, your
engine does this already. (If not, you definitely should because DXTn
crnlib and crunch can read/write the .KTX file format in various pixel formats. compressed textures generally contain a large amount of highly redundant
Rate distortion optimization (clustered DXTc compression) is not yet supported data.)
when writing .KTX files.
Clustered .DDS files are intended to be the simplest/fastest way to
The .KTX file format is just like .DDS, except it's a fairly well specified integrate crnlib's tech into a project.
standard created by the Khronos Group. Unfortunately, almost all of the tools I've
found that support .KTX are fairly (to very) buggy, or are limited to only a handful .CRN
of pixel formats, so there's no guarantee that the .KTX files written by crnlib can The second, better, option is to compress your textures to .CRN files
be reliably read by other tools. using crnlib. To read the resulting .CRN data, you must add the .CRN
transcoder library (located in the included single file, stand-alone
## Building the Examples header file library inc/crn_decomp.h) into your application. .CRN files
provide noticeably higher quality at the same effective bitrate compared
This release contains the source code and projects for three simple to clustered DXTn compressed .DDS files. Also, .CRN files don't require
example projects: further lossless compression because they're already highly compressed.
crn_examples.2008.sln is a Visual Studio 2008 (VC9) solution file .CRN files are a bit more difficult/risky to integrate into a project, but
containing projects for Win32 and x64. crnlib itself also builds with the resulting compression ratio and quality is superior vs. clustered .DDS files.
VS2005, VS2010, and gcc 4.5.0 (TDM GCC+MinGW). A codeblocks 10.05
workspace and project file is also included, but compiling crnlib this .KTX
way hasn't been tested much.
crnlib and crunch can read/write the .KTX file format in various pixel formats.
### example1 Rate distortion optimization (clustered DXTc compression) is not yet supported
when writing .KTX files.
Demonstrates how to use crnlib's high-level C-helper
compression/decompression/transcoding functions in inc/crnlib.h. It's a The .KTX file format is just like .DDS, except it's a fairly well specified
fairly complete example of crnlib's functionality. standard created by the Khronos Group. Unfortunately, almost all of the tools I've
found that support .KTX are fairly (to very) buggy, or are limited to only a handful
### example2 of pixel formats, so there's no guarantee that the .KTX files written by crnlib can
Shows how to transcodec .CRN files to .DDS using **only** be reliably read by other tools.
the functionality in inc/crn_decomp.h. It does not link against against
crnlib.lib or depend on it in any way. (Note: The complete source code, Building the Examples
approx. 4800 lines, to the CRN transcoder is included in inc/crn_decomp.h.) ---------------------
example2 is intended to show how simple it is to integrate CRN textures This release contains the source code and projects for three simple
into your application. example projects:
### example3 crn_examples.2008.sln is a Visual Studio 2008 (VC9) solution file
Shows how to use the regular, low-level DXTn block compressor containing projects for Win32 and x64. crnlib itself also builds with
functions in inc/crnlib.h. This functionality is included for VS2005, VS2010, and gcc 4.5.0 (TDM GCC+MinGW). A codeblocks 10.05
completeness. (Your engine or toolchain most likely already has its own workspace and project file is also included, but compiling crnlib this
DXTn compressor. crnlib's compressor is typically very competitive or way hasn't been tested much.
superior to most available closed and open source CPU-based
compressors.) example1: Demonstrates how to use crnlib's high-level C-helper
compression/decompression/transcoding functions in inc/crnlib.h. It's a
## Creating Compressed Textures from the Command Line (crunch.exe) fairly complete example of crnlib's functionality.
The simplest way to create compressed textures using crnlib is to example2: Shows how to transcodec .CRN files to .DDS using *only*
integrate the bin\crunch.exe or bin\crunch_x64.exe) command line tool the functionality in inc/crn_decomp.h. It does not link against against
into your texture build toolchain or export process. It can write DXTn crnlib.lib or depend on it in any way. (Note: The complete source code,
compressed 2D/cubemap textures to regular DXTn compressed .DDS, approx. 4800 lines, to the CRN transcoder is included in inc/crn_decomp.h.)
clustered (or reduced entropy) DXTn compressed .DDS, or .CRN files. It
can also transcode or decompress files to several standard image example2 is intended to show how simple it is to integrate CRN textures
formats, such as TGA or BMP. Run crunch.exe with no options for help. into your application.
The .CRN files created by crunch.exe can be efficiently transcoded to example3: Shows how to use the regular, low-level DXTn block compressor
DXTn using the included CRN transcoding library, located in full source functions in inc/crnlib.h. This functionality is included for
form under inc/crn_decomp.h. completeness. (Your engine or toolchain most likely already has its own
DXTn compressor. crnlib's compressor is typically very competitive or
Here are a few example crunch.exe command lines: superior to most available closed and open source CPU-based
compressors.)
1. Compress blah.tga to blah.dds using normal DXT1 compression:
* `crunch -file blah.tga -fileformat dds -dxt1` Creating Compressed Textures from the Command Line (crunch.exe)
---------------------------------------------------------------
2. Compress blah.tga to blah.dds using clustered DXT1 at an effective bitrate of 1.5 bits/texel, display image statistic:
* `crunch -file blah.tga -fileformat dds -dxt1 -bitrate 1.5 -imagestats` The simplest way to create compressed textures using crnlib is to
integrate the bin\crunch.exe or bin\crunch_x64.exe) command line tool
3. Compress blah.tga to blah.dds using clustered DXT1 at quality level 100 (from [0,255]), with no mipmaps, display LZMA statistics: into your texture build toolchain or export process. It can write DXTn
* `crunch -file blah.tga -fileformat dds -dxt1 -quality 100 -mipmode none -lzmastats` compressed 2D/cubemap textures to regular DXTn compressed .DDS,
clustered (or reduced entropy) DXTn compressed .DDS, or .CRN files. It
3. Compress blah.tga to blah.crn using clustered DXT1 at a bitrate of 1.2 bits/texel, no mipmaps: can also transcode or decompress files to several standard image
* `crunch -file blah.tga -dxt1 -bitrate 1.2 -mipmode none` formats, such as TGA or BMP. Run crunch.exe with no options for help.
4. Decompress blah.dds to a .tga file: The .CRN files created by crunch.exe can be efficiently transcoded to
* `crunch -file blah.dds -fileformat tga` DXTn using the included CRN transcoding library, located in full source
form under inc/crn_decomp.h.
5. Transcode blah.crn to a .dds file:
* `crunch -file blah.crn` Here are a few example crunch.exe command lines:
6. Decompress blah.crn, writing each mipmap level to a separate .tga file: 1. Compress blah.tga to blah.dds using normal DXT1 compression:
* `crunch -split -file blah.crn -fileformat tga` crunch -file blah.tga -fileformat dds -dxt1
crunch.exe can do a lot more, like rescale/crop images before 2. Compress blah.tga to blah.dds using clustered DXT1 at an effective bitrate of 1.5 bits/texel, display image statistic:
compression, convert images from one file format to another, compare crunch -file blah.tga -fileformat dds -dxt1 -bitrate 1.5 -imagestats
images, process multiple images, etc.
3. Compress blah.tga to blah.dds using clustered DXT1 at quality level 100 (from [0,255]), with no mipmaps, display LZMA statistics:
Note: I would have included the full source to crunch.exe, but it still crunch -file blah.tga -fileformat dds -dxt1 -quality 100 -mipmode none -lzmastats
has some low-level dependencies to crnlib internals which I didn't have
time to address. This version of crunch.exe has some reduced 3. Compress blah.tga to blah.crn using clustered DXT1 at a bitrate of 1.2 bits/texel, no mipmaps:
functionality compared to an earlier eval release. For example, XML file crunch -file blah.tga -dxt1 -bitrate 1.2 -mipmode none
support is not included in this version.
4. Decompress blah.dds to a .tga file:
## Using crnlib crunch -file blah.dds -fileformat tga
The most flexible and powerful way of using crnlib is to integrate the 5. Transcode blah.crn to a .dds file:
library into your editor/toolchain/etc. and directly supply it your crunch -file blah.crn
raw/source texture bits. See the C-style API's and comments in
inc/crnlib.h. 6. Decompress blah.crn, writing each mipmap level to a separate .tga file:
crunch -split -file blah.crn -fileformat tga
To compress, you basically fill in a few structs in and call one function:
crunch.exe can do a lot more, like rescale/crop images before
```c compression, convert images from one file format to another, compare
void *crn_compress( const crn_comp_params &comp_params, images, process multiple images, etc.
crn_uint32 &compressed_size,
crn_uint32 *pActual_quality_level = NULL, Note: I would have included the full source to crunch.exe, but it still
float *pActual_bitrate = NULL); has some low-level dependencies to crnlib internals which I didn't have
``` time to address. This version of crunch.exe has some reduced
functionality compared to an earlier eval release. For example, XML file
Or, if you want crnlib to also generate mipmaps, you call this function: support is not included in this version.
```c Using crnlib
void *crn_compress( const crn_comp_params &comp_params, ------------
const crn_mipmap_params &mip_params,
crn_uint32 &compressed_size, The most flexible and powerful way of using crnlib is to integrate the
crn_uint32 *pActual_quality_level = NULL, library into your editor/toolchain/etc. and directly supply it your
float *pActual_bitrate = NULL); raw/source texture bits. See the C-style API's and comments in
``` inc/crnlib.h.
You can also transcode/uncompress .DDS/.CRN files to raw 32bpp images To compress, you basically fill in a few structs in and call one function:
using `crn_decompress_crn_to_dds()` and `crn_decompress_dds_to_images()`.
void *crn_compress(const crn_comp_params &comp_params, crn_uint32 &compressed_size, crn_uint32 *pActual_quality_level = NULL, float *pActual_bitrate = NULL);
Internally, crnlib just uses inc/crn_decomp.h to transcode textures to
DXTn. If you only need to transcode .CRN format files to raw DXTn bits Or, if you want crnlib to also generate mipmaps, you call this function:
at runtime (and not compress), you don't actually need to compile or
link against crnlib at all. Just include inc/crn_decomp.h, which 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);
contains a completely self-contained CRN transcoder in the "crnd"
namespace. The `crnd_get_texture_info()`, `crnd_unpack_begin()`, You can also transcode/uncompress .DDS/.CRN files to raw 32bpp images
`crnd_unpack_level()`, etc. functions are all you need to efficiently get using crn_decompress_crn_to_dds() and crn_decompress_dds_to_images().
at the raw DXTn bits, which can be directly supplied to whatever API or
GPU you're using. (See example2.) Internally, crnlib just uses inc/crn_decomp.h to transcode textures to
DXTn. If you only need to transcode .CRN format files to raw DXTn bits
Important note: When compiling under native client, be sure to define at runtime (and not compress), you don't actually need to compile or
the `PLATFORM_NACL` macro before including the `inc/crn_decomp.h` header file library. link against crnlib at all. Just include inc/crn_decomp.h, which
contains a completely self-contained CRN transcoder in the "crnd"
## Known Issues/Bugs namespace. The crnd_get_texture_info(), crnd_unpack_begin(),
crnd_unpack_level(), etc. functions are all you need to efficiently get
* crnlib currently assumes you'll be further losslessly compressing its at the raw DXTn bits, which can be directly supplied to whatever API or
output .DDS files using LZMA. However, some engines use weaker codecs GPU you're using. (See example2.)
such as LZO, zlib, or custom codecs, so crnlib's bitrate measurements
will be inaccurate. It should be easy to allow the caller to plug-in Important note: When compiling under native client, be sure to define
custom lossless compressors for bitrate measurement. the PLATFORM_NACL macro before including the inc/crn_decomp.h header file library.
* Compressing to a desired bitrate can be time consuming, especially when Known Issues/Bugs
processing large (2k or 4k) images to the .CRN format. There are several -----------------
high-level optimizations employed when compressing to clustered DXTn .DDS
files using multiple trials, but not so for .CRN. * crnlib currently assumes you'll be further losslessly compressing its
output .DDS files using LZMA. However, some engines use weaker codecs
* The .CRN compressor does not currently use 3 color (transparent) DXT1 such as LZO, zlib, or custom codecs, so crnlib's bitrate measurements
blocks at all, only 4 color blocks. So it doesn't support DXT1A will be inaccurate. It should be easy to allow the caller to plug-in
transparency, and its output quality suffers a little due to this custom lossless compressors for bitrate measurement.
limitation. (Note that the clustered DXTn compressor used when
writing clustered .DDS files does *not* have this limitation.) * Compressing to a desired bitrate can be time consuming, especially when
processing large (2k or 4k) images to the .CRN format. There are several
* Clustered DXT5/DXT5A compressor is able to group DXT5A blocks into high-level optimizations employed when compressing to clustered DXTn .DDS
clusters only if they use absolute (black/white) selector indices. This files using multiple trials, but not so for .CRN.
hurts performance at very low bitrates, because too many bits are
effectively given to alpha. * The .CRN compressor does not currently use 3 color (transparent) DXT1
blocks at all, only 4 color blocks. So it doesn't support DXT1A
* DXT3 is not supported when writing .CRN or clustered DXTn DDS files. transparency, and its output quality suffers a little due to this
(DXT3 is supported by crnlib's when compressing to regular DXTn DDS limitation. (Note that the clustered DXTn compressor used when
files.) You'll get DXT5 files if you request DXT3. However, DXT3 is writing clustered .DDS files does *not* have this limitation.)
supported by the regular DXTn block compressor. (DXT3's 4bpp fixed alpha
sucks verses DXT5 alpha blocks, so I don't see this as a bug deal.) * Clustered DXT5/DXT5A compressor is able to group DXT5A blocks into
clusters only if they use absolute (black/white) selector indices. This
* The DXT5_CCXY format uses a simple YCoCg encoding that is workable but hurts performance at very low bitrates, because too many bits are
hasn't been tuned for max. quality yet. effectively given to alpha.
* Clustered (or rate distortion optimized) DXTc compression is only * DXT3 is not supported when writing .CRN or clustered DXTn DDS files.
supported when writing to .DDS, not .KTX. Also, only plain block by block (DXT3 is supported by crnlib's when compressing to regular DXTn DDS
compression is supported when writing to ETC1, and .CRN does not support ETC1. files.) You'll get DXT5 files if you request DXT3. However, DXT3 is
supported by the regular DXTn block compressor. (DXT3's 4bpp fixed alpha
## Compile to Javascript with Emscripten sucks verses DXT5 alpha blocks, so I don't see this as a bug deal.)
Download and install Emscripten: * The DXT5_CCXY format uses a simple YCoCg encoding that is workable but
http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html hasn't been tuned for max. quality yet.
From the root directory, run: * Clustered (or rate distortion optimized) DXTc compression is only
```c supported when writing to .DDS, not .KTX. Also, only plain block by block
emcc -O3 emscripten/crn.cpp -I./inc -s EXPORTED_FUNCTIONS="['_malloc', '_free', '_crn_get_width', '_crn_get_height', '_crn_get_levels', '_crn_get_dxt_format', '_crn_get_bytes_per_block', '_crn_get_uncompressed_size', '_crn_decompress']" -s NO_EXIT_RUNTIME=1 -s NO_FILESYSTEM=1 -s ELIMINATE_DUPLICATE_FUNCTIONS=1 -s ALLOW_MEMORY_GROWTH=1 --memory-init-file 0 -o crunch.js compression is supported when writing to ETC1, and .CRN does not support ETC1.
```