920cc5e9866f4b46bc2d92815639bddbbed42750
[libdcp.git] / src / types.cc
1 /*
2     Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <vector>
21 #include <cstdio>
22 #include <iomanip>
23 #include <boost/lexical_cast.hpp>
24 #include <boost/algorithm/string.hpp>
25 #include "types.h"
26 #include "exceptions.h"
27 #include "raw_convert.h"
28
29 using namespace std;
30 using namespace libdcp;
31 using namespace boost;
32
33 Fraction::Fraction (string s)
34 {
35         vector<string> b;
36         split (b, s, is_any_of (" "));
37         if (b.size() != 2) {
38                 boost::throw_exception (XMLError ("malformed fraction " + s + " in XML node"));
39         }
40         numerator = raw_convert<int> (b[0]);
41         denominator = raw_convert<int> (b[1]);
42 }
43
44 bool
45 libdcp::operator== (Fraction const & a, Fraction const & b)
46 {
47         return (a.numerator == b.numerator && a.denominator == b.denominator);
48 }
49
50 bool
51 libdcp::operator!= (Fraction const & a, Fraction const & b)
52 {
53         return (a.numerator != b.numerator || a.denominator != b.denominator);
54 }
55
56 Color::Color ()
57         : r (0)
58         , g (0)
59         , b (0)
60 {
61
62 }
63
64 Color::Color (int r_, int g_, int b_)
65         : r (r_)
66         , g (g_)
67         , b (b_)
68 {
69
70 }
71
72 /** Construct a Color from an ARGB hex string; the alpha value is ignored.
73  *  @param argb_hex A string of the form AARRGGBB, where e.g. RR is a two-character
74  *  hex value.
75  */
76 Color::Color (string argb_hex)
77 {
78         int alpha;
79         if (sscanf (argb_hex.c_str(), "%2x%2x%2x%2x", &alpha, &r, &g, &b) < 4) {
80                 boost::throw_exception (XMLError ("could not parse colour string"));
81         }
82 }
83
84 /** @return An ARGB string of the form AARRGGBB, where e.g. RR is a two-character
85  *  hex value.  The alpha value will always be FF (ie 255; maximum alpha).
86  */
87 string
88 Color::to_argb_string () const
89 {
90         stringstream s;
91         s << "FF";
92         s << hex
93           << setw(2) << setfill('0') << r
94           << setw(2) << setfill('0') << g
95           << setw(2) << setfill('0') << b;
96
97         string t = s.str();
98         to_upper (t);
99         return t;
100 }
101
102 /** operator== for Colors.
103  *  @param a First color to compare.
104  *  @param b Second color to compare.
105  */
106 bool
107 libdcp::operator== (Color const & a, Color const & b)
108 {
109         return (a.r == b.r && a.g == b.g && a.b == b.b);
110 }
111
112 /** operator!= for Colors.
113  *  @param a First color to compare.
114  *  @param b Second color to compare.
115  */
116 bool
117 libdcp::operator!= (Color const & a, Color const & b)
118 {
119         return !(a == b);
120 }
121
122 ostream &
123 libdcp::operator<< (ostream& s, Color const & c)
124 {
125         s << "(" << c.r << ", " << c.g << ", " << c.b << ")";
126         return s;
127 }
128
129 string
130 libdcp::effect_to_string (Effect e)
131 {
132         switch (e) {
133         case NONE:
134                 return "none";
135         case BORDER:
136                 return "border";
137         case SHADOW:
138                 return "shadow";
139         }
140
141         boost::throw_exception (MiscError ("unknown effect type"));
142 }
143
144 Effect
145 libdcp::string_to_effect (string s)
146 {
147         if (s == "none") {
148                 return NONE;
149         } else if (s == "border") {
150                 return BORDER;
151         } else if (s == "shadow") {
152                 return SHADOW;
153         }
154
155         boost::throw_exception (DCPReadError ("unknown subtitle effect type"));
156 }
157
158 string
159 libdcp::valign_to_string (VAlign v)
160 {
161         switch (v) {
162         case VERTICAL_TOP:
163                 return "top";
164         case VERTICAL_CENTER:
165                 return "center";
166         case VERTICAL_BOTTOM:
167                 return "bottom";
168         }
169
170         boost::throw_exception (MiscError ("unknown valign type"));
171 }
172
173 VAlign
174 libdcp::string_to_valign (string s)
175 {
176         if (s == "top") {
177                 return VERTICAL_TOP;
178         } else if (s == "center") {
179                 return VERTICAL_CENTER;
180         } else if (s == "bottom") {
181                 return VERTICAL_BOTTOM;
182         }
183         
184         boost::throw_exception (DCPReadError ("unknown subtitle valign type"));
185 }
186
187 string
188 libdcp::halign_to_string (HAlign h)
189 {
190         switch (h) {
191         case HORIZONTAL_LEFT:
192                 return "left";
193         case HORIZONTAL_CENTER:
194                 return "center";
195         case HORIZONTAL_RIGHT:
196                 return "right";
197         }
198
199         boost::throw_exception (MiscError ("unknown halign type"));
200 }
201
202 HAlign
203 libdcp::string_to_halign (string s)
204 {
205         if (s == "left") {
206                 return HORIZONTAL_LEFT;
207         } else if (s == "center") {
208                 return HORIZONTAL_CENTER;
209         } else if (s == "right") {
210                 return HORIZONTAL_RIGHT;
211         }
212         
213         boost::throw_exception (DCPReadError ("unknown subtitle halign type"));
214 }