Add high level compression API to prep for cmgen integration.

This commit is contained in:
Philip Rideout
2018-10-04 15:48:36 -07:00
parent 311d2804bb
commit da698f2e36
3 changed files with 55 additions and 33 deletions

View File

@@ -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_ */

View File

@@ -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();

View File

@@ -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<uint8_t[]> 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<uint8_t>(image);
} else if (g_grayscale) {