You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-05 17:15:09 +00:00
Update basis universal to version 1.16.3.
Enable basis universal uastc internal storage instead of etc1s for better quality.
This commit is contained in:
222
thirdparty/basis_universal/encoder/basisu_enc.cpp
vendored
222
thirdparty/basis_universal/encoder/basisu_enc.cpp
vendored
@@ -13,16 +13,20 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include "basisu_enc.h"
|
||||
#include "lodepng.h"
|
||||
#include "basisu_resampler.h"
|
||||
#include "basisu_resampler_filters.h"
|
||||
#include "basisu_etc.h"
|
||||
#include "../transcoder/basisu_transcoder.h"
|
||||
#include "basisu_bc7enc.h"
|
||||
#include "apg_bmp.h"
|
||||
#include "jpgd.h"
|
||||
#include "pvpngreader.h"
|
||||
#include "basisu_opencl.h"
|
||||
#include <vector>
|
||||
|
||||
#define MINIZ_HEADER_FILE_ONLY
|
||||
#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
|
||||
#include "basisu_miniz.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
// For QueryPerformanceCounter/QueryPerformanceFrequency
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
@@ -158,34 +162,62 @@ namespace basisu
|
||||
{ 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~)
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F
|
||||
};
|
||||
|
||||
|
||||
bool g_library_initialized;
|
||||
std::mutex g_encoder_init_mutex;
|
||||
|
||||
// Encoder library initialization (just call once at startup)
|
||||
void basisu_encoder_init()
|
||||
void basisu_encoder_init(bool use_opencl, bool opencl_force_serialization)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_encoder_init_mutex);
|
||||
|
||||
if (g_library_initialized)
|
||||
return;
|
||||
|
||||
detect_sse41();
|
||||
|
||||
basist::basisu_transcoder_init();
|
||||
pack_etc1_solid_color_init();
|
||||
//uastc_init();
|
||||
bc7enc_compress_block_init(); // must be after uastc_init()
|
||||
|
||||
// Don't bother initializing the OpenCL module at all if it's been completely disabled.
|
||||
if (use_opencl)
|
||||
{
|
||||
opencl_init(opencl_force_serialization);
|
||||
}
|
||||
|
||||
g_library_initialized = true;
|
||||
}
|
||||
|
||||
void error_printf(const char *pFmt, ...)
|
||||
void basisu_encoder_deinit()
|
||||
{
|
||||
char buf[2048];
|
||||
opencl_deinit();
|
||||
|
||||
g_library_initialized = false;
|
||||
}
|
||||
|
||||
void error_vprintf(const char* pFmt, va_list args)
|
||||
{
|
||||
char buf[8192];
|
||||
|
||||
va_list args;
|
||||
va_start(args, pFmt);
|
||||
#ifdef _WIN32
|
||||
vsprintf_s(buf, sizeof(buf), pFmt, args);
|
||||
#else
|
||||
vsnprintf(buf, sizeof(buf), pFmt, args);
|
||||
#endif
|
||||
va_end(args);
|
||||
|
||||
fprintf(stderr, "ERROR: %s", buf);
|
||||
}
|
||||
|
||||
void error_printf(const char *pFmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, pFmt);
|
||||
error_vprintf(pFmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
inline void query_counter(timer_ticks* pTicks)
|
||||
{
|
||||
@@ -195,7 +227,7 @@ namespace basisu
|
||||
{
|
||||
QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER*>(pTicks));
|
||||
}
|
||||
#elif defined(__APPLE__) || defined(__OpenBSD__)
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
#include <sys/time.h>
|
||||
inline void query_counter(timer_ticks* pTicks)
|
||||
{
|
||||
@@ -284,59 +316,6 @@ namespace basisu
|
||||
}
|
||||
|
||||
const uint32_t MAX_32BIT_ALLOC_SIZE = 250000000;
|
||||
|
||||
bool load_bmp(const char* pFilename, image& img)
|
||||
{
|
||||
int w = 0, h = 0;
|
||||
unsigned int n_chans = 0;
|
||||
unsigned char* pImage_data = apg_bmp_read(pFilename, &w, &h, &n_chans);
|
||||
|
||||
if ((!pImage_data) || (!w) || (!h) || ((n_chans != 3) && (n_chans != 4)))
|
||||
{
|
||||
error_printf("Failed loading .BMP image \"%s\"!\n", pFilename);
|
||||
|
||||
if (pImage_data)
|
||||
apg_bmp_free(pImage_data);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sizeof(void *) == sizeof(uint32_t))
|
||||
{
|
||||
if ((w * h * n_chans) > MAX_32BIT_ALLOC_SIZE)
|
||||
{
|
||||
error_printf("Image \"%s\" is too large (%ux%u) to process in a 32-bit build!\n", pFilename, w, h);
|
||||
|
||||
if (pImage_data)
|
||||
apg_bmp_free(pImage_data);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
img.resize(w, h);
|
||||
|
||||
const uint8_t *pSrc = pImage_data;
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
color_rgba *pDst = &img(0, y);
|
||||
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
pDst->r = pSrc[0];
|
||||
pDst->g = pSrc[1];
|
||||
pDst->b = pSrc[2];
|
||||
pDst->a = (n_chans == 3) ? 255 : pSrc[3];
|
||||
|
||||
pSrc += n_chans;
|
||||
++pDst;
|
||||
}
|
||||
}
|
||||
|
||||
apg_bmp_free(pImage_data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool load_tga(const char* pFilename, image& img)
|
||||
{
|
||||
@@ -392,53 +371,35 @@ namespace basisu
|
||||
|
||||
bool load_png(const uint8_t *pBuf, size_t buf_size, image &img, const char *pFilename)
|
||||
{
|
||||
interval_timer tm;
|
||||
tm.start();
|
||||
|
||||
if (!buf_size)
|
||||
return false;
|
||||
|
||||
unsigned err = 0, w = 0, h = 0;
|
||||
|
||||
if (sizeof(void*) == sizeof(uint32_t))
|
||||
uint32_t width = 0, height = 0, num_chans = 0;
|
||||
void* pImage = pv_png::load_png(pBuf, buf_size, 4, width, height, num_chans);
|
||||
if (!pBuf)
|
||||
{
|
||||
// Inspect the image first on 32-bit builds, to see if the image would require too much memory.
|
||||
lodepng::State state;
|
||||
err = lodepng_inspect(&w, &h, &state, pBuf, buf_size);
|
||||
if ((err != 0) || (!w) || (!h))
|
||||
return false;
|
||||
|
||||
const uint32_t exepected_alloc_size = w * h * sizeof(uint32_t);
|
||||
|
||||
// If the file is too large on 32-bit builds then just bail now, to prevent causing a memory exception.
|
||||
if (exepected_alloc_size >= MAX_32BIT_ALLOC_SIZE)
|
||||
{
|
||||
error_printf("Image \"%s\" is too large (%ux%u) to process in a 32-bit build!\n", (pFilename != nullptr) ? pFilename : "<memory>", w, h);
|
||||
return false;
|
||||
}
|
||||
|
||||
w = h = 0;
|
||||
error_printf("pv_png::load_png failed while loading image \"%s\"\n", pFilename);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> out;
|
||||
err = lodepng::decode(out, w, h, pBuf, buf_size);
|
||||
if ((err != 0) || (!w) || (!h))
|
||||
return false;
|
||||
img.grant_ownership(reinterpret_cast<color_rgba*>(pImage), width, height);
|
||||
|
||||
if (out.size() != (w * h * 4))
|
||||
return false;
|
||||
|
||||
img.resize(w, h);
|
||||
|
||||
memcpy(img.get_ptr(), &out[0], out.size());
|
||||
//debug_printf("Total load_png() time: %3.3f secs\n", tm.get_elapsed_secs());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool load_png(const char* pFilename, image& img)
|
||||
{
|
||||
std::vector<uint8_t> buffer;
|
||||
unsigned err = lodepng::load_file(buffer, std::string(pFilename));
|
||||
if (err)
|
||||
uint8_vec buffer;
|
||||
if (!read_file_to_vec(pFilename, buffer))
|
||||
{
|
||||
error_printf("load_png: Failed reading file \"%s\"!\n", pFilename);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return load_png(buffer.data(), buffer.size(), img, pFilename);
|
||||
}
|
||||
@@ -468,8 +429,6 @@ namespace basisu
|
||||
|
||||
if (strcasecmp(pExt, "png") == 0)
|
||||
return load_png(pFilename, img);
|
||||
if (strcasecmp(pExt, "bmp") == 0)
|
||||
return load_bmp(pFilename, img);
|
||||
if (strcasecmp(pExt, "tga") == 0)
|
||||
return load_tga(pFilename, img);
|
||||
if ( (strcasecmp(pExt, "jpg") == 0) || (strcasecmp(pExt, "jfif") == 0) || (strcasecmp(pExt, "jpeg") == 0) )
|
||||
@@ -482,61 +441,67 @@ namespace basisu
|
||||
{
|
||||
if (!img.get_total_pixels())
|
||||
return false;
|
||||
|
||||
const uint32_t MAX_PNG_IMAGE_DIM = 32768;
|
||||
if ((img.get_width() > MAX_PNG_IMAGE_DIM) || (img.get_height() > MAX_PNG_IMAGE_DIM))
|
||||
return false;
|
||||
|
||||
std::vector<uint8_t> out;
|
||||
unsigned err = 0;
|
||||
|
||||
void* pPNG_data = nullptr;
|
||||
size_t PNG_data_size = 0;
|
||||
|
||||
if (image_save_flags & cImageSaveGrayscale)
|
||||
{
|
||||
uint8_vec g_pixels(img.get_width() * img.get_height());
|
||||
uint8_t *pDst = &g_pixels[0];
|
||||
uint8_vec g_pixels(img.get_total_pixels());
|
||||
uint8_t* pDst = &g_pixels[0];
|
||||
|
||||
for (uint32_t y = 0; y < img.get_height(); y++)
|
||||
for (uint32_t x = 0; x < img.get_width(); x++)
|
||||
*pDst++ = img(x, y)[grayscale_comp];
|
||||
|
||||
err = lodepng::encode(out, (const uint8_t*)&g_pixels[0], img.get_width(), img.get_height(), LCT_GREY, 8);
|
||||
pPNG_data = buminiz::tdefl_write_image_to_png_file_in_memory_ex(g_pixels.data(), img.get_width(), img.get_height(), 1, &PNG_data_size, 1, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool has_alpha = img.has_alpha();
|
||||
if ((!has_alpha) || ((image_save_flags & cImageSaveIgnoreAlpha) != 0))
|
||||
bool has_alpha = false;
|
||||
|
||||
if ((image_save_flags & cImageSaveIgnoreAlpha) == 0)
|
||||
has_alpha = img.has_alpha();
|
||||
|
||||
if (!has_alpha)
|
||||
{
|
||||
const uint64_t total_bytes = (uint64_t)img.get_width() * 3U * (uint64_t)img.get_height();
|
||||
if (total_bytes > INT_MAX)
|
||||
return false;
|
||||
uint8_vec rgb_pixels(static_cast<size_t>(total_bytes));
|
||||
uint8_t *pDst = &rgb_pixels[0];
|
||||
|
||||
uint8_vec rgb_pixels(img.get_total_pixels() * 3);
|
||||
uint8_t* pDst = &rgb_pixels[0];
|
||||
|
||||
for (uint32_t y = 0; y < img.get_height(); y++)
|
||||
{
|
||||
const color_rgba* pSrc = &img(0, y);
|
||||
for (uint32_t x = 0; x < img.get_width(); x++)
|
||||
{
|
||||
const color_rgba& c = img(x, y);
|
||||
pDst[0] = c.r;
|
||||
pDst[1] = c.g;
|
||||
pDst[2] = c.b;
|
||||
pDst[0] = pSrc->r;
|
||||
pDst[1] = pSrc->g;
|
||||
pDst[2] = pSrc->b;
|
||||
|
||||
pSrc++;
|
||||
pDst += 3;
|
||||
}
|
||||
}
|
||||
|
||||
err = lodepng::encode(out, (const uint8_t*)& rgb_pixels[0], img.get_width(), img.get_height(), LCT_RGB, 8);
|
||||
pPNG_data = buminiz::tdefl_write_image_to_png_file_in_memory_ex(rgb_pixels.data(), img.get_width(), img.get_height(), 3, &PNG_data_size, 1, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = lodepng::encode(out, (const uint8_t*)img.get_ptr(), img.get_width(), img.get_height(), LCT_RGBA, 8);
|
||||
pPNG_data = buminiz::tdefl_write_image_to_png_file_in_memory_ex(img.get_ptr(), img.get_width(), img.get_height(), 4, &PNG_data_size, 1, false);
|
||||
}
|
||||
}
|
||||
|
||||
err = lodepng::save_file(out, std::string(pFilename));
|
||||
if (err)
|
||||
if (!pPNG_data)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
bool status = write_data_to_file(pFilename, pPNG_data, PNG_data_size);
|
||||
if (!status)
|
||||
{
|
||||
error_printf("save_png: Failed writing to filename \"%s\"!\n", pFilename);
|
||||
}
|
||||
|
||||
free(pPNG_data);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
bool read_file_to_vec(const char* pFilename, uint8_vec& data)
|
||||
@@ -1620,7 +1585,8 @@ namespace basisu
|
||||
|
||||
void job_pool::job_thread(uint32_t index)
|
||||
{
|
||||
debug_printf("job_pool::job_thread: starting %u\n", index);
|
||||
BASISU_NOTE_UNUSED(index);
|
||||
//debug_printf("job_pool::job_thread: starting %u\n", index);
|
||||
|
||||
while (true)
|
||||
{
|
||||
@@ -1656,7 +1622,7 @@ namespace basisu
|
||||
m_no_more_jobs.notify_all();
|
||||
}
|
||||
|
||||
debug_printf("job_pool::job_thread: exiting\n");
|
||||
//debug_printf("job_pool::job_thread: exiting\n");
|
||||
}
|
||||
|
||||
// .TGA image loading
|
||||
@@ -1779,6 +1745,8 @@ namespace basisu
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//const uint32_t bytes_per_line = hdr.m_width * tga_bytes_per_pixel;
|
||||
|
||||
const uint8_t *pSrc = pBuf + sizeof(tga_header);
|
||||
uint32_t bytes_remaining = buf_size - sizeof(tga_header);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user