// basis_wrappers.cpp - Wrappers to the C++ compressor and transcoder for WebAssembly/WebGL use.
// This file exposes wrappers for transcoding and encoding .basis and .KTX2 files.
//
// **Important**:
// Compile with -fno-strict-aliasing (same as the Linux kernel).
// This code HAS NOT been tested with strict aliasing enabled.
// The "initializeBasis()" function MUST be called at least once before using either the compressor or transcoder.
//
// There are four main categories of wrappers in this module:
// 1. Transcoding, low-level .basis file information: See class basis_file. Only depends on transcoder/basisu_transcoder.cpp.
//    getFileDesc(), getImageDesc(), getImageLevelDesc(): These functions return low-level information about where compressed data is located for each image in a .basis file.
//    This is useful for when you want to extract the compressed data and embed it into your own file formats, for container independent transcoding.
//
// 2. Encoding (optional): See class basis_encoder. Encodes LDR .PNG or 32bpp images, or HDR half-float/float or .EXR/.HDR images to .basis/.ktx2 files in memory. 
//    Must compile with BASISU_SUPPORT_ENCODING=1.
//    Requires basisu_transcoder.cpp as well as all the .cpp files in the "encoder" directory. Results in a larger WebAssembly executable.
//
// 3. Low level transcoding/container independent transcoding: See class lowlevel_etc1s_image_transcoder or function transcodeUASTCImage(). 
//	  For transcoding raw compressed ETC1S/UASTC LDR/UASTC HDR texture data from non-.basis files (say from KTX2) to GPU texture data.
//
// 4. Helpers, transcoder texture format information: See functions getBytesPerBlockOrPixel(), formatHasAlpha(), etc.

// If BASISU_SUPPORT_ENCODING is 1, wrappers for the compressor will be included. Otherwise, only the wrappers for the transcoder will be compiled in.
#ifndef BASISU_SUPPORT_ENCODING
#define BASISU_SUPPORT_ENCODING 0
#endif

// Enable debug printf()'s in this module.
#ifndef BASISU_DEBUG_PRINTF
#define BASISU_DEBUG_PRINTF 0
#endif

#define BASISU_ENCODER_MAX_SOURCE_IMAGE_PIXELS (6291456)

#include "basisu_transcoder.h"
#include <algorithm>

#if BASISU_SUPPORT_ENCODING
#include "../../encoder/basisu_comp.h"
#include "../../encoder/basisu_astc_hdr_6x6_enc.h"
#include "../../encoder/basisu_resampler_filters.h"
#endif

#include <emscripten/bind.h>
#if BASISU_SUPPORT_ENCODING
#include <emscripten/threading.h>
#endif
#include <emscripten.h>

using namespace emscripten;
using namespace basist;
using namespace basisu;

static bool g_basis_initialized_flag;

// Global one-time initialization. MUST be called before using any other functionality.
void basis_init()
{
    static std::mutex s_init_mutex;
    std::lock_guard<std::mutex> lock(s_init_mutex);

#if BASISU_DEBUG_PRINTF
    printf("basis_init()\n");
#endif

    if (g_basis_initialized_flag)
        return;

#if BASISU_SUPPORT_ENCODING
    basisu_encoder_init();
#endif

    basisu_transcoder_init();

    g_basis_initialized_flag = true;
}

static void copy_from_jsbuffer(const emscripten::val& srcBuffer, basisu::vector<uint8_t>& dstVec)
{
    unsigned int length = srcBuffer["length"].as<unsigned int>();

    dstVec.resize(length);

    emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
    emscripten::val memoryView = srcBuffer["constructor"].new_(memory, reinterpret_cast<uintptr_t>(dstVec.data()), length);

    // Copy the bytes from the Javascript buffer.
    memoryView.call<void>("set", srcBuffer);
}

static bool copy_to_jsbuffer(const emscripten::val& dstBuffer, const basisu::vector<uint8_t>& srcVec)
{
    if (srcVec.empty())
    {
#if BASISU_DEBUG_PRINTF
        printf("copy_to_jsbuffer: Provided source buffer is empty\n");
#endif
        return false;
    }

    // Make sure the provided buffer from Javascript is big enough. If not, bail.
    int dstBufferLen = dstBuffer["byteLength"].as<int>();

    if (srcVec.size() > dstBufferLen)
    {
#if BASISU_DEBUG_PRINTF
        printf("copy_to_jsbuffer: Provided destination buffer is too small (wanted %u bytes, got %u bytes)!\n", (uint32_t)srcVec.size(), dstBufferLen);
#endif
        assert(0);
        return false;
    }

    emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
    emscripten::val memoryView = emscripten::val::global("Uint8Array").new_(memory, reinterpret_cast<uintptr_t>(srcVec.data()), srcVec.size());

    // Copy the bytes into the Javascript buffer.
    dstBuffer.call<void>("set", memoryView);

    return true;
}

const uint32_t BASIS_MAGIC = 0xD4ADBEA1;
const uint32_t KTX2_MAGIC = 0xD4ADBEF2;

struct basis_file_desc
{
    uint32_t m_version;

    uint32_t m_us_per_frame;

    uint32_t m_total_images;

    uint32_t m_userdata0;
    uint32_t m_userdata1;

    // Type of texture (cETC1S, cUASTC4x4, cUASTC_HDR_4x4, etc.)
    uint32_t m_tex_format; // basis_tex_format

    bool m_y_flipped;
    bool m_has_alpha_slices;

    // ETC1S endpoint codebook
    uint32_t m_num_endpoints;
    uint32_t m_endpoint_palette_ofs;
    uint32_t m_endpoint_palette_len;

    // ETC1S selector codebook
    uint32_t m_num_selectors;
    uint32_t m_selector_palette_ofs;
    uint32_t m_selector_palette_len;

    // Huffman codelength tables
    uint32_t m_tables_ofs;
    uint32_t m_tables_len;

    uint32_t m_block_width;
    uint32_t m_block_height;
};

struct basis_image_desc
{
    uint32_t m_orig_width;
    uint32_t m_orig_height;
    uint32_t m_num_blocks_x;
    uint32_t m_num_blocks_y;
    uint32_t m_num_levels;
    uint32_t m_block_width;
    uint32_t m_block_height;

    // Will be true if the image has alpha (for UASTC this may vary per-image)
    bool m_alpha_flag;
    bool m_iframe_flag;
};

struct basis_image_level_desc
{
    // File offset/length of the compressed ETC1S or UASTC LDR/HDR texture data.
    uint32_t m_rgb_file_ofs;
    uint32_t m_rgb_file_len;

    // Optional alpha data file offset/length - will be 0's for UASTC LDR/HDR or opaque ETC1S files.
    uint32_t m_alpha_file_ofs;
    uint32_t m_alpha_file_len;
};

struct basis_file
{
    int m_magic = 0;
    basisu_transcoder m_transcoder;
    basisu::vector<uint8_t> m_file;

    basis_file(const emscripten::val& jsBuffer)
        : m_file([&]() {
        size_t byteLength = jsBuffer["byteLength"].as<size_t>();
        return basisu::vector<uint8_t>(byteLength);
            }())
    {
        if (!g_basis_initialized_flag)
        {
#if BASISU_DEBUG_PRINTF
            printf("basis_file::basis_file: Must call basis_init() first!\n");
#endif
            assert(0);
            return;
        }

        unsigned int length = jsBuffer["length"].as<unsigned int>();
        emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
        emscripten::val memoryView = jsBuffer["constructor"].new_(memory, reinterpret_cast<uintptr_t>(m_file.data()), length);
        memoryView.call<void>("set", jsBuffer);

        if (!m_transcoder.validate_header(m_file.data(), m_file.size()))
        {
#if BASISU_DEBUG_PRINTF
            printf("basis_file::basis_file: m_transcoder.validate_header() failed!\n");
#endif
            m_file.clear();
        }

        // Initialized after validation
        m_magic = BASIS_MAGIC;
    }

    void close()
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return;

