Avoid calling gamma correction on non-srgb png

This commit is contained in:
Benau 2017-03-17 10:14:46 +08:00
parent 40a94b5562
commit e1a563612f
11 changed files with 57 additions and 25 deletions

View File

@ -42,7 +42,7 @@ public:
//! Creates a surface from the file
/** \param file File handle to check.
\return Pointer to newly created image, or 0 upon error. */
virtual IImage* loadImage(io::IReadFile* file, bool skip_checking = false) const = 0;
virtual IImage* loadImage(io::IReadFile* file, bool skip_checking = false, bool gamma_correction = true) const = 0;
virtual core::dimension2du getImageSize(io::IReadFile* file) const { return core::dimension2du(0, 0); }
virtual bool supportThreadedLoading() const { return false; }
};

View File

@ -216,7 +216,7 @@ void CImageLoaderBMP::decompress4BitRLE(u8*& bmpData, s32 size, s32 width, s32 h
//! creates a surface from the file
IImage* CImageLoaderBMP::loadImage(io::IReadFile* file, bool skip_checking) const
IImage* CImageLoaderBMP::loadImage(io::IReadFile* file, bool skip_checking, bool gamma_correction) const
{
SBMPHeader header;

View File

@ -81,7 +81,7 @@ public:
virtual bool isALoadableFileFormat(io::IReadFile* file) const;
//! creates a surface from the file
virtual IImage* loadImage(io::IReadFile* file, bool skip_checking = false) const;
virtual IImage* loadImage(io::IReadFile* file, bool skip_checking = false, bool gamma_correction = true) const;
private:

View File

@ -135,7 +135,7 @@ bool CImageLoaderJPG::isALoadableFileFormat(io::IReadFile* file) const
}
//! creates a surface from the file
IImage* CImageLoaderJPG::loadImage(io::IReadFile* file, bool skip_checking) const
IImage* CImageLoaderJPG::loadImage(io::IReadFile* file, bool skip_checking, bool gamma_correction) const
{
#ifndef _IRR_COMPILE_WITH_LIBJPEG_
os::Printer::log("Can't load as not compiled with _IRR_COMPILE_WITH_LIBJPEG_:", file->getFileName(), ELL_DEBUG);

View File

@ -49,7 +49,7 @@ public:
virtual bool isALoadableFileFormat(io::IReadFile* file) const;
//! creates a surface from the file
virtual IImage* loadImage(io::IReadFile* file, bool skip_checking = false) const;
virtual IImage* loadImage(io::IReadFile* file, bool skip_checking = false, bool gamma_correction = true) const;
private:

View File

@ -86,7 +86,7 @@ bool CImageLoaderPng::isALoadableFileFormat(io::IReadFile* file) const
// load in the image data
IImage* CImageLoaderPng::loadImage(io::IReadFile* file, bool skip_checking) const
IImage* CImageLoaderPng::loadImage(io::IReadFile* file, bool skip_checking, bool gamma_correction) const
{
#ifdef _IRR_COMPILE_WITH_LIBPNG_
if (!file)
@ -174,18 +174,20 @@ IImage* CImageLoaderPng::loadImage(io::IReadFile* file, bool skip_checking) cons
if (ColorType==PNG_COLOR_TYPE_GRAY || ColorType==PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png_ptr);
int intent;
const double screen_gamma = 2.2;
if (png_get_sRGB(png_ptr, info_ptr, &intent))
png_set_gamma(png_ptr, screen_gamma, 0.45455);
else
if (gamma_correction)
{
double image_gamma;
if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
png_set_gamma(png_ptr, screen_gamma, image_gamma);
else
int intent;
const double screen_gamma = 2.2;
if (png_get_sRGB(png_ptr, info_ptr, &intent))
png_set_gamma(png_ptr, screen_gamma, 0.45455);
else
{
double image_gamma;
if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
png_set_gamma(png_ptr, screen_gamma, image_gamma);
else
png_set_gamma(png_ptr, screen_gamma, 0.45455);
}
}
// Update the changes in between, as we need to get the new color type

View File

@ -33,7 +33,7 @@ public:
virtual bool isALoadableFileFormat(io::IReadFile* file) const;
//! creates a surface from the file
virtual IImage* loadImage(io::IReadFile* file, bool skip_checking = false) const;
virtual IImage* loadImage(io::IReadFile* file, bool skip_checking = false, bool gamma_correction = true) const;
virtual core::dimension2du getImageSize(io::IReadFile* file) const;
virtual bool supportThreadedLoading() const { return true; }
};

View File

@ -19,7 +19,7 @@
#include "graphics/hq_mipmap_generator.hpp"
#include "graphics/stk_tex_manager.hpp"
#undef DUMP_MIPMAP
#define DUMP_MIPMAP
#ifdef DUMP_MIPMAP
#include "graphics/irr_driver.hpp"
#include "utils/string_utils.hpp"
@ -75,13 +75,26 @@ void HQMipmapGenerator::threadedReload(void* ptr, void* param) const
#endif
for (unsigned int i = 0; i < m_mipmap_sizes.size(); i++)
{
const unsigned size = m_mipmap_sizes[i].first.getArea() * 4;
memcpy((uint8_t*)ptr + m_mipmap_sizes[i].second,
mm_cascade->mipmap[i + 1],
m_mipmap_sizes[i].first.getArea() * 4);
mm_cascade->mipmap[i + 1], size);
#ifdef DUMP_MIPMAP
uint8_t* data = (uint8_t*)(mm_cascade->mipmap[i + 1]);
if (!m_tex_config->m_srgb)
{
for (unsigned int j = 0; j < size / 4; j++)
{
data[j * 4] =
(uint8_t)(powf(data[j * 4] / 255.f , 2.2f) * 255);
data[j * 4 + 1] =
(uint8_t)(powf(data[j * 4 + 1] / 255.f , 2.2f) * 255);
data[j * 4 + 2] =
(uint8_t)(powf(data[j * 4 + 2] / 255.f , 2.2f) * 255);
}
}
video::IImage* image = irr_driver->getVideoDriver()
->createImageFromData(video::ECF_A8R8G8B8, m_mipmap_sizes[i].first,
mm_cascade->mipmap[i + 1], false/*ownForeignMemory*/);
data, false/*ownForeignMemory*/);
irr_driver->getVideoDriver()->writeImageToFile(image, std::string
(StringUtils::toString(i) + "_" +
StringUtils::getBasename(NamedPath.getPtr())).c_str());

View File

@ -105,12 +105,12 @@ void STKTexManager::destroyThreadedTexLoaders()
}
delete delete_ttl;
glDeleteBuffers(1, &m_pbo);
pthread_mutex_destroy(&m_threaded_load_textures_mutex);
pthread_cond_destroy(&m_cond_request);
m_pbo = 0;
m_thread_size = 0;
m_threaded_load_textures_counter = 0;
m_all_tex_loaders.clear();
pthread_mutex_destroy(&m_threaded_load_textures_mutex);
pthread_cond_destroy(&m_cond_request);
}
#endif
} // destroyThreadedTexLoaders

