diff --git a/libs/imageio/include/imageio/BlockCompression.h b/libs/imageio/include/imageio/BlockCompression.h index 5e569e6e95..f63a9beaf2 100644 --- a/libs/imageio/include/imageio/BlockCompression.h +++ b/libs/imageio/include/imageio/BlockCompression.h @@ -173,6 +173,19 @@ CompressedTexture s3tcCompress(const LinearImage& source, S3tcConfig config); // with an invalid format. S3tcConfig s3tcParseOptionString(const std::string& options); +/////////////////////////////////////////////////////////////////////////////////////////////////// + +struct CompressionConfig { + enum { INVALID, ASTC, S3TC, ETC } type; + AstcConfig astc; + S3tcConfig s3tc; + EtcConfig etc; +}; + +bool parseOptionString(const std::string& options, CompressionConfig* config); + +CompressedTexture compressTexture(const CompressionConfig& config, const LinearImage& image); + } // namespace image #endif /* IMAGEIO_BLOCKCOMPRESSION_H_ */ diff --git a/libs/imageio/src/BlockCompression.cpp b/libs/imageio/src/BlockCompression.cpp index 3d7a937a37..9361a407eb 100644 --- a/libs/imageio/src/BlockCompression.cpp +++ b/libs/imageio/src/BlockCompression.cpp @@ -515,6 +515,40 @@ EtcConfig etcParseOptionString(const std::string& options) { return result; } +bool parseOptionString(const string& options, CompressionConfig* config) { + config->type = CompressionConfig::INVALID; + if (options.substr(0, 5) == "astc_") { + config->astc = astcParseOptionString(options.substr(5)); + if (config->astc.blocksize[0] != 0) { + config->type = CompressionConfig::ASTC; + } + } else if (options.substr(0, 5) == "s3tc_") { + config->s3tc = s3tcParseOptionString(options.substr(5)); + if (config->s3tc.format != CompressedFormat::INVALID) { + config->type = CompressionConfig::S3TC; + } + } else if (options.substr(0, 4) == "etc_") { + config->etc = etcParseOptionString(options.substr(4)); + if (config->etc.format != CompressedFormat::INVALID) { + config->type = CompressionConfig::ETC; + } + } + return config->type != CompressionConfig::INVALID; +} + +CompressedTexture compressTexture(const CompressionConfig& config, const LinearImage& image) { + if (config.type == CompressionConfig::ASTC) { + return astcCompress(image, config.astc); + } + if (config.type == CompressionConfig::S3TC) { + return s3tcCompress(image, config.s3tc); + } + if (config.type == CompressionConfig::ETC) { + return etcCompress(image, config.etc); + } + return {}; +} + static LinearImage extendToFourChannels(LinearImage original) { LinearImage source = original; const uint32_t width = source.getWidth(); diff --git a/tools/mipgen/src/main.cpp b/tools/mipgen/src/main.cpp index 774e6b7ff2..3e3117cf11 100644 --- a/tools/mipgen/src/main.cpp +++ b/tools/mipgen/src/main.cpp @@ -286,19 +286,10 @@ int main(int argc, char* argv[]) { info.glInternalFormat = info.glBaseInternalFormat = KtxBundle::LUMINANCE; } - AstcConfig astcConfig {}; - S3tcConfig s3tcConfig {}; - EtcConfig etcConfig {}; + CompressionConfig config {}; if (!g_compression.empty()) { - if (g_compression.substr(0, 5) == "astc_") { - astcConfig = astcParseOptionString(g_compression.substr(5)); - } else if (g_compression.substr(0, 5) == "s3tc_") { - s3tcConfig = s3tcParseOptionString(g_compression.substr(5)); - } else if (g_compression.substr(0, 4) == "etc_") { - etcConfig = etcParseOptionString(g_compression.substr(4)); - } - if (astcConfig.blocksize[0] == 0 && s3tcConfig.format == CompressedFormat::INVALID - && etcConfig.format == CompressedFormat::INVALID) { + bool valid = parseOptionString(g_compression, &config); + if (!valid) { cerr << "Unrecognized compression: " << g_compression << endl; return 1; } @@ -315,13 +306,13 @@ int main(int argc, char* argv[]) { image = vectorsToColors(image); } std::unique_ptr data; - if (astcConfig.blocksize[0] > 0) { - // The ASTC encoder calls exit(1) if it fails, so it's very useful to print some + if (config.type != CompressionConfig::INVALID) { + // Some encoders call exit(1) upon failure, so it's very useful to print some // source image information here for when this is invoked from a build script. - // Note that the encoder has limitations in terms of image size. - printf("Starting ASTC compression for %s (%dx%d)\n", inputPath.getName().c_str(), + // Note that some encoders also have limitations in terms of image size. + printf("Starting compression for %s (%dx%d)\n", inputPath.getName().c_str(), image.getWidth(), image.getHeight()); - CompressedTexture tex = astcCompress(image, astcConfig); + CompressedTexture tex = compressTexture(config, image); // Add newline here because the ASTC encoder has a progress indicator that issues a // carriage return without a line feed. putc('\n', stdout); @@ -329,22 +320,6 @@ int main(int argc, char* argv[]) { info.glInternalFormat = (uint32_t) tex.format; return; } - if (s3tcConfig.format != CompressedFormat::INVALID) { - printf("Starting S3TC compression for %s (%dx%d)\n", inputPath.getName().c_str(), - image.getWidth(), image.getHeight()); - CompressedTexture tex = s3tcCompress(image, s3tcConfig); - container.setBlob({mip++}, tex.data.get(), tex.size); - info.glInternalFormat = (uint32_t) tex.format; - return; - } - if (etcConfig.format != CompressedFormat::INVALID) { - printf("Starting ETC compression for %s (%dx%d)\n", inputPath.getName().c_str(), - image.getWidth(), image.getHeight()); - CompressedTexture tex = etcCompress(image, etcConfig); - container.setBlob({mip++}, tex.data.get(), tex.size); - info.glInternalFormat = (uint32_t) tex.format; - return; - } if (g_grayscale && g_linearized) { data = fromLinearToGrayscale(image); } else if (g_grayscale) {