No-op; Fix GPL address and mention libdcp by name.
[libdcp.git] / src / types.cc
1 /*
2     Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
3
4     This file is part of libdcp.
5
6     libdcp is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     libdcp is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with libdcp.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21 #include "raw_convert.h"
22 #include "types.h"
23 #include "exceptions.h"
24 #include "compose.hpp"
25 #include <boost/algorithm/string.hpp>
26 #include <vector>
27 #include <cstdio>
28 #include <iomanip>
29
30 using namespace std;
31 using namespace dcp;
32 using namespace boost;
33
34 /** Construct a Fraction from a string of the form <numerator> <denominator>
35  *  e.g. "1 3".
36  */
37 Fraction::Fraction (string s)
38 {
39         vector<string> b;
40         split (b, s, is_any_of (" "));
41         if (b.size() != 2) {
42                 boost::throw_exception (XMLError ("malformed fraction " + s + " in XML node"));
43         }
44         numerator = raw_convert<int> (b[0]);
45         denominator = raw_convert<int> (b[1]);
46 }
47
48 string
49 Fraction::as_string () const
50 {
51         return String::compose ("%1 %2", numerator, denominator);
52 }
53
54 bool
55 dcp::operator== (Fraction const & a, Fraction const & b)
56 {
57         return (a.numerator == b.numerator && a.denominator == b.denominator);
58 }
59
60 bool
61 dcp::operator!= (Fraction const & a, Fraction const & b)
62 {
63         return (a.numerator != b.numerator || a.denominator != b.denominator);
64 }
65
66 ostream&
67 dcp::operator<< (ostream& s, Fraction const & f)
68 {
69         s << f.numerator << "/" << f.denominator;
70         return s;
71 }
72
73 /** Construct a Colour, initialising it to black. */
74 Colour::Colour ()
75         : r (0)
76         , g (0)
77         , b (0)
78 {
79
80 }
81
82 /** Construct a Colour from R, G and B.  The values run between
83  *  0 and 255.
84  */
85 Colour::Colour (int r_, int g_, int b_)
86         : r (r_)
87         , g (g_)
88         , b (b_)
89 {
90
91 }
92
93 /** Construct a Colour from an ARGB hex string; the alpha value is ignored.
94  *  @param argb_hex A string of the form AARRGGBB, where e.g. RR is a two-character
95  *  hex value.
96  */
97 Colour::Colour (string argb_hex)
98 {
99         int alpha;
100         if (sscanf (argb_hex.c_str(), "%2x%2x%2x%2x", &alpha, &r, &g, &b) != 4) {
101                 boost::throw_exception (XMLError ("could not parse colour string"));
102         }
103 }
104
105 /** @return An ARGB string of the form AARRGGBB, where e.g. RR is a two-character
106  *  hex value.  The alpha value will always be FF (ie 255; maximum alpha).
107  */
108 string
109 Colour::to_argb_string () const
110 {
111         stringstream s;
112         s << "FF";
113         s << hex
114           << setw(2) << setfill('0') << r
115           << setw(2) << setfill('0') << g
116           << setw(2) << setfill('0') << b;
117
118         string t = s.str();
119         to_upper (t);
120         return t;
121 }
122
123 /** operator== for Colours.
124  *  @param a First colour to compare.
125  *  @param b Second colour to compare.
126  */
127 bool
128 dcp::operator== (Colour const & a, Colour const & b)
129 {
130         return (a.r == b.r && a.g == b.g && a.b == b.b);
131 }
132
133 /** operator!= for Colours.
134  *  @param a First colour to compare.
135  *  @param b Second colour to compare.
136  */
137 bool
138 dcp::operator!= (Colour const & a, Colour const & b)
139 {
140         return !(a == b);
141 }
142
143 ostream &
144 dcp::operator<< (ostream& s, Colour const & c)
145 {
146         s << "(" << c.r << ", " << c.g << ", " << c.b << ")";
147         return s;
148 }
149
150 string
151 dcp::effect_to_string (Effect e)
152 {
153         switch (e) {
154         case NONE:
155                 return "none";
156         case BORDER:
157                 return "border";
158         case SHADOW:
159                 return "shadow";
160         }
161
162         boost::throw_exception (MiscError ("unknown effect type"));
163 }
164
165 Effect
166 dcp::string_to_effect (string s)
167 {
168         if (s == "none") {
169                 return NONE;
170         } else if (s == "border") {
171                 return BORDER;
172         } else if (s == "shadow") {
173                 return SHADOW;
174         }
175
176         boost::throw_exception (DCPReadError ("unknown subtitle effect type"));
177 }
178
179 string
180 dcp::halign_to_string (HAlign h)
181 {
182         switch (h) {
183         case HALIGN_LEFT:
184                 return "left";
185         case HALIGN_CENTER:
186                 return "center";
187         case HALIGN_RIGHT:
188                 return "right";
189         }
190
191         boost::throw_exception (MiscError ("unknown subtitle halign type"));
192 }
193
194 HAlign
195 dcp::string_to_halign (string s)
196 {
197         if (s == "left") {
198                 return HALIGN_LEFT;
199         } else if (s == "center") {
200                 return HALIGN_CENTER;
201         } else if (s == "right") {
202                 return HALIGN_RIGHT;
203         }
204
205         boost::throw_exception (DCPReadError ("unknown subtitle halign type"));
206 }
207
208 string
209 dcp::valign_to_string (VAlign v)
210 {
211         switch (v) {
212         case VALIGN_TOP:
213                 return "top";
214         case VALIGN_CENTER:
215                 return "center";
216         case VALIGN_BOTTOM:
217                 return "bottom";
218         }
219
220         boost::throw_exception (MiscError ("unknown subtitle valign type"));
221 }
222
223 VAlign
224 dcp::string_to_valign (string s)
225 {
226         if (s == "top") {
227                 return VALIGN_TOP;
228         } else if (s == "center") {
229                 return VALIGN_CENTER;
230         } else if (s == "bottom") {
231                 return VALIGN_BOTTOM;
232         }
233
234         boost::throw_exception (DCPReadError ("unknown subtitle valign type"));
235 }
236
237 string
238 dcp::direction_to_string (Direction v)
239 {
240         switch (v) {
241         case DIRECTION_LTR:
242                 return "ltr";
243         case DIRECTION_RTL:
244                 return "rtl";
245         case DIRECTION_TTB:
246                 return "ttb";
247         case DIRECTION_BTT:
248                 return "btt";
249         }
250
251         boost::throw_exception (MiscError ("unknown subtitle direction type"));
252 }
253
254 Direction
255 dcp::string_to_direction (string s)
256 {
257         if (s == "ltr" || s == "horizontal") {
258                 return DIRECTION_LTR;
259         } else if (s == "rtl") {
260                 return DIRECTION_RTL;
261         } else if (s == "ttb" || s == "vertical") {
262                 return DIRECTION_TTB;
263         } else if (s == "btt") {
264                 return DIRECTION_BTT;
265         }
266
267         boost::throw_exception (DCPReadError ("unknown subtitle direction type"));
268 }