View File

@ -187,7 +187,8 @@ void STKTexture::reload(bool no_upload, uint8_t* preload_data,
}
else
{
orig_img = m_img_loader->loadImage(m_file);
orig_img = m_img_loader->loadImage(m_file,
false/*skip_checking*/, handleGamma());
m_file->drop();
m_file = NULL;
if (orig_img == NULL || orig_img->getDimension().Width == 0 ||
@ -597,7 +598,7 @@ void STKTexture::threadedReload(void* ptr, void* param) const
{
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
video::IImage* orig_img =
m_img_loader->loadImage(m_file, true/*skip_checking*/);
m_img_loader->loadImage(m_file, true/*skip_checking*/, handleGamma());
orig_img = resizeImage(orig_img);
uint8_t* data = (uint8_t*)orig_img->lock();
if (m_single_channel)
@ -677,3 +678,17 @@ bool STKTexture::isMeshTexture() const
{
return m_tex_config && m_tex_config->m_mesh_tex;
} // isMeshTexture
//-----------------------------------------------------------------------------
bool STKTexture::handleGamma() const
{
#ifndef SERVER_ONLY
if (!CVS->isGLSL() || !m_tex_config)
#endif
return true;
if ((m_tex_config->m_mesh_tex && m_tex_config->m_srgb) ||
(!m_tex_config->m_mesh_tex && !m_tex_config->m_srgb))
return true;
return false;
} // handleGamma

View File

@ -85,6 +85,8 @@ private:
bool isSrgb() const;
// ------------------------------------------------------------------------
bool isPremulAlpha() const;
// ------------------------------------------------------------------------
bool handleGamma() const;
public:
// ------------------------------------------------------------------------