X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=blobdiff_plain;f=src%2Flib%2Fvideo_content_scale.cc;h=47ceab5d1f2f4516f21b071081e4d298abf2f419;hp=418c46eecd121fbf1d4019f27ae1f752758d5105;hb=422be0eece2bf6ee80db1d3c21553cd82efff789;hpb=39029279954b1f346d3ba28ec12c58211bfa7436 diff --git a/src/lib/video_content_scale.cc b/src/lib/video_content_scale.cc index 418c46eec..47ceab5d1 100644 --- a/src/lib/video_content_scale.cc +++ b/src/lib/video_content_scale.cc @@ -1,34 +1,39 @@ /* - Copyright (C) 2013-2014 Carl Hetherington + Copyright (C) 2013-2015 Carl Hetherington - This program is free software; you can redistribute it and/or modify + 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. - This program is distributed in the hope that it will be useful, + 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with DCP-o-matic. If not, see . */ -#include -#include -#include #include "video_content_scale.h" +#include "video_content.h" #include "ratio.h" -#include "safe_stringstream.h" #include "util.h" +#include +#include +#include +#include +#include #include "i18n.h" using std::vector; using std::string; +using std::min; +using std::cout; using boost::shared_ptr; using boost::optional; @@ -80,14 +85,14 @@ VideoContentScale::as_xml (xmlpp::Node* node) const string VideoContentScale::id () const { - SafeStringStream s; - + locked_stringstream s; + if (_ratio) { s << _ratio->id (); } else { s << (_scale ? "S1" : "S0"); } - + return s.str (); } @@ -119,31 +124,44 @@ VideoContentScale::from_id (string id) return VideoContentScale (true); } - + /** @param display_container Size of the container that we are displaying this content in. * @param film_container The size of the film's image. */ dcp::Size -VideoContentScale::size (shared_ptr c, dcp::Size display_container, dcp::Size film_container, int round) const +VideoContentScale::size (shared_ptr c, dcp::Size display_container, dcp::Size film_container) const { + /* Work out the size of the content if it were put inside film_container */ + + dcp::Size const video_size_after_crop = c->size_after_crop (); + + dcp::Size size; + if (_ratio) { - return fit_ratio_within (_ratio->ratio (), display_container, round); + /* Stretch to fit the requested ratio */ + size = fit_ratio_within (_ratio->ratio (), film_container); + } else if (_scale || video_size_after_crop.width > film_container.width || video_size_after_crop.height > film_container.height) { + /* Scale, preserving aspect ratio; this is either if we have been asked to scale with no stretch + or if the unscaled content is too big for film_container. + */ + size = fit_ratio_within (video_size_after_crop.ratio(), film_container); + } else { + /* No stretch nor scale */ + size = video_size_after_crop; } - dcp::Size const ac = c->video_size_after_crop (); + /* Now scale it down if the display container is smaller than the film container */ + if (display_container != film_container) { + float const scale = min ( + float (display_container.width) / film_container.width, + float (display_container.height) / film_container.height + ); - /* Force scale if the film_container is smaller than the content's image */ - if (_scale || film_container.width < ac.width || film_container.height < ac.height) { - return fit_ratio_within (ac.ratio (), display_container, round); + size.width = lrintf (size.width * scale); + size.height = lrintf (size.height * scale); } - /* Scale the image so that it will be in the right place in film_container, even if display_container is a - different size. - */ - return dcp::Size ( - c->video_size().width * float(display_container.width) / film_container.width, - c->video_size().height * float(display_container.height) / film_container.height - ); + return size; } void