        m_file.clear();
    }

    uint32_t getHasAlpha()
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return 0;

        basisu_image_level_info li;
        if (!m_transcoder.get_image_level_info(m_file.data(), m_file.size(), li, 0, 0))
            return 0;

        return li.m_alpha_flag;
    }

    uint32_t getNumImages()
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return 0;

        return m_transcoder.get_total_images(m_file.data(), m_file.size());
    }

    uint32_t getNumLevels(uint32_t image_index)
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return 0;

        basisu_image_info ii;
        if (!m_transcoder.get_image_info(m_file.data(), m_file.size(), ii, image_index))
            return 0;

        return ii.m_total_levels;
    }

    uint32_t getImageWidth(uint32_t image_index, uint32_t level_index)
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return 0;

        uint32_t orig_width, orig_height, total_blocks;
        if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
            return 0;

        return orig_width;
    }

    uint32_t getImageHeight(uint32_t image_index, uint32_t level_index)
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return 0;

        uint32_t orig_width, orig_height, total_blocks;
        if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_blocks))
            return 0;

        return orig_height;
    }

    // Returns a basis_tex_format (cETC1S, cUASTC, cUASTC_HDR_4x4, etc.)
    uint32_t getBasisTexFormat()
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return false;

        basis_tex_format fmt = m_transcoder.get_basis_tex_format(m_file.data(), m_file.size());
        return (uint32_t)fmt;
    }

    // Currently 4 or 6
    uint32_t getBlockWidth() const
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return false;

        basis_tex_format fmt = m_transcoder.get_basis_tex_format(m_file.data(), m_file.size());
        return basis_tex_format_get_block_width(fmt);
    }

    // Currently 4 or 6
    uint32_t getBlockHeight()
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return false;

        basis_tex_format fmt = m_transcoder.get_basis_tex_format(m_file.data(), m_file.size());
        return basis_tex_format_get_block_height(fmt);
    }

    basis_file_desc getFileDesc()
    {
        basis_file_desc result;
        memset(&result, 0, sizeof(result));

        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return result;

        basisu_file_info file_info;

        if (!m_transcoder.get_file_info(m_file.data(), m_file.size(), file_info))
        {
            assert(0);
            return result;
        }

        result.m_version = file_info.m_version;
        result.m_us_per_frame = file_info.m_us_per_frame;
        result.m_total_images = file_info.m_total_images;
        result.m_userdata0 = file_info.m_userdata0;
        result.m_userdata1 = file_info.m_userdata1;
        result.m_tex_format = static_cast<uint32_t>(file_info.m_tex_format);
        result.m_y_flipped = file_info.m_y_flipped;
        result.m_has_alpha_slices = file_info.m_has_alpha_slices;

        result.m_num_endpoints = file_info.m_total_endpoints;
        result.m_endpoint_palette_ofs = file_info.m_endpoint_codebook_ofs;
        result.m_endpoint_palette_len = file_info.m_endpoint_codebook_size;

        result.m_num_selectors = file_info.m_total_selectors;
        result.m_selector_palette_ofs = file_info.m_selector_codebook_ofs;
        result.m_selector_palette_len = file_info.m_selector_codebook_size;

        result.m_tables_ofs = file_info.m_tables_ofs;
        result.m_tables_len = file_info.m_tables_size;

        result.m_block_width = file_info.m_block_width;
        result.m_block_height = file_info.m_block_height;

        return result;
    }

    basis_image_desc getImageDesc(uint32_t image_index)
    {
        basis_image_desc result;
        memset(&result, 0, sizeof(result));

        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return result;

        basisu_image_info image_info;

        // bool get_image_info(const void *pData, uint32_t data_size, basisu_image_info &image_info, uint32_t image_index) const;
        if (!m_transcoder.get_image_info(m_file.data(), m_file.size(), image_info, image_index))
        {
            assert(0);
            return result;
        }

        result.m_orig_width = image_info.m_orig_width;
        result.m_orig_height = image_info.m_orig_height;
        result.m_num_blocks_x = image_info.m_num_blocks_x;
        result.m_num_blocks_y = image_info.m_num_blocks_y;
        result.m_num_levels = image_info.m_total_levels;
        result.m_alpha_flag = image_info.m_alpha_flag;
        result.m_iframe_flag = image_info.m_iframe_flag;
        result.m_block_width = image_info.m_block_width;
        result.m_block_height = image_info.m_block_height;

        return result;
    }

    basis_image_level_desc getImageLevelDesc(uint32_t image_index, uint32_t level_index)
    {
        basis_image_level_desc result;
        memset(&result, 0, sizeof(result));

        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return result;

        basisu_image_level_info image_info;

        if (!m_transcoder.get_image_level_info(m_file.data(), m_file.size(), image_info, image_index, level_index))
        {
            assert(0);
            return result;
        }

        result.m_rgb_file_ofs = image_info.m_rgb_file_ofs;
        result.m_rgb_file_len = image_info.m_rgb_file_len;
        result.m_alpha_file_ofs = image_info.m_alpha_file_ofs;
        result.m_alpha_file_len = image_info.m_alpha_file_len;

        return result;
    }

    uint32_t getImageTranscodedSizeInBytes(uint32_t image_index, uint32_t level_index, uint32_t format)
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return 0;
                
        if (format >= (int)transcoder_texture_format::cTFTotalTextureFormats)
        {
            assert(0);
            return 0;
        }

        const transcoder_texture_format tex_format = static_cast<transcoder_texture_format>(format);
                        
        uint32_t orig_width, orig_height, total_src_blocks;
        if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_src_blocks))
        {
            assert(0);
            return 0;
        }

        return basis_compute_transcoded_image_size_in_bytes(tex_format, orig_width, orig_height);
    }

    // Only true for UASTC LDR 4x4.
    bool isUASTC_LDR_4x4()
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return false;

        return m_transcoder.get_basis_tex_format(m_file.data(), m_file.size()) == basis_tex_format::cUASTC4x4;
    }

    bool isETC1S()
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return false;

        return m_transcoder.get_basis_tex_format(m_file.data(), m_file.size()) == basis_tex_format::cETC1S;
    }

    // True for any LDR texture types
    bool isLDR()
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return false;

        basis_tex_format fmt = m_transcoder.get_basis_tex_format(m_file.data(), m_file.size());
        return (fmt == basis_tex_format::cETC1S) || (fmt == basis_tex_format::cUASTC4x4);
    }
        
	// True if the texture is UASTC HDR 4x4 or ASTC HDR 6x6.
    // In this case, it can only be transcoded to BC6H, ASTC HDR (of the same block dimensions, currently 4x4 or 6x6), RGB9E5 or half-float RGB/RGBA images.
    bool isHDR()
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return false;

        basis_tex_format fmt = m_transcoder.get_basis_tex_format(m_file.data(), m_file.size());
        return basis_tex_format_is_hdr(fmt);
    }
        
    bool isHDR4x4()
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return false;

        basis_tex_format fmt = m_transcoder.get_basis_tex_format(m_file.data(), m_file.size());
        return (fmt == basis_tex_format::cUASTC_HDR_4x4);
    }

    bool isHDR6x6()
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return false;

        basis_tex_format fmt = m_transcoder.get_basis_tex_format(m_file.data(), m_file.size());
        return (fmt == basis_tex_format::cASTC_HDR_6x6) || (fmt == basis_tex_format::cASTC_HDR_6x6_INTERMEDIATE);
    }
        
    uint32_t startTranscoding()
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return 0;

        return m_transcoder.start_transcoding(m_file.data(), m_file.size());
    }

    // Here for backwards compat, prefer transcodeImageWithFlags().
    uint32_t transcodeImage(const emscripten::val& dst, uint32_t image_index, uint32_t level_index, uint32_t format, uint32_t unused, uint32_t get_alpha_for_opaque_formats)
    {
        (void)unused;

        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return 0;

        if (format >= (int)transcoder_texture_format::cTFTotalTextureFormats)
            return 0;

        const transcoder_texture_format transcoder_format = static_cast<transcoder_texture_format>(format);
                
        uint32_t orig_width, orig_height, total_src_blocks;
        if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_src_blocks))
            return 0;

        basisu::vector<uint8_t> dst_data;

        uint32_t flags = get_alpha_for_opaque_formats ? cDecodeFlagsTranscodeAlphaDataToOpaqueFormats : 0;
                
        const uint32_t transcoded_size_in_bytes = getImageTranscodedSizeInBytes(image_index, level_index, format);

        dst_data.resize(transcoded_size_in_bytes);

        uint32_t status;

        if (basis_transcoder_format_is_uncompressed(transcoder_format))
        {
            status = m_transcoder.transcode_image_level(
                m_file.data(), m_file.size(), image_index, level_index,
                dst_data.data(), orig_width * orig_height,
                transcoder_format,
                flags,
                orig_width,
                nullptr,
                orig_height);
        }
        else
        {
            const uint32_t bytes_per_block = basis_get_bytes_per_block_or_pixel(transcoder_format);

            status = m_transcoder.transcode_image_level(
                m_file.data(), m_file.size(), image_index, level_index,
                dst_data.data(), dst_data.size() / bytes_per_block,
                static_cast<basist::transcoder_texture_format>(format),
                flags);
        }

        emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
        emscripten::val memoryView = emscripten::val::global("Uint8Array").new_(memory, reinterpret_cast<uintptr_t>(dst_data.data()), dst_data.size());

        dst.call<void>("set", memoryView);
        return status;
    }
    
    // Like transcodeImage(), but with fixed parameters.
    // For flags, see cDecodeFlagsPVRTCDecodeToNextPow2 etc.
    uint32_t transcodeImageWithFlags(const emscripten::val& dst, uint32_t image_index, uint32_t level_index, uint32_t format, uint32_t flags)
    {
        assert(m_magic == BASIS_MAGIC);
        if (m_magic != BASIS_MAGIC)
            return 0;

        if (format >= (int)transcoder_texture_format::cTFTotalTextureFormats)
            return 0;

        const transcoder_texture_format transcoder_format = static_cast<transcoder_texture_format>(format);
                
        uint32_t orig_width, orig_height, total_src_blocks;
        if (!m_transcoder.get_image_level_desc(m_file.data(), m_file.size(), image_index, level_index, orig_width, orig_height, total_src_blocks))
            return 0;

        basisu::vector<uint8_t> dst_data;
                
        const uint32_t transcoded_size_in_bytes = getImageTranscodedSizeInBytes(image_index, level_index, format);

        dst_data.resize(transcoded_size_in_bytes);

        uint32_t status;

        if (basis_transcoder_format_is_uncompressed(transcoder_format))
        {
            status = m_transcoder.transcode_image_level(
                m_file.data(), m_file.size(), image_index, level_index,
                dst_data.data(), orig_width * orig_height,
                transcoder_format,
                flags,
                orig_width,
                nullptr,
                orig_height);
        }
        else
        {
            const uint32_t bytes_per_block = basis_get_bytes_per_block_or_pixel(transcoder_format);

            status = m_transcoder.transcode_image_level(
                m_file.data(), m_file.size(), image_index, level_index,
                dst_data.data(), dst_data.size() / bytes_per_block,
                static_cast<basist::transcoder_texture_format>(format),
                flags);
        }

        emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
        emscripten::val memoryView = emscripten::val::global("Uint8Array").new_(memory, reinterpret_cast<uintptr_t>(dst_data.data()), dst_data.size());

        dst.call<void>("set", memoryView);
        return status;
    }
};

#if BASISD_SUPPORT_KTX2
struct ktx2_header_js
{
    uint32_t m_vk_format;
    uint32_t m_type_size;
    uint32_t m_pixel_width;
    uint32_t m_pixel_height;
    uint32_t m_pixel_depth;
    uint32_t m_layer_count;
    uint32_t m_face_count;
    uint32_t m_level_count;
    uint32_t m_supercompression_scheme;
    uint32_t m_dfd_byte_offset;
    uint32_t m_dfd_byte_length;
    uint32_t m_kvd_byte_offset;
    uint32_t m_kvd_byte_length;
    uint32_t m_sgd_byte_offset;
    uint32_t m_sgd_byte_length;
};

struct ktx2_file
{
    int m_magic = 0;
    basist::ktx2_transcoder m_transcoder;
    basisu::vector<uint8_t> m_file;
    bool m_is_valid = false;

    ktx2_file(const emscripten::val& jsBuffer)
        : m_file([&]() {
        size_t byteLength = jsBuffer["byteLength"].as<size_t>();
        return basisu::vector<uint8_t>(byteLength);
            }())
    {
        if (!g_basis_initialized_flag)
        {
#if BASISU_DEBUG_PRINTF
            printf("basis_file::basis_file: Must call basis_init() first!\n");
#endif
            assert(0);
            return;
        }

        unsigned int length = jsBuffer["length"].as<unsigned int>();
        emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
        emscripten::val memoryView = jsBuffer["constructor"].new_(memory, reinterpret_cast<uintptr_t>(m_file.data()), length);
        memoryView.call<void>("set", jsBuffer);

        if (!m_transcoder.init(m_file.data(), m_file.size()))
        {
#if BASISU_DEBUG_PRINTF
            printf("m_transcoder.init() failed!\n");
#endif
            assert(0);

            m_file.clear();
        }

        m_is_valid = true;

        // Initialized after validation
        m_magic = KTX2_MAGIC;
    }

    bool isValid()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return false;

