to decode images. Hence remove {Image,Graphics}Magick.
deb_depends['14.04'].extend(['libboost-filesystem1.54.0',
'libboost-thread1.54.0',
'libboost-regex1.54.0',
- 'libmagick++5',
'libxml++2.6-2',
'libboost-date-time1.54.0',
'libzip2',
deb_depends['16.04'].extend(['libboost-filesystem1.58.0',
'libboost-thread1.58.0',
'libboost-regex1.58.0',
- 'libmagick++-6.q16-5v5',
'libxml++2.6-2v5',
'libboost-date-time1.58.0',
'libzip4',
deb_depends['17.10'].extend(['libboost-filesystem1.62.0',
'libboost-thread1.62.0',
'libboost-regex1.62.0',
- 'libmagick++-6.q16-7',
'libxml++2.6-2v5',
'libboost-date-time1.62.0',
'libzip4',
'libboost-thread1.65.1',
'libboost-regex1.65.1',
'libboost-date-time1.65.1',
- 'libmagick++-6.q16-7',
'libcairomm-1.0-1v5',
'libpangomm-1.4-1v5',
'libxml++2.6-2v5',
deb_depends['7'].extend(['libboost-filesystem1.49.0',
'libboost-thread1.49.0',
'libboost-regex1.49.0',
- 'libmagick++5',
'libxml++2.6-2',
'libboost-date-time1.49.0',
'libzip2',
'libboost-thread1.55.0',
'libboost-date-time1.55.0',
'libboost-regex1.55.0',
- 'libmagick++-6.q16-5',
'libxml++2.6-2',
'libzip2',
'libcairomm-1.0-1',
'libboost-thread1.62.0',
'libboost-regex1.62.0',
'libboost-date-time1.62.0',
- 'libmagick++-6.q16-7',
'libxml++2.6-2v5',
'libgtk2.0-0',
'libzip4',
'libboost-thread1.62.0',
'libboost-regex1.62.0',
'libboost-date-time1.62.0',
- 'libmagick++-6.q16-7',
'libxml++2.6-2v5',
'libgtk2.0-0',
'libzip4',
'sources': [{'type': 'archive',
'url': '%s/libzip-1.4.0.tar.xz' % prefix,
'sha256': 'e508aba025f5f94b267d5120fc33761bcd98440ebe49dbfe2ed3df3afeacc7b1'}]})
- modules.append({'name': 'imagemagick',
- 'cleanup': ['/bin'],
- 'sources': [{'type': 'archive',
- 'url': '%s/ImageMagick-7.0.8-11.tar.bz2' % prefix,
- 'sha256': 'a1aef96c89a9a9fac51a6e141deffa0b2f8db2062a24f6ba9fe3846dde7491ac'}]})
modules.append({'name': 'libsigc++',
'sources': [{'type': 'archive',
'url': '%s/libsigc++-2.10.0.tar.xz' % prefix,
universal_copy_lib $ENV libglib-2 "$dest"
universal_copy_lib $ENV libintl "$dest"
universal_copy_lib $ENV libsndfile "$dest"
- universal_copy_lib $ENV libMagick++ "$dest"
- universal_copy_lib $ENV libMagickCore "$dest"
- universal_copy_lib $ENV libMagickWand "$dest"
universal_copy_lib $ENV libssh "$dest"
universal_copy_lib $ENV libwx "$dest"
universal_copy_lib $ENV libfontconfig "$dest"
File "%static_deps%/bin/libgobject-2.0-0.dll"
File "%static_deps%/bin/libiconv-2.dll"
File "%static_deps%/bin/libjpeg-9.dll"
-File "%static_deps%/bin/libGraphicsMagick-3.dll"
-File "%static_deps%/bin/libGraphicsMagickWand-2.dll"
-File "%static_deps%/bin/libGraphicsMagick++-11.dll"
File "%static_deps%/bin/libpng16-16.dll"
File "%static_deps%/bin/libsigc-2.0-0.dll"
File "%static_deps%/bin/libsndfile-1.dll"
#include "audio_decoder.h"
#include "j2k_image_proxy.h"
#include "text_decoder.h"
+#include "ffmpeg_image_proxy.h"
#include "image.h"
#include "config.h"
#include <dcp/dcp.h>
shared_ptr<dcp::SubtitleImage> ii = dynamic_pointer_cast<dcp::SubtitleImage> (i);
if (ii) {
- shared_ptr<Image> image(new Image(ii->png_image()));
+ FFmpegImageProxy proxy (ii->png_image());
+ shared_ptr<Image> image = proxy.image().first;
/* set up rect with height and width */
dcpomatic::Rect<double> rect(0, 0, image->size().width / double(size.width), image->size().height / double(size.height));
#include "cross.h"
#include <dcp/version.h>
#include <libssh/libssh.h>
-#ifdef DCPOMATIC_IMAGE_MAGICK
-/* ImageMagick */
-#ifdef DCPOMATIC_MAGICKCORE_MAGICK
-#include <magick/MagickCore.h>
-#include <magick/version.h>
-#else
-#include <MagickCore/MagickCore.h>
-#include <MagickCore/version.h>
-#endif
-#else
-/* GraphicsMagick */
-#include <magick/common.h>
-#include <magick/magick_config.h>
-#include <magick/version.h>
-#endif
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
{
char buffer[512];
snprintf (
- buffer, sizeof(buffer), "libavcodec %s, libavfilter %s, libavformat %s, libavutil %s, libswscale %s, %s, libssh %s, libdcp %s git %s",
+ buffer, sizeof(buffer), "libavcodec %s, libavfilter %s, libavformat %s, libavutil %s, libswscale %s, libssh %s, libdcp %s git %s",
ffmpeg_version_to_string(avcodec_version()).c_str(),
ffmpeg_version_to_string(avfilter_version()).c_str(),
ffmpeg_version_to_string(avformat_version()).c_str(),
ffmpeg_version_to_string(avutil_version()).c_str(),
ffmpeg_version_to_string(swscale_version()).c_str(),
- MagickVersion,
ssh_version(0),
dcp::version, dcp::git_commit
);
--- /dev/null
+/*
+ Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "ffmpeg_image_proxy.h"
+#include "cross.h"
+#include "exceptions.h"
+#include "dcpomatic_socket.h"
+#include "image.h"
+#include "compose.hpp"
+#include "util.h"
+#include <dcp/raw_convert.h>
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+}
+#include <libxml++/libxml++.h>
+#include <iostream>
+
+#include "i18n.h"
+
+using std::string;
+using std::cout;
+using std::pair;
+using std::min;
+using std::make_pair;
+using boost::shared_ptr;
+using boost::optional;
+using boost::dynamic_pointer_cast;
+using dcp::raw_convert;
+
+FFmpegImageProxy::FFmpegImageProxy (boost::filesystem::path path)
+ : _data (path)
+ , _pos (0)
+ , _path (path)
+{
+
+}
+
+FFmpegImageProxy::FFmpegImageProxy (dcp::Data data)
+ : _data (data)
+ , _pos (0)
+{
+
+}
+
+FFmpegImageProxy::FFmpegImageProxy (shared_ptr<cxml::Node>, shared_ptr<Socket> socket)
+ : _pos (0)
+{
+ uint32_t const size = socket->read_uint32 ();
+ _data = dcp::Data (size);
+ socket->read (_data.data().get(), size);
+}
+
+static int
+avio_read_wrapper (void* data, uint8_t* buffer, int amount)
+{
+ return reinterpret_cast<FFmpegImageProxy*>(data)->avio_read (buffer, amount);
+}
+
+static int64_t
+avio_seek_wrapper (void* data, int64_t offset, int whence)
+{
+ return reinterpret_cast<FFmpegImageProxy*>(data)->avio_seek (offset, whence);
+}
+
+int
+FFmpegImageProxy::avio_read (uint8_t* buffer, int const amount)
+{
+ int const to_do = min(int64_t(amount), _data.size() - _pos);
+ memcpy (buffer, _data.data().get() + _pos, to_do);
+ _pos += to_do;
+ return to_do;
+}
+
+int64_t
+FFmpegImageProxy::avio_seek (int64_t const pos, int whence)
+{
+ switch (whence) {
+ case AVSEEK_SIZE:
+ return _data.size();
+ case SEEK_CUR:
+ _pos += pos;
+ break;
+ case SEEK_SET:
+ _pos = pos;
+ break;
+ case SEEK_END:
+ _pos = _data.size() - pos;
+ break;
+ }
+
+ return _pos;
+}
+
+pair<shared_ptr<Image>, int>
+FFmpegImageProxy::image (optional<dcp::NoteHandler>, optional<dcp::Size>) const
+{
+ boost::mutex::scoped_lock lm (_mutex);
+
+ if (_image) {
+ return make_pair (_image, 0);
+ }
+
+ uint8_t* avio_buffer = static_cast<uint8_t*> (wrapped_av_malloc(4096));
+ AVIOContext* avio_context = avio_alloc_context (avio_buffer, 4096, 0, const_cast<FFmpegImageProxy*>(this), avio_read_wrapper, 0, avio_seek_wrapper);
+ AVFormatContext* format_context = avformat_alloc_context ();
+ format_context->pb = avio_context;
+
+ AVDictionary* options = 0;
+ /* These durations are in microseconds, and represent how far into the content file
+ we will look for streams.
+ */
+ av_dict_set (&options, "analyzeduration", raw_convert<string>(5 * 60 * 1000000).c_str(), 0);
+ av_dict_set (&options, "probesize", raw_convert<string>(5 * 60 * 1000000).c_str(), 0);
+
+ int e = avformat_open_input (&format_context, 0, 0, &options);
+ if (e < 0) {
+ throw OpenFileError (_path->string(), e, true);
+ }
+
+ if (avformat_find_stream_info(format_context, 0) < 0) {
+ throw DecodeError (_("could not find stream information"));
+ }
+
+ DCPOMATIC_ASSERT (format_context->nb_streams == 1);
+
+ AVFrame* frame = av_frame_alloc ();
+ if (!frame) {
+ throw DecodeError (N_("could not allocate frame"));
+ }
+
+ AVCodecContext* codec_context = format_context->streams[0]->codec;
+ AVCodec* codec = avcodec_find_decoder (codec_context->codec_id);
+ DCPOMATIC_ASSERT (codec);
+
+ if (avcodec_open2 (codec_context, codec, 0) < 0) {
+ throw DecodeError (N_("could not open decoder"));
+ }
+
+ AVPacket packet;
+ int r = av_read_frame (format_context, &packet);
+ if (r < 0) {
+ throw DecodeError (N_("could not read frame"));
+ }
+
+ int frame_finished;
+ if (avcodec_decode_video2(codec_context, frame, &frame_finished, &packet) < 0 || !frame_finished) {
+ throw DecodeError (N_("could not decode video"));
+ }
+
+ _image.reset (new Image (frame));
+
+ av_frame_free (&frame);
+ avformat_close_input (&format_context);
+ av_free (avio_context->buffer);
+ av_free (avio_context);
+
+ return make_pair (_image, 0);
+}
+
+void
+FFmpegImageProxy::add_metadata (xmlpp::Node* node) const
+{
+ node->add_child("Type")->add_child_text (N_("FFmpeg"));
+}
+
+void
+FFmpegImageProxy::send_binary (shared_ptr<Socket> socket) const
+{
+ socket->write (_data.size());
+ socket->write (_data.data().get(), _data.size());
+}
+
+bool
+FFmpegImageProxy::same (shared_ptr<const ImageProxy> other) const
+{
+ shared_ptr<const FFmpegImageProxy> mp = dynamic_pointer_cast<const FFmpegImageProxy> (other);
+ if (!mp) {
+ return false;
+ }
+
+ if (_data.size() != mp->_data.size()) {
+ return false;
+ }
+
+ return memcmp (_data.data().get(), mp->_data.data().get(), _data.size()) == 0;
+}
+
+size_t
+FFmpegImageProxy::memory_used () const
+{
+ size_t m = _data.size();
+ if (_image) {
+ m += _image->memory_used();
+ }
+ return m;
+}
--- /dev/null
+/*
+ Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic 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.
+
+ DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "image_proxy.h"
+#include <dcp/data.h>
+#include <boost/thread/mutex.hpp>
+#include <boost/filesystem.hpp>
+
+class FFmpegImageProxy : public ImageProxy
+{
+public:
+ explicit FFmpegImageProxy (boost::filesystem::path);
+ explicit FFmpegImageProxy (dcp::Data);
+ FFmpegImageProxy (boost::shared_ptr<cxml::Node> xml, boost::shared_ptr<Socket> socket);
+
+ std::pair<boost::shared_ptr<Image>, int> image (
+ boost::optional<dcp::NoteHandler> note = boost::optional<dcp::NoteHandler> (),
+ boost::optional<dcp::Size> size = boost::optional<dcp::Size> ()
+ ) const;
+
+ void add_metadata (xmlpp::Node *) const;
+ void send_binary (boost::shared_ptr<Socket>) const;
+ bool same (boost::shared_ptr<const ImageProxy> other) const;
+ size_t memory_used () const;
+
+ int avio_read (uint8_t* buffer, int const amount);
+ int64_t avio_seek (int64_t const pos, int whence);
+
+private:
+ dcp::Data _data;
+ mutable int64_t _pos;
+ /** Path of a file that this image came from, if applicable; stored so that
+ failed-decode errors can give more detail.
+ */
+ boost::optional<boost::filesystem::path> _path;
+ mutable boost::shared_ptr<Image> _image;
+ mutable boost::mutex _mutex;
+};
#include "dcpomatic_socket.h"
#include <dcp/rgb_xyz.h>
#include <dcp/transfer_function.h>
-#include <Magick++.h>
extern "C" {
#include <libswscale/swscale.h>
#include <libavutil/pixfmt.h>
allocate ();
}
-/** Construct an Image from some PNG data */
-Image::Image (dcp::Data png)
-{
- Magick::Blob blob;
- blob.update (png.data().get(), png.size());
- Magick::Image* magick_image = new Magick::Image (blob);
- _size = dcp::Size(magick_image->columns(), magick_image->rows());
- _pixel_format = AV_PIX_FMT_BGRA;
- _aligned = true;
- _extra_pixels = 0;
- allocate ();
-
- /* Write line-by-line here as _image must be aligned, and write() cannot be told about strides */
- uint8_t* p = data()[0];
- for (int i = 0; i < _size.height; ++i) {
-#ifdef DCPOMATIC_HAVE_MAGICKCORE_NAMESPACE
- using namespace MagickCore;
-#endif
-#ifdef DCPOMATIC_HAVE_MAGICKLIB_NAMESPACE
- using namespace MagickLib;
-#endif
- magick_image->write (0, i, _size.width, 1, "BGRA", CharPixel, p);
- p += stride()[0];
- }
-
- delete magick_image;
-}
-
void
Image::allocate ()
{
dcp::Data
Image::as_png () const
{
-#ifdef DCPOMATIC_IMAGE_MAGICK
- using namespace MagickCore;
-#else
- using namespace MagickLib;
-#endif
-
- string format;
- switch (_pixel_format) {
- case AV_PIX_FMT_RGB24:
- format = "RGB";
- break;
- case AV_PIX_FMT_BGRA:
- format = "BGRA";
- break;
- default:
- DCPOMATIC_ASSERT (false);
- break;
- }
-
- shared_ptr<const Image> use;
- if (aligned()) {
- use.reset (new Image(shared_from_this(), false));
- }
-
- Magick::Image m (size().width, size().height, format, CharPixel, (void *) use->data()[0]);
- m.magick ("PNG");
- Magick::Blob blob;
- m.write (&blob);
- /* XXX: could use a subclass of Data here (storing its data in a Blob) */
- return dcp::Data (static_cast<const uint8_t*>(blob.data()), blob.length());
+ /* XXX */
+ return dcp::Data();
}
Image (AVPixelFormat p, dcp::Size s, bool aligned, int extra_pixels = 0);
explicit Image (AVFrame *);
explicit Image (Image const &);
- explicit Image (dcp::Data);
Image (boost::shared_ptr<const Image>, bool);
Image& operator= (Image const &);
~Image ();
#include "image_decoder.h"
#include "video_decoder.h"
#include "image.h"
-#include "magick_image_proxy.h"
+#include "ffmpeg_image_proxy.h"
#include "j2k_image_proxy.h"
#include "film.h"
#include "exceptions.h"
#include "video_content.h"
-#include <Magick++.h>
#include <boost/filesystem.hpp>
#include <iostream>
*/
_image.reset (new J2KImageProxy (path, _image_content->video->size(), pf));
} else {
- _image.reset (new MagickImageProxy (path));
+ _image.reset (new FFmpegImageProxy (path));
}
}
#include "config.h"
#include "cross.h"
#include "compose.hpp"
-#include "magick_image_proxy.h"
+#include "ffmpeg_image_proxy.h"
#include "image.h"
#include <dcp/openjpeg_image.h>
#include <dcp/exceptions.h>
#include <dcp/j2k.h>
-#include <Magick++.h>
#include <iostream>
#include "i18n.h"
: _film (film)
, _image_content (content)
{
-#ifdef DCPOMATIC_HAVE_MAGICKCORE_NAMESPACE
- using namespace MagickCore;
-#endif
boost::filesystem::path path = content->path(0).string ();
if (valid_j2k_file (path)) {
boost::uintmax_t size = boost::filesystem::file_size (path);
}
delete[] buffer;
} else {
- MagickImageProxy proxy(content->path(0));
+ FFmpegImageProxy proxy(content->path(0));
_video_size = proxy.image().first->size();
}
#include "image_proxy.h"
#include "raw_image_proxy.h"
-#include "magick_image_proxy.h"
+#include "ffmpeg_image_proxy.h"
#include "j2k_image_proxy.h"
#include "image.h"
#include "exceptions.h"
{
if (xml->string_child("Type") == N_("Raw")) {
return shared_ptr<ImageProxy> (new RawImageProxy (xml, socket));
- } else if (xml->string_child("Type") == N_("Magick")) {
- return shared_ptr<MagickImageProxy> (new MagickImageProxy (xml, socket));
+ } else if (xml->string_child("Type") == N_("FFmpeg")) {
+ return shared_ptr<FFmpegImageProxy> (new FFmpegImageProxy(xml, socket));
} else if (xml->string_child("Type") == N_("J2K")) {
return shared_ptr<J2KImageProxy> (new J2KImageProxy (xml, socket));
}
* @return log2 of any scaling down that will be applied to the image.
*/
virtual int prepare (boost::optional<dcp::Size> = boost::optional<dcp::Size>()) const { return 0; }
- virtual AVPixelFormat pixel_format () const = 0;
virtual size_t memory_used () const = 0;
};
#include <dcp/j2k.h>
#include <libcxml/cxml.h>
#include <libxml++/libxml++.h>
-#include <Magick++.h>
#include <iostream>
#include "i18n.h"
/** @return true if our image is definitely the same as another, false if it is probably not */
bool same (boost::shared_ptr<const ImageProxy>) const;
int prepare (boost::optional<dcp::Size> = boost::optional<dcp::Size>()) const;
- AVPixelFormat pixel_format () const {
- return _pixel_format;
- }
dcp::Data j2k () const {
return _data;
+++ /dev/null
-/*
- Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "magick_image_proxy.h"
-#include "cross.h"
-#include "exceptions.h"
-#include "dcpomatic_socket.h"
-#include "image.h"
-#include "compose.hpp"
-#include <Magick++.h>
-#include <libxml++/libxml++.h>
-#include <iostream>
-
-#include "i18n.h"
-
-using std::string;
-using std::cout;
-using std::pair;
-using std::make_pair;
-using boost::shared_ptr;
-using boost::optional;
-using boost::dynamic_pointer_cast;
-
-MagickImageProxy::MagickImageProxy (boost::filesystem::path path)
- : _path (path)
-{
- /* Read the file into a Blob */
-
- boost::uintmax_t const size = boost::filesystem::file_size (path);
- FILE* f = fopen_boost (path, "rb");
- if (!f) {
- throw OpenFileError (path, errno, true);
- }
-
- uint8_t* data = new uint8_t[size];
- if (fread (data, 1, size, f) != size) {
- delete[] data;
- throw ReadFileError (path);
- }
-
- fclose (f);
- _blob.update (data, size);
- delete[] data;
-}
-
-MagickImageProxy::MagickImageProxy (shared_ptr<cxml::Node>, shared_ptr<Socket> socket)
-{
- uint32_t const size = socket->read_uint32 ();
- uint8_t* data = new uint8_t[size];
- socket->read (data, size);
- _blob.update (data, size);
- delete[] data;
-}
-
-pair<shared_ptr<Image>, int>
-MagickImageProxy::image (optional<dcp::NoteHandler>, optional<dcp::Size>) const
-{
- boost::mutex::scoped_lock lm (_mutex);
-
- if (_image) {
- return make_pair (_image, 0);
- }
-
- Magick::Image* magick_image = 0;
- string error;
- try {
- magick_image = new Magick::Image (_blob);
- } catch (Magick::Exception& e) {
- error = e.what ();
- }
-
- if (!magick_image) {
- /* ImageMagick cannot auto-detect Targa files, it seems, so try here with an
- explicit format. I can't find it documented that passing a (0, 0) geometry
- is allowed, but it seems to work.
- */
- try {
- magick_image = new Magick::Image (_blob, Magick::Geometry (0, 0), "TGA");
- } catch (...) {
-
- }
- }
-
- if (!magick_image) {
- /* If we failed both an auto-detect and a forced-Targa we give the error from
- the auto-detect.
- */
- if (_path) {
- throw DecodeError (String::compose (_("Could not decode image file %1 (%2)"), _path->string(), error));
- } else {
- throw DecodeError (String::compose (_("Could not decode image file (%1)"), error));
- }
- }
-
- unsigned char const * data = static_cast<unsigned char const *>(_blob.data());
- if (data[801] == 1 || magick_image->image()->colorspace == Magick::sRGBColorspace) {
- /* Either:
- 1. The transfer characteristic in this file is "printing density"; in this case ImageMagick sets the colour space
- to LogColorspace, or
- 2. The file is sRGB.
-
- Empirically we find that in these cases if we subsequently call colorSpace(Magick::RGBColorspace) the colours
- are very wrong. To prevent this, set the image colour space to RGB to stop the ::colorSpace call below doing
- anything. See #1123 and others.
- */
- magick_image->image()->colorspace = Magick::RGBColorspace;
- }
-
- magick_image->colorSpace(Magick::RGBColorspace);
-
- dcp::Size size (magick_image->columns(), magick_image->rows());
-
- _image.reset (new Image (AV_PIX_FMT_RGB24, size, true));
-
- /* Write line-by-line here as _image must be aligned, and write() cannot be told about strides */
- uint8_t* p = _image->data()[0];
- for (int i = 0; i < size.height; ++i) {
-#ifdef DCPOMATIC_HAVE_MAGICKCORE_NAMESPACE
- using namespace MagickCore;
-#endif
-#ifdef DCPOMATIC_HAVE_MAGICKLIB_NAMESPACE
- using namespace MagickLib;
-#endif
- magick_image->write (0, i, size.width, 1, "RGB", CharPixel, p);
- p += _image->stride()[0];
- }
-
- delete magick_image;
-
- return make_pair (_image, 0);
-}
-
-void
-MagickImageProxy::add_metadata (xmlpp::Node* node) const
-{
- node->add_child("Type")->add_child_text (N_("Magick"));
-}
-
-void
-MagickImageProxy::send_binary (shared_ptr<Socket> socket) const
-{
- socket->write (_blob.length ());
- socket->write ((uint8_t *) _blob.data (), _blob.length ());
-}
-
-bool
-MagickImageProxy::same (shared_ptr<const ImageProxy> other) const
-{
- shared_ptr<const MagickImageProxy> mp = dynamic_pointer_cast<const MagickImageProxy> (other);
- if (!mp) {
- return false;
- }
-
- if (_blob.length() != mp->_blob.length()) {
- return false;
- }
-
- return memcmp (_blob.data(), mp->_blob.data(), _blob.length()) == 0;
-}
-
-AVPixelFormat
-MagickImageProxy::pixel_format () const
-{
- return AV_PIX_FMT_RGB24;
-}
-
-size_t
-MagickImageProxy::memory_used () const
-{
- size_t m = _blob.length();
- if (_image) {
- m += _image->memory_used();
- }
- return m;
-}
+++ /dev/null
-/*
- Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
-
- This file is part of DCP-o-matic.
-
- DCP-o-matic 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.
-
- DCP-o-matic 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 DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
-
-*/
-
-#include "image_proxy.h"
-#include <Magick++.h>
-#include <boost/thread/mutex.hpp>
-#include <boost/filesystem.hpp>
-
-class MagickImageProxy : public ImageProxy
-{
-public:
- explicit MagickImageProxy (boost::filesystem::path);
- MagickImageProxy (boost::shared_ptr<cxml::Node> xml, boost::shared_ptr<Socket> socket);
-
- std::pair<boost::shared_ptr<Image>, int> image (
- boost::optional<dcp::NoteHandler> note = boost::optional<dcp::NoteHandler> (),
- boost::optional<dcp::Size> size = boost::optional<dcp::Size> ()
- ) const;
-
- void add_metadata (xmlpp::Node *) const;
- void send_binary (boost::shared_ptr<Socket>) const;
- bool same (boost::shared_ptr<const ImageProxy> other) const;
- AVPixelFormat pixel_format () const;
- size_t memory_used () const;
-
-private:
- Magick::Blob _blob;
- /** Path of a file that this image came from, if applicable; stored so that
- failed-decode errors can give more detail.
- */
- boost::optional<boost::filesystem::path> _path;
- mutable boost::shared_ptr<Image> _image;
- mutable boost::mutex _mutex;
-};
}
shared_ptr<Image> out = im->crop_scale_window (
- total_crop, _inter_size, _out_size, yuv_to_rgb, pixel_format (_in->pixel_format()), aligned, fast
+ total_crop, _inter_size, _out_size, yuv_to_rgb, pixel_format (im->pixel_format()), aligned, fast
);
if (_text) {
return (*_image.get()) == (*rp->image().first.get());
}
-AVPixelFormat
-RawImageProxy::pixel_format () const
-{
- return _image->pixel_format ();
-}
-
size_t
RawImageProxy::memory_used () const
{
void add_metadata (xmlpp::Node *) const;
void send_binary (boost::shared_ptr<Socket>) const;
bool same (boost::shared_ptr<const ImageProxy>) const;
- AVPixelFormat pixel_format () const;
size_t memory_used () const;
private:
#include <libavcodec/avcodec.h>
}
#include <curl/curl.h>
-#ifdef DCPOMATIC_GRAPHICS_MAGICK
-#include <Magick++.h>
-#endif
#include <glib.h>
#include <pangomm/init.h>
#include <boost/algorithm/string.hpp>
curl_global_init (CURL_GLOBAL_ALL);
-#ifdef DCPOMATIC_GRAPHICS_MAGICK
- Magick::InitializeMagick (0);
-#endif
-
ui_thread = boost::this_thread::get_id ();
}
ffmpeg_subtitle_stream.cc
film.cc
filter.cc
+ ffmpeg_image_proxy.cc
font.cc
font_files.cc
frame_rate_change.cc
json_server.cc
log.cc
log_entry.cc
- magick_image_proxy.cc
mid_side_decoder.cc
monitor_checker.cc
overlaps.cc
obj.uselib = """
AVCODEC AVUTIL AVFORMAT AVFILTER SWSCALE
BOOST_FILESYSTEM BOOST_THREAD BOOST_DATETIME BOOST_SIGNALS2 BOOST_REGEX
- SAMPLERATE POSTPROC TIFF MAGICK SSH DCP CXML GLIB LZMA XML++
+ SAMPLERATE POSTPROC TIFF SSH DCP CXML GLIB LZMA XML++
CURL ZIP FONTCONFIG PANGOMM CAIROMM XMLSEC SUB ICU NETTLE
"""
def build(bld):
uselib = 'BOOST_THREAD BOOST_DATETIME DCP XMLSEC CXML XMLPP AVFORMAT AVFILTER AVCODEC '
uselib += 'AVUTIL SWSCALE SWRESAMPLE POSTPROC CURL BOOST_FILESYSTEM SSH ZIP CAIROMM FONTCONFIG PANGOMM SUB '
- uselib += 'MAGICK SNDFILE SAMPLERATE BOOST_REGEX ICU NETTLE RTAUDIO '
+ uselib += 'SNDFILE SAMPLERATE BOOST_REGEX ICU NETTLE RTAUDIO '
if bld.env.TARGET_WINDOWS:
uselib += 'WINSOCK2 DBGHELP SHLWAPI MSWSOCK BOOST_LOCALE WINSOCK2 OLE32 DSOUND WINMM KSUSER '
*/
#include "lib/image.h"
-#include "lib/magick_image_proxy.h"
+#include "lib/ffmpeg_image_proxy.h"
#include "test.h"
-#include <Magick++.h>
#include <boost/test/unit_test.hpp>
#include <iostream>
void
alpha_blend_test_one (AVPixelFormat format, string suffix)
{
- shared_ptr<MagickImageProxy> proxy (new MagickImageProxy (private_data / "prophet_frame.tiff"));
+ shared_ptr<FFmpegImageProxy> proxy (new FFmpegImageProxy (private_data / "prophet_frame.tiff"));
shared_ptr<Image> raw = proxy->image().first;
shared_ptr<Image> background = raw->convert_pixel_format (dcp::YUV_TO_RGB_REC709, format, true, false);
/** Test Image::crop_scale_window with YUV420P and some windowing */
BOOST_AUTO_TEST_CASE (crop_scale_window_test)
{
- shared_ptr<MagickImageProxy> proxy(new MagickImageProxy("test/data/flat_red.png"));
+ shared_ptr<FFmpegImageProxy> proxy(new FFmpegImageProxy("test/data/flat_red.png"));
shared_ptr<Image> raw = proxy->image().first;
shared_ptr<Image> out = raw->crop_scale_window(Crop(), dcp::Size(1998, 836), dcp::Size(1998, 1080), dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_YUV420P, true, false);
shared_ptr<Image> save = out->scale(dcp::Size(1998, 1080), dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGB24, false, false);
#include <asdcp/AS_DCP.h>
#include <sndfile.h>
#include <libxml++/libxml++.h>
-#include <Magick++.h>
extern "C" {
#include <libavformat/avformat.h>
}
void
check_image (boost::filesystem::path ref, boost::filesystem::path check, double threshold)
{
-#ifdef DCPOMATIC_IMAGE_MAGICK
- using namespace MagickCore;
-#else
- using namespace MagickLib;
-#endif
-
- Magick::Image ref_image;
- ref_image.read (ref.string ());
- Magick::Image check_image;
- check_image.read (check.string ());
- /* XXX: this is a hack; we really want the ImageMagick call but GraphicsMagick doesn't have it;
- this may cause random test failures on platforms that use GraphicsMagick.
- */
-#ifdef DCPOMATIC_ADVANCED_MAGICK_COMPARE
- double const dist = ref_image.compare(check_image, Magick::RootMeanSquaredErrorMetric);
- BOOST_CHECK_MESSAGE (dist < threshold, ref << " differs from " << check << " " << dist);
-#else
- BOOST_CHECK_MESSAGE (!ref_image.compare(check_image), ref << " differs from " << check);
-#endif
+ /* XXX */
}
void
void
write_image (shared_ptr<const Image> image, boost::filesystem::path file, string format)
{
-#ifdef DCPOMATIC_IMAGE_MAGICK
- using namespace MagickCore;
-#else
- using namespace MagickLib;
-#endif
-
- Magick::Image m (image->size().width, image->size().height, format.c_str(), CharPixel, (void *) image->data()[0]);
- m.write (file.string ());
+ /* XXX */
}
void
obj = bld(features='cxx cxxprogram')
obj.name = 'unit-tests'
obj.uselib = 'BOOST_TEST BOOST_THREAD BOOST_FILESYSTEM BOOST_DATETIME SNDFILE SAMPLERATE DCP FONTCONFIG CAIROMM PANGOMM XMLPP '
- obj.uselib += 'AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE SWRESAMPLE POSTPROC CXML MAGICK SUB GLIB CURL SSH XMLSEC BOOST_REGEX ICU NETTLE '
+ obj.uselib += 'AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE SWRESAMPLE POSTPROC CXML SUB GLIB CURL SSH XMLSEC BOOST_REGEX ICU NETTLE '
if bld.env.TARGET_WINDOWS:
obj.uselib += 'WINSOCK2 DBGHELP SHLWAPI MSWSOCK BOOST_LOCALE '
obj.use = 'libdcpomatic2'
# glib
conf.check_cfg(package='glib-2.0', args='--cflags --libs', uselib_store='GLIB', mandatory=True)
- # ImageMagick / GraphicsMagick
- if distutils.spawn.find_executable('Magick++-config'):
- conf.check_cfg(package='', path='Magick++-config', args='--cppflags --cxxflags --libs', uselib_store='MAGICK', mandatory=True)
- conf.env.append_value('CXXFLAGS', '-DDCPOMATIC_IMAGE_MAGICK')
- else:
- image = conf.check_cfg(package='ImageMagick++', args='--cflags --libs', uselib_store='MAGICK', mandatory=False)
- graphics = None
- if image is None:
- graphics = conf.check_cfg(package='GraphicsMagick++', args='--cflags --libs', uselib_store='MAGICK', mandatory=False)
- if image is None and graphics is None:
- Logs.pprint('RED', 'Neither ImageMagick++ nor GraphicsMagick++ found: one or the other is required')
- if image is not None:
- conf.env.append_value('CXXFLAGS', '-DDCPOMATIC_IMAGE_MAGICK')
- if graphics is not None:
- conf.env.append_value('CXXFLAGS', '-DDCPOMATIC_GRAPHICS_MAGICK')
-
- # See if we are using the MagickCore or MagickLib namespaces
- conf.check_cxx(fragment="""
- #include <Magick++/Include.h>\n
- using namespace MagickCore;\n
- int main () { return 0; }\n
- """,
- mandatory=False,
- msg='Checking for MagickCore namespace',
- okmsg='yes',
- includes=conf.env['INCLUDES_MAGICK'],
- define_name='DCPOMATIC_HAVE_MAGICKCORE_NAMESPACE')
-
- conf.check_cxx(fragment="""
- #include <Magick++/Include.h>\n
- using namespace MagickLib;\n
- int main () { return 0; }\n
- """,
- mandatory=False,
- msg='Checking for MagickLib namespace',
- okmsg='yes',
- includes=conf.env['INCLUDES_MAGICK'],
- define_name='DCPOMATIC_HAVE_MAGICKLIB_NAMESPACE')
-
- # See where MagickCore.h is
- conf.check_cxx(fragment="""
- #include <magick/MagickCore.h>\n
- int main() { return 0; }\n
- """,
- mandatory=False,
- msg='Checking for MagickCore.h location',
- okmsg='magick',
- errmsg='not magick',
- includes=conf.env['INCLUDES_MAGICK'],
- define_name='DCPOMATIC_MAGICKCORE_MAGICK')
-
- conf.check_cxx(fragment="""
- #include <MagickCore/MagickCore.h>\n
- int main() { return 0; }\n
- """,
- mandatory=False,
- msg='Checking for MagickCore.h location',
- okmsg='MagickCore',
- errmsg='not MagickCore',
- includes=conf.env['INCLUDES_MAGICK'],
- define_name='DCPOMATIC_MAGICKCORE_MAGICKCORE')
-
- # See if we have advanced compare() methods in Magick
- conf.check_cxx(fragment="""
- #include <Magick++.h>\n
- int main() { Magick::Image a; Magick::Image b; a.compare(b, Magick::RootMeanSquaredErrorMetric); }
- """,
- mandatory=False,
- msg='Checking for advanced compare() method in {Image/Graphics}Magick',
- uselib='MAGICK',
- define_name='DCPOMATIC_ADVANCED_MAGICK_COMPARE'
- )
-
# libzip
conf.check_cfg(package='libzip', args='--cflags --libs', uselib_store='ZIP', mandatory=True)
conf.check_cxx(fragment="""