add sRGB support to egg-palettize, sluminance to egg

This commit is contained in:
Brian Lach 2023-02-14 11:02:35 +01:00 committed by rdb
parent 7820c7a363
commit 52d59b2df7
13 changed files with 133 additions and 7 deletions

View File

@ -504,6 +504,7 @@ has_alpha_channel(int num_components) const {
case F_green: case F_green:
case F_blue: case F_blue:
case F_luminance: case F_luminance:
case F_sluminance:
case F_rgb: case F_rgb:
case F_rgb12: case F_rgb12:
case F_rgb8: case F_rgb8:
@ -520,6 +521,7 @@ has_alpha_channel(int num_components) const {
case F_luminance_alpha: case F_luminance_alpha:
case F_luminance_alphamask: case F_luminance_alphamask:
case F_sluminance_alpha:
case F_rgba: case F_rgba:
case F_rgbm: case F_rgbm:
case F_rgba12: case F_rgba12:
@ -732,6 +734,10 @@ string_format(const string &string) {
return F_luminance_alpha; return F_luminance_alpha;
} else if (cmp_nocase_uh(string, "luminance_alphamask") == 0) { } else if (cmp_nocase_uh(string, "luminance_alphamask") == 0) {
return F_luminance_alphamask; return F_luminance_alphamask;
} else if (cmp_nocase_uh(string, "sluminance") == 0) {
return F_sluminance;
} else if (cmp_nocase_uh(string, "sluminance_alpha") == 0) {
return F_sluminance_alpha;
} else { } else {
return F_unspecified; return F_unspecified;
} }
@ -1179,6 +1185,10 @@ ostream &operator << (ostream &out, EggTexture::Format format) {
return out << "luminance_alpha"; return out << "luminance_alpha";
case EggTexture::F_luminance_alphamask: case EggTexture::F_luminance_alphamask:
return out << "luminance_alphamask"; return out << "luminance_alphamask";
case EggTexture::F_sluminance:
return out << "sluminance";
case EggTexture::F_sluminance_alpha:
return out << "sluminance_alpha";
} }
nassertr(false, out); nassertr(false, out);

View File

