1// Aseprite
2// Copyright (C) 2018-2021 Igara Studio S.A.
3//
4// This program is distributed under the terms of
5// the End-User License Agreement for Aseprite.
6
7#ifdef HAVE_CONFIG_H
8#include "config.h"
9#endif
10
11#include "app/color_spaces.h"
12
13#include "app/doc.h"
14#include "app/modules/editors.h"
15#include "app/pref/preferences.h"
16#include "app/ui/editor/editor.h"
17#include "os/system.h"
18#include "os/window.h"
19
20namespace app {
21
22// We use this variable to avoid accessing Preferences::instance()
23// from background threads when a color conversion between color
24// spaces must be done.
25static bool g_manage = false;
26
27void initialize_color_spaces(Preferences& pref)
28{
29 g_manage = pref.color.manage();
30 pref.color.manage.AfterChange.connect(
31 [](bool manage){
32 g_manage = manage;
33 });
34}
35
36os::ColorSpaceRef get_screen_color_space()
37{
38 return os::instance()->defaultWindow()->colorSpace();
39}
40
41os::ColorSpaceRef get_current_color_space()
42{
43#ifdef ENABLE_UI
44 if (current_editor)
45 return current_editor->document()->osColorSpace();
46 else
47#endif
48 return get_screen_color_space();
49}
50
51gfx::ColorSpaceRef get_working_rgb_space_from_preferences()
52{
53 if (Preferences::instance().color.manage()) {
54 const std::string name = Preferences::instance().color.workingRgbSpace();
55 if (name == "sRGB")
56 return gfx::ColorSpace::MakeSRGB();
57
58 std::vector<os::ColorSpaceRef> colorSpaces;
59 os::instance()->listColorSpaces(colorSpaces);
60 for (auto& cs : colorSpaces) {
61 if (cs->gfxColorSpace()->name() == name)
62 return cs->gfxColorSpace();
63 }
64 }
65 return gfx::ColorSpace::MakeNone();
66}
67
68//////////////////////////////////////////////////////////////////////
69// Color conversion
70
71ConvertCS::ConvertCS()
72{
73 if (g_manage) {
74 auto srcCS = get_current_color_space();
75 auto dstCS = get_screen_color_space();
76 if (srcCS && dstCS)
77 m_conversion = os::instance()->convertBetweenColorSpace(srcCS, dstCS);
78 }
79}
80
81ConvertCS::ConvertCS(const os::ColorSpaceRef& srcCS,
82 const os::ColorSpaceRef& dstCS)
83{
84 if (g_manage) {
85 m_conversion = os::instance()->convertBetweenColorSpace(srcCS, dstCS);
86 }
87}
88
89ConvertCS::ConvertCS(ConvertCS&& that)
90 : m_conversion(std::move(that.m_conversion))
91{
92}
93
94gfx::Color ConvertCS::operator()(const gfx::Color c)
95{
96 if (m_conversion) {
97 gfx::Color out;
98 m_conversion->convertRgba((uint32_t*)&out, (const uint32_t*)&c, 1);
99 return out;
100 }
101 else {
102 return c;
103 }
104}
105
106ConvertCS convert_from_current_to_screen_color_space()
107{
108 return ConvertCS();
109}
110
111ConvertCS convert_from_custom_to_srgb(const os::ColorSpaceRef& from)
112{
113 return ConvertCS(from,
114 os::instance()->makeColorSpace(gfx::ColorSpace::MakeSRGB()));
115}
116
117} // namespace app
118