Move things round a bit.
[dcpomatic.git] / src / lib / format.cc
1 /*
2     Copyright (C) 2012 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 /** @file src/format.cc
21  *  @brief Class to describe a format (aspect ratio) that a Film should
22  *  be shown in.
23  */
24
25 #include <sstream>
26 #include <cstdlib>
27 #include <cassert>
28 #include <iomanip>
29 #include <iostream>
30 #include "format.h"
31
32 using namespace std;
33
34 vector<Format const *> Format::_formats;
35
36 /** @param r Ratio multiplied by 100 (e.g. 185)
37  *  @param dcp Size (in pixels) of the images that we should put in a DCP.
38  *  @param id ID (e.g. 185)
39  *  @param n Nick name (e.g. Flat)
40  */
41 Format::Format (int r, Size dcp, string id, string n)
42         : _ratio (r)
43         , _dcp_size (dcp)
44         , _id (id)
45         , _nickname (n)
46 {
47
48 }
49
50 /** @return A name to be presented to the user */
51 string
52 Format::name () const
53 {
54         stringstream s;
55         if (!_nickname.empty ()) {
56                 s << _nickname << " (";
57         }
58
59         s << setprecision(3) << (_ratio / 100.0) << ":1";
60
61         if (!_nickname.empty ()) {
62                 s << ")";
63         }
64
65         return s.str ();
66 }
67
68 /** @return Identifier for this format as metadata for a Film's metadata file */
69 string
70 Format::as_metadata () const
71 {
72         return _id;
73 }
74
75 /** Fill our _formats vector with all available formats */
76 void
77 Format::setup_formats ()
78 {
79         _formats.push_back (new Format (133, Size (1998, 1080), "133-in-flat", "4:3 within Flat"));
80         _formats.push_back (new Format (137, Size (1480, 1080), "137", "Academy"));
81         _formats.push_back (new Format (178, Size (1998, 1080), "178-in-flat", "16:9 within Flat"));
82         _formats.push_back (new Format (185, Size (1998, 1080), "185", "Flat"));
83         _formats.push_back (new Format (239, Size (2048, 858), "239", "Scope"));
84 }
85
86 /** @param r Ratio multiplied by 100.
87  *  @return Matching Format, or 0.
88  */
89 Format const *
90 Format::from_ratio (int r)
91 {
92         vector<Format const *>::iterator i = _formats.begin ();
93         while (i != _formats.end() && (*i)->ratio_as_integer() != r) {
94                 ++i;
95         }
96
97         if (i == _formats.end ()) {
98                 return 0;
99         }
100
101         return *i;
102 }
103
104 /** @param n Nickname.
105  *  @return Matching Format, or 0.
106  */
107 Format const *
108 Format::from_nickname (string n)
109 {
110         vector<Format const *>::iterator i = _formats.begin ();
111         while (i != _formats.end() && (*i)->nickname() != n) {
112                 ++i;
113         }
114
115         if (i == _formats.end ()) {
116                 return 0;
117         }
118
119         return *i;
120 }
121
122 /** @param i Id.
123  *  @return Matching Format, or 0.
124  */
125 Format const *
126 Format::from_id (string i)
127 {
128         vector<Format const *>::iterator j = _formats.begin ();
129         while (j != _formats.end() && (*j)->id() != i) {
130                 ++j;
131         }
132
133         if (j == _formats.end ()) {
134                 return 0;
135         }
136
137         return *j;
138 }
139
140
141 /** @param m Metadata, as returned from as_metadata().
142  *  @return Matching Format, or 0.
143  */
144 Format const *
145 Format::from_metadata (string m)
146 {
147         return from_id (m);
148 }
149
150 /** @param f A Format.
151  *  @return Index of f within our static list, or -1.
152  */
153 int
154 Format::as_index (Format const * f)
155 {
156         vector<Format*>::size_type i = 0;
157         while (i < _formats.size() && _formats[i] != f) {
158                 ++i;
159         }
160
161         if (i == _formats.size ()) {
162                 return -1;
163         }
164
165         return i;
166 }
167
168 /** @param i An index returned from as_index().
169  *  @return Corresponding Format.
170  */
171 Format const *
172 Format::from_index (int i)
173 {
174         assert (i >= 0 && i < int(_formats.size ()));
175         return _formats[i];
176 }
177
178 /** @return All available formats */
179 vector<Format const *>
180 Format::all ()
181 {
182         return _formats;
183 }
184
185 int
186 Format::dcp_padding () const
187 {
188         return rint ((_dcp_size.width - (_dcp_size.height * _ratio / 100.0)) / 2.0);
189 }