Add high level compression API to prep for cmgen integration.
This commit is contained in:
@@ -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_ */
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user