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