        return m_is_valid;
    }

    void close()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return;

        m_file.clear();
        m_transcoder.clear();
    }

    uint32_t getDFDSize()
    {
        return m_transcoder.get_dfd().size();
    }

    uint32_t getDFD(const emscripten::val& dst)
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;

        const uint8_vec &dst_data = m_transcoder.get_dfd();

        if (dst_data.size())
            return copy_to_jsbuffer(dst, dst_data);

        return 1;
    }

    ktx2_header_js getHeader()
    {
        ktx2_header_js hdr;
        memset(&hdr, 0, sizeof(hdr));

        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return hdr;

        const basist::ktx2_header& h = m_transcoder.get_header();

        hdr.m_vk_format = h.m_vk_format;
        hdr.m_type_size = h.m_type_size;
        hdr.m_pixel_width = h.m_pixel_width;
        hdr.m_pixel_height = h.m_pixel_height;
        hdr.m_pixel_depth = h.m_pixel_depth;
        hdr.m_layer_count = h.m_layer_count;
        hdr.m_face_count = h.m_face_count;
        hdr.m_level_count = h.m_level_count;
        hdr.m_supercompression_scheme = h.m_supercompression_scheme;
        hdr.m_dfd_byte_offset = h.m_dfd_byte_offset;
        hdr.m_dfd_byte_length = h.m_dfd_byte_length;
        hdr.m_kvd_byte_offset = h.m_kvd_byte_offset;
        hdr.m_kvd_byte_length = h.m_kvd_byte_length;

        // emscripten doesn't support binding uint64_t for some reason
        assert(h.m_sgd_byte_offset <= UINT32_MAX);
        assert(h.m_sgd_byte_length <= UINT32_MAX);
        hdr.m_sgd_byte_offset = (uint32_t)h.m_sgd_byte_offset;
        hdr.m_sgd_byte_length = (uint32_t)h.m_sgd_byte_length;

        return hdr;
    }

    bool hasKey(std::string key_name)
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return false;

        return m_transcoder.find_key(key_name) != nullptr;
    }

    uint32_t getTotalKeys()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;

        return m_transcoder.get_key_values().size();
    }

    std::string getKey(uint32_t index)
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return std::string("");

        return std::string((const char*)m_transcoder.get_key_values()[index].m_key.data());
    }

    uint32_t getKeyValueSize(std::string key_name)
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;

        const uint8_vec* p = m_transcoder.find_key(key_name);
        return p ? p->size() : 0;
    }

    uint32_t getKeyValue(std::string key_name, const emscripten::val& dst)
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;

        const uint8_vec* p = m_transcoder.find_key(key_name);
        if (!p)
            return 0;

        if (p->size())
            return copy_to_jsbuffer(dst, *p);

        return 1;
    }

    uint32_t getWidth()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return m_transcoder.get_width();
    }

    uint32_t getHeight()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return m_transcoder.get_height();
    }

    uint32_t getBlockWidth()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return m_transcoder.get_block_width();
    }

    uint32_t getBlockHeight()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return m_transcoder.get_block_height();
    }

    uint32_t getFaces()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return m_transcoder.get_faces();
    }

    uint32_t getLayers()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return m_transcoder.get_layers();
    }

    uint32_t getLevels()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return m_transcoder.get_levels();
    }

	// Returns a basis_tex_format: cETC1S, cUASTC4x4, or cUASTC_HDR_4x4, etc.
    uint32_t getBasisTexFormat()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return (uint32_t)m_transcoder.get_basis_tex_format();
    }

	// Returns true if the texture is UASTC LDR 4x4 (and not HDR - see isHDR()).
    bool isUASTC_LDR_4x4()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return false;
        return m_transcoder.is_uastc();
    }

    // Returns true if the texture is UASTC LDR 4x4 (and not HDR - see isHDR()).
    bool isUASTC()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return false;
        return m_transcoder.is_uastc();
    }

    bool isLDR()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return false;
        return !m_transcoder.is_hdr();
    }

    bool isETC1S()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return false;
        return m_transcoder.is_etc1s();
    }

	// Returns true if the texture is UASTC HDR or ASTC HDR. In this case, it can only be transcoded to BC6H, ASTC HDR (of the same block dimensions), RGB9E5 or half-float RGB/RGBA images.	
	bool isHDR()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return false;
        return m_transcoder.is_hdr();
    }

    bool isHDR4x4()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return false;
        return m_transcoder.is_hdr_4x4();
    }

    bool isHDR6x6()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return false;
        return m_transcoder.is_hdr_6x6();
    }

    bool getHasAlpha()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return false;
        return m_transcoder.get_has_alpha();
    }

    uint32_t getDFDColorModel()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return m_transcoder.get_dfd_color_model();
    }

    uint32_t getDFDColorPrimaries()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return m_transcoder.get_dfd_color_primaries();
    }

    uint32_t getDFDTransferFunc()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return m_transcoder.get_dfd_transfer_func();
    }

    uint32_t getDFDFlags()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return m_transcoder.get_dfd_flags();
    }

    uint32_t getDFDTotalSamples()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return m_transcoder.get_dfd_total_samples();
    }

    uint32_t getDFDChannelID0()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return m_transcoder.get_dfd_channel_id0();
    }

    uint32_t getDFDChannelID1()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return m_transcoder.get_dfd_channel_id1();
    }

    // isVideo() will return true if there was a KTXanimData key, or if (after calling start_transcoding()) there were any P-frames on ETC1S files.
    bool isVideo()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return m_transcoder.is_video();
    }

    float getLDRHDRUpconversionNitMultiplier()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;
        return m_transcoder.get_ldr_hdr_upconversion_nit_multiplier();
    }

    // startTranscoding() must be called before calling getETC1SImageDescImageFlags().
    uint32_t getETC1SImageDescImageFlags(uint32_t level_index, uint32_t layer_index, uint32_t face_index)
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;

        return m_transcoder.get_etc1s_image_descs_image_flags(level_index, layer_index, face_index);
    }

    ktx2_image_level_info getImageLevelInfo(uint32_t level_index, uint32_t layer_index, uint32_t face_index)
    {
        ktx2_image_level_info info;
        memset(&info, 0, sizeof(info));

        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return info;

        if (!m_transcoder.get_image_level_info(info, level_index, layer_index, face_index))
        {
            assert(0);
            return info;
        }

        return info;
    }

    uint32_t getImageTranscodedSizeInBytes(uint32_t level_index, uint32_t layer_index, uint32_t face_index, uint32_t format)
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;

        if (format >= (int)transcoder_texture_format::cTFTotalTextureFormats)
        {
            assert(0);
            return 0;
        }

        const transcoder_texture_format tex_format = static_cast<transcoder_texture_format>(format);
                
        ktx2_image_level_info info;
        if (!m_transcoder.get_image_level_info(info, level_index, layer_index, face_index))
        {
            assert(0);
            return 0;
        }

        return basis_compute_transcoded_image_size_in_bytes(tex_format, info.m_orig_width, info.m_orig_height);
    }

    // Must be called before transcodeImage() can be called.
    // On ETC1S files this method decompresses the ETC1S global data, along with fetching the ETC1S image desc array, so it's not free to call.
    uint32_t startTranscoding()
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;

        return m_transcoder.start_transcoding();
    }

    // Here for backwards compat, prefer transcodeImageWithFlags().
    // get_alpha_for_opaque_formats defaults to false
    // channel0/channel1 default to -1
    uint32_t transcodeImage(const emscripten::val& dst, uint32_t level_index, uint32_t layer_index, uint32_t face_index, uint32_t format, uint32_t get_alpha_for_opaque_formats, int channel0, int channel1)
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;

        if (format >= (int)transcoder_texture_format::cTFTotalTextureFormats)
            return 0;

        const transcoder_texture_format transcoder_format = static_cast<transcoder_texture_format>(format);

        const uint32_t dst_block_width = basis_get_block_width(transcoder_format);
        const uint32_t dst_block_height = basis_get_block_height(transcoder_format);
                
        ktx2_image_level_info info;
        if (!m_transcoder.get_image_level_info(info, level_index, layer_index, face_index))
            return 0;

        uint32_t orig_width = info.m_orig_width, orig_height = info.m_orig_height, total_src_blocks = info.m_total_blocks;

        basisu::vector<uint8_t> dst_data;

        uint32_t flags = get_alpha_for_opaque_formats ? cDecodeFlagsTranscodeAlphaDataToOpaqueFormats : 0;

        const uint32_t transcoded_size_in_bytes = getImageTranscodedSizeInBytes(level_index, layer_index, face_index, format);

        dst_data.resize(transcoded_size_in_bytes);

        uint32_t status;

        if (basis_transcoder_format_is_uncompressed(transcoder_format))
        {
            status = m_transcoder.transcode_image_level(
                level_index, layer_index, face_index,
                dst_data.data(), orig_width * orig_height,
                transcoder_format,
                flags,
                orig_width,
                orig_height,
                channel0, channel1,
                nullptr);
        }
        else
        {
            const uint32_t bytes_per_block = basis_get_bytes_per_block_or_pixel(transcoder_format);

            status = m_transcoder.transcode_image_level(
                level_index, layer_index, face_index,
                dst_data.data(), dst_data.size() / bytes_per_block,
                static_cast<basist::transcoder_texture_format>(format),
                flags,
                0,
                0,
                channel0, channel1,
                nullptr);
        }

        emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
        emscripten::val memoryView = emscripten::val::global("Uint8Array").new_(memory, reinterpret_cast<uintptr_t>(dst_data.data()), dst_data.size());

        dst.call<void>("set", memoryView);
        return status;
    }
    
    // like transcodeImage(), but with fixed parameters (includes flags)
    // For flags, see cDecodeFlagsPVRTCDecodeToNextPow2 etc.
    uint32_t transcodeImageWithFlags(const emscripten::val& dst, uint32_t level_index, uint32_t layer_index, uint32_t face_index, uint32_t format, uint32_t flags, int channel0, int channel1)
    {
        assert(m_magic == KTX2_MAGIC);
        if (m_magic != KTX2_MAGIC)
            return 0;

        if (format >= (int)transcoder_texture_format::cTFTotalTextureFormats)
            return 0;
                
        const transcoder_texture_format transcoder_format = static_cast<transcoder_texture_format>(format);

        const uint32_t dst_block_width = basis_get_block_width(transcoder_format);
        const uint32_t dst_block_height = basis_get_block_height(transcoder_format);
                
        ktx2_image_level_info info;
        if (!m_transcoder.get_image_level_info(info, level_index, layer_index, face_index))
            return 0;

        uint32_t orig_width = info.m_orig_width, orig_height = info.m_orig_height, total_src_blocks = info.m_total_blocks;

        basisu::vector<uint8_t> dst_data;

        const uint32_t transcoded_size_in_bytes = getImageTranscodedSizeInBytes(level_index, layer_index, face_index, format);

        dst_data.resize(transcoded_size_in_bytes);

        uint32_t status;

        if (basis_transcoder_format_is_uncompressed(transcoder_format))
        {
            status = m_transcoder.transcode_image_level(
                level_index, layer_index, face_index,
                dst_data.data(), orig_width * orig_height,
                transcoder_format,
                flags,
                orig_width,
                orig_height,
                channel0, channel1,
                nullptr);
        }
        else
        {
            const uint32_t bytes_per_block = basis_get_bytes_per_block_or_pixel(transcoder_format);

            status = m_transcoder.transcode_image_level(
                level_index, layer_index, face_index,
                dst_data.data(), dst_data.size() / bytes_per_block,
                static_cast<basist::transcoder_texture_format>(format),
                flags,
                0,
                0,
                channel0, channel1,
                nullptr);
        }

        emscripten::val memory = emscripten::val::module_property("HEAP8")["buffer"];
        emscripten::val memoryView = emscripten::val::global("Uint8Array").new_(memory, reinterpret_cast<uintptr_t>(dst_data.data()), dst_data.size());

        dst.call<void>("set", memoryView);
        return status;
    }

};
#endif // BASISD_SUPPORT_KTX2

#if BASISU_SUPPORT_ENCODING

enum class ldr_image_type
{
    cRGBA32 = 0,
    cPNGImage = 1,
    cJPGImage = 2
};

class basis_encoder
{
    bool m_threading_enabled = false;
    uint32_t m_num_extra_worker_threads = 0;

public:
    basis_compressor_params m_params;

    basis_encoder()
    {
    }

    void control_threading(bool enabled_flag, uint32_t num_extra_worker_threads)
    {
        m_threading_enabled = enabled_flag;
        m_num_extra_worker_threads = num_extra_worker_threads;
    }

	// Only works for LDR inputs.
    bool set_slice_source_image(uint32_t slice_index, const emscripten::val& src_image_js_val, uint32_t src_image_width, uint32_t src_image_height, ldr_image_type img_type)
    {
        // Resize the source_images array if necessary
        if (slice_index >= m_params.m_source_images.size())
            m_params.m_source_images.resize(slice_index + 1);

        // First copy the src image buffer to the heap.
        basisu::vector<uint8_t> src_image_buf;
        copy_from_jsbuffer(src_image_js_val, src_image_buf);

        // Now load the source image.
        image& src_img = m_params.m_source_images[slice_index];
        if (img_type == ldr_image_type::cPNGImage)
        {
            // It's a PNG file, so try and parse it.
            if (!load_png(src_image_buf.data(), src_image_buf.size(), src_img, nullptr))
            {
#if BASISU_DEBUG_PRINTF
                printf("basis_encoder::set_slice_source_image: Failed parsing provided PNG file!\n");
#endif
                return false;
            }

            src_image_width = src_img.get_width();
            src_image_height = src_img.get_height();
        }
        else if (img_type == ldr_image_type::cJPGImage)
        {
            // It's a JPG file, so try and parse it.
            if (!load_jpg(src_image_buf.data(), src_image_buf.size(), src_img))
            {
#if BASISU_DEBUG_PRINTF
                printf("basis_encoder::set_slice_source_image: Failed parsing provided JPG file!\n");
#endif
                return false;
            }

            src_image_width = src_img.get_width();
            src_image_height = src_img.get_height();
        }
        else if (img_type == ldr_image_type::cRGBA32)
        {
            // It's a raw image, so check the buffer's size.
            if (src_image_buf.size() != src_image_width * src_image_height * sizeof(uint32_t))
            {
#if BASISU_DEBUG_PRINTF
                printf("basis_encoder::set_slice_source_image: Provided source buffer has an invalid size!\n");
#endif
                return false;
            }

            // Copy the raw image's data into our source image.
            src_img.resize(src_image_width, src_image_height);
            memcpy(src_img.get_ptr(), src_image_buf.data(), src_image_width * src_image_height * sizeof(uint32_t));
        }
        else
        {
#if BASISU_DEBUG_PRINTF
            printf("basis_encoder::set_slice_source_image: Invalid img_type parameter\n");
#endif
            assert(0);
            return false;
        }

        return true;
    }

	// Accepts RGBA half float or RGBA float images, or .EXR, .HDR, .PNG, or .JPG file data.
    bool set_slice_source_image_hdr(
        uint32_t slice_index,
        const emscripten::val& src_image_js_val,
        uint32_t src_image_width, uint32_t src_image_height,
        hdr_image_type img_type, bool ldr_srgb_to_linear_conversion, float ldr_to_hdr_nit_multiplier)
    {
        assert(ldr_to_hdr_nit_multiplier > 0.0f);
                
        // Resize the source_images_hdr array if necessary
        if (slice_index >= m_params.m_source_images_hdr.size())
            m_params.m_source_images_hdr.resize(slice_index + 1);

        // First copy the src image buffer to the heap.
        basisu::vector<uint8_t> src_image_buf;
        copy_from_jsbuffer(src_image_js_val, src_image_buf);

        // Now load the source image.
        imagef& src_img = m_params.m_source_images_hdr[slice_index];

        if (!load_image_hdr(src_image_buf.get_ptr(), src_image_buf.size(), src_img, src_image_width, src_image_height, img_type, ldr_srgb_to_linear_conversion, ldr_to_hdr_nit_multiplier))
            return false;

        if ((img_type == hdr_image_type::cHITPNGImage) || (img_type == hdr_image_type::cHITJPGImage))
        {
            // Because we're loading the image ourselves we need to add these tags so the UI knows how to tone map LDR upconverted outputs. 
            // Normally basis_compressor adds them when it loads the images itself from source files.
            basist::ktx2_add_key_value(m_params.m_ktx2_key_values, "LDRUpconversionMultiplier", fmt_string("{}", ldr_to_hdr_nit_multiplier));

            if (ldr_srgb_to_linear_conversion)
                basist::ktx2_add_key_value(m_params.m_ktx2_key_values, "LDRUpconversionSRGBToLinear", "1");
        }
                		
        return true;
    }

    uint32_t encode(const emscripten::val& dst_basis_file_js_val)
    {
        if (!g_basis_initialized_flag)
        {
#if BASISU_DEBUG_PRINTF
            printf("basis_encoder::encode: Must call basis_init() first!\n");
#endif
            assert(0);
            return 0;
        }

        // We don't use threading for now, but the compressor needs a job pool.
        uint32_t num_new_threads = 0;
        bool enable_threading = false;
        
#if WASM_THREADS_ENABLED
        if ((emscripten_has_threading_support()) && (m_threading_enabled) && (m_num_extra_worker_threads))
        {
            enable_threading = true;
            num_new_threads = m_num_extra_worker_threads;
        }
#endif

        // We always need a job pool, but making a job pool with just 1 thread doesn't actually create any additional helper threads (i.e. it always utilizes the main thread).
        job_pool jpool(1 + num_new_threads);

        // Initialize the compression parameters structure. This is the same structure that the command line tool fills in.
        basis_compressor_params &params = m_params;
        
        // Check to see if we would risk running out of memory in 32-bit WASM. There's not much we can do about this limit until memory64 is available.
        uint64_t total_src_texels = 0;
        
        for (uint32_t i = 0; i < m_params.m_source_images.size(); i++)
            total_src_texels += m_params.m_source_images[i].get_total_pixels();

        for (uint32_t i = 0; i < m_params.m_source_images_hdr.size(); i++)
            total_src_texels += m_params.m_source_images_hdr[i].get_total_pixels();
                
        if (total_src_texels > BASISU_ENCODER_MAX_SOURCE_IMAGE_PIXELS)
        {
            printf("ERROR: basis_encoder::encode(): The total number of source texels to compress is too large for 32-bit WASM (above BASISU_ENCODER_MAX_SOURCE_IMAGE_PIXELS in basis_wrappers.cpp)." 
                "This is not a fundamental limitation of the library, but of WASM. Processing images this large risks running out of memory until WASM memory64 is available.\n");
            return 0;
        }

        params.m_pJob_pool = &jpool;

        params.m_multithreading = enable_threading;

        params.m_status_output = params.m_debug;

        params.m_read_source_images = false;
        params.m_write_output_basis_or_ktx2_files = false;

        basis_compressor comp;

        if (!comp.init(params))
        {
#if BASISU_DEBUG_PRINTF
            printf("Failed initializing BasisU compressor! One or more provided parameters may be invalid.\n");
#endif
            return 0;
        }

#if BASISU_DEBUG_PRINTF
        printf("Begin BasisU compression\n");
#endif

        basis_compressor::error_code ec = comp.process();

#if BASISU_DEBUG_PRINTF
        printf("BasisU compression done, status %u, %u bytes\n", (uint32_t)ec, (uint32_t)comp.get_output_basis_file().size());
#endif

        if (ec != basis_compressor::cECSuccess)
        {
            // Something failed during compression.
#if BASISU_DEBUG_PRINTF
            printf("BasisU compression failed with status %u!\n", (uint32_t)ec);
#endif
            return 0;
        }

        if (params.m_create_ktx2_file)
        {
            // Compression succeeded, so copy the .ktx2 file bytes to the caller's buffer.
            if (!copy_to_jsbuffer(dst_basis_file_js_val, comp.get_output_ktx2_file()))
                return 0;

            // Return the file size of the .basis file in bytes.
            return (uint32_t)comp.get_output_ktx2_file().size();
        }
        else
        {
            // Compression succeeded, so copy the .basis file bytes to the caller's buffer.
            if (!copy_to_jsbuffer(dst_basis_file_js_val, comp.get_output_basis_file()))
                return 0;

            // Return the file size of the .basis file in bytes.
            return (uint32_t)comp.get_output_basis_file().size();
        }
    }
};
#endif

