summaryrefslogtreecommitdiff
path: root/thirdparty/basis_universal/encoder/basisu_enc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/basis_universal/encoder/basisu_enc.cpp')
-rw-r--r--thirdparty/basis_universal/encoder/basisu_enc.cpp222
1 files changed, 95 insertions, 127 deletions
diff --git a/thirdparty/basis_universal/encoder/basisu_enc.cpp b/thirdparty/basis_universal/encoder/basisu_enc.cpp
index daaf65badc..b427215ee3 100644
--- a/thirdparty/basis_universal/encoder/basisu_enc.cpp
+++ b/thirdparty/basis_universal/encoder/basisu_enc.cpp
@@ -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;
- }
-
- std::vector<uint8_t> out;
- err = lodepng::decode(out, w, h, pBuf, buf_size);
- if ((err != 0) || (!w) || (!h))
- return false;
-
- if (out.size() != (w * h * 4))
+ error_printf("pv_png::load_png failed while loading image \"%s\"\n", pFilename);
return false;
+ }
- img.resize(w, h);
+ img.grant_ownership(reinterpret_cast<color_rgba*>(pImage), width, height);
- 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);