Clean up slightly; use set_default_colour_conversion rather than doing things in...
[dcpomatic.git] / src / lib / image_content.cc
1 /*
2     Copyright (C) 2013-2015 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 "image_content.h"
21 #include "image_examiner.h"
22 #include "compose.hpp"
23 #include "film.h"
24 #include "job.h"
25 #include "frame_rate_change.h"
26 #include "exceptions.h"
27 #include "safe_stringstream.h"
28 #include <libcxml/cxml.h>
29 #include <libxml++/libxml++.h>
30 #include <boost/foreach.hpp>
31
32 #include "i18n.h"
33
34 #include "image_filename_sorter.cc"
35
36 using std::string;
37 using std::cout;
38 using boost::shared_ptr;
39
40 ImageContent::ImageContent (shared_ptr<const Film> film, boost::filesystem::path p)
41         : Content (film)
42         , VideoContent (film)
43 {
44         if (boost::filesystem::is_regular_file (p) && valid_image_file (p)) {
45                 _paths.push_back (p);
46         } else {
47                 for (boost::filesystem::directory_iterator i(p); i != boost::filesystem::directory_iterator(); ++i) {
48                         if (boost::filesystem::is_regular_file (i->path()) && valid_image_file (i->path())) {
49                                 _paths.push_back (i->path ());
50                         }
51                 }
52
53                 if (_paths.empty()) {
54                         throw FileError (_("No valid image files were found in the folder."), p);
55                 }
56
57                 sort (_paths.begin(), _paths.end(), ImageFilenameSorter ());
58         }
59 }
60
61
62 ImageContent::ImageContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
63         : Content (film, node)
64         , VideoContent (film, node, version)
65 {
66
67 }
68
69 string
70 ImageContent::summary () const
71 {
72         string s = path_summary () + " ";
73         /* Get the string() here so that the name does not have quotes around it */
74         if (still ()) {
75                 s += _("[still]");
76         } else {
77                 s += _("[moving images]");
78         }
79
80         return s;
81 }
82
83 string
84 ImageContent::technical_summary () const
85 {
86         string s = Content::technical_summary() + " - "
87                 + VideoContent::technical_summary() + " - ";
88
89         if (still ()) {
90                 s += _("still");
91         } else {
92                 s += _("moving");
93         }
94
95         return s;
96 }
97
98 void
99 ImageContent::as_xml (xmlpp::Node* node) const
100 {
101         node->add_child("Type")->add_child_text ("Image");
102         Content::as_xml (node);
103         VideoContent::as_xml (node);
104 }
105
106 void
107 ImageContent::examine (shared_ptr<Job> job)
108 {
109         Content::examine (job);
110
111         shared_ptr<const Film> film = _film.lock ();
112         DCPOMATIC_ASSERT (film);
113
114         shared_ptr<ImageExaminer> examiner (new ImageExaminer (film, shared_from_this(), job));
115         take_from_video_examiner (examiner);
116 }
117
118 void
119 ImageContent::set_video_length (Frame len)
120 {
121         {
122                 boost::mutex::scoped_lock lm (_mutex);
123                 _video_length = len;
124         }
125
126         signal_changed (ContentProperty::LENGTH);
127 }
128
129 DCPTime
130 ImageContent::full_length () const
131 {
132         shared_ptr<const Film> film = _film.lock ();
133         DCPOMATIC_ASSERT (film);
134         FrameRateChange const frc (video_frame_rate(), film->video_frame_rate());
135         return DCPTime::from_frames (llrint (video_length_after_3d_combine() * frc.factor ()), film->video_frame_rate ());
136 }
137
138 string
139 ImageContent::identifier () const
140 {
141         SafeStringStream s;
142         s << VideoContent::identifier ();
143         s << "_" << video_length();
144         return s.str ();
145 }
146
147 bool
148 ImageContent::still () const
149 {
150         return number_of_paths() == 1;
151 }
152
153 void
154 ImageContent::set_video_frame_rate (float r)
155 {
156         {
157                 boost::mutex::scoped_lock lm (_mutex);
158                 if (_video_frame_rate == r) {
159                         return;
160                 }
161
162                 _video_frame_rate = r;
163         }
164
165         signal_changed (VideoContentProperty::VIDEO_FRAME_RATE);
166 }
167
168 void
169 ImageContent::set_default_colour_conversion ()
170 {
171         BOOST_FOREACH (boost::filesystem::path i, _paths) {
172                 if (valid_j2k_file (i)) {
173                         /* We default to no colour conversion if we have JPEG2000 files */
174                         unset_colour_conversion ();
175                         return;
176                 }
177         }
178
179         bool const s = still ();
180
181         boost::mutex::scoped_lock lm (_mutex);
182
183         if (s) {
184                 _colour_conversion = PresetColourConversion::from_id ("srgb").conversion;
185         } else {
186                 _colour_conversion = PresetColourConversion::from_id ("rec709").conversion;
187         }
188 }