From: Carl Hetherington Date: Sun, 16 Aug 2015 23:37:39 +0000 (+0100) Subject: Fix crop of some YUV content. X-Git-Tag: v2.1.38~2 X-Git-Url: https://main.carlh.net/gitweb/?a=commitdiff_plain;h=d8883a2742d289c2eab3dd4ef92839435b37c95c;p=dcpomatic.git Fix crop of some YUV content. --- diff --git a/ChangeLog b/ChangeLog index 7d4d3b96c..d2be31f94 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2015-08-17 Carl Hetherington + + * Fix crop of some YUV content. + 2015-08-11 Carl Hetherington * Prevent multiple creation of certificate chains diff --git a/src/lib/image.cc b/src/lib/image.cc index c403b61ab..30b997737 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -54,7 +54,7 @@ Image::line_factor (int n) const AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format); if (!d) { - throw PixelFormatError ("lines()", _pixel_format); + throw PixelFormatError ("line_factor()", _pixel_format); } return pow (2.0f, d->log2_chroma_h); @@ -130,10 +130,21 @@ Image::crop_scale_window ( 0, 1 << 16, 1 << 16 ); + AVPixFmtDescriptor const * desc = av_pix_fmt_desc_get (_pixel_format); + if (!desc) { + throw PixelFormatError ("crop_scale_window()", _pixel_format); + } + /* Prepare input data pointers with crop */ uint8_t* scale_in_data[components()]; for (int c = 0; c < components(); ++c) { - scale_in_data[c] = data()[c] + int (rint (bytes_per_pixel(c) * crop.left)) + stride()[c] * (crop.top / line_factor(c)); + /* To work out the crop in bytes, start by multiplying + the crop by the (average) bytes per pixel. Then + round down so that we don't crop a subsampled pixel until + we've cropped all of its Y-channel pixels. + */ + int const x = int (rint (bytes_per_pixel(c) * crop.left)) & ~ ((int) desc->log2_chroma_w); + scale_in_data[c] = data()[c] + x + stride()[c] * (crop.top / line_factor(c)); } /* Corner of the image within out_size */ @@ -515,7 +526,7 @@ Image::bytes_per_pixel (int c) const { AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format); if (!d) { - throw PixelFormatError ("lines()", _pixel_format); + throw PixelFormatError ("bytes_per_pixel()", _pixel_format); } if (c >= components()) {