class lowlevel_etc1s_image_transcoder : public basisu_lowlevel_etc1s_transcoder
{
    // Using our own transcoder state, for video support.
    basisu_transcoder_state m_state;

public:
    lowlevel_etc1s_image_transcoder()
    {
    }

    bool decode_palettes(uint32_t num_endpoints, const emscripten::val& endpoint_data, uint32_t num_selectors, const emscripten::val& selector_data)
    {
        basisu::vector<uint8_t> temp_endpoint_data, temp_selector_data;
        copy_from_jsbuffer(endpoint_data, temp_endpoint_data);
        copy_from_jsbuffer(selector_data, temp_selector_data);

#if 0
        printf("decode_palettes: %u %u %u %u, %u %u\n",
            num_endpoints, (uint32_t)temp_endpoint_data.size(),
            num_selectors, (uint32_t)temp_selector_data.size(),
            temp_endpoint_data[0], temp_selector_data[0]);
#endif

        if (!temp_endpoint_data.size() || !temp_selector_data.size())
        {
#if BASISU_DEBUG_PRINTF
            printf("decode_tables: endpoint_data and/or selector_data is empty\n");
#endif
            assert(0);
            return false;
        }

        return basisu_lowlevel_etc1s_transcoder::decode_palettes(num_endpoints, &temp_endpoint_data[0], (uint32_t)temp_endpoint_data.size(),
            num_selectors, &temp_selector_data[0], (uint32_t)temp_selector_data.size());
    }

    bool decode_tables(const emscripten::val& table_data)
    {
        basisu::vector<uint8_t> temp_table_data;
        copy_from_jsbuffer(table_data, temp_table_data);

        if (!temp_table_data.size())
        {
#if BASISU_DEBUG_PRINTF
            printf("decode_tables: table_data is empty\n");
#endif
            assert(0);
            return false;
        }

        return basisu_lowlevel_etc1s_transcoder::decode_tables(&temp_table_data[0], (uint32_t)temp_table_data.size());
    }

    bool transcode_image(
        uint32_t target_format, // see transcoder_texture_format
        const emscripten::val& output_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels,
        const emscripten::val& compressed_data,
        uint32_t num_blocks_x, uint32_t num_blocks_y, uint32_t orig_width, uint32_t orig_height, uint32_t level_index,
        uint32_t rgb_offset, uint32_t rgb_length, uint32_t alpha_offset, uint32_t alpha_length,
        uint32_t decode_flags, // see cDecodeFlagsPVRTCDecodeToNextPow2 etc.
        bool basis_file_has_alpha_slices,
        bool is_video,
        uint32_t output_row_pitch_in_blocks_or_pixels,
        uint32_t output_rows_in_pixels)
    {
        if (!g_basis_initialized_flag)
        {
#if BASISU_DEBUG_PRINTF
            printf("transcode_etc1s_image: basis_init() must be called first\n");
#endif
            assert(0);
            return false;
        }

        // FIXME: Access the JavaScript buffer directly vs. copying it.
        basisu::vector<uint8_t> temp_comp_data;
        copy_from_jsbuffer(compressed_data, temp_comp_data);

        if (!temp_comp_data.size())
        {
#if BASISU_DEBUG_PRINTF
            printf("transcode_etc1s_image: compressed_data is empty\n");
#endif
            assert(0);
            return false;
        }

        uint32_t output_blocks_len = output_blocks["byteLength"].as<uint32_t>();
        if (!output_blocks_len)
        {
#if BASISU_DEBUG_PRINTF
            printf("transcode_etc1s_image: output_blocks is empty\n");
#endif
            assert(0);
            return false;
        }

        basisu::vector<uint8_t> temp_output_blocks(output_blocks_len);

        bool status = basisu_lowlevel_etc1s_transcoder::transcode_image(
            (transcoder_texture_format)target_format,
            &temp_output_blocks[0], output_blocks_buf_size_in_blocks_or_pixels,
            &temp_comp_data[0], temp_comp_data.size(),
            num_blocks_x, num_blocks_y, orig_width, orig_height, level_index,
            rgb_offset, rgb_length, alpha_offset, alpha_length,
            decode_flags,
            basis_file_has_alpha_slices,
            is_video,
            output_row_pitch_in_blocks_or_pixels,
            &m_state,
            output_rows_in_pixels);

        if (!status)
        {
#if BASISU_DEBUG_PRINTF
            printf("transcode_etc1s_image: basisu_lowlevel_etc1s_transcoder::transcode_image failed\n");
#endif
            assert(0);
            return false;
        }

        if (!copy_to_jsbuffer(output_blocks, temp_output_blocks))
            return false;

        return true;
    }
};

// Supports UASTC LDR 4x4, UASTC HDR 4x4, and ASTC HDR 6x6/intermediate (but not ETC1S).
bool transcode_uastc_image(
    uint32_t basis_tex_format_int, 
    uint32_t target_format_int, // see transcoder_texture_format
    const emscripten::val& output_blocks, uint32_t output_blocks_buf_size_in_blocks_or_pixels,
    const emscripten::val& compressed_data,
    uint32_t num_blocks_x, uint32_t num_blocks_y, uint32_t orig_width, uint32_t orig_height, uint32_t level_index,
    uint32_t slice_offset, uint32_t slice_length,
    uint32_t decode_flags, // see cDecodeFlagsPVRTCDecodeToNextPow2 etc.
    bool has_alpha,
    bool is_video,
    uint32_t output_row_pitch_in_blocks_or_pixels,
    uint32_t output_rows_in_pixels,
    int channel0, int channel1)
{
    assert(basis_tex_format_int < (uint32_t)basis_tex_format::cTotalFormats);
    assert(target_format_int < (uint32_t)transcoder_texture_format::cTFTotalTextureFormats);

    transcoder_texture_format target_format = static_cast<transcoder_texture_format>(target_format_int);
    basis_tex_format tex_format = static_cast<basis_tex_format>(basis_tex_format_int);

    if (!g_basis_initialized_flag)
    {
#if BASISU_DEBUG_PRINTF
        printf("transcode_uastc_image: basis_init() must be called first\n");
#endif
        assert(0);
        return false;
    }

    // FIXME: Access the JavaScript buffer directly vs. copying it.
    basisu::vector<uint8_t> temp_comp_data;
    copy_from_jsbuffer(compressed_data, temp_comp_data);

    if (!temp_comp_data.size())
    {
#if BASISU_DEBUG_PRINTF
        printf("transcode_uastc_image: compressed_data is empty\n");
#endif
        assert(0);
        return false;
    }

    uint32_t output_blocks_len = output_blocks["byteLength"].as<uint32_t>();
    if (!output_blocks_len)
    {
#if BASISU_DEBUG_PRINTF
        printf("transcode_uastc_image: output_blocks is empty\n");
#endif
        assert(0);
        return false;
    }

#if 0
    printf("format: %u\n", (uint32_t)target_format);
    printf("output_blocks size: %u buf size: %u\n", output_blocks_len, output_blocks_buf_size_in_blocks_or_pixels);
    printf("compressed_data size: %u\n", compressed_data["byteLength"].as<uint32_t>());
    printf("%u %u %u %u %u\n", num_blocks_x, num_blocks_y, orig_width, orig_height, level_index);
    printf("%u %u\n", slice_offset, slice_length);
    printf("%u\n", decode_flags);
    printf("has_alpha: %u is_video: %u\n", has_alpha, is_video);
#endif

    basisu::vector<uint8_t> temp_output_blocks(output_blocks_len);

	bool status = false;	
	if (tex_format == basis_tex_format::cUASTC_HDR_4x4)
	{
		basisu_lowlevel_uastc_hdr_4x4_transcoder transcoder;

    	status = transcoder.transcode_image(
        	(transcoder_texture_format)target_format,
        	&temp_output_blocks[0], output_blocks_buf_size_in_blocks_or_pixels,
        	&temp_comp_data[0], temp_comp_data.size(),
        	num_blocks_x, num_blocks_y, orig_width, orig_height, level_index,
        	slice_offset, slice_length,
        	decode_flags,
        	has_alpha,
        	is_video,
        	output_row_pitch_in_blocks_or_pixels,
        	nullptr,
        	output_rows_in_pixels,
        	channel0, channel1);
	}
    else if (tex_format == basis_tex_format::cASTC_HDR_6x6)
    {
        basisu_lowlevel_astc_hdr_6x6_transcoder transcoder;

        status = transcoder.transcode_image(
            (transcoder_texture_format)target_format,
            &temp_output_blocks[0], output_blocks_buf_size_in_blocks_or_pixels,
            &temp_comp_data[0], temp_comp_data.size(),
            num_blocks_x, num_blocks_y, orig_width, orig_height, level_index,
            slice_offset, slice_length,
            decode_flags,
            has_alpha,
            is_video,
            output_row_pitch_in_blocks_or_pixels,
            nullptr,
            output_rows_in_pixels,
            channel0, channel1);
    }
    else if (tex_format == basis_tex_format::cASTC_HDR_6x6_INTERMEDIATE)
    {
        basisu_lowlevel_astc_hdr_6x6_intermediate_transcoder transcoder;

        status = transcoder.transcode_image(
            (transcoder_texture_format)target_format,
            &temp_output_blocks[0], output_blocks_buf_size_in_blocks_or_pixels,
            &temp_comp_data[0], temp_comp_data.size(),
            num_blocks_x, num_blocks_y, orig_width, orig_height, level_index,
            slice_offset, slice_length,
            decode_flags,
            has_alpha,
            is_video,
            output_row_pitch_in_blocks_or_pixels,
            nullptr,
            output_rows_in_pixels,
            channel0, channel1);
    }
	else if (tex_format == basis_tex_format::cUASTC4x4)
	{
    	basisu_lowlevel_uastc_ldr_4x4_transcoder transcoder;

    	status = transcoder.transcode_image(
        	(transcoder_texture_format)target_format,
        	&temp_output_blocks[0], output_blocks_buf_size_in_blocks_or_pixels,
        	&temp_comp_data[0], temp_comp_data.size(),
        	num_blocks_x, num_blocks_y, orig_width, orig_height, level_index,
        	slice_offset, slice_length,
        	decode_flags,
        	has_alpha,
        	is_video,
        	output_row_pitch_in_blocks_or_pixels,
        	nullptr,
        	output_rows_in_pixels,
        	channel0, channel1);
	}
    else
    {
        assert(0);
    }

    if (!status)
    {
#if BASISU_DEBUG_PRINTF
        printf("transcode_uastc_image: basisu_lowlevel_uastc_transcoder::transcode_image failed\n");
#endif
        assert(0);
        return false;
    }

    if (!copy_to_jsbuffer(output_blocks, temp_output_blocks))
        return false;

    return true;
}

uint32_t get_bytes_per_block_or_pixel(uint32_t transcoder_tex_fmt)
{
    assert(transcoder_tex_fmt < (uint32_t)transcoder_texture_format::cTFTotalTextureFormats);
    return basis_get_bytes_per_block_or_pixel(static_cast<transcoder_texture_format>(transcoder_tex_fmt));
}

bool format_has_alpha(uint32_t transcoder_tex_fmt)
{
    assert(transcoder_tex_fmt < (uint32_t)transcoder_texture_format::cTFTotalTextureFormats);
    return basis_transcoder_format_has_alpha(static_cast<transcoder_texture_format>(transcoder_tex_fmt));
}

bool format_is_hdr(uint32_t transcode_tex_fmt)
{
    assert(transcode_tex_fmt < (uint32_t)transcoder_texture_format::cTFTotalTextureFormats);
	return basis_transcoder_format_is_hdr(static_cast<transcoder_texture_format>(transcode_tex_fmt));
}

bool format_is_ldr(uint32_t transcode_tex_fmt)
{
    assert(transcode_tex_fmt < (uint32_t)transcoder_texture_format::cTFTotalTextureFormats);
    return !basis_transcoder_format_is_hdr(static_cast<transcoder_texture_format>(transcode_tex_fmt));
}

bool format_is_uncompressed(uint32_t transcoder_tex_fmt)
{
    assert(transcoder_tex_fmt < (uint32_t)transcoder_texture_format::cTFTotalTextureFormats);
    return basis_transcoder_format_is_uncompressed(static_cast<transcoder_texture_format>(transcoder_tex_fmt));
}

