Make sure inputs to sws_scale are aligned, as I think they must be.
authorCarl Hetherington <cth@carlh.net>
Wed, 23 Jan 2013 15:04:54 +0000 (15:04 +0000)
committerCarl Hetherington <cth@carlh.net>
Wed, 23 Jan 2013 15:04:54 +0000 (15:04 +0000)
src/lib/image.cc
src/lib/image.h
test/test.cc

index 3afb6205eb21f11245ac8e3f3e41e48f8b2738d6..0a51add002cf7787c919a9c29a03e36237a72200 100644 (file)
@@ -96,11 +96,15 @@ Image::components () const
 }
 
 shared_ptr<Image>
-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<Image> scaled (new SimpleImage (pixel_format(), out_size, aligned));
+       shared_ptr<Image> 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>
-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<Image> rgb (new SimpleImage (PIX_FMT_RGB24, content_size, aligned));
+       shared_ptr<Image> 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<Image> padded_rgb (new SimpleImage (PIX_FMT_RGB24, out_size, aligned));
+               shared_ptr<Image> 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<const Image> im)
        : SimpleImage (im->pixel_format(), im->size(), false)
 {
index 5ca3f337c82cc15df66b8779e20ece84771b5d6f..23f13a648c8b8cd29d16d1c25772d3dd50b89bf1 100644 (file)
@@ -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 ();
index 13eb1f17fec42802ac9ff7cc7cb7c5b625df759e..9f1248f294dc0a92e07e78ec620eb7b1b2079bc9 100644 (file)
@@ -385,26 +385,30 @@ do_remote_encode (shared_ptr<DCPVideoFrame> frame, ServerDescription* descriptio
 
 BOOST_AUTO_TEST_CASE (client_server_test)
 {
-       shared_ptr<Image> image (new SimpleImage (PIX_FMT_RGB24, libdcp::Size (1998, 1080), false));
+       shared_ptr<Image> 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<Image> sub_image (new SimpleImage (PIX_FMT_RGBA, libdcp::Size (100, 200), false));
+       shared_ptr<Image> 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> subtitle (new Subtitle (Position (50, 60), sub_image));