Adding initial support for user-provided mipmaps. This isn't hooked up to the command line tool or the JS wrappers yet.
diff --git a/encoder/basisu_comp.cpp b/encoder/basisu_comp.cpp
index 0e57a4c..e9c9d1a 100644
--- a/encoder/basisu_comp.cpp
+++ b/encoder/basisu_comp.cpp
@@ -71,8 +71,16 @@
debug_printf("Has global selector codebook: %i\n", m_params.m_pSel_codebook != nullptr);
- debug_printf("Source images: %u, source filenames: %u, source alpha filenames: %i\n",
- (uint32_t)m_params.m_source_images.size(), (uint32_t)m_params.m_source_filenames.size(), (uint32_t)m_params.m_source_alpha_filenames.size());
+ debug_printf("Source images: %u, source filenames: %u, source alpha filenames: %i, Source mipmap images: %u\n",
+ m_params.m_source_images.size(), m_params.m_source_filenames.size(), m_params.m_source_alpha_filenames.size(), m_params.m_source_mipmap_images.size());
+
+ if (m_params.m_source_mipmap_images.size())
+ {
+ debug_printf("m_source_mipmap_images array sizes:\n");
+ for (uint32_t i = 0; i < m_params.m_source_mipmap_images.size(); i++)
+ debug_printf("%u ", m_params.m_source_mipmap_images[i].size());
+ debug_printf("\n");
+ }
PRINT_BOOL_VALUE(m_uastc);
PRINT_BOOL_VALUE(m_y_flip);
@@ -540,7 +548,7 @@
debug_printf("Resampling to %ix%i\n", new_width, new_height);
- // TODO: A box filter - kaiser looks too sharp on video.
+ // TODO: A box filter - kaiser looks too sharp on video. Let the caller control this.
image temp_img(new_width, new_height);
image_resample(file_image, temp_img, m_params.m_perceptual, "box"); // "kaiser");
temp_img.swap(file_image);
@@ -562,6 +570,39 @@
source_filenames.push_back(pSource_filename);
}
+ // Check if the caller has generated their own mipmaps.
+ if (m_params.m_source_mipmap_images.size())
+ {
+ // Make sure they've passed us enough mipmap chains.
+ if ((m_params.m_source_images.size() != m_params.m_source_mipmap_images.size()) || (total_source_files != m_params.m_source_images.size()))
+ {
+ error_printf("basis_compressor::read_source_images(): m_params.m_source_mipmap_images.size() must equal m_params.m_source_images.size()!\n");
+ return false;
+ }
+
+ // Check if any of the user-supplied mipmap levels has alpha.
+ // We're assuming the user has already preswizzled their mipmap source images.
+ if (!m_any_source_image_has_alpha)
+ {
+ for (uint32_t source_file_index = 0; source_file_index < total_source_files; source_file_index++)
+ {
+ for (uint32_t mip_index = 0; mip_index < m_params.m_source_mipmap_images[source_file_index].size(); mip_index++)
+ {
+ const image& mip_img = m_params.m_source_mipmap_images[source_file_index][mip_index];
+
+ if (mip_img.has_alpha())
+ {
+ m_any_source_image_has_alpha = true;
+ break;
+ }
+ }
+
+ if (m_any_source_image_has_alpha)
+ break;
+ }
+ }
+ }
+
debug_printf("Any source image has alpha: %u\n", m_any_source_image_has_alpha);
for (uint32_t source_file_index = 0; source_file_index < total_source_files; source_file_index++)
@@ -573,10 +614,22 @@
basisu::vector<image> slices;
slices.reserve(32);
+
+ // The first (largest) mipmap level.
slices.push_back(file_image);
-
- if (m_params.m_mip_gen)
+
+ if (m_params.m_source_mipmap_images.size())
{
+ // User-provided mipmaps for each layer or image in the texture array.
+ for (uint32_t mip_index = 0; mip_index < m_params.m_source_mipmap_images[source_file_index].size(); mip_index++)
+ {
+ const image& mip_img = m_params.m_source_mipmap_images[source_file_index][mip_index];
+ slices.push_back(mip_img);
+ }
+ }
+ else if (m_params.m_mip_gen)
+ {
+ // Automatically generate mipmaps.
if (!generate_mipmaps(file_image, slices, m_any_source_image_has_alpha))
return false;
}
diff --git a/encoder/basisu_comp.h b/encoder/basisu_comp.h
index fd8a913..1964565 100644
--- a/encoder/basisu_comp.h
+++ b/encoder/basisu_comp.h
@@ -241,6 +241,7 @@
m_source_alpha_filenames.clear();
m_source_images.clear();
+ m_source_mipmap_images.clear();
m_out_filename.clear();
@@ -329,7 +330,11 @@
basisu::vector<std::string> m_source_alpha_filenames;
basisu::vector<image> m_source_images;
- // TODO: Allow caller to supply their own mipmaps
+
+ // Stores mipmaps starting from level 1. Level 0 is still stored in m_source_images, as usual.
+ // If m_source_mipmaps isn't empty, automatic mipmap generation isn't done. m_source_mipmaps.size() MUST equal m_source_images.size() or the compressor returns an error.
+ // Note the compressor doesn't apply the user-provided swizzling (in m_swizzle), or any other preprocessing, to these images.
+ basisu::vector< basisu::vector<image> > m_source_mipmap_images;
// Filename of the output basis file
std::string m_out_filename;
diff --git a/webgl/encoder/build/basis_encoder.wasm b/webgl/encoder/build/basis_encoder.wasm
index 379d4a9..e64b734 100644
--- a/webgl/encoder/build/basis_encoder.wasm
+++ b/webgl/encoder/build/basis_encoder.wasm
Binary files differ