bool is_format_supported(uint32_t transcoder_tex_fmt, uint32_t file_fmt)
{
    assert(transcoder_tex_fmt < (uint32_t)transcoder_texture_format::cTFTotalTextureFormats);
    return basis_is_format_supported(static_cast<transcoder_texture_format>(transcoder_tex_fmt), static_cast<basis_tex_format>(file_fmt));
}

// transcoder_texture_format
uint32_t get_format_block_width(uint32_t transcoder_tex_fmt)
{
    assert(transcoder_tex_fmt < (uint32_t)transcoder_texture_format::cTFTotalTextureFormats);
    return basis_get_block_width(static_cast<transcoder_texture_format>(transcoder_tex_fmt));
}

// transcoder_texture_format
uint32_t get_format_block_height(uint32_t transcoder_tex_fmt)
{
    assert(transcoder_tex_fmt < (uint32_t)transcoder_texture_format::cTFTotalTextureFormats);
    return basis_get_block_height(static_cast<transcoder_texture_format>(transcoder_tex_fmt));
}

// basis_tex_format
uint32_t get_basis_tex_format_block_width(uint32_t fmt) 
{
    assert(fmt < (uint32_t)basis_tex_format::cTotalFormats);
    return basis_tex_format_get_block_width(static_cast<basis_tex_format>(fmt));
}

// basis_tex_format
uint32_t get_basis_tex_format_block_height(uint32_t fmt)
{
    assert(fmt < (uint32_t)basis_tex_format::cTotalFormats);
    return basis_tex_format_get_block_height(static_cast<basis_tex_format>(fmt));
}

// basis_tex_format
bool is_basis_tex_format_hdr(uint32_t fmt)
{
    assert(fmt < (uint32_t)basis_tex_format::cTotalFormats);
    return ((basis_tex_format)fmt == basis_tex_format::cUASTC_HDR_4x4) || ((basis_tex_format)fmt == basis_tex_format::cASTC_HDR_6x6) || ((basis_tex_format)fmt == basis_tex_format::cASTC_HDR_6x6_INTERMEDIATE);
}

// basis_tex_format
bool is_basis_tex_format_ldr(uint32_t fmt)
{
    assert(fmt < (uint32_t)basis_tex_format::cTotalFormats);
    return ((basis_tex_format)fmt == basis_tex_format::cETC1S) || ((basis_tex_format)fmt == basis_tex_format::cUASTC4x4);
}

uint32_t convert_float_to_half(float f)
{
	return basist::float_to_half(f);
}

float convert_half_to_float(uint32_t h)
{
	assert(h < 65536);
	return basist::half_to_float(h);
}

void set_debug_flags_wrapper(uint32_t flags)
{
	basist::set_debug_flags(flags);
}

uint32_t get_debug_flags_wrapper()
{
	return basist::get_debug_flags();
}

