Use a struct rather than a std::pair as the return type from ImageProxy::image.
authorCarl Hetherington <cth@carlh.net>
Tue, 14 Apr 2020 19:38:26 +0000 (21:38 +0200)
committerCarl Hetherington <cth@carlh.net>
Tue, 14 Apr 2020 19:38:26 +0000 (21:38 +0200)
src/lib/ffmpeg_image_proxy.cc
src/lib/ffmpeg_image_proxy.h
src/lib/image_examiner.cc
src/lib/image_proxy.h
src/lib/j2k_image_proxy.cc
src/lib/j2k_image_proxy.h
src/lib/player_video.cc
src/lib/raw_image_proxy.cc
src/lib/raw_image_proxy.h
src/lib/util.cc
test/image_test.cc

index 9c91d1d87d7d6c60eb883ee346acbb14876bf5ee..87fb154d0a7741517e7fc0b35b47a75ee14f3c06 100644 (file)
@@ -112,13 +112,14 @@ FFmpegImageProxy::avio_seek (int64_t const pos, int whence)
        return _pos;
 }
 
-pair<shared_ptr<Image>, int>
+
+ImageProxy::Result
 FFmpegImageProxy::image (optional<dcp::Size>) const
 {
        boost::mutex::scoped_lock lm (_mutex);
 
        if (_image) {
-               return make_pair (_image, 0);
+               return Result (_image, 0);
        }
 
        uint8_t* avio_buffer = static_cast<uint8_t*> (wrapped_av_malloc(4096));
@@ -192,7 +193,7 @@ FFmpegImageProxy::image (optional<dcp::Size>) const
        av_free (avio_context->buffer);
        av_free (avio_context);
 
-       return make_pair (_image, 0);
+       return Result (_image, 0);
 }
 
 void
index 5f9b3b1313935d6fcfbd754f2f4f7a7d80eedb05..88e31ad4a238513d6fa83a471de66a61106a1c7f 100644 (file)
@@ -30,7 +30,7 @@ public:
        explicit FFmpegImageProxy (dcp::Data);
        FFmpegImageProxy (boost::shared_ptr<cxml::Node> xml, boost::shared_ptr<Socket> socket);
 
