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 //! Creates a surface from the file
/** \param file File handle to check. /** \param file File handle to check.
\return Pointer to newly created image, or 0 upon error. */ \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 core::dimension2du getImageSize(io::IReadFile* file) const { return core::dimension2du(0, 0); }
virtual bool supportThreadedLoading() const { return false; } 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 //! 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; SBMPHeader header;

View File

@ -81,7 +81,7 @@ public:
virtual bool isALoadableFileFormat(io::IReadFile* file) const; virtual bool isALoadableFileFormat(io::IReadFile* file) const;
//! creates a surface from the file //! 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: private:

View File

@ -135,7 +135,7 @@ bool CImageLoaderJPG::isALoadableFileFormat(io::IReadFile* file) const
} }
//! creates a surface from the file //! 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_ #ifndef _IRR_COMPILE_WITH_LIBJPEG_
os::Printer::log("Can't load as not compiled with _IRR_COMPILE_WITH_LIBJPEG_:", file->getFileName(), ELL_DEBUG); 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; virtual bool isALoadableFileFormat(io::IReadFile* file) const;
//! creates a surface from the file //! 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: private:

View File

@ -86,7 +86,7 @@ bool CImageLoaderPng::isALoadableFileFormat(io::IReadFile* file) const
// load in the image data // 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_ #ifdef _IRR_COMPILE_WITH_LIBPNG_
if (!file) if (!file)
@ -174,9 +174,10 @@ IImage* CImageLoaderPng::loadImage(io::IReadFile* file, bool skip_checking) cons
if (ColorType==PNG_COLOR_TYPE_GRAY || ColorType==PNG_COLOR_TYPE_GRAY_ALPHA) if (ColorType==PNG_COLOR_TYPE_GRAY || ColorType==PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png_ptr); png_set_gray_to_rgb(png_ptr);
if (gamma_correction)
{
int intent; int intent;
const double screen_gamma = 2.2; const double screen_gamma = 2.2;
if (png_get_sRGB(png_ptr, info_ptr, &intent)) if (png_get_sRGB(png_ptr, info_ptr, &intent))
png_set_gamma(png_ptr, screen_gamma, 0.45455); png_set_gamma(png_ptr, screen_gamma, 0.45455);
else else
@ -187,6 +188,7 @@ IImage* CImageLoaderPng::loadImage(io::IReadFile* file, bool skip_checking) cons
else else
png_set_gamma(png_ptr, screen_gamma, 0.45455); png_set_gamma(png_ptr, screen_gamma, 0.45455);
} }
}
// Update the changes in between, as we need to get the new color type // Update the changes in between, as we need to get the new color type
// for proper processing of the RGBA type // for proper processing of the RGBA type

View File

@ -33,7 +33,7 @@ public:
virtual bool isALoadableFileFormat(io::IReadFile* file) const; virtual bool isALoadableFileFormat(io::IReadFile* file) const;
//! creates a surface from the file //! 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 core::dimension2du getImageSize(io::IReadFile* file) const;
virtual bool supportThreadedLoading() const { return true; } virtual bool supportThreadedLoading() const { return true; }
}; };

View File

@ -19,7 +19,7 @@
#include "graphics/hq_mipmap_generator.hpp" #include "graphics/hq_mipmap_generator.hpp"
#include "graphics/stk_tex_manager.hpp" #include "graphics/stk_tex_manager.hpp"
#undef DUMP_MIPMAP #define DUMP_MIPMAP
#ifdef DUMP_MIPMAP #ifdef DUMP_MIPMAP
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "utils/string_utils.hpp" #include "utils/string_utils.hpp"
@ -75,13 +75,26 @@ void HQMipmapGenerator::threadedReload(void* ptr, void* param) const
#endif #endif
for (unsigned int i = 0; i < m_mipmap_sizes.size(); i++) 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, memcpy((uint8_t*)ptr + m_mipmap_sizes[i].second,
mm_cascade->mipmap[i + 1], mm_cascade->mipmap[i + 1], size);
m_mipmap_sizes[i].first.getArea() * 4);
#ifdef DUMP_MIPMAP #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() video::IImage* image = irr_driver->getVideoDriver()
->createImageFromData(video::ECF_A8R8G8B8, m_mipmap_sizes[i].first, ->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 irr_driver->getVideoDriver()->writeImageToFile(image, std::string
(StringUtils::toString(i) + "_" + (StringUtils::toString(i) + "_" +
StringUtils::getBasename(NamedPath.getPtr())).c_str()); StringUtils::getBasename(NamedPath.getPtr())).c_str());

View File

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

View File

@ -187,7 +187,8 @@ void STKTexture::reload(bool no_upload, uint8_t* preload_data,
} }
else 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->drop();
m_file = NULL; m_file = NULL;
if (orig_img == NULL || orig_img->getDimension().Width == 0 || 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)) #if !(defined(SERVER_ONLY) || defined(USE_GLES2))
video::IImage* orig_img = 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); orig_img = resizeImage(orig_img);
uint8_t* data = (uint8_t*)orig_img->lock(); uint8_t* data = (uint8_t*)orig_img->lock();
if (m_single_channel) if (m_single_channel)
@ -677,3 +678,17 @@ bool STKTexture::isMeshTexture() const
{ {
return m_tex_config && m_tex_config->m_mesh_tex; return m_tex_config && m_tex_config->m_mesh_tex;
} // isMeshTexture } // 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 isSrgb() const;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
bool isPremulAlpha() const; bool isPremulAlpha() const;
// ------------------------------------------------------------------------
bool handleGamma() const;
public: public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------