2 Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
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.
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.
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.
20 /** @file src/tiff_decoder.cc
21 * @brief A decoder which reads a numbered set of TIFF files, one per frame.
28 #include <boost/shared_ptr.hpp>
29 #include <boost/filesystem.hpp>
32 #include <libavformat/avformat.h>
35 #include "tiff_decoder.h"
36 #include "film_state.h"
37 #include "exceptions.h"
42 using namespace boost;
44 /** @param fs FilmState of our Film.
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.
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)
55 string const dir = _fs->content_path ();
57 if (!filesystem::is_directory (dir)) {
58 throw DecodeError ("TIFF content must be in a directory");
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();
67 string const ext = filesystem::path(*i).extension();
68 string const l = i->leaf ();
70 if (ext == ".tif" || ext == ".tiff") {
77 _iter = _files.begin ();
82 TIFFDecoder::length_in_frames () const
84 return _files.size ();
88 TIFFDecoder::frames_per_second () const
95 TIFFDecoder::native_size () const
97 if (_files.empty ()) {
98 throw DecodeError ("no TIFF files found");
101 TIFF* t = TIFFOpen (file_path (_files.front()).c_str (), "r");
103 throw DecodeError ("could not open TIFF file");
107 TIFFGetField (t, TIFFTAG_IMAGEWIDTH, &width);
109 TIFFGetField (t, TIFFTAG_IMAGELENGTH, &height);
111 return Size (width, height);
115 TIFFDecoder::audio_channels () const
122 TIFFDecoder::audio_sample_rate () const
128 TIFFDecoder::audio_sample_format () const
130 return AV_SAMPLE_FMT_NONE;
135 TIFFDecoder::audio_channel_layout () const
141 TIFFDecoder::do_pass ()
143 if (_iter == _files.end ()) {
147 TIFF* t = TIFFOpen (file_path (*_iter).c_str (), "r");
149 throw DecodeError ("could not open TIFF file");
153 TIFFGetField (t, TIFFTAG_IMAGEWIDTH, &width);
155 TIFFGetField (t, TIFFTAG_IMAGELENGTH, &height);
157 int const num_pixels = width * height;
158 uint32_t * raster = (uint32_t *) _TIFFmalloc (num_pixels * sizeof (uint32_t));
160 throw DecodeError ("could not allocate memory to decode TIFF file");
163 if (TIFFReadRGBAImage (t, width, height, raster, 0) < 0) {
164 throw DecodeError ("could not read TIFF data");
167 RGBFrameImage image (Size (width, height));
169 uint8_t* p = image.data()[0];
170 for (uint32_t y = 0; y < height; ++y) {
171 for (uint32_t x = 0; x < width; ++x) {
172 uint32_t const i = (height - y - 1) * width + x;
173 *p++ = raster[i] & 0xff;
174 *p++ = (raster[i] & 0xff00) >> 8;
175 *p++ = (raster[i] & 0xff0000) >> 16;
182 process_video (image.frame ());
188 /** @param file name within our content directory
189 * @return full path to the file
192 TIFFDecoder::file_path (string f) const
195 s << _fs->content_path() << "/" << f;
196 return _fs->file (s.str ());
200 TIFFDecoder::pixel_format () const
202 return PIX_FMT_RGB24;
206 TIFFDecoder::time_base_numerator () const
208 return rint (_fs->frames_per_second);;
213 TIFFDecoder::time_base_denominator () const
219 TIFFDecoder::sample_aspect_ratio_numerator () const
226 TIFFDecoder::sample_aspect_ratio_denominator () const