@ -63,7 +63,8 @@ PUBLISHED:
F_luminance_alpha, F_luminance_alphamask, F_luminance_alpha, F_luminance_alphamask,
// Only for compatibility with .bam, use is discouraged! // Only for compatibility with .bam, use is discouraged!
F_srgb, F_srgb_alpha F_srgb, F_srgb_alpha,
F_sluminance, F_sluminance_alpha
}; };
enum CompressionMode { enum CompressionMode {
CM_default, CM_off, CM_on, CM_default, CM_off, CM_on,

View File

@ -887,12 +887,14 @@ load_texture(TextureDef &def, EggTexture *egg_tex) {
case EggTexture::F_blue: case EggTexture::F_blue:
case EggTexture::F_alpha: case EggTexture::F_alpha:
case EggTexture::F_luminance: case EggTexture::F_luminance:
case EggTexture::F_sluminance:
wanted_channels = 1; wanted_channels = 1;
wanted_alpha = false; wanted_alpha = false;
break; break;
case EggTexture::F_luminance_alpha: case EggTexture::F_luminance_alpha:
case EggTexture::F_luminance_alphamask: case EggTexture::F_luminance_alphamask:
case EggTexture::F_sluminance_alpha:
wanted_channels = 2; wanted_channels = 2;
wanted_alpha = true; wanted_alpha = true;
break; break;
@ -1225,6 +1227,7 @@ check_texture_attributes(Texture *tex, SamplerState sampler, const EggTexture *e
case EggTexture::F_blue: case EggTexture::F_blue:
case EggTexture::F_alpha: case EggTexture::F_alpha:
case EggTexture::F_luminance: case EggTexture::F_luminance:
case EggTexture::F_sluminance:
break; break;
default: default:
egg2pg_cat.warning() egg2pg_cat.warning()
@ -1238,6 +1241,7 @@ check_texture_attributes(Texture *tex, SamplerState sampler, const EggTexture *e
case EggTexture::F_unspecified: case EggTexture::F_unspecified:
case EggTexture::F_luminance_alpha: case EggTexture::F_luminance_alpha:
case EggTexture::F_luminance_alphamask: case EggTexture::F_luminance_alphamask:
case EggTexture::F_sluminance:
break; break;
default: default:
egg2pg_cat.error() egg2pg_cat.error()
@ -1389,6 +1393,12 @@ convert_format(EggTexture::Format format, EggTexture::EnvType env) {
case EggTexture::F_srgb_alpha: case EggTexture::F_srgb_alpha:
return Texture::F_srgb_alpha; return Texture::F_srgb_alpha;
case EggTexture::F_sluminance:
return Texture::F_sluminance;
case EggTexture::F_sluminance_alpha:
return Texture::F_sluminance_alpha;
} }
egg2pg_cat.warning() egg2pg_cat.warning()

View File

@ -1462,6 +1462,12 @@ get_egg_texture(Texture *tex) {
case Texture::F_srgb_alpha: case Texture::F_srgb_alpha:
temp.set_format(EggTexture::F_srgb_alpha); temp.set_format(EggTexture::F_srgb_alpha);
break; break;
case Texture::F_sluminance:
temp.set_format(EggTexture::F_sluminance);
break;
case Texture::F_sluminance_alpha:
temp.set_format(EggTexture::F_sluminance_alpha);
break;
default: default:
break; break;
} }

View File

@ -321,6 +321,12 @@ describe_input_file() {
"match the number of channels. As above, any valid egg texture " "match the number of channels. As above, any valid egg texture "
"format may be used, e.g. force-rgba12, force-rgb5, etc.\n\n"); "format may be used, e.g. force-rgba12, force-rgb5, etc.\n\n");
show_text(" srgb", 10,
"This specifies that this texture is in sRGB space and the format "
"should be changed to reflect that. The texture format will be "
"changed to the appropriate sRGB equivalent based on the number "
"of image channels.\n\n");
show_text(" keep-format", 10, show_text(" keep-format", 10,
"This specifies that the image format requested by an egg file " "This specifies that the image format requested by an egg file "
"should be exactly preserved, without attempting to optimize " "should be exactly preserved, without attempting to optimize "

View File

@ -39,7 +39,7 @@ Palettizer *pal = nullptr;
// update egg-palettize to write out additional information to its pi file, // update egg-palettize to write out additional information to its pi file,
// without having it increment the bam version number for all bam and boo // without having it increment the bam version number for all bam and boo
// files anywhere in the world. // files anywhere in the world.
int Palettizer::_pi_version = 20; int Palettizer::_pi_version = 21;
/* /*
* Updated to version 8 on 32003 to remove extensions from texture key names. * Updated to version 8 on 32003 to remove extensions from texture key names.
* Updated to version 9 on 41303 to add a few properties in various places. * Updated to version 9 on 41303 to add a few properties in various places.
@ -54,6 +54,7 @@ int Palettizer::_pi_version = 20;
* TextureProperties::_quality_level. Updated to version 19 on 71609 to add * TextureProperties::_quality_level. Updated to version 19 on 71609 to add
* PaletteGroup::_override_margin Updated to version 20 on 72709 to add * PaletteGroup::_override_margin Updated to version 20 on 72709 to add
* TexturePlacement::_swapTextures * TexturePlacement::_swapTextures
* Updated to version 21 on 110120 to add sRGB support.
*/ */
int Palettizer::_min_pi_version = 8; int Palettizer::_min_pi_version = 8;

View File

@ -360,6 +360,8 @@ post_txa_file() {
_properties._anisotropic_degree = _request._anisotropic_degree; _properties._anisotropic_degree = _request._anisotropic_degree;
_properties._srgb = _request._srgb;
if (_properties._color_type == nullptr) { if (_properties._color_type == nullptr) {
_properties._color_type = _request._properties._color_type; _properties._color_type = _request._properties._color_type;
_properties._alpha_type = _request._properties._alpha_type; _properties._alpha_type = _request._properties._alpha_type;

View File

@ -42,6 +42,7 @@ TextureProperties() {
_anisotropic_degree = 0; _anisotropic_degree = 0;
_color_type = nullptr; _color_type = nullptr;
_alpha_type = nullptr; _alpha_type = nullptr;
_srgb = false;
} }
/** /**
@ -59,6 +60,7 @@ TextureProperties(const TextureProperties &copy) :
_anisotropic_degree(copy._anisotropic_degree), _anisotropic_degree(copy._anisotropic_degree),
_color_type(copy._color_type), _color_type(copy._color_type),
_alpha_type(copy._alpha_type), _alpha_type(copy._alpha_type),
_srgb(copy._srgb),
_got_num_channels(copy._got_num_channels), _got_num_channels(copy._got_num_channels),
_num_channels(copy._num_channels), _num_channels(copy._num_channels),
_effective_num_channels(copy._effective_num_channels) _effective_num_channels(copy._effective_num_channels)
@ -83,6 +85,7 @@ operator = (const TextureProperties &copy) {
_num_channels = copy._num_channels; _num_channels = copy._num_channels;
_effective_num_channels = copy._effective_num_channels; _effective_num_channels = copy._effective_num_channels;
_format = copy._format; _format = copy._format;
_srgb = copy._srgb;
} }
/** /**
@ -168,6 +171,8 @@ uses_alpha() const {
case EggTexture::F_alpha: case EggTexture::F_alpha:
case EggTexture::F_luminance_alpha: case EggTexture::F_luminance_alpha:
case EggTexture::F_luminance_alphamask: case EggTexture::F_luminance_alphamask:
case EggTexture::F_srgb_alpha:
case EggTexture::F_sluminance_alpha:
return true; return true;
default: default:
@ -210,6 +215,9 @@ update_properties(const TextureProperties &other) {
_num_channels = other._num_channels; _num_channels = other._num_channels;
_effective_num_channels = _num_channels; _effective_num_channels = _num_channels;
} }
_srgb = other._srgb;
if (_force_format) { if (_force_format) {
// If we've forced our own format, it doesn't change. // If we've forced our own format, it doesn't change.
} else if (other._force_format) { } else if (other._force_format) {
@ -260,6 +268,7 @@ fully_define() {
case EggTexture::F_luminance_alpha: case EggTexture::F_luminance_alpha:
case EggTexture::F_luminance_alphamask: case EggTexture::F_luminance_alphamask:
case EggTexture::F_sluminance_alpha:
_num_channels = 2; _num_channels = 2;
break; break;
@ -268,6 +277,7 @@ fully_define() {
case EggTexture::F_blue: case EggTexture::F_blue:
case EggTexture::F_alpha: case EggTexture::F_alpha:
case EggTexture::F_luminance: case EggTexture::F_luminance:
case EggTexture::F_sluminance:
_num_channels = 1; _num_channels = 1;
break; break;
} }
@ -294,6 +304,8 @@ fully_define() {
case EggTexture::F_luminance_alphamask: case EggTexture::F_luminance_alphamask:
case EggTexture::F_srgb: case EggTexture::F_srgb:
case EggTexture::F_srgb_alpha: case EggTexture::F_srgb_alpha:
case EggTexture::F_sluminance:
case EggTexture::F_sluminance_alpha:
break; break;
case EggTexture::F_rgba12: case EggTexture::F_rgba12:
@ -323,6 +335,7 @@ fully_define() {
case EggTexture::F_blue: case EggTexture::F_blue:
case EggTexture::F_alpha: case EggTexture::F_alpha:
case EggTexture::F_luminance: case EggTexture::F_luminance:
case EggTexture::F_sluminance:
break; break;
// These formats suggest an alpha channel; they are quietly replaced // These formats suggest an alpha channel; they are quietly replaced
@ -332,8 +345,16 @@ fully_define() {
_format = EggTexture::F_luminance; _format = EggTexture::F_luminance;
break; break;
case EggTexture::F_sluminance_alpha:
_format = EggTexture::F_sluminance;
break;
default: default:
_format = EggTexture::F_luminance; if (_srgb) {
_format = EggTexture::F_sluminance;
} else {
_format = EggTexture::F_luminance;
}
} }
break; break;
@ -341,6 +362,7 @@ fully_define() {
switch (_format) { switch (_format) {
case EggTexture::F_luminance_alpha: case EggTexture::F_luminance_alpha:
case EggTexture::F_luminance_alphamask: case EggTexture::F_luminance_alphamask:
case EggTexture::F_sluminance_alpha:
break; break;
// These formats implicitly reduce the number of channels to 1. // These formats implicitly reduce the number of channels to 1.
@ -349,10 +371,15 @@ fully_define() {
case EggTexture::F_blue: case EggTexture::F_blue:
case EggTexture::F_alpha: case EggTexture::F_alpha:
case EggTexture::F_luminance: case EggTexture::F_luminance:
case EggTexture::F_sluminance:
break; break;
default: default:
_format = EggTexture::F_luminance_alpha; if (_srgb) {
_format = EggTexture::F_sluminance_alpha;
} else {
_format = EggTexture::F_luminance_alpha;
}
} }
break; break;
@ -363,6 +390,7 @@ fully_define() {
case EggTexture::F_rgb8: case EggTexture::F_rgb8:
case EggTexture::F_rgb5: case EggTexture::F_rgb5:
case EggTexture::F_rgb332: case EggTexture::F_rgb332:
case EggTexture::F_srgb:
break; break;
// These formats suggest an alpha channel; they are quietly replaced // These formats suggest an alpha channel; they are quietly replaced
@ -382,10 +410,15 @@ fully_define() {
case EggTexture::F_blue: case EggTexture::F_blue:
case EggTexture::F_alpha: case EggTexture::F_alpha:
case EggTexture::F_luminance: case EggTexture::F_luminance:
case EggTexture::F_sluminance:
break; break;
default: default:
_format = EggTexture::F_rgb; if (_srgb) {
_format = EggTexture::F_srgb;
} else {
_format = EggTexture::F_rgb;
}
} }
break; break;
@ -397,6 +430,7 @@ fully_define() {
case EggTexture::F_rgba8: case EggTexture::F_rgba8:
case EggTexture::F_rgba4: case EggTexture::F_rgba4:
case EggTexture::F_rgba5: case EggTexture::F_rgba5:
case EggTexture::F_srgb_alpha:
break; break;
// These formats implicitly reduce the number of channels to 3. // These formats implicitly reduce the number of channels to 3.
@ -405,12 +439,14 @@ fully_define() {
case EggTexture::F_rgb8: case EggTexture::F_rgb8:
case EggTexture::F_rgb5: case EggTexture::F_rgb5:
case EggTexture::F_rgb332: case EggTexture::F_rgb332:
case EggTexture::F_srgb:
_effective_num_channels = 3; _effective_num_channels = 3;
break; break;
// These formats implicitly reduce the number of channels to 2. // These formats implicitly reduce the number of channels to 2.
case EggTexture::F_luminance_alpha: case EggTexture::F_luminance_alpha:
case EggTexture::F_luminance_alphamask: case EggTexture::F_luminance_alphamask:
case EggTexture::F_sluminance_alpha:
_effective_num_channels = 2; _effective_num_channels = 2;
break; break;
@ -420,15 +456,40 @@ fully_define() {
case EggTexture::F_blue: case EggTexture::F_blue:
case EggTexture::F_alpha: case EggTexture::F_alpha:
case EggTexture::F_luminance: case EggTexture::F_luminance:
case EggTexture::F_sluminance:
_effective_num_channels = 1; _effective_num_channels = 1;
break; break;
default: default:
_format = EggTexture::F_rgba; if (_srgb) {
_format = EggTexture::F_srgb_alpha;
} else {
_format = EggTexture::F_rgba;
}
} }
} }
} }
// Respect the _srgb flag. If this is set, it means the texture is in sRGB
// space and the format should be changed to reflect that.
if (_srgb) {
switch (_num_channels) {
case 1:
_format = EggTexture::F_sluminance;
break;
case 2:
_format = EggTexture::F_sluminance_alpha;
break;
case 3:
_format = EggTexture::F_srgb;
break;
case 4:
default:
_format = EggTexture::F_srgb_alpha;
break;
}
}
switch (_minfilter) { switch (_minfilter) {
case EggTexture::FT_unspecified: case EggTexture::FT_unspecified:
_minfilter = EggTexture::FT_linear; _minfilter = EggTexture::FT_linear;
@ -504,6 +565,9 @@ operator < (const TextureProperties &other) const {
if (_anisotropic_degree != other._anisotropic_degree) { if (_anisotropic_degree != other._anisotropic_degree) {
return _anisotropic_degree < other._anisotropic_degree; return _anisotropic_degree < other._anisotropic_degree;
} }
if (_srgb != other._srgb) {
return _srgb < other._srgb;
}
if (_color_type != other._color_type) { if (_color_type != other._color_type) {
return _color_type < other._color_type; return _color_type < other._color_type;
} }
@ -525,6 +589,7 @@ operator == (const TextureProperties &other) const {
_magfilter == other._magfilter && _magfilter == other._magfilter &&
_quality_level == other._quality_level && _quality_level == other._quality_level &&
_anisotropic_degree == other._anisotropic_degree && _anisotropic_degree == other._anisotropic_degree &&
_srgb == other._srgb &&
_color_type == other._color_type && _color_type == other._color_type &&
(_color_type == nullptr || (_color_type == nullptr ||
_alpha_type == other._alpha_type)); _alpha_type == other._alpha_type));
@ -606,6 +671,12 @@ get_format_string(EggTexture::Format format) {
case EggTexture::F_srgb_alpha: case EggTexture::F_srgb_alpha:
return "sa"; return "sa";
case EggTexture::F_sluminance:
return "sl";
case EggTexture::F_sluminance_alpha:
return "st";
} }
return "x"; return "x";
@ -779,6 +850,7 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
datagram.add_int32((int)_magfilter); datagram.add_int32((int)_magfilter);
datagram.add_int32((int)_quality_level); datagram.add_int32((int)_quality_level);
datagram.add_int32(_anisotropic_degree); datagram.add_int32(_anisotropic_degree);
datagram.add_bool(_srgb);
writer->write_pointer(datagram, _color_type); writer->write_pointer(datagram, _color_type);
writer->write_pointer(datagram, _alpha_type); writer->write_pointer(datagram, _alpha_type);
} }
@ -852,6 +924,10 @@ fillin(DatagramIterator &scan, BamReader *manager) {
} }
_anisotropic_degree = scan.get_int32(); _anisotropic_degree = scan.get_int32();
if (Palettizer::_read_pi_version >= 21) {
_srgb = scan.get_bool();
}
manager->read_pointer(scan); // _color_type manager->read_pointer(scan); // _color_type
manager->read_pointer(scan); // _alpha_type manager->read_pointer(scan); // _alpha_type
} }

View File

@ -62,6 +62,7 @@ public:
int _anisotropic_degree; int _anisotropic_degree;
PNMFileType *_color_type; PNMFileType *_color_type;
PNMFileType *_alpha_type; PNMFileType *_alpha_type;
bool _srgb;
private: private:
static std::string get_format_string(EggTexture::Format format); static std::string get_format_string(EggTexture::Format format);

View File

@ -21,6 +21,7 @@ TextureRequest::
TextureRequest() { TextureRequest() {
_got_size = false; _got_size = false;
_got_num_channels = false; _got_num_channels = false;
_srgb = false;
_x_size = 0; _x_size = 0;
_y_size = 0; _y_size = 0;
_num_channels = 0; _num_channels = 0;

View File

@ -41,6 +41,7 @@ public:
bool _force_format; bool _force_format;
bool _generic_format; bool _generic_format;
bool _keep_format; bool _keep_format;
bool _srgb;
EggTexture::FilterType _minfilter; EggTexture::FilterType _minfilter;
EggTexture::FilterType _magfilter; EggTexture::FilterType _magfilter;
int _anisotropic_degree; int _anisotropic_degree;

View File

@ -179,6 +179,9 @@ parse(const string &line) {
} else if (word == "cont") { } else if (word == "cont") {
_keywords.push_back(KW_cont); _keywords.push_back(KW_cont);
} else if (word == "srgb") {
_keywords.push_back(KW_srgb);
} else if (word == "margin") { } else if (word == "margin") {
++wi; ++wi;
if (wi == words.end()) { if (wi == words.end()) {
@ -502,6 +505,9 @@ match_texture(TextureImage *texture) const {
case KW_cont: case KW_cont:
got_cont = true; got_cont = true;
break; break;
case KW_srgb:
request._srgb = true;
} }
} }
@ -586,6 +592,10 @@ output(std::ostream &out) const {
case KW_anisotropic: case KW_anisotropic:
out << " aniso " << _aniso_degree; out << " aniso " << _aniso_degree;
break; break;
case KW_srgb:
out << " srgb";
break;
} }
} }

View File

@ -81,7 +81,8 @@ private:
KW_linear, KW_linear,
KW_mipmap, KW_mipmap,
KW_cont, KW_cont,
KW_anisotropic KW_anisotropic,
KW_srgb,
}; };
typedef pvector<Keyword> Keywords; typedef pvector<Keyword> Keywords;