Merge master branch.
[dcpomatic.git] / src / lib / image.cc
index feda09ec578bb41baeda31f033c7b770d650a45a..9223fdc5d0019cdfecbe2a2e20930c8546a7c426 100644 (file)
@@ -42,6 +42,7 @@ extern "C" {
 
 using namespace std;
 using namespace boost;
+using libdcp::Size;
 
 void
 Image::swap (Image& other)
@@ -95,11 +96,15 @@ Image::components () const
 }
 
 shared_ptr<Image>
-Image::scale (libdcp::Size out_size, Scaler const * scaler, bool aligned) const
+Image::scale (libdcp::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(),
@@ -124,14 +129,18 @@ Image::scale (libdcp::Size out_size, Scaler const * scaler, bool aligned) const
  *  @param scaler Scaler to use.
  */
 shared_ptr<Image>
-Image::scale_and_convert_to_rgb (libdcp::Size out_size, int padding, Scaler const * scaler, bool aligned) const
+Image::scale_and_convert_to_rgb (libdcp::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 ());
 
        libdcp::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(),
@@ -152,7 +161,7 @@ Image::scale_and_convert_to_rgb (libdcp::Size out_size, int padding, Scaler cons
           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
@@ -244,13 +253,25 @@ Image::make_black ()
 {
        switch (_pixel_format) {
        case PIX_FMT_YUV420P:
-       case PIX_FMT_YUV422P10LE:
        case PIX_FMT_YUV422P:
                memset (data()[0], 0, lines(0) * stride()[0]);
-               memset (data()[1], 0x80, lines(1) * stride()[1]);
-               memset (data()[2], 0x80, lines(2) * stride()[2]);
+               memset (data()[1], 0x7f, lines(1) * stride()[1]);
+               memset (data()[2], 0x7f, lines(2) * stride()[2]);
                break;
 
+       case PIX_FMT_YUV422P10LE:
+               memset (data()[0], 0, lines(0) * stride()[0]);
+               for (int i = 1; i < 3; ++i) {
+                       int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
+                       for (int y = 0; y < size().height; ++y) {
+                               for (int x = 0; x < line_size()[i] / 2; ++x) {
+                                       p[x] = (1 << 9) - 1;
+                               }
+                               p += stride()[i] / 2;
+                       }
+               }
+               break;
+               
        case PIX_FMT_RGB24:             
                memset (data()[0], 0, lines(0) * stride()[0]);
                break;
@@ -349,7 +370,7 @@ Image::bytes_per_pixel (int c) const
                        return 0.5;
                }
        case PIX_FMT_YUV422P10LE:
-               if (c == 1) {
+               if (c == 0) {
                        return 2;
                } else {
                        return 1;
@@ -472,6 +493,12 @@ SimpleImage::size () const
        return _size;
 }
 
+bool
+SimpleImage::aligned () const
+{
+       return _aligned;
+}
+
 FilterBufferImage::FilterBufferImage (AVPixelFormat p, AVFilterBufferRef* b)
        : Image (p)
        , _buffer (b)
@@ -509,6 +536,13 @@ FilterBufferImage::size () const
        return libdcp::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)
 {