From 52821965206bce3e5d47200d838e54996857d212 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 23 Jan 2013 15:04:54 +0000 Subject: [PATCH] Make sure inputs to sws_scale are aligned, as I think they must be. --- src/lib/image.cc | 31 ++++++++++++++++++++++++++----- src/lib/image.h | 4 ++++ test/test.cc | 22 +++++++++++++--------- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/lib/image.cc b/src/lib/image.cc index 3afb6205e..0a51add00 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -96,11 +96,15 @@ Image::components () const } shared_ptr -Image::scale (Size out_size, Scaler const * scaler, bool aligned) const +Image::scale (Size out_size, Scaler const * scaler, bool result_aligned) const { assert (scaler); + /* Empirical testing suggests that sws_scale() will crash if + the input image is not aligned. + */ + assert (aligned ()); - shared_ptr scaled (new SimpleImage (pixel_format(), out_size, aligned)); + shared_ptr scaled (new SimpleImage (pixel_format(), out_size, result_aligned)); struct SwsContext* scale_context = sws_getContext ( size().width, size().height, pixel_format(), @@ -125,14 +129,18 @@ Image::scale (Size out_size, Scaler const * scaler, bool aligned) const * @param scaler Scaler to use. */ shared_ptr -Image::scale_and_convert_to_rgb (Size out_size, int padding, Scaler const * scaler, bool aligned) const +Image::scale_and_convert_to_rgb (Size out_size, int padding, Scaler const * scaler, bool result_aligned) const { assert (scaler); + /* Empirical testing suggests that sws_scale() will crash if + the input image is not aligned. + */ + assert (aligned ()); Size content_size = out_size; content_size.width -= (padding * 2); - shared_ptr rgb (new SimpleImage (PIX_FMT_RGB24, content_size, aligned)); + shared_ptr rgb (new SimpleImage (PIX_FMT_RGB24, content_size, result_aligned)); struct SwsContext* scale_context = sws_getContext ( size().width, size().height, pixel_format(), @@ -153,7 +161,7 @@ Image::scale_and_convert_to_rgb (Size out_size, int padding, Scaler const * scal scheme of things. */ if (padding > 0) { - shared_ptr padded_rgb (new SimpleImage (PIX_FMT_RGB24, out_size, aligned)); + shared_ptr padded_rgb (new SimpleImage (PIX_FMT_RGB24, out_size, result_aligned)); padded_rgb->make_black (); /* XXX: we are cheating a bit here; we know the frame is RGB so we can @@ -485,6 +493,12 @@ SimpleImage::size () const return _size; } +bool +SimpleImage::aligned () const +{ + return _aligned; +} + FilterBufferImage::FilterBufferImage (AVPixelFormat p, AVFilterBufferRef* b) : Image (p) , _buffer (b) @@ -522,6 +536,13 @@ FilterBufferImage::size () const return Size (_buffer->video->w, _buffer->video->h); } +bool +FilterBufferImage::aligned () const +{ + /* XXX? */ + return true; +} + RGBPlusAlphaImage::RGBPlusAlphaImage (shared_ptr im) : SimpleImage (im->pixel_format(), im->size(), false) { diff --git a/src/lib/image.h b/src/lib/image.h index 5ca3f337c..23f13a648 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -68,6 +68,8 @@ public: /** @return Size of the image, in pixels */ virtual libdcp::Size size () const = 0; + virtual bool aligned () const = 0; + int components () const; int lines (int) const; @@ -107,6 +109,7 @@ public: int * line_size () const; int * stride () const; libdcp::Size size () const; + bool aligned () const; private: /* Not allowed */ @@ -131,6 +134,7 @@ public: int * line_size () const; int * stride () const; libdcp::Size size () const; + bool aligned () const; protected: void allocate (); diff --git a/test/test.cc b/test/test.cc index 13eb1f17f..9f1248f29 100644 --- a/test/test.cc +++ b/test/test.cc @@ -385,26 +385,30 @@ do_remote_encode (shared_ptr frame, ServerDescription* descriptio BOOST_AUTO_TEST_CASE (client_server_test) { - shared_ptr image (new SimpleImage (PIX_FMT_RGB24, libdcp::Size (1998, 1080), false)); + shared_ptr image (new SimpleImage (PIX_FMT_RGB24, libdcp::Size (1998, 1080), true)); uint8_t* p = image->data()[0]; for (int y = 0; y < 1080; ++y) { + uint8_t* q = p; for (int x = 0; x < 1998; ++x) { - *p++ = x % 256; - *p++ = y % 256; - *p++ = (x + y) % 256; + *q++ = x % 256; + *q++ = y % 256; + *q++ = (x + y) % 256; } + p += image->stride()[0]; } - shared_ptr sub_image (new SimpleImage (PIX_FMT_RGBA, libdcp::Size (100, 200), false)); + shared_ptr sub_image (new SimpleImage (PIX_FMT_RGBA, libdcp::Size (100, 200), true)); p = sub_image->data()[0]; for (int y = 0; y < 200; ++y) { + uint8_t* q = p; for (int x = 0; x < 100; ++x) { - *p++ = y % 256; - *p++ = x % 256; - *p++ = (x + y) % 256; - *p++ = 1; + *q++ = y % 256; + *q++ = x % 256; + *q++ = (x + y) % 256; + *q++ = 1; } + p += sub_image->stride()[0]; } shared_ptr subtitle (new Subtitle (Position (50, 60), sub_image)); -- 2.30.2