EMSCRIPTEN_BINDINGS(basis_codec) {
  function("initializeBasis", &basis_init);
  
  function("setDebugFlags", &set_debug_flags_wrapper);
  function("getDebugFlags", &get_debug_flags_wrapper);
    
  // Expose BasisFileDesc structure
  value_object<basis_file_desc>("BasisFileDesc")
      .field("version", &basis_file_desc::m_version)
      .field("usPerFrame", &basis_file_desc::m_us_per_frame)
      .field("totalImages", &basis_file_desc::m_total_images)
      .field("userdata0", &basis_file_desc::m_userdata0)
      .field("userdata1", &basis_file_desc::m_userdata1)
      .field("texFormat", &basis_file_desc::m_tex_format)
      .field("yFlipped", &basis_file_desc::m_y_flipped)
      .field("hasAlphaSlices", &basis_file_desc::m_has_alpha_slices)
      .field("numEndpoints", &basis_file_desc::m_num_endpoints)
      .field("endpointPaletteOfs", &basis_file_desc::m_endpoint_palette_ofs)
      .field("endpointPaletteLen", &basis_file_desc::m_endpoint_palette_len)
      .field("numSelectors", &basis_file_desc::m_num_selectors)
      .field("selectorPaletteOfs", &basis_file_desc::m_selector_palette_ofs)
      .field("selectorPaletteLen", &basis_file_desc::m_selector_palette_len)
      .field("tablesOfs", &basis_file_desc::m_tables_ofs)
      .field("tablesLen", &basis_file_desc::m_tables_len)
      .field("blockWidth", &basis_file_desc::m_block_width)
      .field("blockHeight", &basis_file_desc::m_block_height)
    ;

  // Expose BasisImageDesc structure
  value_object<basis_image_desc>("BasisImageDesc")
    .field("origWidth", &basis_image_desc::m_orig_width)
    .field("origHeight", &basis_image_desc::m_orig_height)
    .field("numBlocksX", &basis_image_desc::m_num_blocks_x)
    .field("numBlocksY", &basis_image_desc::m_num_blocks_y)
    .field("numLevels", &basis_image_desc::m_num_levels)
    .field("blockWidth", &basis_image_desc::m_block_width)
    .field("blockHeight", &basis_image_desc::m_block_height)
    .field("alphaFlag", &basis_image_desc::m_alpha_flag)
    .field("iframeFlag", &basis_image_desc::m_iframe_flag)
    ;

  // Expose BasisImageLevelDesc structure
  value_object<basis_image_level_desc>("BasisImageLevelDesc")
    .field("rgbFileOfs", &basis_image_level_desc::m_rgb_file_ofs)
    .field("rgbFileLen", &basis_image_level_desc::m_rgb_file_len)
    .field("alphaFileOfs", &basis_image_level_desc::m_alpha_file_ofs)
    .field("alphaFileLen", &basis_image_level_desc::m_alpha_file_len)
    ;

  // Expose some key enums to JavaScript code.

  // enum class transcoder_texture_format
  enum_<transcoder_texture_format>("transcoder_texture_format")
        .value("cTFETC1_RGB", transcoder_texture_format::cTFETC1_RGB)
        .value("cTFETC2_RGBA", transcoder_texture_format::cTFETC2_RGBA)
        .value("cTFBC1_RGB", transcoder_texture_format::cTFBC1_RGB)
        .value("cTFBC3_RGBA", transcoder_texture_format::cTFBC3_RGBA)
        .value("cTFBC4_R", transcoder_texture_format::cTFBC4_R)
        .value("cTFBC5_RG", transcoder_texture_format::cTFBC5_RG)
        .value("cTFBC7_RGBA", transcoder_texture_format::cTFBC7_RGBA)
        .value("cTFPVRTC1_4_RGB", transcoder_texture_format::cTFPVRTC1_4_RGB)
        .value("cTFPVRTC1_4_RGBA", transcoder_texture_format::cTFPVRTC1_4_RGBA)
        .value("cTFASTC_4x4_RGBA", transcoder_texture_format::cTFASTC_4x4_RGBA)
        .value("cTFATC_RGB", transcoder_texture_format::cTFATC_RGB)
        .value("cTFATC_RGBA", transcoder_texture_format::cTFATC_RGBA)
        .value("cTFFXT1_RGB", transcoder_texture_format::cTFFXT1_RGB)
        .value("cTFPVRTC2_4_RGB", transcoder_texture_format::cTFPVRTC2_4_RGB)
        .value("cTFPVRTC2_4_RGBA", transcoder_texture_format::cTFPVRTC2_4_RGBA)
        .value("cTFETC2_EAC_R11", transcoder_texture_format::cTFETC2_EAC_R11)
        .value("cTFETC2_EAC_RG11", transcoder_texture_format::cTFETC2_EAC_RG11)
		.value("cTFBC6H", transcoder_texture_format::cTFBC6H)
		.value("cTFASTC_HDR_4x4_RGBA", transcoder_texture_format::cTFASTC_HDR_4x4_RGBA)
        .value("cTFRGBA32", transcoder_texture_format::cTFRGBA32)
        .value("cTFRGB565", transcoder_texture_format::cTFRGB565)
        .value("cTFBGR565", transcoder_texture_format::cTFBGR565)
        .value("cTFRGBA4444", transcoder_texture_format::cTFRGBA4444)
		.value("cTFRGB_HALF", transcoder_texture_format::cTFRGB_HALF)
		.value("cTFRGBA_HALF", transcoder_texture_format::cTFRGBA_HALF)
		.value("cTFRGB_9E5", transcoder_texture_format::cTFRGB_9E5)
        .value("cTFASTC_HDR_6x6_RGBA", transcoder_texture_format::cTFASTC_HDR_6x6_RGBA)
        .value("cTFTotalTextureFormats", transcoder_texture_format::cTFTotalTextureFormats)
    ;

    // Expose some useful transcoder_texture_format helper functions
    function("getBytesPerBlockOrPixel", &::get_bytes_per_block_or_pixel);
    function("formatHasAlpha", &format_has_alpha);
	function("formatIsHDR", &format_is_hdr);
    function("formatIsLDR", &format_is_ldr);
    function("formatIsUncompressed", &format_is_uncompressed);
    function("isFormatSupported", &is_format_supported);
    function("getFormatBlockWidth", &get_format_block_width);
    function("getFormatBlockHeight", &get_format_block_height);

    function("getBasisTexFormatBlockWidth", &get_basis_tex_format_block_width);
    function("getBasisTexFormatBlockHeight", &get_basis_tex_format_block_height);

    function("isBasisTexFormatHDR", &is_basis_tex_format_hdr);
    function("isBasisTexFormatLDR", &is_basis_tex_format_ldr);
	
	function("convertFloatToHalf", &convert_float_to_half);
	function("convertHalfToFloat", &convert_half_to_float);

    // Expose enum basis_texture_type
    enum_<basis_texture_type>("basis_texture_type")
    .value("cBASISTexType2D", cBASISTexType2D)
        .value("cBASISTexType2DArray", cBASISTexType2DArray)
        .value("cBASISTexTypeCubemapArray", cBASISTexTypeCubemapArray)
        .value("cBASISTexTypeVideoFrames", cBASISTexTypeVideoFrames)
        .value("cBASISTexTypeVolume", cBASISTexTypeVolume)
    ;

    // Expose enum basis_tex_format
    enum_<basis_tex_format>("basis_tex_format")
        .value("cETC1S", basis_tex_format::cETC1S)
        .value("cUASTC4x4", basis_tex_format::cUASTC4x4)
        .value("cUASTC_HDR_4x4", basis_tex_format::cUASTC_HDR_4x4)
        .value("cASTC_HDR_6x6", basis_tex_format::cASTC_HDR_6x6)
        .value("cASTC_HDR_6x6_INTERMEDIATE", basis_tex_format::cASTC_HDR_6x6_INTERMEDIATE)
    ;

  // .basis file transcoder object. If all you want to do is transcode already encoded .basis files, this is all you really need.
  class_<basis_file>("BasisFile")
    .constructor<const emscripten::val&>()
    .function("close", optional_override([](basis_file& self) {
      return self.close();
    }))
    .function("getHasAlpha", optional_override([](basis_file& self) {
      return self.getHasAlpha();
    }))
    .function("getBasisTexFormat", optional_override([](basis_file& self) {
      return self.getBasisTexFormat();
    }))
    .function("isUASTC_LDR_4x4", optional_override([](basis_file& self) {
      return self.isUASTC_LDR_4x4();
    }))
    .function("isUASTC", optional_override([](basis_file& self) {
      return self.isUASTC_LDR_4x4();
    }))
    .function("isETC1S", optional_override([](basis_file& self) {
      return self.isETC1S();
    }))
	.function("isHDR", optional_override([](basis_file& self) {
      return self.isHDR();
    }))
    .function("isHDR4x4", optional_override([](basis_file& self) {
      return self.isHDR4x4();
    }))
    .function("isHDR6x6", optional_override([](basis_file& self) {
      return self.isHDR6x6();
    }))
      .function("isLDR", optional_override([](basis_file& self) {
      return self.isLDR();
    }))
    .function("getNumImages", optional_override([](basis_file& self) {
      return self.getNumImages();
    }))
    .function("getNumLevels", optional_override([](basis_file& self, uint32_t imageIndex) {
      return self.getNumLevels(imageIndex);
    }))
    .function("getImageWidth", optional_override([](basis_file& self, uint32_t imageIndex, uint32_t levelIndex) {
      return self.getImageWidth(imageIndex, levelIndex);
    }))
    .function("getImageHeight", optional_override([](basis_file& self, uint32_t imageIndex, uint32_t levelIndex) {
      return self.getImageHeight(imageIndex, levelIndex);
    }))
    .function("getBlockWidth", optional_override([](basis_file& self) {
      return self.getBlockWidth();
    }))
    .function("getBlockHeight", optional_override([](basis_file& self) {
      return self.getBlockHeight();
    }))
    // format is enum class transcoder_texture_format
    .function("getImageTranscodedSizeInBytes", optional_override([](basis_file& self, uint32_t imageIndex, uint32_t levelIndex, uint32_t format) {
      return self.getImageTranscodedSizeInBytes(imageIndex, levelIndex, format);
    }))
    .function("startTranscoding", optional_override([](basis_file& self) {
      return self.startTranscoding();
    }))
    // format is enum class transcoder_texture_format
    .function("transcodeImage", optional_override([](basis_file& self, const emscripten::val& dst, uint32_t imageIndex, uint32_t levelIndex, uint32_t format, uint32_t unused, uint32_t getAlphaForOpaqueFormats) {
      return self.transcodeImage(dst, imageIndex, levelIndex, format, unused, getAlphaForOpaqueFormats);
    }))
    .function("transcodeImageWithFlags", optional_override([](basis_file& self, const emscripten::val& dst, uint32_t imageIndex, uint32_t levelIndex, uint32_t format, uint32_t flags) {
      return self.transcodeImageWithFlags(dst, imageIndex, levelIndex, format, flags);
    }))
    // Returns low-level information about the basis file.
    .function("getFileDesc", optional_override([](basis_file& self) {
      return self.getFileDesc();
    }))
    // Returns low-level information about a specific image in a basis file. An image can contain 1 or more mipmap levels.
    .function("getImageDesc", optional_override([](basis_file& self, uint32_t imageIndex) {
      return self.getImageDesc(imageIndex);
    }))
    // Returns low-level information about a specific image mipmap level in a basis file.
    .function("getImageLevelDesc", optional_override([](basis_file& self, uint32_t imageIndex, uint32_t levelIndex) {
      return self.getImageLevelDesc(imageIndex, levelIndex);
    }))

  ;

  // Low-level container independent transcoding of ETC1S and UASTC slice data.
  // These functions allow the caller to transcode compressed ETC1S or UASTC texture data that is embedded within arbitrary data files, such as from KTX2.
  enum_<basisu_decode_flags>("basisu_decode_flags")
    .value("cDecodeFlagsPVRTCDecodeToNextPow2", cDecodeFlagsPVRTCDecodeToNextPow2)
    .value("cDecodeFlagsTranscodeAlphaDataToOpaqueFormats", cDecodeFlagsTranscodeAlphaDataToOpaqueFormats)
    .value("cDecodeFlagsBC1ForbidThreeColorBlocks", cDecodeFlagsBC1ForbidThreeColorBlocks)
    .value("cDecodeFlagsOutputHasAlphaIndices", cDecodeFlagsOutputHasAlphaIndices)
    .value("cDecodeFlagsHighQuality", cDecodeFlagsHighQuality)
    .value("cDecodeFlagsNoETC1SChromaFiltering", cDecodeFlagsNoETC1SChromaFiltering)
  ;

  // The low-level ETC1S transcoder is a class because it has persistent state (such as the endpoint/selector codebooks and Huffman tables, and transcoder state for video)
  class_<lowlevel_etc1s_image_transcoder>("LowLevelETC1SImageTranscoder")
    .constructor<>()
    .function("decodePalettes", &lowlevel_etc1s_image_transcoder::decode_palettes)
    .function("decodeTables", &lowlevel_etc1s_image_transcoder::decode_tables)
    .function("transcodeImage", &lowlevel_etc1s_image_transcoder::transcode_image)
   ;

  // The low-level UASTC transcoder (for UASTC LDR 4x4, HDR 4x4, or ASTC HDR 6x6) is a single function.
  function("transcodeUASTCImage", &transcode_uastc_image);

  function("transcoderSupportsKTX2", &basisu_transcoder_supports_ktx2);
  function("transcoderSupportsKTX2Zstd", &basisu_transcoder_supports_ktx2_zstd);
    
#if BASISD_SUPPORT_KTX2
  // KTX2 enums/constants
  enum_<ktx2_supercompression>("ktx2_supercompression")
      .value("KTX2_SS_NONE", KTX2_SS_NONE)
      .value("KTX2_SS_BASISLZ", KTX2_SS_BASISLZ)
      .value("KTX2_SS_ZSTANDARD", KTX2_SS_ZSTANDARD)
      ;

  constant("KTX2_VK_FORMAT_UNDEFINED", KTX2_VK_FORMAT_UNDEFINED);
  constant("KTX2_KDF_DF_MODEL_UASTC", KTX2_KDF_DF_MODEL_UASTC_LDR_4X4);
  constant("KTX2_KDF_DF_MODEL_ETC1S", KTX2_KDF_DF_MODEL_ETC1S);
  constant("KTX2_KDF_DF_MODEL_ASTC_HDR_6X6_INTERMEDIATE", KTX2_KDF_DF_MODEL_ASTC_HDR_6X6_INTERMEDIATE);

  constant("KTX2_IMAGE_IS_P_FRAME", KTX2_IMAGE_IS_P_FRAME);
  constant("KTX2_UASTC_BLOCK_SIZE", KTX2_UASTC_BLOCK_SIZE);
  constant("KTX2_MAX_SUPPORTED_LEVEL_COUNT", KTX2_MAX_SUPPORTED_LEVEL_COUNT);

  constant("KTX2_KHR_DF_TRANSFER_LINEAR", KTX2_KHR_DF_TRANSFER_LINEAR);
  constant("KTX2_KHR_DF_TRANSFER_SRGB", KTX2_KHR_DF_TRANSFER_SRGB);

  enum_<ktx2_df_channel_id>("ktx2_df_channel_id")
      .value("KTX2_DF_CHANNEL_ETC1S_RGB", KTX2_DF_CHANNEL_ETC1S_RGB)
      .value("KTX2_DF_CHANNEL_ETC1S_RRR", KTX2_DF_CHANNEL_ETC1S_RRR)
      .value("KTX2_DF_CHANNEL_ETC1S_GGG", KTX2_DF_CHANNEL_ETC1S_GGG)
      .value("KTX2_DF_CHANNEL_ETC1S_AAA", KTX2_DF_CHANNEL_ETC1S_AAA)
      .value("KTX2_DF_CHANNEL_UASTC_DATA", KTX2_DF_CHANNEL_UASTC_DATA)
      .value("KTX2_DF_CHANNEL_UASTC_RGB", KTX2_DF_CHANNEL_UASTC_RGB)
      .value("KTX2_DF_CHANNEL_UASTC_RGBA", KTX2_DF_CHANNEL_UASTC_RGBA)
      .value("KTX2_DF_CHANNEL_UASTC_RRR", KTX2_DF_CHANNEL_UASTC_RRR)
      .value("KTX2_DF_CHANNEL_UASTC_RRRG", KTX2_DF_CHANNEL_UASTC_RRRG)
      .value("KTX2_DF_CHANNEL_UASTC_RG", KTX2_DF_CHANNEL_UASTC_RG)
      ;

  enum_<ktx2_df_color_primaries>("ktx2_df_color_primaries")
      .value("KTX2_DF_PRIMARIES_UNSPECIFIED", KTX2_DF_PRIMARIES_UNSPECIFIED)
      .value("KTX2_DF_PRIMARIES_BT709", KTX2_DF_PRIMARIES_BT709)
      .value("KTX2_DF_PRIMARIES_SRGB", KTX2_DF_PRIMARIES_SRGB)
      .value("KTX2_DF_PRIMARIES_BT601_EBU", KTX2_DF_PRIMARIES_BT601_EBU)
      .value("KTX2_DF_PRIMARIES_BT601_SMPTE", KTX2_DF_PRIMARIES_BT601_SMPTE)
      .value("KTX2_DF_PRIMARIES_BT2020", KTX2_DF_PRIMARIES_BT2020)
      .value("KTX2_DF_PRIMARIES_CIEXYZ", KTX2_DF_PRIMARIES_CIEXYZ)
      .value("KTX2_DF_PRIMARIES_ACES", KTX2_DF_PRIMARIES_ACES)
      .value("KTX2_DF_PRIMARIES_ACESCC", KTX2_DF_PRIMARIES_ACESCC)
      .value("KTX2_DF_PRIMARIES_NTSC1953", KTX2_DF_PRIMARIES_NTSC1953)
      .value("KTX2_DF_PRIMARIES_PAL525", KTX2_DF_PRIMARIES_PAL525)
      .value("KTX2_DF_PRIMARIES_DISPLAYP3", KTX2_DF_PRIMARIES_DISPLAYP3)
      .value("KTX2_DF_PRIMARIES_ADOBERGB", KTX2_DF_PRIMARIES_ADOBERGB)
      ;

  // Expose ktx2_image_level_info structure
  value_object<ktx2_image_level_info>("KTX2ImageLevelInfo")
      .field("levelIndex", &ktx2_image_level_info::m_level_index)
      .field("layerIndex", &ktx2_image_level_info::m_layer_index)
      .field("faceIndex", &ktx2_image_level_info::m_face_index)
      .field("origWidth", &ktx2_image_level_info::m_orig_width)
      .field("origHeight", &ktx2_image_level_info::m_orig_height)
      .field("width", &ktx2_image_level_info::m_width)
      .field("height", &ktx2_image_level_info::m_height)
      .field("numBlocksX", &ktx2_image_level_info::m_num_blocks_x)
      .field("numBlocksY", &ktx2_image_level_info::m_num_blocks_y)
      .field("blockWidth", &ktx2_image_level_info::m_block_width)
      .field("blockHeight", &ktx2_image_level_info::m_block_height)
      .field("totalBlocks", &ktx2_image_level_info::m_total_blocks)
      .field("alphaFlag", &ktx2_image_level_info::m_alpha_flag)
      .field("iframeFlag", &ktx2_image_level_info::m_iframe_flag)
      ;

  // Expose the ktx2_header_js structure
  value_object<ktx2_header_js>("KTX2Header")
      .field("vkFormat", &ktx2_header_js::m_vk_format)
      .field("typeSize", &ktx2_header_js::m_type_size)
      .field("pixelWidth", &ktx2_header_js::m_pixel_width)
      .field("pixelHeight", &ktx2_header_js::m_pixel_height)
      .field("pixelDepth", &ktx2_header_js::m_pixel_depth)
      .field("layerCount", &ktx2_header_js::m_layer_count)
      .field("faceCount", &ktx2_header_js::m_face_count)
      .field("levelCount", &ktx2_header_js::m_level_count)
      .field("supercompressionScheme", &ktx2_header_js::m_supercompression_scheme)
      .field("dfdByteOffset", &ktx2_header_js::m_dfd_byte_offset)
      .field("dfdByteLength", &ktx2_header_js::m_dfd_byte_length)
      .field("kvdByteOffset", &ktx2_header_js::m_kvd_byte_offset)
      .field("kvdByteLength", &ktx2_header_js::m_kvd_byte_length)
      .field("sgdByteOffset", &ktx2_header_js::m_sgd_byte_offset)
      .field("sgdByteLength", &ktx2_header_js::m_sgd_byte_length)
      ;

  // KTX2 transcoder class
  class_<ktx2_file>("KTX2File")
      .constructor<const emscripten::val&>()
        .function("isValid", &ktx2_file::isValid)
        .function("close", &ktx2_file::close)
        .function("getDFDSize", &ktx2_file::getDFDSize)
        .function("getDFD", &ktx2_file::getDFD)
        .function("getHeader", &ktx2_file::getHeader)
        .function("hasKey", &ktx2_file::hasKey)
        .function("getTotalKeys", &ktx2_file::getTotalKeys)
        .function("getKey", &ktx2_file::getKey)
        .function("getKeyValueSize", &ktx2_file::getKeyValueSize)
        .function("getKeyValue", &ktx2_file::getKeyValue)
        .function("getWidth", &ktx2_file::getWidth)
        .function("getHeight", &ktx2_file::getHeight)
        .function("getBlockWidth", &ktx2_file::getBlockWidth)
        .function("getBlockHeight", &ktx2_file::getBlockHeight)
        .function("getFaces", &ktx2_file::getFaces)
        .function("getLayers", &ktx2_file::getLayers)
        .function("getLevels", &ktx2_file::getLevels)
        .function("getBasisTexFormat", &ktx2_file::getBasisTexFormat)
        .function("isUASTC_LDR_4x4", &ktx2_file::isUASTC_LDR_4x4)
        .function("isUASTC", &ktx2_file::isUASTC_LDR_4x4)
        .function("isHDR", &ktx2_file::isHDR)
        .function("isHDR4x4", &ktx2_file::isHDR4x4)
        .function("isHDR6x6", &ktx2_file::isHDR6x6)
        .function("isLDR", &ktx2_file::isLDR)
        .function("isETC1S", &ktx2_file::isETC1S)
        .function("getHasAlpha", &ktx2_file::getHasAlpha)
        .function("getDFDColorModel", &ktx2_file::getDFDColorModel)
        .function("getDFDColorPrimaries", &ktx2_file::getDFDColorPrimaries)
        .function("getDFDTransferFunc", &ktx2_file::getDFDTransferFunc)
        .function("getDFDFlags", &ktx2_file::getDFDFlags)
        .function("getDFDTotalSamples", &ktx2_file::getDFDTotalSamples)
        .function("getDFDChannelID0", &ktx2_file::getDFDChannelID0)
        .function("getDFDChannelID1", &ktx2_file::getDFDChannelID1)
        .function("isVideo", &ktx2_file::isVideo)
        .function("getLDRHDRUpconversionNitMultiplier", &ktx2_file::getLDRHDRUpconversionNitMultiplier)
        .function("getETC1SImageDescImageFlags", &ktx2_file::getETC1SImageDescImageFlags)
        .function("getImageLevelInfo", &ktx2_file::getImageLevelInfo)
        .function("getImageTranscodedSizeInBytes", &ktx2_file::getImageTranscodedSizeInBytes)
        .function("startTranscoding", &ktx2_file::startTranscoding)
        .function("transcodeImage", &ktx2_file::transcodeImage)
        .function("transcodeImageWithFlags", &ktx2_file::transcodeImageWithFlags)
      ;

#endif // BASISD_SUPPORT_KTX2

  // Optional encoding/compression support of .basis and .KTX2 files (the same class encodes/compresses to either format).

#if BASISU_SUPPORT_ENCODING

    // Compressor Constants

    constant("BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION", BASISU_MAX_SUPPORTED_TEXTURE_DIMENSION);
    constant("BASISU_DEFAULT_ENDPOINT_RDO_THRESH", BASISU_DEFAULT_ENDPOINT_RDO_THRESH);
    constant("BASISU_DEFAULT_SELECTOR_RDO_THRESH", BASISU_DEFAULT_SELECTOR_RDO_THRESH);
    constant("BASISU_DEFAULT_QUALITY", BASISU_DEFAULT_QUALITY);
    constant("BASISU_DEFAULT_HYBRID_SEL_CB_QUALITY_THRESH", BASISU_DEFAULT_HYBRID_SEL_CB_QUALITY_THRESH);
    constant("BASISU_MAX_IMAGE_DIMENSION", BASISU_MAX_IMAGE_DIMENSION);
    constant("BASISU_QUALITY_MIN", BASISU_QUALITY_MIN);
    constant("BASISU_QUALITY_MAX", BASISU_QUALITY_MAX);
    constant("BASISU_MAX_ENDPOINT_CLUSTERS", BASISU_MAX_ENDPOINT_CLUSTERS);
    constant("BASISU_MAX_SELECTOR_CLUSTERS", BASISU_MAX_SELECTOR_CLUSTERS);
    constant("BASISU_MAX_SLICES", BASISU_MAX_SLICES);
    constant("BASISU_RDO_UASTC_DICT_SIZE_DEFAULT", BASISU_RDO_UASTC_DICT_SIZE_DEFAULT);
    constant("BASISU_RDO_UASTC_DICT_SIZE_MIN", BASISU_RDO_UASTC_DICT_SIZE_MIN);
    constant("BASISU_RDO_UASTC_DICT_SIZE_MAX", BASISU_RDO_UASTC_DICT_SIZE_MAX);
    constant("BASISU_MAX_RESAMPLER_FILTERS", g_num_resample_filters);
    constant("BASISU_DEFAULT_COMPRESSION_LEVEL", BASISU_DEFAULT_COMPRESSION_LEVEL);
    constant("BASISU_MAX_COMPRESSION_LEVEL", BASISU_MAX_COMPRESSION_LEVEL);

	// The maximum representable floating point value in a UASTC HDR or ASTC HDR texture (any larger values will get clamped and a warning issued).	
	constant("ASTC_HDR_MAX_VAL", basist::ASTC_HDR_MAX_VAL);

    // UASTC LDR/HDR flags/options
    constant("cPackUASTCLevelFastest", cPackUASTCLevelFastest);
    constant("cPackUASTCLevelFaster", cPackUASTCLevelFaster);
    constant("cPackUASTCLevelDefault", cPackUASTCLevelDefault);
    constant("cPackUASTCLevelSlower", cPackUASTCLevelSlower);
    constant("cPackUASTCLevelVerySlow", cPackUASTCLevelVerySlow);
    constant("cPackUASTCLevelMask", cPackUASTCLevelMask);
    constant("cPackUASTCFavorUASTCError", cPackUASTCFavorUASTCError);
    constant("cPackUASTCFavorBC7Error", cPackUASTCFavorBC7Error);
    constant("cPackUASTCETC1FasterHints", cPackUASTCETC1FasterHints);
    constant("cPackUASTCETC1FastestHints", cPackUASTCETC1FastestHints);
    constant("cPackUASTCETC1DisableFlipAndIndividual", cPackUASTCETC1DisableFlipAndIndividual);
    
    constant("UASTC_RDO_DEFAULT_MAX_ALLOWED_RMS_INCREASE_RATIO", UASTC_RDO_DEFAULT_MAX_ALLOWED_RMS_INCREASE_RATIO);
    constant("UASTC_RDO_DEFAULT_SKIP_BLOCK_RMS_THRESH", UASTC_RDO_DEFAULT_SKIP_BLOCK_RMS_THRESH);

    constant("cPackASTC6x6MaxUserCompLevel", ::astc_6x6_hdr::ASTC_HDR_6X6_MAX_USER_COMP_LEVEL);
	
	enum_<hdr_image_type>("hdr_image_type")
		.value("cHITRGBAHalfFloat", hdr_image_type::cHITRGBAHalfFloat)
		.value("cHITRGBAFloat", hdr_image_type::cHITRGBAFloat)
		.value("cHITPNGImage", hdr_image_type::cHITPNGImage)
		.value("cHITEXRImage", hdr_image_type::cHITEXRImage)
		.value("cHITHDRImage", hdr_image_type::cHITHDRImage)
        .value("cHITJPGImage", hdr_image_type::cHITJPGImage)
	;

    enum_<ldr_image_type>("ldr_image_type")
        .value("cRGBA32", ldr_image_type::cRGBA32)
        .value("cPNGImage", ldr_image_type::cPNGImage)
        .value("cJPGImage", ldr_image_type::cJPGImage)
	;

  // Compression/encoding object.
  // You create this object, call the set() methods to fill in the parameters/source images/options, call encode(), and you get back a .basis or .KTX2 file.
  // You can call .encode() multiple times, changing the parameters/options in between calls.
  // By default this class encodes to .basis, but call setCreateKTX2File() with true to get .KTX2 files.
  class_<basis_encoder>("BasisEncoder")
    .constructor<>()

    // Compresses the provided source slice(s) to an output .basis file.
    // At the minimum, you must provided at least 1 source slice by calling setSliceSourceImage() or setSliceSourceImageHDR() (for UASTC HDR) before calling this method.
    .function("encode", optional_override([](basis_encoder& self, const emscripten::val& dst_basis_file_js_val) {
        return self.encode(dst_basis_file_js_val);
    }))
          
    // Sets the slice's source image, either from a PNG/JPG file or from a raw 32-bit RGBA raster image.
    // If the input is a raster image, the buffer must be width*height*4 bytes in size. The raster image is stored in top down scanline order.
    // The first texel is the top-left texel. The texel byte order in memory is R,G,B,A (R first at offset 0, A last at offset 3).
    // slice_index is the slice to change. Valid range is [0,BASISU_MAX_SLICES-1].
    // All formats, including HDR formats. The compressor will upconvert LDR/SDR content to absolute light HDR as needed. See LDR upconversion options below.
    .function("setSliceSourceImage", optional_override([](basis_encoder& self, uint32_t slice_index, const emscripten::val& src_image_js_val, uint32_t width, uint32_t height, uint32_t img_type) {
        return self.set_slice_source_image(slice_index, src_image_js_val, width, height, (ldr_image_type)img_type);
    }))

    .function("controlThreading", optional_override([](basis_encoder& self, bool enable_threading, uint32_t num_extra_worker_threads) {
      return self.control_threading(enable_threading, num_extra_worker_threads);
    }))

    // HDR targets only
	.function("setSliceSourceImageHDR", optional_override([](basis_encoder& self, uint32_t slice_index, const emscripten::val& src_image_js_val, uint32_t width, uint32_t height, uint32_t img_type, 
        bool ldr_srgb_to_linear_conversion, float ldr_to_hdr_nit_multiplier) {
        return self.set_slice_source_image_hdr(slice_index, src_image_js_val, width, height, (hdr_image_type)img_type, ldr_srgb_to_linear_conversion, ldr_to_hdr_nit_multiplier);
    }))

    // Sets the desired encoding format. This is the preferred way to control which format the encoder creates.
    // tex_format is a basis_tex_format (cETC1s, cUASTC4x4, cUASTC_HDR_4x4 etc.)
    // This can be used instead of the older setUASTC(), setHDR() etc. methods.
    // All formats
    .function("setFormatMode", optional_override([](basis_encoder& self, int tex_format) {
      assert((tex_format >= 0) && (tex_format < (uint32_t)basis_tex_format::cTotalFormats));
      self.m_params.set_format_mode((basis_tex_format)tex_format);
    }))

    // If true, the encoder will output a UASTC LDR 4x4 texture, otherwise a ETC1S texture.
    // (This is for backwards compatibility, prefer setFormatMode() instead.)
    // All formats
    .function("setUASTC", optional_override([](basis_encoder& self, bool uastc_flag) {
      if (uastc_flag)
          self.m_params.set_format_mode(basis_tex_format::cUASTC4x4);
      else
          self.m_params.set_format_mode(basis_tex_format::cETC1S);
    }))

    // If true, the encoder will output a UASTC HDR 4x4 texture, otherwise a ETC1S texture.
    // (This is for backwards compatibility, prefer setFormatMode() instead.)
    // All formats
    .function("setHDR", optional_override([](basis_encoder& self, bool hdr_flag) {
      if (hdr_flag)
          self.m_params.set_format_mode(basis_tex_format::cUASTC_HDR_4x4);
      else
          self.m_params.set_format_mode(basis_tex_format::cETC1S); // don't really know what to set
    }))
	
	// Sets the UASTC HDR 4x4 quality vs. encoder performance tradeoff (0-4, default is 1). Higher=slower but better quality.	
    // UASTC HDR 4x4
    .function("setUASTCHDRQualityLevel", optional_override([](basis_encoder& self, int level) {
		assert((level >= uastc_hdr_4x4_codec_options::cMinLevel) && (level <= uastc_hdr_4x4_codec_options::cMaxLevel));
		self.m_params.m_uastc_hdr_4x4_options.set_quality_level(level);
    }))

    // If true the source images will be Y flipped before compression.
    // All formats
    .function("setYFlip", optional_override([](basis_encoder& self, bool y_flip_flag) {
        self.m_params.m_y_flip = y_flip_flag;
    }))

    // Enables debug output to stdout
    // All formats
    .function("setDebug", optional_override([](basis_encoder& self, bool debug_flag) {
        self.m_params.m_debug = debug_flag;
        g_debug_printf = debug_flag;
    }))

    // If true, the input is assumed to be in sRGB space. Be sure to set this correctly! (Examples: True on photos, albedo/spec maps, and false on normal maps.)
	// In HDR mode, if perceptual is true R and G are weighted higher (2.0, 3.0) than B (1.0). Otherwise the encoder uses equal weightings for each channel.
    // ETC1S, UASTC LDR 4x4, UASTC HDR 4x4
    .function("setPerceptual", optional_override([](basis_encoder& self, bool perceptual_flag) {
        self.m_params.m_perceptual = perceptual_flag;
    }))

    // Check source images for active/used alpha channels
    // ETC1S, UASTC LDR 4x4
    .function("setCheckForAlpha", optional_override([](basis_encoder& self, bool check_for_alpha_flag) {
        self.m_params.m_check_for_alpha = check_for_alpha_flag;
    }))

    // Fource output .basis/.ktx2 file to have an alpha channel
    // ETC1S, UASTC LDR 4x4
    .function("setForceAlpha", optional_override([](basis_encoder& self, bool force_alpha_flag) {
        self.m_params.m_force_alpha = force_alpha_flag;
    }))

    // Set source image component swizzle.
    // r,g,b,a - valid range is [0,3]
    // All formats (but formats without alpha will ignore a)
    .function("setSwizzle", optional_override([](basis_encoder& self, uint32_t r, uint32_t g, uint32_t b, uint32_t a) {
        assert((r < 4) && (g < 4) && (b < 4) && (a < 4));
        self.m_params.m_swizzle[0] = (char)r;
        self.m_params.m_swizzle[1] = (char)g;
        self.m_params.m_swizzle[2] = (char)b;
        self.m_params.m_swizzle[3] = (char)a;
    }))

    // ASTC HDR 6x6 options
    // Sets ASTC HDR 6x6/6x6 intermediate lambda setting. The higher this setting, the lower the bitrate.
    // ASTC HDR 6x6
    .function("setLambda", optional_override([](basis_encoder& self, float rdo_quality) {
        self.m_params.m_astc_hdr_6x6_options.m_lambda = rdo_quality;
    }))
          
    // ASTC HDR 6x6: Enables REC 2020 delta E ITP vs. REC 709 in the  encoder.
    .function("setRec2020", optional_override([](basis_encoder& self, bool rec2020) {
        self.m_params.m_astc_hdr_6x6_options.m_rec2020_bt2100_color_gamut = rec2020;
    }))

    // ASTC HDR 6x6: Enables JND (Just Noticeable Difference) optimization
    .function("setJND", optional_override([](basis_encoder& self, float thresh) {
      if (thresh == 0.0f)
      {
          self.m_params.m_astc_hdr_6x6_options.m_jnd_optimization = false;
      }
      else
      {
          self.m_params.m_astc_hdr_6x6_options.m_jnd_optimization = true;
          self.m_params.m_astc_hdr_6x6_options.m_jnd_delta_itp_thresh = thresh;
      }
    }))

    // ASTC HDR 6x6: Compression speed vs. quality level. Ranges from [0,cPackASTC6x6MaxUserCompLevel].
    .function("setASTC_HDR_6x6_Level", optional_override([](basis_encoder& self, int level) {
        self.m_params.m_astc_hdr_6x6_options.set_user_level(level);
    }))

    // ASTC HDR 6x6: Enable extra 2/3 subset patterns (slower)
    .function("setASTC_HDR_6x6_ExtraPats", optional_override([](basis_encoder& self, bool flag) {
        self.m_params.m_astc_hdr_6x6_options.m_extra_patterns_flag = flag;
    }))

    // ASTC HDR 6x6: Enable brute force pattern searching (slower)
    .function("setASTC_HDR_6x6_BruteForcePats", optional_override([](basis_encoder& self, bool flag) {
        self.m_params.m_astc_hdr_6x6_options.m_brute_force_partition_matching = flag;
    }))

    // ASTC HDR 6x6: Control gaussian filtering on very hard blocks
    .function("setASTC_HDR_6x6_SetGaussian1", optional_override([](basis_encoder& self, float strength) {
        if (strength <= 0.0f)
            self.m_params.m_astc_hdr_6x6_options.m_gaussian1_fallback = false;
        else
        {
            self.m_params.m_astc_hdr_6x6_options.m_gaussian1_fallback = true;
            self.m_params.m_astc_hdr_6x6_options.m_gaussian1_strength = strength;
        }
    }))

    // ASTC HDR 6x6
    .function("setASTC_HDR_6x6_SetGaussian2", optional_override([](basis_encoder& self, float strength) {
        if (strength <= 0.0f)
            self.m_params.m_astc_hdr_6x6_options.m_gaussian2_fallback = false;
        else
        {
            self.m_params.m_astc_hdr_6x6_options.m_gaussian2_fallback = true;
            self.m_params.m_astc_hdr_6x6_options.m_gaussian2_strength = strength;
        }
    }))

    // LDR->HDR upconversion options (all HDR modes)
    // All HDR modes
    .function("setLDR_HDR_Upconversion_sRGBToLinear", optional_override([](basis_encoder& self, bool srgb_to_linear) {
        self.m_params.m_ldr_hdr_upconversion_srgb_to_linear = srgb_to_linear;
    }))

    // All HDR modes
    .function("setLDR_HDR_Upconversion_NitMultiplier", optional_override([](basis_encoder& self, float multiplier) {
        self.m_params.m_ldr_hdr_upconversion_nit_multiplier = multiplier;
    }))

    // If true, the input is assumed to be a normal map, and all source texels will be renormalized before encoding.
    // Impacts LDR images only
    .function("setRenormalize", optional_override([](basis_encoder& self, bool renormalize_flag) {
        self.m_params.m_renormalize = renormalize_flag;
    }))

    // Sets the max # of endpoint clusters for ETC1S mode. Use instead of setQualityLevel.
    // Default is 512, range is [1,BASISU_MAX_ENDPOINT_CLUSTERS]
    // ETC1S mode
    .function("setMaxEndpointClusters", optional_override([](basis_encoder& self, uint32_t max_endpoint_clusters) {
        assert(max_endpoint_clusters <= BASISU_MAX_ENDPOINT_CLUSTERS);
        self.m_params.m_etc1s_max_endpoint_clusters = max_endpoint_clusters;
    }))

    // Sets the max # of selectors clusters for ETC1S mode. Use instead of setQualityLevel.
    // Default is 512, range is [1,BASISU_MAX_ENDPOINT_CLUSTERS]
    // ETC1S mode
    .function("setMaxSelectorClusters", optional_override([](basis_encoder& self, uint32_t max_selector_clusters) {
        assert(max_selector_clusters <= BASISU_MAX_SELECTOR_CLUSTERS);
        self.m_params.m_etc1s_max_selector_clusters = max_selector_clusters;
    }))

    // Sets the ETC1S encoder's quality level, which controls the file size vs. quality tradeoff.
    // Default is -1 (meaning unused - the compressor will use m_max_endpoint_clusters/m_max_selector_clusters instead to control the codebook sizes).
    // Range is [1,BASISU_QUALITY_MAX]
    // ETC1S mode
    .function("setQualityLevel", optional_override([](basis_encoder& self, int quality_level) {
        assert(quality_level >= -1 && quality_level <= BASISU_QUALITY_MAX);
        self.m_params.m_etc1s_quality_level = quality_level;
    }))

    // The compression_level parameter controls the encoder perf vs. file size tradeoff for ETC1S files.
    // It does not directly control file size vs. quality - see quality_level().
    // Default is BASISU_DEFAULT_COMPRESSION_LEVEL, range is [0,BASISU_MAX_COMPRESSION_LEVEL]
    // ETC1S mode
    .function("setCompressionLevel", optional_override([](basis_encoder& self, int comp_level) {
        assert(comp_level >= 0 && comp_level <= BASISU_MAX_COMPRESSION_LEVEL);
        self.m_params.m_compression_level = comp_level;
    }))

    // setNormalMapMode is the same as the basisu.exe "-normal_map" option. It tunes several codec parameters so compression works better on normal maps.
    // ETC1S/UASTC LDR 4x4/UASTC HDR 4x4
    .function("setNormalMap", optional_override([](basis_encoder& self) {
        self.m_params.m_perceptual = false;
        self.m_params.m_mip_srgb = false;
        self.m_params.m_no_selector_rdo = true;
        self.m_params.m_no_endpoint_rdo = true;
    }))

    // Sets ETC1S selector RDO threshold
    // Default is BASISU_DEFAULT_SELECTOR_RDO_THRESH, range is [0,1e+10]
    // ETC1S
    .function("setSelectorRDOThresh", optional_override([](basis_encoder& self, float selector_rdo_thresh) {
        self.m_params.m_selector_rdo_thresh = selector_rdo_thresh;
    }))

    // Sets ETC1S endpoint RDO threshold
    // Default is BASISU_DEFAULT_ENDPOINT_RDO_THRESH, range is [0,1e+10]
    // ETC1S
    .function("setEndpointRDOThresh", optional_override([](basis_encoder& self, float endpoint_rdo_thresh) {
        self.m_params.m_endpoint_rdo_thresh = endpoint_rdo_thresh;
    }))

#if BASISD_SUPPORT_KTX2
    // --- KTX2 related options
    //
    // Create .KTX2 files instead of .basis files. By default this is FALSE.
    // All formats
    .function("setCreateKTX2File", optional_override([](basis_encoder& self, bool create_ktx2_file) {
    self.m_params.m_create_ktx2_file = create_ktx2_file;
        }))

    // KTX2: Use UASTC Zstandard supercompression. Defaults to disabled or KTX2_SS_NONE.
    // Impacts UASTC LDR 4x4, UASTC HDR 4x4, and ASTC HDR 6x6 (but not ASTC HDR 6x6 intermediate)
    .function("setKTX2UASTCSupercompression", optional_override([](basis_encoder& self, bool use_zstandard) {
    self.m_params.m_ktx2_uastc_supercompression = use_zstandard ? basist::KTX2_SS_ZSTANDARD : basist::KTX2_SS_NONE;
        }))

    // KTX2: Use sRGB transfer func in the file's DFD. Default is FALSE. This should very probably match the "perceptual" setting.
    // All formats
    .function("setKTX2SRGBTransferFunc", optional_override([](basis_encoder& self, bool srgb_transfer_func) {
    self.m_params.m_ktx2_srgb_transfer_func = srgb_transfer_func;
        }))

    // TODO: Expose KTX2 key value array, other options to JavaScript. See encoder/basisu_comp.h.
#endif

    // --- Mip-map options (format independent)

    // If true mipmaps will be generated from the source images
    .function("setMipGen", optional_override([](basis_encoder& self, bool mip_gen_flag) {
        self.m_params.m_mip_gen = mip_gen_flag;
    }))

    // Set mipmap filter's scale factor
    // default is 1, range is [.000125, 4.0]
    .function("setMipScale", optional_override([](basis_encoder& self, float mip_scale) {
        self.m_params.m_mip_scale = mip_scale;
    }))

    // Sets the mipmap filter to apply
    // mip_filter must be < BASISU_MAX_RESAMPLER_FILTERS
    // See the end of basisu_resample_filters.cpp: g_resample_filters[]
    .function("setMipFilter", optional_override([](basis_encoder& self, uint32_t mip_filter) {
        assert(mip_filter < g_num_resample_filters);
        if (mip_filter < g_num_resample_filters)
            self.m_params.m_mip_filter = g_resample_filters[mip_filter].name;
    }))

    // If true mipmap filtering occurs in sRGB space - this generally should match the perceptual parameter.
    .function("setMipSRGB", optional_override([](basis_encoder& self, bool mip_srgb_flag) {
        self.m_params.m_mip_srgb = mip_srgb_flag;
    }))

    // If true, the input is assumed to be a normal map, and the texels of each mipmap will be renormalized before encoding.
    .function("setMipRenormalize", optional_override([](basis_encoder& self, bool mip_renormalize_flag) {
        self.m_params.m_mip_renormalize = mip_renormalize_flag;
    }))

    // If true the source texture will be sampled using wrap addressing during mipmap generation, otherwise clamp.
    .function("setMipWrapping", optional_override([](basis_encoder& self, bool mip_wrapping_flag) {
        self.m_params.m_mip_wrapping = mip_wrapping_flag;
    }))

    // Sets the mipmap generator's smallest allowed dimension.
    // default is 1, range is [1,16384]
    .function("setMipSmallestDimension", optional_override([](basis_encoder& self, int mip_smallest_dimension) {
        self.m_params.m_mip_smallest_dimension = mip_smallest_dimension;
    }))

    // Sets the .basis texture type.
    // cBASISTexTypeVideoFrames changes the encoder into video mode.
    // tex_type is enum basis_texture_type
    // default is cBASISTexType2D
    // All formats
    .function("setTexType", optional_override([](basis_encoder& self, uint32_t tex_type) {
        assert(tex_type < cBASISTexTypeTotal);
        self.m_params.m_tex_type = (basist::basis_texture_type)tex_type;
    }))

    // All formats (.basis only)
    .function("setUserData0", optional_override([](basis_encoder& self, uint32_t userdata0) {
        self.m_params.m_userdata0 = userdata0;
    }))

    // All formats (.basis only)
    .function("setUserData1", optional_override([](basis_encoder& self, uint32_t userdata1) {
        self.m_params.m_userdata1 = userdata1;
    }))

    // UASTC LDR 4x4 specific flags.

    // Sets the UASTC encoding performance vs. quality tradeoff, and other lesser used UASTC encoder flags.
    // This is a combination of flags. See cPackUASTCLevelDefault, etc.
    // UASTC LDR 4x4
    .function("setPackUASTCFlags", optional_override([](basis_encoder& self, uint32_t pack_uastc_flags) {
        assert((pack_uastc_flags & cPackUASTCLevelMask) >= cPackUASTCLevelFastest);
        assert((pack_uastc_flags & cPackUASTCLevelMask) <= cPackUASTCLevelVerySlow);
        self.m_params.m_pack_uastc_ldr_4x4_flags = pack_uastc_flags;
    }))

    // If true, the RDO post-processor will be applied to the encoded UASTC texture data.
    // UASTC LDR 4x4
    .function("setRDOUASTC", optional_override([](basis_encoder& self, bool rdo_uastc) {
        self.m_params.m_rdo_uastc_ldr_4x4 = rdo_uastc;
    }))

    // Default is 1.0 range is [0.001, 10.0]
    // UASTC LDR 4x4
    .function("setRDOUASTCQualityScalar", optional_override([](basis_encoder& self, float rdo_quality) {
        self.m_params.m_rdo_uastc_ldr_4x4_quality_scalar = rdo_quality;
    }))
            
    // Default is BASISU_RDO_UASTC_DICT_SIZE_DEFAULT, range is [BASISU_RDO_UASTC_DICT_SIZE_MIN, BASISU_RDO_UASTC_DICT_SIZE_MAX]
    // UASTC LDR 4x4
    .function("setRDOUASTCDictSize", optional_override([](basis_encoder& self, int dict_size) {
        assert((dict_size >= BASISU_RDO_UASTC_DICT_SIZE_MIN) && (dict_size <= BASISU_RDO_UASTC_DICT_SIZE_MAX));
        self.m_params.m_rdo_uastc_ldr_4x4_dict_size = dict_size;
    }))

    // Default is UASTC_RDO_DEFAULT_MAX_ALLOWED_RMS_INCREASE_RATIO, range is [01, 100.0]
    // UASTC LDR 4x4
    .function("setRDOUASTCMaxAllowedRMSIncreaseRatio", optional_override([](basis_encoder& self, float rdo_uastc_max_allowed_rms_increase_ratio) {
        self.m_params.m_rdo_uastc_ldr_4x4_max_allowed_rms_increase_ratio = rdo_uastc_max_allowed_rms_increase_ratio;
    }))

    // Default is UASTC_RDO_DEFAULT_SKIP_BLOCK_RMS_THRESH, range is [.01f, 100.0f]
    // UASTC LDR 4x4
    .function("setRDOUASTCSkipBlockRMSThresh", optional_override([](basis_encoder& self, float rdo_uastc_skip_block_rms_thresh) {
        self.m_params.m_rdo_uastc_ldr_4x4_skip_block_rms_thresh = rdo_uastc_skip_block_rms_thresh;
    }))

    // --- Low level options

    // Disables ETC1S selector RDO
    .function("setNoSelectorRDO", optional_override([](basis_encoder& self, bool no_selector_rdo_flag) {
        self.m_params.m_no_selector_rdo = no_selector_rdo_flag;
    }))

    // Disables ETC1S endpoint RDO
    .function("setNoEndpointRDO", optional_override([](basis_encoder& self, bool no_endpoint_rdo_flag) {
        self.m_params.m_no_endpoint_rdo = no_endpoint_rdo_flag;
    }))

    // Display output PSNR statistics
    // All formats
    .function("setComputeStats", optional_override([](basis_encoder& self, bool compute_stats_flag) {
        self.m_params.m_compute_stats = compute_stats_flag;
    }))

    // Write output .PNG/.EXR files for debugging
    // All formats
    .function("setDebugImages", optional_override([](basis_encoder& self, bool debug_images_flag) {
        self.m_params.m_debug_images = debug_images_flag;
    }))

  ;
#endif // BASISU_SUPPORT_ENCODING

}
