Some work on DCI naming. Clean up compacted / aligned image handling somewhat.
[dcpomatic.git] / src / lib / image.cc
index 2c0338b5357c8b0b7199a6c6ecf9ad68018b4481..f5aef84442c545d56c8d817a48228a75bea47d6a 100644 (file)
@@ -26,6 +26,7 @@
 #include <iostream>
 #include <sys/time.h>
 #include <boost/algorithm/string.hpp>
+#include <boost/bind.hpp>
 #include <openjpeg.h>
 extern "C" {
 #include <libavcodec/avcodec.h>
@@ -88,7 +89,7 @@ Image::scale (Size out_size, Scaler const * scaler) const
 {
        assert (scaler);
 
-       shared_ptr<Image> scaled (new SimpleImage (pixel_format(), out_size));
+       shared_ptr<Image> scaled (new AlignedImage (pixel_format(), out_size));
 
        struct SwsContext* scale_context = sws_getContext (
                size().width, size().height, pixel_format(),
@@ -120,7 +121,7 @@ Image::scale_and_convert_to_rgb (Size out_size, int padding, Scaler const * scal
        Size content_size = out_size;
        content_size.width -= (padding * 2);
 
-       shared_ptr<Image> rgb (new SimpleImage (PIX_FMT_RGB24, content_size));
+       shared_ptr<Image> rgb (new AlignedImage (PIX_FMT_RGB24, content_size));
 
        struct SwsContext* scale_context = sws_getContext (
                size().width, size().height, pixel_format(),
@@ -141,7 +142,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));
+               shared_ptr<Image> padded_rgb (new AlignedImage (PIX_FMT_RGB24, out_size));
                padded_rgb->make_black ();
 
                /* XXX: we are cheating a bit here; we know the frame is RGB so we can
@@ -170,7 +171,7 @@ Image::scale_and_convert_to_rgb (Size out_size, int padding, Scaler const * scal
 shared_ptr<Image>
 Image::post_process (string pp) const
 {
-       shared_ptr<Image> out (new SimpleImage (PIX_FMT_YUV420P, size ()));
+       shared_ptr<Image> out (new AlignedImage (PIX_FMT_YUV420P, size ()));
        
        pp_mode* mode = pp_get_mode_by_name_and_quality (pp.c_str (), PP_QUALITY_MAX);
        pp_context* context = pp_get_context (size().width, size().height, PP_FORMAT_420 | PP_CPU_CAPS_MMX2);
@@ -249,14 +250,16 @@ Image::alpha_blend (shared_ptr<Image> other, Position position)
  *  @param p Pixel format.
  *  @param s Size in pixels.
  */
-SimpleImage::SimpleImage (PixelFormat p, Size s)
+SimpleImage::SimpleImage (PixelFormat p, Size s, function<int (int)> rounder)
        : Image (p)
        , _size (s)
 {
        _data = (uint8_t **) av_malloc (4 * sizeof (uint8_t *));
        _data[0] = _data[1] = _data[2] = _data[3] = 0;
+       
        _line_size = (int *) av_malloc (4);
        _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
+       
        _stride = (int *) av_malloc (4);
        _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
 
@@ -277,7 +280,7 @@ SimpleImage::SimpleImage (PixelFormat p, Size s)
        }
 
        for (int i = 0; i < components(); ++i) {
-               _stride[i] = round_up (_line_size[i], 32);
+               _stride[i] = rounder (_line_size[i]);
                _data[i] = (uint8_t *) av_malloc (_stride[i] * lines (i));
        }
 }
@@ -318,6 +321,37 @@ SimpleImage::size () const
        return _size;
 }
 
+AlignedImage::AlignedImage (PixelFormat f, Size s)
+       : SimpleImage (f, s, boost::bind (round_up, _1, 32))
+{
+
+}
+
+CompactImage::CompactImage (PixelFormat f, Size s)
+       : SimpleImage (f, s, boost::bind (round_up, _1, 1))
+{
+
+}
+
+CompactImage::CompactImage (shared_ptr<Image> im)
+       : SimpleImage (im->pixel_format(), im->size(), boost::bind (round_up, _1, 1))
+{
+       assert (components() == im->components());
+
+       for (int c = 0; c < components(); ++c) {
+
+               assert (line_size()[c] == im->line_size()[c]);
+
+               uint8_t* t = data()[c];
+               uint8_t* o = im->data()[c];
+               
+               for (int y = 0; y < lines(c); ++y) {
+                       memcpy (t, o, line_size()[c]);
+                       t += stride()[c];
+                       o += im->stride()[c];
+               }
+       }
+}
 
 FilterBufferImage::FilterBufferImage (PixelFormat p, AVFilterBufferRef* b)
        : Image (p)