Use ImageMagick for tiff decoding too.
authorCarl Hetherington <cth@carlh.net>
Wed, 14 Nov 2012 21:58:47 +0000 (21:58 +0000)
committerCarl Hetherington <cth@carlh.net>
Wed, 14 Nov 2012 21:58:47 +0000 (21:58 +0000)
12 files changed:
src/lib/decoder_factory.cc
src/lib/film.cc
src/lib/imagemagick_decoder.cc
src/lib/imagemagick_decoder.h
src/lib/j2k_still_encoder.cc
src/lib/make_dcp_job.cc
src/lib/tiff_decoder.cc [deleted file]
src/lib/tiff_decoder.h [deleted file]
src/lib/util.cc
src/lib/util.h
src/lib/wscript
wscript

index d4a91d8d97d312954247f4287e018013fdaa370b..bb6eff97140edd27328ef957b2793d998466728e 100644 (file)
@@ -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));
        }
        
index c38b59d9efde32bedfba6a3e39b5d8861de8f2c7..ac5b43a987d8a61399e9b09ad4184040b755ec28 100644 (file)
@@ -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;
        }
 
index 53e1db879e16ea94a45b4e64860f37fc1c92869b..7faf74c6196c42b72a82356136a303218a8509e3 100644 (file)
 */
 
 #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;
 }
 
index 1bf50378bc3788bbc723f9c2ad79750582cd272f..6506d0177f1196667eccfe7d8eab5dbb6680f3f3 100644 (file)
@@ -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;
 };
index a4ac54e7aa42a9d62d11d61370159549837928df..dd6ef49b2a414fdf9c3567a06012aeb4f353ed8b 100644 (file)
@@ -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                 
index a1ffd967236b45f736691995ed24e211362dc76f..026724806b971bd029570e04075fdaa64dfca6c7 100644 (file)
@@ -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 (file)
index a58ea99..0000000
+++ /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 (file)
index e6821ee..0000000
+++ /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
index 5e82650a56c6e29a5c00ff988cf1c493fe3e3b1b..862ddc1112f2672f53ee536780f2fcefab21553e 100644 (file)
@@ -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");
+}
index bb68b627355cf1604aada40a2cd1d51460802e0f..301a8bc4e9398dd48babbf84475ba24dd980b77a 100644 (file)
@@ -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
 
index ef4011c5f7ccab07dd42266e05ff6bcbc8b62746..6d006f559cc5b578343a0a56f5b7df9ef3d7413f 100644 (file)
@@ -48,7 +48,6 @@ def build(bld):
                  sound_processor.cc
                  stream.cc
                  subtitle.cc
-                 tiff_decoder.cc
                  timer.cc
                 transcode_job.cc
                 transcoder.cc
diff --git a/wscript b/wscript
index d6cfd45c6db74971a8b10ddadf87db3cf44470d6..3b43f3aecbcdd0cdc11a1121679db12bc4cb7aef 100644 (file)
--- a/wscript
+++ b/wscript
@@ -63,7 +63,6 @@ def configure(conf):
     conf.check_cfg(package = 'libdcp', atleast_version = '0.24', args = '--cflags --libs', uselib_store = 'DCP', mandatory = True)
     conf.check_cfg(package = 'glib-2.0', args = '--cflags --libs', uselib_store = 'GLIB', mandatory = True)
     conf.check_cfg(package = '', path = 'Magick++-config', args = '--cppflags --cxxflags --libs', uselib_store = 'MAGICK', mandatory = True)
-    conf.check_cc(msg = 'Checking for library libtiff', function_name = 'TIFFOpen', header_name = 'tiffio.h', lib = 'tiff', uselib_store = 'TIFF')
     conf.check_cc(fragment  = """
                              #include <stdio.h>\n
                              #include <openjpeg.h>\n