work on internal color management

This commit is contained in:
itsmattkc
2019-09-28 01:38:15 +10:00
parent 4c90405feb
commit d2dc0d2823
24 changed files with 983 additions and 175 deletions
+4 -2
View File
@@ -18,8 +18,10 @@ add_subdirectory(gl)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
render/colorservice.h
render/colorservice.cpp
render/colormanager.h
render/colormanager.cpp
render/colorprocessor.h
render/colorprocessor.cpp
render/pixelformat.h
render/pixelformat.cpp
render/pixelservice.h
+155
View File
@@ -0,0 +1,155 @@
#include "colormanager.h"
#include <QFloat16>
#include "common/define.h"
ColorManager* ColorManager::instance_ = nullptr;
void ColorManager::SetConfig(const QString &filename)
{
SetConfig(OCIO::Config::CreateFromFile(filename.toUtf8()));
}
void ColorManager::SetConfig(OpenColorIO::v1::ConstConfigRcPtr config)
{
OCIO::SetCurrentConfig(config);
emit ConfigChanged();
}
void ColorManager::CreateInstance()
{
if (instance_ == nullptr) {
instance_ = new ColorManager();
}
}
ColorManager *ColorManager::instance()
{
return instance_;
}
void ColorManager::DestroyInstance()
{
delete instance_;
instance_ = nullptr;
}
void ColorManager::DisassociateAlpha(FramePtr f)
{
AssociateAlphaPixFmtFilter(kDisassociate, f);
}
void ColorManager::AssociateAlpha(FramePtr f)
{
AssociateAlphaPixFmtFilter(kAssociate, f);
}
void ColorManager::ReassociateAlpha(FramePtr f)
{
AssociateAlphaPixFmtFilter(kReassociate, f);
}
QStringList ColorManager::ListAvailableDisplays()
{
QStringList displays;
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
int number_of_displays = config->getNumDisplays();
for (int i=0;i<number_of_displays;i++) {
displays.append(config->getDisplay(i));
}
return displays;
}
QString ColorManager::GetDefaultDisplay()
{
return OCIO::GetCurrentConfig()->getDefaultDisplay();
}
QStringList ColorManager::ListAvailableViews(QString display)
{
QStringList views;
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
int number_of_views = config->getNumViews(display.toUtf8());
for (int i=0;i<number_of_views;i++) {
views.append(config->getView(display.toUtf8(), i));
}
return views;
}
QString ColorManager::GetDefaultView(const QString &display)
{
return OCIO::GetCurrentConfig()->getDefaultView(display.toUtf8());
}
QStringList ColorManager::ListAvailableLooks()
{
QStringList looks;
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
int number_of_looks = config->getNumLooks();
for (int i=0;i<number_of_looks;i++) {
looks.append(config->getLookNameByIndex(i));
}
return looks;
}
ColorManager::ColorManager()
{
}
void ColorManager::AssociateAlphaPixFmtFilter(ColorManager::AlphaAction action, FramePtr f)
{
int pixel_count = f->width() * f->height() * kRGBAChannels;
switch (static_cast<olive::PixelFormat>(f->format())) {
case olive::PIX_FMT_INVALID:
case olive::PIX_FMT_COUNT:
qWarning() << "Alpha association functions received an invalid pixel format";
break;
case olive::PIX_FMT_RGBA8:
case olive::PIX_FMT_RGBA16U:
qWarning() << "Alpha association functions only works on float-based pixel formats at this time";
break;
case olive::PIX_FMT_RGBA16F:
{
AssociateAlphaInternal<qfloat16>(action, reinterpret_cast<qfloat16*>(f->data()), pixel_count);
break;
}
case olive::PIX_FMT_RGBA32F:
{
AssociateAlphaInternal<float>(action, reinterpret_cast<float*>(f->data()), pixel_count);
break;
}
}
}
template<typename T>
void ColorManager::AssociateAlphaInternal(ColorManager::AlphaAction action, T *data, int pix_count)
{
for (int i=0;i<pix_count;i+=kRGBAChannels) {
T alpha = data[i+kRGBChannels];
if (action == kAssociate || alpha > 0) {
for (int j=0;j<kRGBChannels;j++) {
if (action == kDisassociate) {
data[i+j] /= alpha;
} else {
data[i+j] *= alpha;
}
}
}
}
}
+60
View File
@@ -0,0 +1,60 @@
#ifndef COLORSERVICE_H
#define COLORSERVICE_H
#include <memory>
#include "colorprocessor.h"
#include "decoder/frame.h"
#include "render/gl/shadergenerators.h"
class ColorManager : public QObject
{
Q_OBJECT
public:
void SetConfig(const QString& filename);
void SetConfig(OCIO::ConstConfigRcPtr config);
static void CreateInstance();
static ColorManager* instance();
static void DestroyInstance();
static void DisassociateAlpha(FramePtr f);
static void AssociateAlpha(FramePtr f);
static void ReassociateAlpha(FramePtr f);
static QStringList ListAvailableDisplays();
static QString GetDefaultDisplay();
static QStringList ListAvailableViews(QString display);
static QString GetDefaultView(const QString& display);
static QStringList ListAvailableLooks();
signals:
void ConfigChanged();
private:
ColorManager();
static ColorManager* instance_;
enum AlphaAction {
kAssociate,
kDisassociate,
kReassociate
};
static void AssociateAlphaPixFmtFilter(AlphaAction action, FramePtr f);
template<typename T>
static void AssociateAlphaInternal(AlphaAction action, T* data, int pix_count);
};
#endif // COLORSERVICE_H
+62
View File
@@ -0,0 +1,62 @@
#include "colorprocessor.h"
#include "common/define.h"
ColorProcessor::ColorProcessor(const QString& source_space, const QString& dest_space)
{
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
processor = config->getProcessor(source_space.toUtf8(),
dest_space.toUtf8());
}
ColorProcessor::ColorProcessor(const QString& source_space,
QString display,
QString view,
const QString& look)
{
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
if (display.isEmpty()) {
display = config->getDefaultDisplay();
}
if (view.isEmpty()) {
view = config->getDefaultView(display.toUtf8());
}
// Get current display stats
OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create();
transform->setInputColorSpaceName(source_space.toUtf8());
transform->setDisplay(display.toUtf8());
transform->setView(view.toUtf8());
if (!look.isEmpty()) {
transform->setLooksOverride(look.toUtf8());
transform->setLooksOverrideEnabled(true);
}
processor = config->getProcessor(transform);
}
void ColorProcessor::ConvertFrame(FramePtr f)
{
OCIO::PackedImageDesc img(reinterpret_cast<float*>(f->data()), f->width(), f->height(), kRGBAChannels);
processor->apply(img);
}
ColorProcessorPtr ColorProcessor::Create(const QString& source_space, const QString& dest_space)
{
return std::make_shared<ColorProcessor>(source_space, dest_space);
}
ColorProcessorPtr ColorProcessor::Create(const QString &source_space, const QString &display, const QString &view, const QString &look)
{
return std::make_shared<ColorProcessor>(source_space, display, view, look);
}
OpenColorIO::v1::ConstProcessorRcPtr ColorProcessor::GetProcessor()
{
return processor;
}
+38
View File
@@ -0,0 +1,38 @@
#ifndef COLORPROCESSOR_H
#define COLORPROCESSOR_H
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE::v1;
#include "decoder/frame.h"
class ColorProcessor;
using ColorProcessorPtr = std::shared_ptr<ColorProcessor>;
class ColorProcessor
{
public:
ColorProcessor(const QString &source_space, const QString &dest_space);
ColorProcessor(const QString& source_space,
QString display,
QString view,
const QString& look);
static ColorProcessorPtr Create(const QString& source_space, const QString& dest_space);
static ColorProcessorPtr Create(const QString& source_space,
const QString& display,
const QString& view,
const QString& look);
OCIO::ConstProcessorRcPtr GetProcessor();
void ConvertFrame(FramePtr f);
private:
OCIO::ConstProcessorRcPtr processor;
};
#endif // COLORPROCESSOR_H
-102
View File
@@ -1,102 +0,0 @@
#include "colorservice.h"
#include <QFloat16>
#include "common/define.h"
ColorService::ColorService(const char* source_space, const char* dest_space)
{
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
processor = config->getProcessor(source_space,
dest_space);
}
void ColorService::Init()
{
// FIXME: Load configured config file for this session
/*try {
// FIXME: Hardcoded values for testing purposes
OCIO::ConstConfigRcPtr config = OCIO::Config::CreateFromFile("/run/media/matt/Home/OpenColorIO/ocio.configs.0.7v4/nuke-default/config.ocio");
OCIO::SetCurrentConfig(config);
} catch (OCIO::Exception& exception) {
qWarning() << "OpenColorIO Error:" << exception.what();
}*/
}
ColorServicePtr ColorService::Create(const char *source_space, const char *dest_space)
{
return std::make_shared<ColorService>(source_space, dest_space);
}
void ColorService::ConvertFrame(FramePtr f)
{
OCIO::PackedImageDesc img(reinterpret_cast<float*>(f->data()), f->width(), f->height(), kRGBAChannels);
processor->apply(img);
}
void ColorService::DisassociateAlpha(FramePtr f)
{
AssociateAlphaPixFmtFilter(kDisassociate, f);
}
void ColorService::AssociateAlpha(FramePtr f)
{
AssociateAlphaPixFmtFilter(kAssociate, f);
}
void ColorService::ReassociateAlpha(FramePtr f)
{
AssociateAlphaPixFmtFilter(kReassociate, f);
}
OpenColorIO::v1::ConstProcessorRcPtr ColorService::GetProcessor()
{
return processor;
}
void ColorService::AssociateAlphaPixFmtFilter(ColorService::AlphaAction action, FramePtr f)
{
int pixel_count = f->width() * f->height() * kRGBAChannels;
switch (static_cast<olive::PixelFormat>(f->format())) {
case olive::PIX_FMT_INVALID:
case olive::PIX_FMT_COUNT:
qWarning() << "Alpha association functions received an invalid pixel format";
break;
case olive::PIX_FMT_RGBA8:
case olive::PIX_FMT_RGBA16U:
qWarning() << "Alpha association functions only works on float-based pixel formats at this time";
break;
case olive::PIX_FMT_RGBA16F:
{
AssociateAlphaInternal<qfloat16>(action, reinterpret_cast<qfloat16*>(f->data()), pixel_count);
break;
}
case olive::PIX_FMT_RGBA32F:
{
AssociateAlphaInternal<float>(action, reinterpret_cast<float*>(f->data()), pixel_count);
break;
}
}
}
template<typename T>
void ColorService::AssociateAlphaInternal(ColorService::AlphaAction action, T *data, int pix_count)
{
for (int i=0;i<pix_count;i+=kRGBAChannels) {
T alpha = data[i+kRGBChannels];
if (action == kAssociate || alpha > 0) {
for (int j=0;j<kRGBChannels;j++) {
if (action == kDisassociate) {
data[i+j] /= alpha;
} else {
data[i+j] *= alpha;
}
}
}
}
}
-48
View File
@@ -1,48 +0,0 @@
#ifndef COLORSERVICE_H
#define COLORSERVICE_H
#include <memory>
#include <OpenColorIO/OpenColorIO.h>
namespace OCIO = OCIO_NAMESPACE::v1;
#include "decoder/frame.h"
#include "render/gl/shadergenerators.h"
class ColorService;
using ColorServicePtr = std::shared_ptr<ColorService>;
class ColorService
{
public:
ColorService(const char *source_space, const char *dest_space);
static void Init();
static ColorServicePtr Create(const char *source_space, const char *dest_space);
void ConvertFrame(FramePtr f);
static void DisassociateAlpha(FramePtr f);
static void AssociateAlpha(FramePtr f);
static void ReassociateAlpha(FramePtr f);
OCIO::ConstProcessorRcPtr GetProcessor();
private:
OCIO::ConstProcessorRcPtr processor;
enum AlphaAction {
kAssociate,
kDisassociate,
kReassociate
};
static void AssociateAlphaPixFmtFilter(AlphaAction action, FramePtr f);
template<typename T>
static void AssociateAlphaInternal(AlphaAction action, T* data, int pix_count);
};
#endif // COLORSERVICE_H