Add video_to_full_range implementation for RGB48LE.
[dcpomatic.git] / src / lib / image.cc
index c4312cb8e6529ddd197100882e52f9cbc1fef730..5b926d77c07feb69e52daeeb44c1655f8b51d2b1 100644 (file)
 #include "rect.h"
 #include "timer.h"
 #include "util.h"
+#include "warnings.h"
 #include <dcp/rgb_xyz.h>
 #include <dcp/transfer_function.h>
+DCPOMATIC_DISABLE_WARNINGS
 extern "C" {
 #include <libavutil/frame.h>
 #include <libavutil/pixdesc.h>
 #include <libavutil/pixfmt.h>
 #include <libswscale/swscale.h>
 }
+DCPOMATIC_ENABLE_WARNINGS
 #include <png.h>
 #if HAVE_VALGRIND_MEMCHECK_H
 #include <valgrind/memcheck.h>
@@ -1015,7 +1018,7 @@ Image::Image (Image const & other)
        }
 }
 
-Image::Image (AVFrame* frame)
+Image::Image (AVFrame const * frame)
        : _size (frame->width, frame->height)
        , _pixel_format (static_cast<AVPixelFormat>(frame->format))
        , _aligned (true)
@@ -1430,13 +1433,29 @@ Image::video_range_to_full_range ()
                for (int y = 0; y < lines; ++y) {
                        uint8_t* q = p;
                        for (int x = 0; x < line_size()[0]; ++x) {
-                               *q = int((*q - 16) * factor);
+                               *q = clamp(lrintf((*q - 16) * factor), 0L, 255L);
                                ++q;
                        }
                        p += stride()[0];
                }
                break;
        }
+       case AV_PIX_FMT_RGB48LE:
+       {
+               float const factor = 65536.0 / 56064.0;
+               uint16_t* p = reinterpret_cast<uint16_t*>(data()[0]);
+               int const lines = sample_size(0).height;
+               for (int y = 0; y < lines; ++y) {
+                       uint16_t* q = p;
+                       int const line_size_pixels = line_size()[0] / 2;
+                       for (int x = 0; x < line_size_pixels; ++x) {
+                               *q = clamp(lrintf((*q - 4096) * factor), 0L, 65535L);
+                               ++q;
+                       }
+                       p += stride()[0] / 2;
+               }
+               break;
+       }
        case AV_PIX_FMT_GBRP12LE:
        {
                float const factor = 4096.0 / 3504.0;
@@ -1447,7 +1466,7 @@ Image::video_range_to_full_range ()
                                uint16_t* q = p;
                                int const line_size_pixels = line_size()[c] / 2;
                                for (int x = 0; x < line_size_pixels; ++x) {
-                                       *q = int((*q - 256) * factor);
+                                       *q = clamp(lrintf((*q - 256) * factor), 0L, 4095L);
                                        ++q;
                                }
                        }