X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fimage.cc;h=d4ec6f99a6381070835b2fd54a875f414e5d7f87;hb=39bc73fe192f932ed6695eb87b19de446e8b4f55;hp=926aefd3662659583f0116abcd76abb9e16439c1;hpb=e6f28e7cda23c1ba3c49cc1bf2dc1491c2f87160;p=dcpomatic.git diff --git a/src/lib/image.cc b/src/lib/image.cc index 926aefd36..d4ec6f99a 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -22,6 +22,7 @@ */ #include +#include extern "C" { #include #include @@ -31,6 +32,7 @@ extern "C" { #include "exceptions.h" #include "scaler.h" #include "timer.h" +#include "rect.h" #include "i18n.h" @@ -38,6 +40,8 @@ using std::string; using std::min; using std::cout; using std::cerr; +using std::list; +using std::stringstream; using boost::shared_ptr; using dcp::Size; @@ -342,6 +346,16 @@ Image::make_black () } } +void +Image::make_transparent () +{ + if (_pixel_format != PIX_FMT_RGBA) { + throw PixelFormatError ("make_transparent()", _pixel_format); + } + + memset (data()[0], 0, lines(0) * stride()[0]); +} + void Image::alpha_blend (shared_ptr other, Position position) { @@ -630,3 +644,44 @@ Image::aligned () const return _aligned; } +PositionImage +merge (list images) +{ + if (images.empty ()) { + return PositionImage (); + } + + dcpomatic::Rect all (images.front().position, images.front().image->size().width, images.front().image->size().height); + for (list::const_iterator i = images.begin(); i != images.end(); ++i) { + all.extend (dcpomatic::Rect (i->position, i->image->size().width, i->image->size().height)); + } + + shared_ptr merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true)); + merged->make_transparent (); + for (list::const_iterator i = images.begin(); i != images.end(); ++i) { + merged->alpha_blend (i->image, i->position); + } + + return PositionImage (merged, all.position ()); +} + +string +Image::digest () const +{ + MD5_CTX md5_context; + MD5_Init (&md5_context); + + for (int i = 0; i < components(); ++i) { + MD5_Update (&md5_context, data()[i], line_size()[i]); + } + + unsigned char digest[MD5_DIGEST_LENGTH]; + MD5_Final (digest, &md5_context); + + stringstream s; + for (int i = 0; i < MD5_DIGEST_LENGTH; ++i) { + s << std::hex << std::setfill('0') << std::setw(2) << ((int) digest[i]); + } + + return s.str (); +}