Rename TYPE_DEBUG_PLAYER to TYPE_DEBUG_VIDEO_VIEW.
[dcpomatic.git] / src / lib / types.cc
1 /*
2     Copyright (C) 2013-2019 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
6     DCP-o-matic 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     DCP-o-matic 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 DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21 #include "types.h"
22 #include "compose.hpp"
23 #include "dcpomatic_assert.h"
24 #include <dcp/raw_convert.h>
25 #include <dcp/cpl.h>
26 #include <dcp/dcp.h>
27 #include <dcp/reel_mxf.h>
28 #include <dcp/reel_asset.h>
29 #include <libxml++/libxml++.h>
30 #include <libcxml/cxml.h>
31 #include <boost/foreach.hpp>
32
33 #include "i18n.h"
34
35 using std::max;
36 using std::min;
37 using std::string;
38 using std::list;
39 using boost::shared_ptr;
40 using dcp::raw_convert;
41
42 bool operator== (Crop const & a, Crop const & b)
43 {
44         return (a.left == b.left && a.right == b.right && a.top == b.top && a.bottom == b.bottom);
45 }
46
47 bool operator!= (Crop const & a, Crop const & b)
48 {
49         return !(a == b);
50 }
51
52 /** @param r Resolution.
53  *  @return Untranslated string representation.
54  */
55 string
56 resolution_to_string (Resolution r)
57 {
58         switch (r) {
59         case RESOLUTION_2K:
60                 return "2K";
61         case RESOLUTION_4K:
62                 return "4K";
63         }
64
65         DCPOMATIC_ASSERT (false);
66         return "";
67 }
68
69
70 Resolution
71 string_to_resolution (string s)
72 {
73         if (s == "2K") {
74                 return RESOLUTION_2K;
75         }
76
77         if (s == "4K") {
78                 return RESOLUTION_4K;
79         }
80
81         DCPOMATIC_ASSERT (false);
82         return RESOLUTION_2K;
83 }
84
85 Crop::Crop (shared_ptr<cxml::Node> node)
86 {
87         left = node->number_child<int> ("LeftCrop");
88         right = node->number_child<int> ("RightCrop");
89         top = node->number_child<int> ("TopCrop");
90         bottom = node->number_child<int> ("BottomCrop");
91 }
92
93 void
94 Crop::as_xml (xmlpp::Node* node) const
95 {
96         node->add_child("LeftCrop")->add_child_text (raw_convert<string> (left));
97         node->add_child("RightCrop")->add_child_text (raw_convert<string> (right));
98         node->add_child("TopCrop")->add_child_text (raw_convert<string> (top));
99         node->add_child("BottomCrop")->add_child_text (raw_convert<string> (bottom));
100 }
101
102 TextType
103 string_to_text_type (string s)
104 {
105         if (s == "unknown") {
106                 return TEXT_UNKNOWN;
107         } else if (s == "open-subtitle") {
108                 return TEXT_OPEN_SUBTITLE;
109         } else if (s == "closed-caption") {
110                 return TEXT_CLOSED_CAPTION;
111         } else {
112                 throw MetadataError (String::compose ("Unknown text type %1", s));
113         }
114 }
115
116 string
117 text_type_to_string (TextType t)
118 {
119         switch (t) {
120         case TEXT_UNKNOWN:
121                 return "unknown";
122         case TEXT_OPEN_SUBTITLE:
123                 return "open-subtitle";
124         case TEXT_CLOSED_CAPTION:
125                 return "closed-caption";
126         default:
127                 DCPOMATIC_ASSERT (false);
128         }
129 }
130
131 string
132 text_type_to_name (TextType t)
133 {
134         switch (t) {
135         case TEXT_UNKNOWN:
136                 return _("Timed text");
137         case TEXT_OPEN_SUBTITLE:
138                 return _("Open subtitles");
139         case TEXT_CLOSED_CAPTION:
140                 return _("Closed captions");
141         default:
142                 DCPOMATIC_ASSERT (false);
143         }
144 }
145
146 string
147 video_frame_type_to_string (VideoFrameType t)
148 {
149         switch (t) {
150         case VIDEO_FRAME_TYPE_2D:
151                 return "2d";
152         case VIDEO_FRAME_TYPE_3D:
153                 return "3d";
154         case VIDEO_FRAME_TYPE_3D_LEFT_RIGHT:
155                 return "3d-left-right";
156         case VIDEO_FRAME_TYPE_3D_TOP_BOTTOM:
157                 return "3d-top-bottom";
158         case VIDEO_FRAME_TYPE_3D_ALTERNATE:
159                 return "3d-alternate";
160         case VIDEO_FRAME_TYPE_3D_LEFT:
161                 return "3d-left";
162         case VIDEO_FRAME_TYPE_3D_RIGHT:
163                 return "3d-right";
164         default:
165                 DCPOMATIC_ASSERT (false);
166         }
167
168         DCPOMATIC_ASSERT (false);
169 }
170
171 VideoFrameType
172 string_to_video_frame_type (string s)
173 {
174         if (s == "2d") {
175                 return VIDEO_FRAME_TYPE_2D;
176         } else if (s == "3d") {
177                 return VIDEO_FRAME_TYPE_3D;
178         } else if (s == "3d-left-right") {
179                 return VIDEO_FRAME_TYPE_3D_LEFT_RIGHT;
180         } else if (s == "3d-top-bottom") {
181                 return VIDEO_FRAME_TYPE_3D_TOP_BOTTOM;
182         } else if (s == "3d-alternate") {
183                 return VIDEO_FRAME_TYPE_3D_ALTERNATE;
184         } else if (s == "3d-left") {
185                 return VIDEO_FRAME_TYPE_3D_LEFT;
186         } else if (s == "3d-right") {
187                 return VIDEO_FRAME_TYPE_3D_RIGHT;
188         }
189
190         DCPOMATIC_ASSERT (false);
191 }
192
193 CPLSummary::CPLSummary (boost::filesystem::path p)
194         : dcp_directory (p.leaf().string())
195 {
196         dcp::DCP dcp (p);
197         list<dcp::VerificationNote> notes;
198         dcp.read (&notes);
199         if (!notes.empty()) {
200                 throw dcp::ReadError(dcp::note_to_string(notes.front()));
201         }
202
203         cpl_id = dcp.cpls().front()->id();
204         cpl_annotation_text = dcp.cpls().front()->annotation_text();
205         cpl_file = dcp.cpls().front()->file().get();
206
207         encrypted = false;
208         BOOST_FOREACH (shared_ptr<dcp::CPL> j, dcp.cpls()) {
209                 BOOST_FOREACH (shared_ptr<const dcp::ReelMXF> k, j->reel_mxfs()) {
210                         if (k->key_id()) {
211                                 encrypted = true;
212                         }
213                 }
214         }
215
216         last_write_time = boost::filesystem::last_write_time (p);
217 }