summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2012-11-14 21:58:47 +0000
committerCarl Hetherington <cth@carlh.net>2012-11-14 21:58:47 +0000
commit967dc3f4461d4b8caf809ebce7bdcb6e818809f0 (patch)
treec599bad3a8a3797ccdc3d25963059a668baa6649 /src/lib
parent05c37b9bb09f7bfa4c2ec8ea6b3fa4a83d0fec20 (diff)
Use ImageMagick for tiff decoding too.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/decoder_factory.cc9
-rw-r--r--src/lib/film.cc13
-rw-r--r--src/lib/imagemagick_decoder.cc47
-rw-r--r--src/lib/imagemagick_decoder.h11
-rw-r--r--src/lib/j2k_still_encoder.cc2
-rw-r--r--src/lib/make_dcp_job.cc2
-rw-r--r--src/lib/tiff_decoder.cc214
-rw-r--r--src/lib/tiff_decoder.h70
-rw-r--r--src/lib/util.cc15
-rw-r--r--src/lib/util.h1
-rw-r--r--src/lib/wscript1
11 files changed, 67 insertions, 318 deletions
diff --git a/src/lib/decoder_factory.cc b/src/lib/decoder_factory.cc
index d4a91d8d9..bb6eff971 100644
--- a/src/lib/decoder_factory.cc
+++ b/src/lib/decoder_factory.cc
@@ -23,7 +23,6 @@
#include <boost/filesystem.hpp>
#include "ffmpeg_decoder.h"
-#include "tiff_decoder.h"
#include "imagemagick_decoder.h"
#include "film.h"
@@ -35,12 +34,8 @@ decoder_factory (
shared_ptr<Film> f, shared_ptr<const Options> o, Job* j
)
{
- if (boost::filesystem::is_directory (f->content_path ())) {
- /* Assume a directory contains TIFFs */
- return shared_ptr<Decoder> (new TIFFDecoder (f, o, j));
- }
-
- if (f->content_type() == STILL) {
+ if (boost::filesystem::is_directory (f->content_path()) || f->content_type() == STILL) {
+ /* A single image file, or a directory of them */
return shared_ptr<Decoder> (new ImageMagickDecoder (f, o, j));
}
diff --git a/src/lib/film.cc b/src/lib/film.cc
index c38b59d9e..ac5b43a98 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -686,15 +686,12 @@ Film::content_path () const
ContentType
Film::content_type () const
{
-#if BOOST_FILESYSTEM_VERSION == 3
- string ext = boost::filesystem::path(_content).extension().string();
-#else
- string ext = boost::filesystem::path(_content).extension();
-#endif
+ if (boost::filesystem::is_directory (_content)) {
+ /* Directory of images, we assume */
+ return VIDEO;
+ }
- transform (ext.begin(), ext.end(), ext.begin(), ::tolower);
-
- if (ext == ".tif" || ext == ".tiff" || ext == ".jpg" || ext == ".jpeg" || ext == ".png") {
+ if (still_image_file (_content)) {
return STILL;
}
diff --git a/src/lib/imagemagick_decoder.cc b/src/lib/imagemagick_decoder.cc
index 53e1db879..7faf74c61 100644
--- a/src/lib/imagemagick_decoder.cc
+++ b/src/lib/imagemagick_decoder.cc
@@ -18,10 +18,12 @@
*/
#include <iostream>
+#include <boost/filesystem.hpp>
#include <Magick++.h>
#include "imagemagick_decoder.h"
#include "image.h"
#include "film.h"
+#include "exceptions.h"
using std::cout;
using boost::shared_ptr;
@@ -29,49 +31,76 @@ using boost::shared_ptr;
ImageMagickDecoder::ImageMagickDecoder (
boost::shared_ptr<Film> f, boost::shared_ptr<const Options> o, Job* j)
: Decoder (f, o, j)
- , _done (false)
{
- _magick_image = new Magick::Image (_film->content_path ());
+ if (boost::filesystem::is_directory (_film->content_path())) {
+ for (
+ boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator (_film->content_path());
+ i != boost::filesystem::directory_iterator();
+ ++i) {
+
+ if (still_image_file (i->path().string())) {
+ _files.push_back (i->path().string());
+ }
+ }
+ } else {
+ _files.push_back (_film->content_path ());
+ }
+
+ _iter = _files.begin ();
}
Size
ImageMagickDecoder::native_size () const
{
- return Size (_magick_image->columns(), _magick_image->rows());
+ if (_files.empty ()) {
+ throw DecodeError ("no still image files found");
+ }
+
+ /* Look at the first file and assume its size holds for all */
+ using namespace MagickCore;
+ Magick::Image* image = new Magick::Image (_film->content_path ());
+ Size const s = Size (image->columns(), image->rows());
+ delete image;
+
+ return s;
}
bool
ImageMagickDecoder::pass ()
{
- using namespace MagickCore;
-
- if (_done) {
+ if (_iter == _files.end()) {
return true;
}
+
+ using namespace MagickCore;
+ Magick::Image* magick_image = new Magick::Image (_film->content_path ());
+
Size size = native_size ();
shared_ptr<CompactImage> image (new CompactImage (PIX_FMT_RGB24, size));
uint8_t* p = image->data()[0];
for (int y = 0; y < size.height; ++y) {
for (int x = 0; x < size.width; ++x) {
- Magick::Color c = _magick_image->pixelColor (x, y);
+ Magick::Color c = magick_image->pixelColor (x, y);
*p++ = c.redQuantum() * 255 / QuantumRange;
*p++ = c.greenQuantum() * 255 / QuantumRange;
*p++ = c.blueQuantum() * 255 / QuantumRange;
}
-
}
+
+ delete magick_image;
emit_video (image);
- _done = true;
+ ++_iter;
return false;
}
PixelFormat
ImageMagickDecoder::pixel_format () const
{
+ /* XXX: always true? */
return PIX_FMT_RGB24;
}
diff --git a/src/lib/imagemagick_decoder.h b/src/lib/imagemagick_decoder.h
index 1bf50378b..6506d0177 100644
--- a/src/lib/imagemagick_decoder.h
+++ b/src/lib/imagemagick_decoder.h
@@ -29,7 +29,8 @@ public:
ImageMagickDecoder (boost::shared_ptr<Film>, boost::shared_ptr<const Options>, Job *);
float frames_per_second () const {
- return static_frames_per_second ();
+ /* We don't know */
+ return 0;
}
Size native_size () const;
@@ -50,10 +51,6 @@ public:
return false;
}
- static float static_frames_per_second () {
- return 24;
- }
-
protected:
bool pass ();
PixelFormat pixel_format () const;
@@ -77,6 +74,6 @@ protected:
}
private:
- Magick::Image* _magick_image;
- bool _done;
+ std::list<std::string> _files;
+ std::list<std::string>::iterator _iter;
};
diff --git a/src/lib/j2k_still_encoder.cc b/src/lib/j2k_still_encoder.cc
index a4ac54e7a..dd6ef49b2 100644
--- a/src/lib/j2k_still_encoder.cc
+++ b/src/lib/j2k_still_encoder.cc
@@ -64,7 +64,7 @@ J2KStillEncoder::do_process_video (shared_ptr<Image> yuv, shared_ptr<Subtitle> s
}
string const real = _opt->frame_out_path (0, false);
- for (int i = 1; i < (_film->still_duration() * ImageMagickDecoder::static_frames_per_second()); ++i) {
+ for (int i = 1; i < (_film->still_duration() * 24); ++i) {
if (!boost::filesystem::exists (_opt->frame_out_path (i, false))) {
string const link = _opt->frame_out_path (i, false);
#ifdef DVDOMATIC_POSIX
diff --git a/src/lib/make_dcp_job.cc b/src/lib/make_dcp_job.cc
index a1ffd9672..026724806 100644
--- a/src/lib/make_dcp_job.cc
+++ b/src/lib/make_dcp_job.cc
@@ -90,7 +90,7 @@ MakeDCPJob::run ()
frames = _film->dcp_length().get() / dfr.skip;
break;
case STILL:
- frames = _film->still_duration() * ImageMagickDecoder::static_frames_per_second ();
+ frames = _film->still_duration() * 24;
break;
}
diff --git a/src/lib/tiff_decoder.cc b/src/lib/tiff_decoder.cc
deleted file mode 100644
index a58ea9974..000000000
--- a/src/lib/tiff_decoder.cc
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-/** @file src/tiff_decoder.cc
- * @brief A decoder which reads a numbered set of TIFF files, one per frame.
- */
-
-#include <vector>
-#include <string>
-#include <iostream>
-#include <stdint.h>
-#include <boost/shared_ptr.hpp>
-#include <boost/filesystem.hpp>
-#include <tiffio.h>
-extern "C" {
-#include <libavformat/avformat.h>
-}
-#include "util.h"
-#include "tiff_decoder.h"
-#include "exceptions.h"
-#include "image.h"
-#include "options.h"
-#include "film.h"
-
-using std::cout;
-using std::string;
-using std::stringstream;
-using boost::shared_ptr;
-
-/** @param f Our Film.
- * @param o Options.
- * @param j Job that we are associated with, or 0.
- */
-TIFFDecoder::TIFFDecoder (boost::shared_ptr<Film> f, boost::shared_ptr<const Options> o, Job* j)
- : Decoder (f, o, j)
-{
- string const dir = _film->content_path ();
-
- if (!boost::filesystem::is_directory (dir)) {
- throw DecodeError ("TIFF content must be in a directory");
- }
-
- for (boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator (dir); i != boost::filesystem::directory_iterator(); ++i) {
- /* Aah, the sweet smell of progress */
-#if BOOST_FILESYSTEM_VERSION == 3
- string const ext = boost::filesystem::path(*i).extension().string();
- string const l = boost::filesystem::path(*i).leaf().generic_string();
-#else
- string const ext = boost::filesystem::path(*i).extension();
- string const l = i->leaf ();
-#endif
- if (ext == ".tif" || ext == ".tiff") {
- _files.push_back (l);
- }
- }
-
- _files.sort ();
-
- _iter = _files.begin ();
-}
-
-float
-TIFFDecoder::frames_per_second () const
-{
- /* We don't know */
- return 0;
-}
-
-Size
-TIFFDecoder::native_size () const
-{
- if (_files.empty ()) {
- throw DecodeError ("no TIFF files found");
- }
-
- TIFF* t = TIFFOpen (file_path (_files.front()).c_str (), "r");
- if (t == 0) {
- throw DecodeError ("could not open TIFF file");
- }
-
- uint32_t width;
- TIFFGetField (t, TIFFTAG_IMAGEWIDTH, &width);
- uint32_t height;
- TIFFGetField (t, TIFFTAG_IMAGELENGTH, &height);
-
- return Size (width, height);
-}
-
-int
-TIFFDecoder::audio_channels () const
-{
- /* No audio */
- return 0;
-}
-
-int
-TIFFDecoder::audio_sample_rate () const
-{
- return 0;
-}
-
-int64_t
-TIFFDecoder::audio_channel_layout () const
-{
- return 0;
-}
-
-bool
-TIFFDecoder::pass ()
-{
- if (_iter == _files.end ()) {
- return true;
- }
-
- TIFF* t = TIFFOpen (file_path (*_iter).c_str (), "r");
- if (t == 0) {
- throw DecodeError ("could not open TIFF file");
- }
-
- uint32_t width;
- TIFFGetField (t, TIFFTAG_IMAGEWIDTH, &width);
- uint32_t height;
- TIFFGetField (t, TIFFTAG_IMAGELENGTH, &height);
-
- int const num_pixels = width * height;
- uint32_t * raster = (uint32_t *) _TIFFmalloc (num_pixels * sizeof (uint32_t));
- if (raster == 0) {
- throw DecodeError ("could not allocate memory to decode TIFF file");
- }
-
- if (TIFFReadRGBAImage (t, width, height, raster, 0) < 0) {
- throw DecodeError ("could not read TIFF data");
- }
-
- shared_ptr<CompactImage> image (new CompactImage (PIX_FMT_RGB24, Size (width, height)));
-
- uint8_t* p = image->data()[0];
- for (uint32_t y = 0; y < height; ++y) {
- for (uint32_t x = 0; x < width; ++x) {
- uint32_t const i = (height - y - 1) * width + x;
- *p++ = raster[i] & 0xff;
- *p++ = (raster[i] & 0xff00) >> 8;
- *p++ = (raster[i] & 0xff0000) >> 16;
- }
- }
-
- _TIFFfree (raster);
- TIFFClose (t);
-
- emit_video (image);
-
- ++_iter;
- return false;
-}
-
-/** @param file name within our content directory
- * @return full path to the file
- */
-string
-TIFFDecoder::file_path (string f) const
-{
- stringstream s;
- s << _film->content_path() << "/" << f;
- return _film->file (s.str ());
-}
-
-PixelFormat
-TIFFDecoder::pixel_format () const
-{
- return PIX_FMT_RGB24;
-}
-
-int
-TIFFDecoder::time_base_numerator () const
-{
- return dcp_frame_rate(_film->frames_per_second()).frames_per_second;
-}
-
-
-int
-TIFFDecoder::time_base_denominator () const
-{
- return 1;
-}
-
-int
-TIFFDecoder::sample_aspect_ratio_numerator () const
-{
- /* XXX */
- return 1;
-}
-
-int
-TIFFDecoder::sample_aspect_ratio_denominator () const
-{
- /* XXX */
- return 1;
-}
diff --git a/src/lib/tiff_decoder.h b/src/lib/tiff_decoder.h
deleted file mode 100644
index e6821eec6..000000000
--- a/src/lib/tiff_decoder.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-/** @file src/tiff_decoder.h
- * @brief A decoder which reads a numbered set of TIFF files, one per frame.
- */
-
-#ifndef DVDOMATIC_TIFF_DECODER_H
-#define DVDOMATIC_TIFF_DECODER_H
-
-#include <vector>
-#include <string>
-#include <stdint.h>
-#include <boost/shared_ptr.hpp>
-#include "util.h"
-#include "decoder.h"
-
-class Job;
-class FilmState;
-class Options;
-class Image;
-
-/** @class TIFFDecoder.
- * @brief A decoder which reads a numbered set of TIFF files, one per frame.
- */
-class TIFFDecoder : public Decoder
-{
-public:
- TIFFDecoder (boost::shared_ptr<Film>, boost::shared_ptr<const Options>, Job *);
-
- /* Methods to query our input video */
- float frames_per_second () const;
- Size native_size () const;
- int audio_channels () const;
- int audio_sample_rate () const;
- int64_t audio_channel_layout () const;
- bool has_subtitles () const {
- return false;
- }
-
-private:
- bool pass ();
- PixelFormat pixel_format () const;
- int time_base_numerator () const;
- int time_base_denominator () const;
- int sample_aspect_ratio_numerator () const;
- int sample_aspect_ratio_denominator () const;
-
- std::string file_path (std::string) const;
- std::list<std::string> _files;
- std::list<std::string>::iterator _iter;
-};
-
-#endif
diff --git a/src/lib/util.cc b/src/lib/util.cc
index 5e82650a5..862ddc111 100644
--- a/src/lib/util.cc
+++ b/src/lib/util.cc
@@ -37,6 +37,7 @@
#include <boost/lambda/lambda.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
+#include <boost/filesystem.hpp>
#include <openjpeg.h>
#include <openssl/md5.h>
#include <magick/MagickCore.h>
@@ -827,3 +828,17 @@ video_frames_to_audio_frames (SourceFrame v, float audio_sample_rate, float fram
{
return ((int64_t) v * audio_sample_rate / frames_per_second);
}
+
+bool
+still_image_file (string f)
+{
+#if BOOST_FILESYSTEM_VERSION == 3
+ string ext = boost::filesystem::path(f).extension().string();
+#else
+ string ext = boost::filesystem::path(f).extension();
+#endif
+
+ transform (ext.begin(), ext.end(), ext.begin(), ::tolower);
+
+ return (ext == ".tif" || ext == ".tiff" || ext == ".jpg" || ext == ".jpeg" || ext == ".png");
+}
diff --git a/src/lib/util.h b/src/lib/util.h
index bb68b6273..301a8bc4e 100644
--- a/src/lib/util.h
+++ b/src/lib/util.h
@@ -255,6 +255,7 @@ private:
};
extern int64_t video_frames_to_audio_frames (SourceFrame v, float audio_sample_rate, float frames_per_second);
+extern bool still_image_file (std::string);
#endif
diff --git a/src/lib/wscript b/src/lib/wscript
index ef4011c5f..6d006f559 100644
--- a/src/lib/wscript
+++ b/src/lib/wscript
@@ -48,7 +48,6 @@ def build(bld):
sound_processor.cc
stream.cc
subtitle.cc
- tiff_decoder.cc
timer.cc
transcode_job.cc
transcoder.cc