-       std::pair<boost::shared_ptr<Image>, int> image (
+       Result image (
                boost::optional<dcp::Size> size = boost::optional<dcp::Size> ()
                ) const;
 
index b9ef89865163e17e4622f04bfdb1b85d06cedef7..6586a0d09bc5ad10ce09660a14d159ce5c695f6f 100644 (file)
@@ -64,7 +64,7 @@ ImageExaminer::ImageExaminer (shared_ptr<const Film> film, shared_ptr<const Imag
                delete[] buffer;
        } else {
                FFmpegImageProxy proxy(content->path(0));
-               _video_size = proxy.image().first->size();
+               _video_size = proxy.image().image->size();
        }
 
        if (content->still ()) {
index b6fe877321ecc06d460faf283522997d4a22c8dc..9619fab75d345fe53b3ad278d4466756dc5dbcd0 100644 (file)
@@ -60,14 +60,26 @@ class ImageProxy : public boost::noncopyable
 public:
        virtual ~ImageProxy () {}
 
+       struct Result {
+               Result (boost::shared_ptr<Image> image_, int log2_scaling_)
+                       : image (image_)
+                       , log2_scaling (log2_scaling_)
+               {}
+
+               /** Image (which will be aligned) */
+               boost::shared_ptr<Image> image;
+               /** log2 of any scaling down that has already been applied to the image;
+                *  e.g. if the image is already half the size of the original, this value
+                *  will be 1.
+                */
+               int log2_scaling;
+       };
+
        /** @param log Log to write to, or 0.
         *  @param size Size that the returned image will be scaled to, in case this
         *  can be used as an optimisation.
-        *  @return Image (which must be aligned) and log2 of any scaling down that has
-        *  already been applied to the image; e.g. if the the image is already half the size
-        *  of the original, the second part of the return value will be 1.
         */
-       virtual std::pair<boost::shared_ptr<Image>, int> image (
+       virtual Result image (
                boost::optional<dcp::Size> size = boost::optional<dcp::Size> ()
                ) const = 0;
 
index 31fda2510492d9285f8987c73a41acd9551a5435..da3e23caf7bf64fd621fd74ee4cdfc8fe356b245 100644 (file)
@@ -167,14 +167,15 @@ J2KImageProxy::prepare (optional<dcp::Size> target_size) const
        return reduce;
 }
 
-pair<shared_ptr<Image>, int>
+
+ImageProxy::Result
 J2KImageProxy::image (optional<dcp::Size> target_size) const
 {
        int const r = prepare (target_size);
        /* I think this is safe without a lock on mutex.  _image is guaranteed to be
           set up when prepare() has happened.
        */
-       return make_pair (_image, r);
+       return Result (_image, r);
 }
 
 void
index 510c0ff2599a2143abbcdf8595d2f31e4f66660b..ec99e71a938c19c0b39d9af4c26d4a9baccf8f78 100644 (file)
@@ -50,7 +50,7 @@ public:
 
        J2KImageProxy (boost::shared_ptr<cxml::Node> xml, boost::shared_ptr<Socket> socket);
 
-       std::pair<boost::shared_ptr<Image>, int> image (
+       Result image (
                boost::optional<dcp::Size> size = boost::optional<dcp::Size> ()
                ) const;
 
index 75479136f0682bea3be97bf9e1debc8bf4bb390b..bd643af60c4c248d777bb2e16b59c526c29b981b 100644 (file)
@@ -132,31 +132,29 @@ PlayerVideo::make_image (function<AVPixelFormat (AVPixelFormat)> pixel_format, b
        _image_out_size = _out_size;
        _image_fade = _fade;
 
-       pair<shared_ptr<Image>, int> prox = _in->image (_inter_size);
-       shared_ptr<Image> im = prox.first;
-       int const reduce = prox.second;
+       ImageProxy::Result prox = _in->image (_inter_size);
 
        Crop total_crop = _crop;
        switch (_part) {
        case PART_LEFT_HALF:
-               total_crop.right += im->size().width / 2;
+               total_crop.right += prox.image->size().width / 2;
                break;
        case PART_RIGHT_HALF:
-               total_crop.left += im->size().width / 2;
+               total_crop.left += prox.image->size().width / 2;
                break;
        case PART_TOP_HALF:
-               total_crop.bottom += im->size().height / 2;
+               total_crop.bottom += prox.image->size().height / 2;
                break;
        case PART_BOTTOM_HALF:
-               total_crop.top += im->size().height / 2;
+               total_crop.top += prox.image->size().height / 2;
                break;
        default:
                break;
        }
 
-       if (reduce > 0) {
+       if (prox.log2_scaling > 0) {
                /* Scale the crop down to account for the scaling that has already happened in ImageProxy::image */
-               int const r = pow(2, reduce);
+               int const r = pow(2, prox.log2_scaling);
                total_crop.left /= r;
                total_crop.right /= r;
                total_crop.top /= r;
@@ -168,8 +166,8 @@ PlayerVideo::make_image (function<AVPixelFormat (AVPixelFormat)> pixel_format, b
                yuv_to_rgb = _colour_conversion.get().yuv_to_rgb();
        }
 
-       _image = im->crop_scale_window (
-               total_crop, _inter_size, _out_size, yuv_to_rgb, _video_range, pixel_format (im->pixel_format()), aligned, fast
+       _image = prox.image->crop_scale_window (
+               total_crop, _inter_size, _out_size, yuv_to_rgb, _video_range, pixel_format (prox.image->pixel_format()), aligned, fast
                );
 
        if (_text) {
index 21201faa69264826db4129b7db3eaccb931e10c1..5bd8c4811306feea406d5e023dfe3e0cbd706780 100644 (file)
@@ -54,10 +54,10 @@ RawImageProxy::RawImageProxy (shared_ptr<cxml::Node> xml, shared_ptr<Socket> soc
        _image->read_from_socket (socket);
 }
 
-pair<shared_ptr<Image>, int>
+ImageProxy::Result
 RawImageProxy::image (optional<dcp::Size>) const
 {
-       return make_pair (_image, 0);
+       return Result (_image, 0);
 }
 
 void
@@ -83,7 +83,7 @@ RawImageProxy::same (shared_ptr<const ImageProxy> other) const
                return false;
        }
 
-       return (*_image.get()) == (*rp->image().first.get());
+       return (*_image.get()) == (*rp->image().image.get());
 }
 
 size_t
index dcd107a9ebc4f9255c226228681d25a41bcc029c..a247d7610b4489b2198e24c5cffb4127eb14bf6c 100644 (file)
@@ -29,7 +29,7 @@ public:
        explicit RawImageProxy (boost::shared_ptr<Image>);
        RawImageProxy (boost::shared_ptr<cxml::Node> xml, boost::shared_ptr<Socket> socket);
 
-       std::pair<boost::shared_ptr<Image>, int> image (
+       Result image (
                boost::optional<dcp::Size> size = boost::optional<dcp::Size> ()
                ) const;
 
index e4f552c4d7c46177414b1db0e40352847f7bf705..d04bbdf24cc8b0948b6c45c18591d39f117c1150 100644 (file)
@@ -927,7 +927,7 @@ emit_subtitle_image (ContentTimePeriod period, dcp::SubtitleImage sub, dcp::Size
 {
        /* XXX: this is rather inefficient; decoding the image just to get its size */
        FFmpegImageProxy proxy (sub.png_image());
-       shared_ptr<Image> image = proxy.image().first;
+       shared_ptr<Image> image = proxy.image().image;
        /* 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));
 
index e021322e095d9f81d407c020aa40e429f7d014a8..5fccf6b9ba7acdf158febe3decdb8a61b609a3f6 100644 (file)
@@ -138,7 +138,7 @@ void
 alpha_blend_test_one (AVPixelFormat format, string suffix)
 {
        shared_ptr<FFmpegImageProxy> proxy (new FFmpegImageProxy (TestPaths::private_data / "prophet_frame.tiff"));
-       shared_ptr<Image> raw = proxy->image().first;
+       shared_ptr<Image> raw = proxy->image().image;
        shared_ptr<Image> background = raw->convert_pixel_format (dcp::YUV_TO_RGB_REC709, format, true, false);
 
        shared_ptr<Image> overlay (new Image (AV_PIX_FMT_BGRA, dcp::Size(431, 891), true));
@@ -260,7 +260,7 @@ BOOST_AUTO_TEST_CASE (merge_test2)
 BOOST_AUTO_TEST_CASE (crop_scale_window_test)
 {
        shared_ptr<FFmpegImageProxy> proxy(new FFmpegImageProxy("test/data/flat_red.png"));
-       shared_ptr<Image> raw = proxy->image().first;
+       shared_ptr<Image> raw = proxy->image().image;
        shared_ptr<Image> out = raw->crop_scale_window(Crop(), dcp::Size(1998, 836), dcp::Size(1998, 1080), dcp::YUV_TO_RGB_REC709, VIDEO_RANGE_FULL, 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);
        write_image(save, "build/test/crop_scale_window_test.png", "RGB");
@@ -278,7 +278,7 @@ BOOST_AUTO_TEST_CASE (crop_scale_window_test2)
 BOOST_AUTO_TEST_CASE (crop_scale_window_test3)
 {
        shared_ptr<FFmpegImageProxy> proxy(new FFmpegImageProxy("test/data/player_seek_test_0.png"));
-       shared_ptr<Image> xyz = proxy->image().first->convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGB24, true, false);
+       shared_ptr<Image> xyz = proxy->image().image->convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGB24, true, false);
        shared_ptr<Image> cropped = xyz->crop_scale_window(Crop(512, 0, 0, 0), dcp::Size(1486, 1080), dcp::Size(1998, 1080), dcp::YUV_TO_RGB_REC709, VIDEO_RANGE_FULL, AV_PIX_FMT_RGB24, false, false);
        write_image(cropped, "build/test/crop_scale_window_test3.png", "RGB", MagickCore::CharPixel);
        check_image("test/data/crop_scale_window_test3.png", "build/test/crop_scale_window_test3.png");
@@ -287,7 +287,7 @@ BOOST_AUTO_TEST_CASE (crop_scale_window_test3)
 BOOST_AUTO_TEST_CASE (crop_scale_window_test4)
 {
        shared_ptr<FFmpegImageProxy> proxy(new FFmpegImageProxy("test/data/player_seek_test_0.png"));
-       shared_ptr<Image> xyz = proxy->image().first->convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGB24, true, false);
+       shared_ptr<Image> xyz = proxy->image().image->convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGB24, true, false);
        shared_ptr<Image> cropped = xyz->crop_scale_window(Crop(512, 0, 0, 0), dcp::Size(1486, 1080), dcp::Size(1998, 1080), dcp::YUV_TO_RGB_REC709, VIDEO_RANGE_FULL, AV_PIX_FMT_XYZ12LE, false, false);
        write_image(cropped, "build/test/crop_scale_window_test4.png", "RGB", MagickCore::ShortPixel);
        check_image("test/data/crop_scale_window_test4.png", "build/test/crop_scale_window_test4.png");
@@ -296,7 +296,7 @@ BOOST_AUTO_TEST_CASE (crop_scale_window_test4)
 BOOST_AUTO_TEST_CASE (crop_scale_window_test5)
 {
        shared_ptr<FFmpegImageProxy> proxy(new FFmpegImageProxy("test/data/player_seek_test_0.png"));
-       shared_ptr<Image> xyz = proxy->image().first->convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_XYZ12LE, true, false);
+       shared_ptr<Image> xyz = proxy->image().image->convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_XYZ12LE, true, false);
        shared_ptr<Image> cropped = xyz->crop_scale_window(Crop(512, 0, 0, 0), dcp::Size(1486, 1080), dcp::Size(1998, 1080), dcp::YUV_TO_RGB_REC709, VIDEO_RANGE_FULL, AV_PIX_FMT_RGB24, false, false);
        write_image(cropped, "build/test/crop_scale_window_test5.png", "RGB", MagickCore::CharPixel);
        check_image("test/data/crop_scale_window_test5.png", "build/test/crop_scale_window_test5.png");
@@ -305,7 +305,7 @@ BOOST_AUTO_TEST_CASE (crop_scale_window_test5)
 BOOST_AUTO_TEST_CASE (crop_scale_window_test6)
 {
        shared_ptr<FFmpegImageProxy> proxy(new FFmpegImageProxy("test/data/player_seek_test_0.png"));
-       shared_ptr<Image> xyz = proxy->image().first->convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_XYZ12LE, true, false);
+       shared_ptr<Image> xyz = proxy->image().image->convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_XYZ12LE, true, false);
        shared_ptr<Image> cropped = xyz->crop_scale_window(Crop(512, 0, 0, 0), dcp::Size(1486, 1080), dcp::Size(1998, 1080), dcp::YUV_TO_RGB_REC709, VIDEO_RANGE_FULL, AV_PIX_FMT_XYZ12LE, false, false);
        write_image(cropped, "build/test/crop_scale_window_test6.png", "RGB", MagickCore::ShortPixel);
        check_image("test/data/crop_scale_window_test6.png", "build/test/crop_scale_window_test6.png");
@@ -314,7 +314,7 @@ BOOST_AUTO_TEST_CASE (crop_scale_window_test6)
 BOOST_AUTO_TEST_CASE (as_png_test)
 {
        shared_ptr<FFmpegImageProxy> proxy(new FFmpegImageProxy("test/data/3d_test/000001.png"));
-       shared_ptr<Image> image_rgb = proxy->image().first;
+       shared_ptr<Image> image_rgb = proxy->image().image;
        shared_ptr<Image> image_bgr = image_rgb->convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_BGRA, true, false);
        image_rgb->as_png().write ("build/test/as_png_rgb.png");
        image_bgr->as_png().write ("build/test/as_png_bgr.png");
@@ -340,7 +340,7 @@ static void
 fade_test_format_red (AVPixelFormat f, float amount, string name)
 {
        shared_ptr<FFmpegImageProxy> proxy(new FFmpegImageProxy("test/data/flat_red.png"));
-       shared_ptr<Image> red = proxy->image().first->convert_pixel_format(dcp::YUV_TO_RGB_REC709, f, true, false);
+       shared_ptr<Image> red = proxy->image().image->convert_pixel_format(dcp::YUV_TO_RGB_REC709, f, true, false);
        red->fade (amount);
        string const filename = "fade_test_red_" + name + ".png";
        red->convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGBA, true, false)->as_png().write("build/test/" + filename);