2 Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
6 DCP-o-matic is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 DCP-o-matic is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
22 /** @file src/image.cc
23 * @brief A class to describe a video image.
27 #include "compose.hpp"
28 #include "dcpomatic_socket.h"
29 #include "exceptions.h"
34 #include <dcp/rgb_xyz.h>
35 #include <dcp/transfer_function.h>
36 DCPOMATIC_DISABLE_WARNINGS
38 #include <libavutil/frame.h>
39 #include <libavutil/pixdesc.h>
40 #include <libavutil/pixfmt.h>
41 #include <libswscale/swscale.h>
43 DCPOMATIC_ENABLE_WARNINGS
45 #if HAVE_VALGRIND_MEMCHECK_H
46 #include <valgrind/memcheck.h>
57 using std::make_shared;
60 using std::runtime_error;
61 using std::shared_ptr;
66 /** The memory alignment, in bytes, used for each row of an image if aligment is requested */
69 /* U/V black value for 8-bit colour */
70 static uint8_t const eight_bit_uv = (1 << 7) - 1;
71 /* U/V black value for 9-bit colour */
72 static uint16_t const nine_bit_uv = (1 << 8) - 1;
73 /* U/V black value for 10-bit colour */
74 static uint16_t const ten_bit_uv = (1 << 9) - 1;
75 /* U/V black value for 16-bit colour */
76 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
80 Image::vertical_factor (int n) const
86 auto d = av_pix_fmt_desc_get(_pixel_format);
88 throw PixelFormatError ("line_factor()", _pixel_format);
91 return lrintf(powf(2.0f, d->log2_chroma_h));
95 Image::horizontal_factor (int n) const
101 auto d = av_pix_fmt_desc_get(_pixel_format);
103 throw PixelFormatError ("sample_size()", _pixel_format);
106 return lrintf(powf(2.0f, d->log2_chroma_w));
109 /** @param n Component index.
110 * @return Number of samples (i.e. pixels, unless sub-sampled) in each direction for this component.
113 Image::sample_size (int n) const
116 lrint (ceil(static_cast<double>(size().width) / horizontal_factor(n))),
117 lrint (ceil(static_cast<double>(size().height) / vertical_factor(n)))
121 /** @return Number of planes */
123 Image::planes () const
125 auto d = av_pix_fmt_desc_get(_pixel_format);
127 throw PixelFormatError ("planes()", _pixel_format);
130 if (_pixel_format == AV_PIX_FMT_PAL8) {
134 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
138 return d->nb_components;
144 round_width_for_subsampling (int p, AVPixFmtDescriptor const * desc)
146 return p & ~ ((1 << desc->log2_chroma_w) - 1);
152 round_height_for_subsampling (int p, AVPixFmtDescriptor const * desc)
154 return p & ~ ((1 << desc->log2_chroma_h) - 1);
158 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size'.
159 * @param crop Amount to crop by.
160 * @param inter_size Size to scale the cropped image to.
161 * @param out_size Size of output frame; if this is larger than inter_size there will be black padding.
162 * @param yuv_to_rgb YUV to RGB transformation to use, if required.
163 * @param video_range Video range of the image.
164 * @param out_format Output pixel format.
165 * @param out_aligned true to make the output image aligned.
166 * @param out_video_range Video range to use for the output image.
167 * @param fast Try to be fast at the possible expense of quality; at present this means using
168 * fast bilinear rather than bicubic scaling.
171 Image::crop_scale_window (
173 dcp::Size inter_size,
175 dcp::YUVToRGB yuv_to_rgb,
176 VideoRange video_range,
177 AVPixelFormat out_format,
178 VideoRange out_video_range,
183 /* Empirical testing suggests that sws_scale() will crash if
184 the input image is not aligned.
186 DCPOMATIC_ASSERT (aligned ());
188 DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
189 DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
191 auto out = make_shared<Image>(out_format, out_size, out_aligned);
194 auto in_desc = av_pix_fmt_desc_get (_pixel_format);
196 throw PixelFormatError ("crop_scale_window()", _pixel_format);
199 /* Round down so that we crop only the number of pixels that is straightforward
200 * considering any subsampling.
203 round_width_for_subsampling(crop.left, in_desc),
204 round_width_for_subsampling(crop.right, in_desc),
205 round_height_for_subsampling(crop.top, in_desc),
206 round_height_for_subsampling(crop.bottom, in_desc)
209 /* Also check that we aren't cropping more image than there actually is */
210 if ((corrected_crop.left + corrected_crop.right) >= (size().width - 4)) {
211 corrected_crop.left = 0;
212 corrected_crop.right = size().width - 4;
215 if ((corrected_crop.top + corrected_crop.bottom) >= (size().height - 4)) {
216 corrected_crop.top = 0;
217 corrected_crop.bottom = size().height - 4;
220 /* Size of the image after any crop */
221 auto const cropped_size = corrected_crop.apply (size());
223 /* Scale context for a scale from cropped_size to inter_size */
224 auto scale_context = sws_getContext (
225 cropped_size.width, cropped_size.height, pixel_format(),
226 inter_size.width, inter_size.height, out_format,
227 fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
230 if (!scale_context) {
231 throw runtime_error (N_("Could not allocate SwsContext"));
234 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUVToRGB::COUNT);
235 int const lut[static_cast<int>(dcp::YUVToRGB::COUNT)] = {
240 /* The 3rd parameter here is:
241 0 -> source range MPEG (i.e. "video", 16-235)
242 1 -> source range JPEG (i.e. "full", 0-255)
244 0 -> destination range MPEG (i.e. "video", 16-235)
245 1 -> destination range JPEG (i.e. "full", 0-255)
247 But remember: sws_setColorspaceDetails ignores these
248 parameters unless the both source and destination images
249 are isYUV or isGray. (If either is not, it uses video range).
251 sws_setColorspaceDetails (
253 sws_getCoefficients (lut[static_cast<int>(yuv_to_rgb)]), video_range == VideoRange::VIDEO ? 0 : 1,
254 sws_getCoefficients (lut[static_cast<int>(yuv_to_rgb)]), out_video_range == VideoRange::VIDEO ? 0 : 1,
258 /* Prepare input data pointers with crop */
259 uint8_t* scale_in_data[planes()];
260 for (int c = 0; c < planes(); ++c) {
261 int const x = lrintf(bytes_per_pixel(c) * corrected_crop.left);
262 scale_in_data[c] = data()[c] + x + stride()[c] * (corrected_crop.top / vertical_factor(c));
265 auto out_desc = av_pix_fmt_desc_get (out_format);
267 throw PixelFormatError ("crop_scale_window()", out_format);
270 /* Corner of the image within out_size */
271 Position<int> const corner (
272 round_width_for_subsampling((out_size.width - inter_size.width) / 2, out_desc),
273 round_height_for_subsampling((out_size.height - inter_size.height) / 2, out_desc)
276 uint8_t* scale_out_data[out->planes()];
277 for (int c = 0; c < out->planes(); ++c) {
278 int const x = lrintf(out->bytes_per_pixel(c) * corner.x);
279 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
284 scale_in_data, stride(),
285 0, cropped_size.height,
286 scale_out_data, out->stride()
289 sws_freeContext (scale_context);
291 if (corrected_crop != Crop() && cropped_size == inter_size) {
292 /* We are cropping without any scaling or pixel format conversion, so FFmpeg may have left some
293 data behind in our image. Clear it out. It may get to the point where we should just stop
294 trying to be clever with cropping.
296 out->make_part_black (corner.x + cropped_size.width, out_size.width - cropped_size.width);
303 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
305 return scale(size(), yuv_to_rgb, out_format, out_aligned, fast);
308 /** @param out_size Size to scale to.
309 * @param yuv_to_rgb YUVToRGB transform transform to use, if required.
310 * @param out_format Output pixel format.
311 * @param out_aligned true to make an aligned output image.
312 * @param fast Try to be fast at the possible expense of quality; at present this means using
313 * fast bilinear rather than bicubic scaling.
316 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
318 /* Empirical testing suggests that sws_scale() will crash if
319 the input image is not aligned.
321 DCPOMATIC_ASSERT (aligned ());
323 auto scaled = make_shared<Image>(out_format, out_size, out_aligned);
324 auto scale_context = sws_getContext (
325 size().width, size().height, pixel_format(),
326 out_size.width, out_size.height, out_format,
327 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
330 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUVToRGB::COUNT);
331 int const lut[static_cast<int>(dcp::YUVToRGB::COUNT)] = {
336 /* The 3rd parameter here is:
337 0 -> source range MPEG (i.e. "video", 16-235)
338 1 -> source range JPEG (i.e. "full", 0-255)
340 0 -> destination range MPEG (i.e. "video", 16-235)
341 1 -> destination range JPEG (i.e. "full", 0-255)
343 But remember: sws_setColorspaceDetails ignores these
344 parameters unless the corresponding image isYUV or isGray.
345 (If it's neither, it uses video range).
347 sws_setColorspaceDetails (
349 sws_getCoefficients (lut[static_cast<int>(yuv_to_rgb)]), 0,
350 sws_getCoefficients (lut[static_cast<int>(yuv_to_rgb)]), 0,
358 scaled->data(), scaled->stride()
361 sws_freeContext (scale_context);
366 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
368 Image::yuv_16_black (uint16_t v, bool alpha)
370 memset (data()[0], 0, sample_size(0).height * stride()[0]);
371 for (int i = 1; i < 3; ++i) {
372 auto p = reinterpret_cast<int16_t*> (data()[i]);
373 int const lines = sample_size(i).height;
374 for (int y = 0; y < lines; ++y) {
375 /* We divide by 2 here because we are writing 2 bytes at a time */
376 for (int x = 0; x < line_size()[i] / 2; ++x) {
379 p += stride()[i] / 2;
384 memset (data()[3], 0, sample_size(3).height * stride()[3]);
389 Image::swap_16 (uint16_t v)
391 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
395 Image::make_part_black (int const start, int const width)
397 auto y_part = [&]() {
398 int const bpp = bytes_per_pixel(0);
399 int const h = sample_size(0).height;
400 int const s = stride()[0];
402 for (int y = 0; y < h; ++y) {
403 memset (p + start * bpp, 0, width * bpp);
408 switch (_pixel_format) {
409 case AV_PIX_FMT_RGB24:
410 case AV_PIX_FMT_ARGB:
411 case AV_PIX_FMT_RGBA:
412 case AV_PIX_FMT_ABGR:
413 case AV_PIX_FMT_BGRA:
414 case AV_PIX_FMT_RGB555LE:
415 case AV_PIX_FMT_RGB48LE:
416 case AV_PIX_FMT_RGB48BE:
417 case AV_PIX_FMT_XYZ12LE:
419 int const h = sample_size(0).height;
420 int const bpp = bytes_per_pixel(0);
421 int const s = stride()[0];
422 uint8_t* p = data()[0];
423 for (int y = 0; y < h; y++) {
424 memset (p + start * bpp, 0, width * bpp);
429 case AV_PIX_FMT_YUV420P:
432 for (int i = 1; i < 3; ++i) {
434 int const h = sample_size(i).height;
435 for (int y = 0; y < h; ++y) {
436 for (int x = start / 2; x < (start + width) / 2; ++x) {
444 case AV_PIX_FMT_YUV422P10LE:
447 for (int i = 1; i < 3; ++i) {
448 auto p = reinterpret_cast<int16_t*>(data()[i]);
449 int const h = sample_size(i).height;
450 for (int y = 0; y < h; ++y) {
451 for (int x = start / 2; x < (start + width) / 2; ++x) {
454 p += stride()[i] / 2;
460 throw PixelFormatError ("make_part_black()", _pixel_format);
467 switch (_pixel_format) {
468 case AV_PIX_FMT_YUV420P:
469 case AV_PIX_FMT_YUV422P:
470 case AV_PIX_FMT_YUV444P:
471 case AV_PIX_FMT_YUV411P:
472 memset (data()[0], 0, sample_size(0).height * stride()[0]);
473 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
474 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
477 case AV_PIX_FMT_YUVJ420P:
478 case AV_PIX_FMT_YUVJ422P:
479 case AV_PIX_FMT_YUVJ444P:
480 memset (data()[0], 0, sample_size(0).height * stride()[0]);
481 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
482 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
485 case AV_PIX_FMT_YUV422P9LE:
486 case AV_PIX_FMT_YUV444P9LE:
487 yuv_16_black (nine_bit_uv, false);
490 case AV_PIX_FMT_YUV422P9BE:
491 case AV_PIX_FMT_YUV444P9BE:
492 yuv_16_black (swap_16 (nine_bit_uv), false);
495 case AV_PIX_FMT_YUV422P10LE:
496 case AV_PIX_FMT_YUV444P10LE:
497 yuv_16_black (ten_bit_uv, false);
500 case AV_PIX_FMT_YUV422P16LE:
501 case AV_PIX_FMT_YUV444P16LE:
502 yuv_16_black (sixteen_bit_uv, false);
505 case AV_PIX_FMT_YUV444P10BE:
506 case AV_PIX_FMT_YUV422P10BE:
507 yuv_16_black (swap_16 (ten_bit_uv), false);
510 case AV_PIX_FMT_YUVA420P9BE:
511 case AV_PIX_FMT_YUVA422P9BE:
512 case AV_PIX_FMT_YUVA444P9BE:
513 yuv_16_black (swap_16 (nine_bit_uv), true);
516 case AV_PIX_FMT_YUVA420P9LE:
517 case AV_PIX_FMT_YUVA422P9LE:
518 case AV_PIX_FMT_YUVA444P9LE:
519 yuv_16_black (nine_bit_uv, true);
522 case AV_PIX_FMT_YUVA420P10BE:
523 case AV_PIX_FMT_YUVA422P10BE:
524 case AV_PIX_FMT_YUVA444P10BE:
525 yuv_16_black (swap_16 (ten_bit_uv), true);
528 case AV_PIX_FMT_YUVA420P10LE:
529 case AV_PIX_FMT_YUVA422P10LE:
530 case AV_PIX_FMT_YUVA444P10LE:
531 yuv_16_black (ten_bit_uv, true);
534 case AV_PIX_FMT_YUVA420P16BE:
535 case AV_PIX_FMT_YUVA422P16BE:
536 case AV_PIX_FMT_YUVA444P16BE:
537 yuv_16_black (swap_16 (sixteen_bit_uv), true);
540 case AV_PIX_FMT_YUVA420P16LE:
541 case AV_PIX_FMT_YUVA422P16LE:
542 case AV_PIX_FMT_YUVA444P16LE:
543 yuv_16_black (sixteen_bit_uv, true);
546 case AV_PIX_FMT_RGB24:
547 case AV_PIX_FMT_ARGB:
548 case AV_PIX_FMT_RGBA:
549 case AV_PIX_FMT_ABGR:
550 case AV_PIX_FMT_BGRA:
551 case AV_PIX_FMT_RGB555LE:
552 case AV_PIX_FMT_RGB48LE:
553 case AV_PIX_FMT_RGB48BE:
554 case AV_PIX_FMT_XYZ12LE:
555 memset (data()[0], 0, sample_size(0).height * stride()[0]);
558 case AV_PIX_FMT_UYVY422:
560 int const Y = sample_size(0).height;
561 int const X = line_size()[0];
562 uint8_t* p = data()[0];
563 for (int y = 0; y < Y; ++y) {
564 for (int x = 0; x < X / 4; ++x) {
565 *p++ = eight_bit_uv; // Cb
567 *p++ = eight_bit_uv; // Cr
575 throw PixelFormatError ("make_black()", _pixel_format);
580 Image::make_transparent ()
582 if (_pixel_format != AV_PIX_FMT_BGRA && _pixel_format != AV_PIX_FMT_RGBA) {
583 throw PixelFormatError ("make_transparent()", _pixel_format);
586 memset (data()[0], 0, sample_size(0).height * stride()[0]);
590 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
592 /* We're blending RGBA or BGRA images */
593 DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA || other->pixel_format() == AV_PIX_FMT_RGBA);
594 int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
595 int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
597 int const other_bpp = 4;
599 int start_tx = position.x;
603 start_ox = -start_tx;
607 int start_ty = position.y;
611 start_oy = -start_ty;
615 switch (_pixel_format) {
616 case AV_PIX_FMT_RGB24:
618 /* Going onto RGB24. First byte is red, second green, third blue */
619 int const this_bpp = 3;
620 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
621 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
622 uint8_t* op = other->data()[0] + oy * other->stride()[0];
623 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
624 float const alpha = float (op[3]) / 255;
625 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
626 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
627 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
635 case AV_PIX_FMT_BGRA:
637 int const this_bpp = 4;
638 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
639 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
640 uint8_t* op = other->data()[0] + oy * other->stride()[0];
641 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
642 float const alpha = float (op[3]) / 255;
643 tp[0] = op[blue] * alpha + tp[0] * (1 - alpha);
644 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
645 tp[2] = op[red] * alpha + tp[2] * (1 - alpha);
646 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
654 case AV_PIX_FMT_RGBA:
656 int const this_bpp = 4;
657 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
658 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
659 uint8_t* op = other->data()[0] + oy * other->stride()[0];
660 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
661 float const alpha = float (op[3]) / 255;
662 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
663 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
664 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
665 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
673 case AV_PIX_FMT_RGB48LE:
675 int const this_bpp = 6;
676 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
677 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
678 uint8_t* op = other->data()[0] + oy * other->stride()[0];
679 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
680 float const alpha = float (op[3]) / 255;
681 /* Blend high bytes */
682 tp[1] = op[red] * alpha + tp[1] * (1 - alpha);
683 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
684 tp[5] = op[blue] * alpha + tp[5] * (1 - alpha);
692 case AV_PIX_FMT_XYZ12LE:
694 auto conv = dcp::ColourConversion::srgb_to_xyz();
695 double fast_matrix[9];
696 dcp::combined_rgb_to_xyz (conv, fast_matrix);
697 double const * lut_in = conv.in()->lut (8, false);
698 double const * lut_out = conv.out()->lut (16, true);
699 int const this_bpp = 6;
700 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
701 uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
702 uint8_t* op = other->data()[0] + oy * other->stride()[0];
703 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
704 float const alpha = float (op[3]) / 255;
706 /* Convert sRGB to XYZ; op is BGRA. First, input gamma LUT */
707 double const r = lut_in[op[red]];
708 double const g = lut_in[op[1]];
709 double const b = lut_in[op[blue]];
711 /* RGB to XYZ, including Bradford transform and DCI companding */
712 double const x = max (0.0, min (65535.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
713 double const y = max (0.0, min (65535.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
714 double const z = max (0.0, min (65535.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
716 /* Out gamma LUT and blend */
717 tp[0] = lrint(lut_out[lrint(x)] * 65535) * alpha + tp[0] * (1 - alpha);
718 tp[1] = lrint(lut_out[lrint(y)] * 65535) * alpha + tp[1] * (1 - alpha);
719 tp[2] = lrint(lut_out[lrint(z)] * 65535) * alpha + tp[2] * (1 - alpha);
727 case AV_PIX_FMT_YUV420P:
729 auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, false, false);
730 dcp::Size const ts = size();
731 dcp::Size const os = yuv->size();
732 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
733 int const hty = ty / 2;
734 int const hoy = oy / 2;
735 uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
736 uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
737 uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
738 uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
739 uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
740 uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
741 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
742 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
743 float const a = float(alpha[3]) / 255;
744 *tY = *oY * a + *tY * (1 - a);
745 *tU = *oU * a + *tU * (1 - a);
746 *tV = *oV * a + *tV * (1 - a);
762 case AV_PIX_FMT_YUV420P10:
764 auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, false, false);
765 dcp::Size const ts = size();
766 dcp::Size const os = yuv->size();
767 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
768 int const hty = ty / 2;
769 int const hoy = oy / 2;
770 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
771 uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
772 uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
773 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
774 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
775 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
776 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
777 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
778 float const a = float(alpha[3]) / 255;
779 *tY = *oY * a + *tY * (1 - a);
780 *tU = *oU * a + *tU * (1 - a);
781 *tV = *oV * a + *tV * (1 - a);
797 case AV_PIX_FMT_YUV422P10LE:
799 auto yuv = other->convert_pixel_format (dcp::YUVToRGB::REC709, _pixel_format, false, false);
800 dcp::Size const ts = size();
801 dcp::Size const os = yuv->size();
802 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
803 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
804 uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
805 uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
806 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
807 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
808 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
809 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
810 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
811 float const a = float(alpha[3]) / 255;
812 *tY = *oY * a + *tY * (1 - a);
813 *tU = *oU * a + *tU * (1 - a);
814 *tV = *oV * a + *tV * (1 - a);
831 throw PixelFormatError ("alpha_blend()", _pixel_format);
836 Image::copy (shared_ptr<const Image> other, Position<int> position)
838 /* Only implemented for RGB24 onto RGB24 so far */
839 DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
840 DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
842 int const N = min (position.x + other->size().width, size().width) - position.x;
843 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
844 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
845 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
846 memcpy (tp, op, N * 3);
851 Image::read_from_socket (shared_ptr<Socket> socket)
853 for (int i = 0; i < planes(); ++i) {
854 uint8_t* p = data()[i];
855 int const lines = sample_size(i).height;
856 for (int y = 0; y < lines; ++y) {
857 socket->read (p, line_size()[i]);
864 Image::write_to_socket (shared_ptr<Socket> socket) const
866 for (int i = 0; i < planes(); ++i) {
867 uint8_t* p = data()[i];
868 int const lines = sample_size(i).height;
869 for (int y = 0; y < lines; ++y) {
870 socket->write (p, line_size()[i]);
877 Image::bytes_per_pixel (int c) const
879 auto d = av_pix_fmt_desc_get(_pixel_format);
881 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
888 float bpp[4] = { 0, 0, 0, 0 };
890 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
891 bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
892 if (d->nb_components > 1) {
893 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
895 if (d->nb_components > 2) {
896 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
898 if (d->nb_components > 3) {
899 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
902 bpp[0] = floor ((d->comp[0].depth + 7) / 8);
903 if (d->nb_components > 1) {
904 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
906 if (d->nb_components > 2) {
907 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
909 if (d->nb_components > 3) {
910 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
914 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
915 /* Not planar; sum them up */
916 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
922 /** Construct a Image of a given size and format, allocating memory
925 * @param p Pixel format.
926 * @param s Size in pixels.
927 * @param aligned true to make each row of this image aligned to a ALIGNMENT-byte boundary.
929 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned)
940 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
941 _data[0] = _data[1] = _data[2] = _data[3] = 0;
943 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
944 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
946 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
947 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
949 for (int i = 0; i < planes(); ++i) {
950 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
951 _stride[i] = stride_round_up (i, _line_size, _aligned ? ALIGNMENT : 1);
953 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
954 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
955 Hence on the last pixel of the last line it reads over the end of
956 the actual data by 1 byte. If the width of an image is a multiple
957 of the stride alignment there will be no padding at the end of image lines.
958 OS X crashes on this illegal read, though other operating systems don't
959 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
960 for that instruction to read safely.
962 Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
963 over-reads by more then _avx. I can't follow the code to work out how much,
964 so I'll just over-allocate by ALIGNMENT bytes and have done with it. Empirical
965 testing suggests that it works.
967 In addition to these concerns, we may read/write as much as a whole extra line
968 at the end of each plane in cases where we are messing with offsets in order to
969 do pad or crop. To solve this we over-allocate by an extra _stride[i] bytes.
971 As an example: we may write to images starting at an offset so we get some padding.
972 Hence we want to write in the following pattern:
974 block start write start line end
975 |..(padding)..|<------line-size------------->|..(padding)..|
976 |..(padding)..|<------line-size------------->|..(padding)..|
977 |..(padding)..|<------line-size------------->|..(padding)..|
979 where line-size is of the smaller (inter_size) image and the full padded line length is that of
980 out_size. To get things to work we have to tell FFmpeg that the stride is that of out_size.
981 However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
982 specified *stride*. This does not matter until we get to the last line:
984 block start write start line end
985 |..(padding)..|<------line-size------------->|XXXwrittenXXX|
986 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
987 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
990 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
991 #if HAVE_VALGRIND_MEMCHECK_H
992 /* The data between the end of the line size and the stride is undefined but processed by
993 libswscale, causing lots of valgrind errors. Mark it all defined to quell these errors.
995 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
1000 Image::Image (Image const & other)
1001 : std::enable_shared_from_this<Image>(other)
1002 , _size (other._size)
1003 , _pixel_format (other._pixel_format)
1004 , _aligned (other._aligned)
1008 for (int i = 0; i < planes(); ++i) {
1009 uint8_t* p = _data[i];
1010 uint8_t* q = other._data[i];
1011 int const lines = sample_size(i).height;
1012 for (int j = 0; j < lines; ++j) {
1013 memcpy (p, q, _line_size[i]);
1015 q += other.stride()[i];
1020 Image::Image (AVFrame* frame)
1021 : _size (frame->width, frame->height)
1022 , _pixel_format (static_cast<AVPixelFormat>(frame->format))
1025 DCPOMATIC_ASSERT (_pixel_format != AV_PIX_FMT_NONE);
1029 for (int i = 0; i < planes(); ++i) {
1030 uint8_t* p = _data[i];
1031 uint8_t* q = frame->data[i];
1032 int const lines = sample_size(i).height;
1033 for (int j = 0; j < lines; ++j) {
1034 memcpy (p, q, _line_size[i]);
1036 /* AVFrame's linesize is what we call `stride' */
1037 q += frame->linesize[i];
1042 Image::Image (shared_ptr<const Image> other, bool aligned)
1043 : _size (other->_size)
1044 , _pixel_format (other->_pixel_format)
1045 , _aligned (aligned)
1049 for (int i = 0; i < planes(); ++i) {
1050 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
1051 uint8_t* p = _data[i];
1052 uint8_t* q = other->data()[i];
1053 int const lines = sample_size(i).height;
1054 for (int j = 0; j < lines; ++j) {
1055 memcpy (p, q, line_size()[i]);
1057 q += other->stride()[i];
1063 Image::operator= (Image const & other)
1065 if (this == &other) {
1075 Image::swap (Image & other)
1077 std::swap (_size, other._size);
1078 std::swap (_pixel_format, other._pixel_format);
1080 for (int i = 0; i < 4; ++i) {
1081 std::swap (_data[i], other._data[i]);
1082 std::swap (_line_size[i], other._line_size[i]);
1083 std::swap (_stride[i], other._stride[i]);
1086 std::swap (_aligned, other._aligned);
1091 for (int i = 0; i < planes(); ++i) {
1096 av_free (_line_size);
1101 Image::data () const
1107 Image::line_size () const
1113 Image::stride () const
1119 Image::size () const
1125 Image::aligned () const
1132 merge (list<PositionImage> images)
1134 if (images.empty ()) {
1138 if (images.size() == 1) {
1139 return images.front ();
1142 dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1143 for (auto const& i: images) {
1144 all.extend (dcpomatic::Rect<int>(i.position, i.image->size().width, i.image->size().height));
1147 auto merged = make_shared<Image>(images.front().image->pixel_format(), dcp::Size(all.width, all.height), true);
1148 merged->make_transparent ();
1149 for (auto const& i: images) {
1150 merged->alpha_blend (i.image, i.position - all.position());
1153 return PositionImage (merged, all.position ());
1158 operator== (Image const & a, Image const & b)
1160 if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1164 for (int c = 0; c < a.planes(); ++c) {
1165 if (a.sample_size(c).height != b.sample_size(c).height || a.line_size()[c] != b.line_size()[c] || a.stride()[c] != b.stride()[c]) {
1169 uint8_t* p = a.data()[c];
1170 uint8_t* q = b.data()[c];
1171 int const lines = a.sample_size(c).height;
1172 for (int y = 0; y < lines; ++y) {
1173 if (memcmp (p, q, a.line_size()[c]) != 0) {
1186 * @param f Amount to fade by; 0 is black, 1 is no fade.
1189 Image::fade (float f)
1191 /* U/V black value for 8-bit colour */
1192 static int const eight_bit_uv = (1 << 7) - 1;
1193 /* U/V black value for 10-bit colour */
1194 static uint16_t const ten_bit_uv = (1 << 9) - 1;
1196 switch (_pixel_format) {
1197 case AV_PIX_FMT_YUV420P:
1200 uint8_t* p = data()[0];
1201 int const lines = sample_size(0).height;
1202 for (int y = 0; y < lines; ++y) {
1204 for (int x = 0; x < line_size()[0]; ++x) {
1205 *q = int(float(*q) * f);
1212 for (int c = 1; c < 3; ++c) {
1213 uint8_t* p = data()[c];
1214 int const lines = sample_size(c).height;
1215 for (int y = 0; y < lines; ++y) {
1217 for (int x = 0; x < line_size()[c]; ++x) {
1218 *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1228 case AV_PIX_FMT_RGB24:
1231 uint8_t* p = data()[0];
1232 int const lines = sample_size(0).height;
1233 for (int y = 0; y < lines; ++y) {
1235 for (int x = 0; x < line_size()[0]; ++x) {
1236 *q = int (float (*q) * f);
1244 case AV_PIX_FMT_XYZ12LE:
1245 case AV_PIX_FMT_RGB48LE:
1246 /* 16-bit little-endian */
1247 for (int c = 0; c < 3; ++c) {
1248 int const stride_pixels = stride()[c] / 2;
1249 int const line_size_pixels = line_size()[c] / 2;
1250 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1251 int const lines = sample_size(c).height;
1252 for (int y = 0; y < lines; ++y) {
1254 for (int x = 0; x < line_size_pixels; ++x) {
1255 *q = int (float (*q) * f);
1263 case AV_PIX_FMT_YUV422P10LE:
1267 int const stride_pixels = stride()[0] / 2;
1268 int const line_size_pixels = line_size()[0] / 2;
1269 uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1270 int const lines = sample_size(0).height;
1271 for (int y = 0; y < lines; ++y) {
1273 for (int x = 0; x < line_size_pixels; ++x) {
1274 *q = int(float(*q) * f);
1282 for (int c = 1; c < 3; ++c) {
1283 int const stride_pixels = stride()[c] / 2;
1284 int const line_size_pixels = line_size()[c] / 2;
1285 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1286 int const lines = sample_size(c).height;
1287 for (int y = 0; y < lines; ++y) {
1289 for (int x = 0; x < line_size_pixels; ++x) {
1290 *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1301 throw PixelFormatError ("fade()", _pixel_format);
1305 shared_ptr<const Image>
1306 Image::ensure_aligned (shared_ptr<const Image> image)
1308 if (image->aligned()) {
1312 return make_shared<Image>(image, true);
1316 Image::memory_used () const
1319 for (int i = 0; i < planes(); ++i) {
1320 m += _stride[i] * sample_size(i).height;
1343 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1345 auto mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1346 size_t size = mem->size + length;
1349 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1351 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1355 throw EncodeError (N_("could not allocate memory for PNG"));
1358 memcpy (mem->data + mem->size, data, length);
1359 mem->size += length;
1363 png_flush (png_structp)
1369 png_error_fn (png_structp png_ptr, char const * message)
1371 reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1375 Image::png_error (char const * message)
1377 throw EncodeError (String::compose ("Error during PNG write: %1", message));
1381 Image::as_png () const
1383 DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1384 DCPOMATIC_ASSERT (planes() == 1);
1385 if (pixel_format() != AV_PIX_FMT_RGBA) {
1386 return convert_pixel_format(dcp::YUVToRGB::REC709, AV_PIX_FMT_RGBA, true, false)->as_png();
1389 /* error handling? */
1390 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1392 throw EncodeError (N_("could not create PNG write struct"));
1397 png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1399 png_infop info_ptr = png_create_info_struct(png_ptr);
1401 png_destroy_write_struct (&png_ptr, &info_ptr);
1402 throw EncodeError (N_("could not create PNG info struct"));
1405 png_set_IHDR (png_ptr, info_ptr, size().width, size().height, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1407 png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1408 for (int i = 0; i < size().height; ++i) {
1409 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1412 png_write_info (png_ptr, info_ptr);
1413 png_write_image (png_ptr, row_pointers);
1414 png_write_end (png_ptr, info_ptr);
1416 png_destroy_write_struct (&png_ptr, &info_ptr);
1417 png_free (png_ptr, row_pointers);
1419 return dcp::ArrayData (state.data, state.size);
1424 Image::video_range_to_full_range ()
1426 switch (_pixel_format) {
1427 case AV_PIX_FMT_RGB24:
1429 float const factor = 256.0 / 219.0;
1430 uint8_t* p = data()[0];
1431 int const lines = sample_size(0).height;
1432 for (int y = 0; y < lines; ++y) {
1434 for (int x = 0; x < line_size()[0]; ++x) {
1435 *q = int((*q - 16) * factor);
1442 case AV_PIX_FMT_GBRP12LE:
1444 float const factor = 4096.0 / 3504.0;
1445 for (int c = 0; c < 3; ++c) {
1446 uint16_t* p = reinterpret_cast<uint16_t*>(data()[c]);
1447 int const lines = sample_size(c).height;
1448 for (int y = 0; y < lines; ++y) {
1450 int const line_size_pixels = line_size()[c] / 2;
1451 for (int x = 0; x < line_size_pixels; ++x) {
1452 *q = int((*q - 256) * factor);
1460 throw PixelFormatError ("video_range_to_full_range()", _pixel_format);