Skip to content

Commit 563f621

Browse files
Merge branch 'main' into main
2 parents c8b5c29 + 5abbdaf commit 563f621

38 files changed

+680
-25
lines changed

ADOPTERS.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ Below is a partial list of organizations and projects that are using OpenTimelin
77
| [Adobe Premiere Pro](https://www.adobe.com/products/premiere.html) | [Timeline import/export](https://community.adobe.com/t5/premiere-pro-beta-discussions/new-in-beta-otio-import-and-export/td-p/14937493) (beta) |
88
| [AVID Media Composer](https://www.avid.com/media-composer) | Timeline export (preview) |
99
| [Black Magic Design DaVinci Resolve](https://www.blackmagicdesign.com/products/davinciresolve/) | Timeline import/export |
10-
| [CineSync](https://www.backlight.co/product/cinesync) | Timeline viewing | |
11-
| [ColorFront Transkoder](https://colorfront.com/index.php?page=SOFTWARE&spage=Transkoder) | Timeline import |
12-
| [Nuke Studio](https://www.foundry.com/products/nuke) | Timeline import/export with full timeline round-tripping |
13-
| [Hiero](https://www.foundry.com/products/nuke-family/hiero) | Timeline import/export |
14-
| [OpenRV](https://github.com/AcademySoftwareFoundation/OpenRV) | Timeline import and viewing |
10+
| [CineSync](https://www.backlight.co/product/cinesync) | Timeline viewing |
11+
| [ColorFront Transkoder](https://colorfront.com/index.php?page=SOFTWARE&spage=Transkoder) | Timeline import |
12+
| [Hiero](https://www.foundry.com/products/nuke-family/hiero) | Timeline import/export |
13+
| [Kdenlive](https://kdenlive.org) | Timeline import/export |
14+
| [Nuke Studio](https://www.foundry.com/products/nuke) | Timeline import/export with full timeline round-tripping |
15+
| [OpenRV](https://github.com/AcademySoftwareFoundation/OpenRV) | Timeline import and viewing |

docs/tutorials/otio-serialized-schema-only-fields.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ parameters:
3131

3232
## Module: opentimelineio.core
3333

34+
### Color.1
35+
36+
parameters:
37+
- *a*
38+
- *b*
39+
- *g*
40+
- *name*
41+
- *r*
42+
3443
### Composable.1
3544

3645
parameters:
@@ -40,6 +49,7 @@ parameters:
4049
### Composition.1
4150

4251
parameters:
52+
- *color*
4353
- *effects*
4454
- *enabled*
4555
- *markers*
@@ -50,6 +60,7 @@ parameters:
5060
### Item.1
5161

5262
parameters:
63+
- *color*
5364
- *effects*
5465
- *enabled*
5566
- *markers*
@@ -132,6 +143,7 @@ parameters:
132143

133144
parameters:
134145
- *active_media_reference_key*
146+
- *color*
135147
- *effects*
136148
- *enabled*
137149
- *markers*
@@ -169,6 +181,7 @@ parameters:
169181
### Gap.1
170182

171183
parameters:
184+
- *color*
172185
- *effects*
173186
- *enabled*
174187
- *markers*
@@ -237,6 +250,7 @@ parameters:
237250
### Stack.1
238251

239252
parameters:
253+
- *color*
240254
- *effects*
241255
- *enabled*
242256
- *markers*
@@ -263,6 +277,7 @@ parameters:
263277
### Track.1
264278

265279
parameters:
280+
- *color*
266281
- *effects*
267282
- *enabled*
268283
- *kind*

docs/tutorials/otio-serialized-schema.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,27 @@ parameters:
5656

5757
## Module: opentimelineio.core
5858

59+
### Color.1
60+
61+
*full module path*: `opentimelineio.core.Color`
62+
63+
*documentation*:
64+
65+
```
66+
:class:`Color` is a definition of red, green, blue, and alpha double floating point values, allowing
67+
conversion between different formats. To be considered interoperable, the sRGB transfer function
68+
encoded values, ranging between zero and one, are expected to be accurate to within 1/255 of the
69+
intended value. Round-trip conversions may not be guaranteed outside that. This Color class is meant
70+
for use in user interface elements, like marker or clip coloring, NOT for image pixel content.
71+
```
72+
73+
parameters:
74+
- *a*:
75+
- *b*:
76+
- *g*:
77+
- *name*:
78+
- *r*:
79+
5980
### Composable.1
6081

6182
*full module path*: `opentimelineio.core.Composable`
@@ -88,6 +109,7 @@ Should be subclassed (for example by :class:`.Track` and :class:`.Stack`), not u
88109
```
89110

90111
parameters:
112+
- *color*:
91113
- *effects*:
92114
- *enabled*: If true, an Item contributes to compositions. For example, when an audio/video clip is ``enabled=false`` the clip is muted/hidden.
93115
- *markers*:
@@ -106,6 +128,7 @@ None
106128
```
107129

108130
parameters:
131+
- *color*:
109132
- *effects*:
110133
- *enabled*: If true, an Item contributes to compositions. For example, when an audio/video clip is ``enabled=false`` the clip is muted/hidden.
111134
- *markers*:
@@ -290,6 +313,7 @@ Contains a :class:`.MediaReference` and a trim on that media reference.
290313

291314
parameters:
292315
- *active_media_reference_key*:
316+
- *color*:
293317
- *effects*:
294318
- *enabled*: If true, an Item contributes to compositions. For example, when an audio/video clip is ``enabled=false`` the clip is muted/hidden.
295319
- *markers*:
@@ -363,6 +387,7 @@ None
363387
```
364388

365389
parameters:
390+
- *color*:
366391
- *effects*:
367392
- *enabled*: If true, an Item contributes to compositions. For example, when an audio/video clip is ``enabled=false`` the clip is muted/hidden.
368393
- *markers*:
@@ -591,6 +616,7 @@ None
591616
```
592617

593618
parameters:
619+
- *color*:
594620
- *effects*:
595621
- *enabled*: If true, an Item contributes to compositions. For example, when an audio/video clip is ``enabled=false`` the clip is muted/hidden.
596622
- *markers*:
@@ -641,6 +667,7 @@ None
641667
```
642668

643669
parameters:
670+
- *color*:
644671
- *effects*:
645672
- *enabled*: If true, an Item contributes to compositions. For example, when an audio/video clip is ``enabled=false`` the clip is muted/hidden.
646673
- *kind*:

src/opentimelineio/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
set(OPENTIMELINEIO_HEADER_FILES
55
anyDictionary.h
66
anyVector.h
7+
color.h
78
clip.h
89
composable.h
910
composition.h
@@ -37,7 +38,8 @@ set(OPENTIMELINEIO_HEADER_FILES
3738
unknownSchema.h
3839
vectorIndexing.h)
3940

40-
add_library(opentimelineio ${OTIO_SHARED_OR_STATIC_LIB}
41+
add_library(opentimelineio ${OTIO_SHARED_OR_STATIC_LIB}
42+
color.cpp
4143
clip.cpp
4244
composable.cpp
4345
composition.cpp

src/opentimelineio/clip.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ Clip::Clip(
1515
AnyDictionary const& metadata,
1616
std::vector<Effect*> const& effects,
1717
std::vector<Marker*> const& markers,
18-
std::string const& active_media_reference_key)
19-
: Parent{ name, source_range, metadata, effects, markers }
18+
std::string const& active_media_reference_key,
19+
std::optional<Color> const& color)
20+
: Parent{ name, source_range, metadata, effects, markers, /*enabled*/ true, color }
2021
, _active_media_reference_key(active_media_reference_key)
2122
{
2223
set_media_reference(media_reference);

src/opentimelineio/clip.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ class Clip : public Item
4646
AnyDictionary const& metadata = AnyDictionary(),
4747
std::vector<Effect*> const& effects = std::vector<Effect*>(),
4848
std::vector<Marker*> const& markers = std::vector<Marker*>(),
49-
std::string const& active_media_reference_key = default_media_key);
49+
std::string const& active_media_reference_key = default_media_key,
50+
std::optional<Color> const& color = std::nullopt);
5051

5152
/// @name Media References
5253
///@{

src/opentimelineio/color.cpp

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright Contributors to the OpenTimelineIO project
3+
4+
#include <iomanip>
5+
#include <sstream>
6+
7+
#include "opentimelineio/color.h"
8+
9+
namespace opentimelineio { namespace OPENTIMELINEIO_VERSION {
10+
11+
Color::Color(
12+
double const r,
13+
double const g,
14+
double const b,
15+
double const a,
16+
std::string const& name)
17+
: _name(name),
18+
_r(r),
19+
_g(g),
20+
_b(b),
21+
_a(a) {}
22+
23+
Color::Color(Color const& other) : _name(other.name()),
24+
_r(other.r()),
25+
_g(other.g()),
26+
_b(other.b()),
27+
_a(other.a()) {}
28+
29+
const Color Color::pink(1.0, 0.0, 1.0, 1.0, "Pink");
30+
const Color Color::red(1.0, 0.0, 0.0, 1.0, "Red");
31+
const Color Color::orange(1.0, 0.5, 0.0, 1.0, "Orange");
32+
const Color Color::yellow(1.0, 1.0, 0.0, 1.0, "Yellow");
33+
const Color Color::green(0.0, 1.0, 0.0, 1.0, "Green");
34+
const Color Color::cyan(0.0, 1.0, 1.0, 1.0, "Cyan");
35+
const Color Color::blue(0.0, 0.0, 1.0, 1.0, "Blue");
36+
const Color Color::purple(0.5, 0.0, 0.5, 1.0, "Purple");
37+
const Color Color::magenta(1.0, 0.0, 1.0, 1.0, "Magenta");
38+
const Color Color::black(0.0, 0.0, 0.0, 1.0, "Black");
39+
const Color Color::white(1.0, 1.0, 1.0, 1.0, "White");
40+
const Color Color::transparent(1.0, 1.0, 1.0, 0.0, "Transparent");
41+
42+
Color*
43+
Color::from_hex(std::string const& color)
44+
{
45+
std::string temp = color;
46+
if (temp[0] == '#')
47+
{
48+
temp = temp.substr(1);
49+
}
50+
else if (temp[0] == '0' && (temp[1] == 'x' || temp[1] == 'X'))
51+
{
52+
temp = temp.substr(2);
53+
}
54+
55+
double _r, _g, _b, _a;
56+
// 0xFFFFFFFF (rgba, 255)
57+
int BASE_16 = 16;
58+
double BASE_16_DIV = 255.0;
59+
double BASE_8_DIV = 15.0;
60+
if (temp.length() == 8)
61+
{
62+
_r = std::stoi(temp.substr(0, 2), nullptr, BASE_16) / BASE_16_DIV;
63+
_g = std::stoi(temp.substr(2, 2), nullptr, BASE_16) / BASE_16_DIV;
64+
_b = std::stoi(temp.substr(4, 2), nullptr, BASE_16) / BASE_16_DIV;
65+
_a = std::stoi(temp.substr(6, 2), nullptr, BASE_16) / BASE_16_DIV;
66+
}
67+
// 0xFFFFFF (rgb, 255)
68+
else if (temp.length() == 6)
69+
{
70+
_r = std::stoi(temp.substr(0, 2), nullptr, BASE_16) / BASE_16_DIV;
71+
_g = std::stoi(temp.substr(2, 2), nullptr, BASE_16) / BASE_16_DIV;
72+
_b = std::stoi(temp.substr(4, 2), nullptr, BASE_16) / BASE_16_DIV;
73+
_a = 1.0;
74+
}
75+
// 0xFFF (rgb, 16)
76+
else if (temp.length() == 3)
77+
{
78+
_r = std::stoi(temp.substr(0, 1), nullptr, BASE_16) / BASE_8_DIV;
79+
_g = std::stoi(temp.substr(1, 1), nullptr, BASE_16) / BASE_8_DIV;
80+
_b = std::stoi(temp.substr(2, 1), nullptr, BASE_16) / BASE_8_DIV;
81+
_a = 1.0;
82+
}
83+
// 0xFFFF (rgba, 16)
84+
else if (temp.length() == 4)
85+
{
86+
_r = std::stoi(temp.substr(0, 1), nullptr, BASE_16) / BASE_8_DIV;
87+
_g = std::stoi(temp.substr(1, 1), nullptr, BASE_16) / BASE_8_DIV;
88+
_b = std::stoi(temp.substr(2, 1), nullptr, BASE_16) / BASE_8_DIV;
89+
_a = std::stoi(temp.substr(3, 1), nullptr, BASE_16) / BASE_8_DIV;
90+
}
91+
else {
92+
throw std::invalid_argument("Invalid hex format");
93+
}
94+
return new Color(_r, _g, _b, _a);
95+
}
96+
97+
Color*
98+
Color::from_int_list(std::vector<int> const& color, int bit_depth)
99+
{
100+
double depth = pow(2, bit_depth) - 1.0; // e.g. 8 = 255.0
101+
if (color.size() == 3)
102+
return new Color(color[0] / depth, color[1] / depth, color[2] / depth, 1.0);
103+
else if (color.size() == 4)
104+
return new Color(color[0] / depth, color[1] / depth, color[2] / depth, color[3] / depth);
105+
106+
throw std::invalid_argument("List must have exactly 3 or 4 elements");
107+
}
108+
109+
Color*
110+
Color::from_agbr_int(unsigned int agbr) noexcept
111+
{
112+
auto conv_r = (agbr & 0xFF) / 255.0;
113+
auto conv_g = ((agbr >> 16) & 0xFF) / 255.0;
114+
auto conv_b = ((agbr >> 8) & 0xFF) / 255.0;
115+
auto conv_a = ((agbr >> 24) & 0xFF) / 255.0;
116+
return new Color(conv_r, conv_g, conv_b, conv_a);
117+
}
118+
119+
Color*
120+
Color::from_float_list(std::vector<double> const& color)
121+
{
122+
if (color.size() == 3)
123+
return new Color(color[0], color[1], color[2], 1.0);
124+
else if (color.size() == 4)
125+
return new Color(color[0], color[1], color[2], color[3]);
126+
127+
throw std::invalid_argument("List must have exactly 3 or 4 elements");
128+
}
129+
130+
std::string
131+
Color::to_hex()
132+
{
133+
auto rgba = to_rgba_int_list(8);
134+
std::stringstream ss;
135+
ss << "#";
136+
137+
ss << std::hex << std::setfill('0');
138+
ss << std::setw(2) << rgba[0];
139+
ss << std::setw(2) << rgba[1];
140+
ss << std::setw(2) << rgba[2];
141+
ss << std::setw(2) << rgba[3];
142+
return ss.str();
143+
}
144+
145+
std::vector<int>
146+
Color::to_rgba_int_list(int base)
147+
{
148+
double math_base = pow(2, base) - 1.0;
149+
return {int(_r * math_base), int(_g * math_base), int(_b * math_base), int(_a * math_base)};
150+
}
151+
152+
unsigned int
153+
Color::to_agbr_integer()
154+
{
155+
auto rgba = to_rgba_int_list(8);
156+
return (rgba[3] << 24) + (rgba[2] << 16) + (rgba[1] << 8) + rgba[0];
157+
}
158+
159+
std::vector<double>
160+
Color::to_rgba_float_list()
161+
{
162+
return {_r, _g, _b, _a};
163+
}
164+
165+
}} // namespace opentimelineio::OPENTIMELINEIO_VERSION

0 commit comments

Comments
 (0)