51c0b60d1d09c1cac9de3b4fea8857b981644ecf
[dcpomatic.git] / src / lib / tiff_decoder.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/tiff_decoder.cc
21  *  @brief A decoder which reads a numbered set of TIFF files, one per frame.
22  */
23
24 #include <vector>
25 #include <string>
26 #include <iostream>
27 #include <stdint.h>
28 #include <boost/shared_ptr.hpp>
29 #include <boost/filesystem.hpp>
30 #include <tiffio.h>
31 extern "C" {
32 #include <libavformat/avformat.h>
33 }
34 #include "util.h"
35 #include "tiff_decoder.h"
36 #include "film_state.h"
37 #include "exceptions.h"
38 #include "image.h"
39 #include "options.h"
40
41 using namespace std;
42 using namespace boost;
43
44 /** @param fs FilmState of our Film.
45  *  @param o Options.
46  *  @param j Job that we are associated with, or 0.
47  *  @param l Log that we can write to.
48  *  @param minimal true to do the bare minimum of work; just run through the content.  Useful for acquiring
49  *  accurate frame counts as quickly as possible.  This generates no video or audio output.
50  *  @param ignore_length Ignore the content's claimed length when computing progress.
51  */
52 TIFFDecoder::TIFFDecoder (boost::shared_ptr<const FilmState> fs, boost::shared_ptr<const Options> o, Job* j, Log* l, bool minimal, bool ignore_length)
53         : Decoder (fs, o, j, l, minimal, ignore_length)
54 {
55         string const dir = _fs->content_path ();
56         
57         if (!filesystem::is_directory (dir)) {
58                 throw DecodeError ("TIFF content must be in a directory");
59         }
60
61         for (filesystem::directory_iterator i = filesystem::directory_iterator (dir); i != filesystem::directory_iterator(); ++i) {
62                 /* Aah, the sweet smell of progress */
63 #if BOOST_FILESYSTEM_VERSION == 3
64                 string const ext = filesystem::path(*i).extension().string();
65                 string const l = filesystem::path(*i).leaf().generic_string();
66 #else
67                 string const ext = filesystem::path(*i).extension();
68                 string const l = i->leaf ();
69 #endif
70                 if (ext == ".tif" || ext == ".tiff") {
71                         _files.push_back (l);
72                 }
73         }
74
75         _files.sort ();
76
77         _iter = _files.begin ();
78
79 }
80
81 float
82 TIFFDecoder::frames_per_second () const
83 {
84         /* We don't know */
85         return 0;
86 }
87
88 Size
89 TIFFDecoder::native_size () const
90 {
91         if (_files.empty ()) {
92                 throw DecodeError ("no TIFF files found");
93         }
94         
95         TIFF* t = TIFFOpen (file_path (_files.front()).c_str (), "r");
96         if (t == 0) {
97                 throw DecodeError ("could not open TIFF file");
98         }
99
100         uint32_t width;
101         TIFFGetField (t, TIFFTAG_IMAGEWIDTH, &width);
102         uint32_t height;
103         TIFFGetField (t, TIFFTAG_IMAGELENGTH, &height);
104
105         return Size (width, height);
106 }
107
108 int
109 TIFFDecoder::audio_channels () const
110 {
111         /* No audio */
112         return 0;
113 }
114
115 int
116 TIFFDecoder::audio_sample_rate () const
117 {
118         return 0;
119 }
120
121 AVSampleFormat
122 TIFFDecoder::audio_sample_format () const
123 {
124         return AV_SAMPLE_FMT_NONE;
125 }
126
127
128 int64_t
129 TIFFDecoder::audio_channel_layout () const
130 {
131         return 0;
132 }
133
134 bool
135 TIFFDecoder::do_pass ()
136 {
137         if (_iter == _files.end ()) {
138                 return true;
139         }
140
141         TIFF* t = TIFFOpen (file_path (*_iter).c_str (), "r");
142         if (t == 0) {
143                 throw DecodeError ("could not open TIFF file");
144         }
145
146         uint32_t width;
147         TIFFGetField (t, TIFFTAG_IMAGEWIDTH, &width);
148         uint32_t height;
149         TIFFGetField (t, TIFFTAG_IMAGELENGTH, &height);
150
151         int const num_pixels = width * height;
152         uint32_t * raster = (uint32_t *) _TIFFmalloc (num_pixels * sizeof (uint32_t));
153         if (raster == 0) {
154                 throw DecodeError ("could not allocate memory to decode TIFF file");
155         }
156
157         if (TIFFReadRGBAImage (t, width, height, raster, 0) < 0) {
158                 throw DecodeError ("could not read TIFF data");
159         }
160
161         RGBFrameImage image (Size (width, height));
162
163         uint8_t* p = image.data()[0];
164         for (uint32_t y = 0; y < height; ++y) {
165                 for (uint32_t x = 0; x < width; ++x) {
166                         uint32_t const i = (height - y - 1) * width + x;
167                         *p++ = raster[i] & 0xff;
168                         *p++ = (raster[i] & 0xff00) >> 8;
169                         *p++ = (raster[i] & 0xff0000) >> 16;
170                 }
171         }
172
173         _TIFFfree (raster);
174         TIFFClose (t);
175
176         process_video (image.frame ());
177
178         ++_iter;
179         return false;
180 }
181
182 /** @param file name within our content directory
183  *  @return full path to the file
184  */
185 string
186 TIFFDecoder::file_path (string f) const
187 {
188         stringstream s;
189         s << _fs->content_path() << "/" << f;
190         return _fs->file (s.str ());
191 }
192
193 PixelFormat
194 TIFFDecoder::pixel_format () const
195 {
196         return PIX_FMT_RGB24;
197 }
198
199 int
200 TIFFDecoder::time_base_numerator () const
201 {
202         return rint (_fs->frames_per_second());
203 }
204
205
206 int
207 TIFFDecoder::time_base_denominator () const
208 {
209         return 1;
210 }
211
212 int
213 TIFFDecoder::sample_aspect_ratio_numerator () const
214 {
215         /* XXX */
216         return 1;
217 }
218
219 int
220 TIFFDecoder::sample_aspect_ratio_denominator () const
221 {
222         /* XXX */
223         return 1;
224 }