ImageData can track whether they're meant to be loaded into a Texture with a non-sRGB format when gamma correct rendering is enabled.

Fixes #1556.

* Add ImageData/CompressedImageData:setLinear and ImageData/CompressedImageData:isLinear.
  The flag is used as a hint when loading a texture from the data to determine if the format should not be treated as sRGB-encoded. The 'linear' flag in newImage overrides this.

* love.graphics.readbackTexture automatically sets the linear flag on ImageData it returns when the texture's format is linear.
  This allows an ImageData generated via readback to be fed back into a new Texture and the format will match the original Canvas.

* Also clean up some image decoding code.
This commit is contained in:
Sasha Szpakowski
2023-10-14 20:48:21 -03:00
parent bd55100d56
commit 8c13943f64
26 changed files with 149 additions and 105 deletions
+13 -5
View File
@@ -30,7 +30,6 @@ love::Type CompressedImageData::type("CompressedImageData", &Data::type);
CompressedImageData::CompressedImageData(const std::list<FormatHandler *> &formats, Data *filedata)
: format(PIXELFORMAT_UNKNOWN)
, sRGB(false)
{
FormatHandler *parser = nullptr;
@@ -46,7 +45,7 @@ CompressedImageData::CompressedImageData(const std::list<FormatHandler *> &forma
if (parser == nullptr)
throw love::Exception("Could not parse compressed data: Unknown format.");
memory = parser->parseCompressed(filedata, dataImages, format, sRGB);
memory = parser->parseCompressed(filedata, dataImages, format);
if (memory == nullptr)
throw love::Exception("Could not parse compressed data.");
@@ -56,11 +55,14 @@ CompressedImageData::CompressedImageData(const std::list<FormatHandler *> &forma
if (dataImages.size() == 0 || memory->getSize() == 0)
throw love::Exception("Could not parse compressed data: No valid data?");
// This throws away some information the decoder could give us, but we
// can't really rely on it I think...
format = getLinearPixelFormat(format);
}
CompressedImageData::CompressedImageData(const CompressedImageData &c)
: format(c.format)
, sRGB(c.sRGB)
{
memory.set(c.memory->clone(), Acquire::NORETAIN);
@@ -134,9 +136,15 @@ PixelFormat CompressedImageData::getFormat() const
return format;
}
bool CompressedImageData::isSRGB() const
void CompressedImageData::setLinear(bool linear)
{
return sRGB;
for (auto &slice : dataImages)
slice->setLinear(linear);
}
bool CompressedImageData::isLinear() const
{
return dataImages.empty() ? false : dataImages[0]->isLinear();
}
CompressedSlice *CompressedImageData::getSlice(int slice, int miplevel) const