X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fimage.cc;h=ce3f5817d5cd78e12f6ae1a67348e8711d224cf1;hb=9bfa07293928c371d59db2091ba2b7e715ce5994;hp=c4312cb8e6529ddd197100882e52f9cbc1fef730;hpb=0aabe4060ea4bad7c7caac633aef0737fccff8c2;p=dcpomatic.git diff --git a/src/lib/image.cc b/src/lib/image.cc index c4312cb8e..ce3f5817d 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -31,14 +31,17 @@ #include "rect.h" #include "timer.h" #include "util.h" +#include "warnings.h" #include #include +DCPOMATIC_DISABLE_WARNINGS extern "C" { #include #include #include #include } +DCPOMATIC_ENABLE_WARNINGS #include #if HAVE_VALGRIND_MEMCHECK_H #include @@ -294,6 +297,15 @@ Image::crop_scale_window ( out->make_part_black (corner.x + cropped_size.width, out_size.width - cropped_size.width); } + if ( + video_range == VideoRange::VIDEO && + out_video_range == VideoRange::FULL && + av_pix_fmt_desc_get(_pixel_format)->flags & AV_PIX_FMT_FLAG_RGB + ) { + /* libswscale will not convert video range for RGB sources, so we have to do it ourselves */ + out->video_range_to_full_range (); + } + return out; } @@ -1015,10 +1027,10 @@ Image::Image (Image const & other) } } -Image::Image (AVFrame* frame) +Image::Image (AVFrame const * frame, bool aligned) : _size (frame->width, frame->height) , _pixel_format (static_cast(frame->format)) - , _aligned (true) + , _aligned (aligned) { DCPOMATIC_ASSERT (_pixel_format != AV_PIX_FMT_NONE); @@ -1127,7 +1139,7 @@ Image::aligned () const PositionImage -merge (list images) +merge (list images, bool aligned) { if (images.empty ()) { return {}; @@ -1142,7 +1154,7 @@ merge (list images) all.extend (dcpomatic::Rect(i.position, i.image->size().width, i.image->size().height)); } - auto merged = make_shared(images.front().image->pixel_format(), dcp::Size(all.width, all.height), true); + auto merged = make_shared(images.front().image->pixel_format(), dcp::Size(all.width, all.height), aligned); merged->make_transparent (); for (auto const& i: images) { merged->alpha_blend (i.image, i.position - all.position()); @@ -1300,16 +1312,18 @@ Image::fade (float f) } } + shared_ptr -Image::ensure_aligned (shared_ptr image) +Image::ensure_aligned (shared_ptr image, bool aligned) { - if (image->aligned()) { + if (image->aligned() == aligned) { return image; } - return make_shared(image, true); + return make_shared(image, aligned); } + size_t Image::memory_used () const { @@ -1430,13 +1444,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(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 +1477,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; } }