Adds color space to textures.
PiperOrigin-RevId: 761907261 Change-Id: Iec546d1d5907a15e57ef809ec31850640fc52915
This commit is contained in:
committed by
Copybara-Service
parent
62a9d5b98d
commit
3e9bc79b54
+36
-10
@@ -55,6 +55,8 @@ class PNGImage {
|
||||
LodePNGColorType color_type);
|
||||
int Width() const { return width_; }
|
||||
int Height() const { return height_; }
|
||||
bool IsSRGB() const { return is_srgb_; }
|
||||
|
||||
uint8_t operator[] (int i) const { return data_[i]; }
|
||||
std::vector<unsigned char>& MoveData() { return data_; }
|
||||
|
||||
@@ -65,6 +67,7 @@ class PNGImage {
|
||||
|
||||
int width_;
|
||||
int height_;
|
||||
bool is_srgb_;
|
||||
LodePNGColorType color_type_;
|
||||
std::vector<uint8_t> data_;
|
||||
};
|
||||
@@ -104,8 +107,11 @@ PNGImage PNGImage::Load(const mjCBase* obj, mjResource* resource,
|
||||
|
||||
// decode PNG from buffer
|
||||
unsigned int w, h;
|
||||
unsigned err = lodepng::decode(image.data_, w, h,
|
||||
buffer, nbuffer, image.color_type_, 8);
|
||||
|
||||
lodepng::State state;
|
||||
state.info_raw.colortype = image.color_type_;
|
||||
state.info_raw.bitdepth = 8;
|
||||
unsigned err = lodepng::decode(image.data_, w, h, state, buffer, nbuffer);
|
||||
|
||||
// check for errors
|
||||
if (err) {
|
||||
@@ -116,6 +122,7 @@ PNGImage PNGImage::Load(const mjCBase* obj, mjResource* resource,
|
||||
|
||||
image.width_ = w;
|
||||
image.height_ = h;
|
||||
image.is_srgb_ = (state.info_png.srgb_defined == 1);
|
||||
|
||||
if (image.width_ <= 0 || image.height_ < 0) {
|
||||
std::stringstream ss;
|
||||
@@ -4257,7 +4264,7 @@ void mjCTexture::BuiltinCube(void) {
|
||||
// load PNG file
|
||||
void mjCTexture::LoadPNG(mjResource* resource,
|
||||
std::vector<unsigned char>& image,
|
||||
unsigned int& w, unsigned int& h) {
|
||||
unsigned int& w, unsigned int& h, bool& is_srgb) {
|
||||
LodePNGColorType color_type;
|
||||
if (nchannel == 4) {
|
||||
color_type = LCT_RGBA;
|
||||
@@ -4272,13 +4279,14 @@ void mjCTexture::LoadPNG(mjResource* resource,
|
||||
PNGImage png_image = PNGImage::Load(this, resource, color_type);
|
||||
w = png_image.Width();
|
||||
h = png_image.Height();
|
||||
is_srgb = png_image.IsSRGB();
|
||||
image = png_image.MoveData();
|
||||
}
|
||||
|
||||
// load custom file
|
||||
void mjCTexture::LoadCustom(mjResource* resource,
|
||||
std::vector<unsigned char>& image,
|
||||
unsigned int& w, unsigned int& h) {
|
||||
unsigned int& w, unsigned int& h, bool& is_srgb) {
|
||||
const void* buffer = 0;
|
||||
int buffer_sz = mju_readResource(resource, &buffer);
|
||||
|
||||
@@ -4295,6 +4303,9 @@ void mjCTexture::LoadCustom(mjResource* resource,
|
||||
w = pint[0];
|
||||
h = pint[1];
|
||||
|
||||
// assume linear color space
|
||||
is_srgb = false;
|
||||
|
||||
// check dimensions
|
||||
if (w < 1 || h < 1) {
|
||||
throw mjCError(this, "Non-PNG texture, assuming custom binary file format,\n"
|
||||
@@ -4317,7 +4328,7 @@ void mjCTexture::LoadCustom(mjResource* resource,
|
||||
// load from PNG or custom file, flip if specified
|
||||
void mjCTexture::LoadFlip(std::string filename, const mjVFS* vfs,
|
||||
std::vector<unsigned char>& image,
|
||||
unsigned int& w, unsigned int& h) {
|
||||
unsigned int& w, unsigned int& h, bool& is_srgb) {
|
||||
std::string asset_type = GetAssetContentType(filename, content_type_);
|
||||
|
||||
// fallback to custom
|
||||
@@ -4333,9 +4344,9 @@ void mjCTexture::LoadFlip(std::string filename, const mjVFS* vfs,
|
||||
|
||||
try {
|
||||
if (asset_type == "image/png") {
|
||||
LoadPNG(resource, image, w, h);
|
||||
LoadPNG(resource, image, w, h, is_srgb);
|
||||
} else {
|
||||
LoadCustom(resource, image, w, h);
|
||||
LoadCustom(resource, image, w, h, is_srgb);
|
||||
}
|
||||
mju_closeResource(resource);
|
||||
} catch(mjCError err) {
|
||||
@@ -4402,12 +4413,16 @@ void mjCTexture::LoadFlip(std::string filename, const mjVFS* vfs,
|
||||
void mjCTexture::Load2D(std::string filename, const mjVFS* vfs) {
|
||||
// load PNG or custom
|
||||
unsigned int w, h;
|
||||
bool is_srgb;
|
||||
std::vector<unsigned char> image;
|
||||
LoadFlip(filename, vfs, image, w, h);
|
||||
LoadFlip(filename, vfs, image, w, h, is_srgb);
|
||||
|
||||
// assign size
|
||||
width = w;
|
||||
height = h;
|
||||
if (colorspace == mjCOLORSPACE_AUTO) {
|
||||
colorspace = is_srgb ? mjCOLORSPACE_SRGB : mjCOLORSPACE_LINEAR;
|
||||
}
|
||||
|
||||
// allocate and copy data
|
||||
std::int64_t size = static_cast<std::int64_t>(width)*height;
|
||||
@@ -4435,8 +4450,13 @@ void mjCTexture::LoadCubeSingle(std::string filename, const mjVFS* vfs) {
|
||||
|
||||
// load PNG or custom
|
||||
unsigned int w, h;
|
||||
bool is_srgb;
|
||||
std::vector<unsigned char> image;
|
||||
LoadFlip(filename, vfs, image, w, h);
|
||||
LoadFlip(filename, vfs, image, w, h, is_srgb);
|
||||
|
||||
if (colorspace == mjCOLORSPACE_AUTO) {
|
||||
colorspace = is_srgb ? mjCOLORSPACE_SRGB : mjCOLORSPACE_LINEAR;
|
||||
}
|
||||
|
||||
// check gridsize for compatibility
|
||||
if (w/gridsize[1] != h/gridsize[0] || (w%gridsize[1]) || (h%gridsize[0])) {
|
||||
@@ -4549,8 +4569,14 @@ void mjCTexture::LoadCubeSeparate(const mjVFS* vfs) {
|
||||
|
||||
// load PNG or custom
|
||||
unsigned int w, h;
|
||||
bool is_srgb;
|
||||
std::vector<unsigned char> image;
|
||||
LoadFlip(filename.Str(), vfs, image, w, h);
|
||||
LoadFlip(filename.Str(), vfs, image, w, h, is_srgb);
|
||||
|
||||
// assume all faces have the same colorspace
|
||||
if (colorspace == mjCOLORSPACE_AUTO) {
|
||||
colorspace = is_srgb ? mjCOLORSPACE_SRGB : mjCOLORSPACE_LINEAR;
|
||||
}
|
||||
|
||||
// PNG must be square
|
||||
if (w != h) {
|
||||
|
||||
Reference in New Issue
Block a user