2 Copyright (C) 2012-2016 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/>.
21 /** @file src/image.cc
22 * @brief A class to describe a video image.
26 #include "exceptions.h"
30 #include "compose.hpp"
31 #include "dcpomatic_socket.h"
32 #include <dcp/rgb_xyz.h>
33 #include <dcp/transfer_function.h>
35 #include <libswscale/swscale.h>
36 #include <libavutil/pixfmt.h>
37 #include <libavutil/pixdesc.h>
38 #include <libavutil/frame.h>
41 #if HAVE_VALGRIND_MEMCHECK_H
42 #include <valgrind/memcheck.h>
54 using std::runtime_error;
55 using boost::shared_ptr;
59 Image::vertical_factor (int n) const
65 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
67 throw PixelFormatError ("line_factor()", _pixel_format);
70 return pow (2.0f, d->log2_chroma_h);
74 Image::horizontal_factor (int n) const
80 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
82 throw PixelFormatError ("sample_size()", _pixel_format);
85 return pow (2.0f, d->log2_chroma_w);
88 /** @param n Component index.
89 * @return Number of samples (i.e. pixels, unless sub-sampled) in each direction for this component.
92 Image::sample_size (int n) const
95 lrint (ceil (static_cast<double>(size().width) / horizontal_factor (n))),
96 lrint (ceil (static_cast<double>(size().height) / vertical_factor (n)))
100 /** @return Number of planes */
102 Image::planes () const
104 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
106 throw PixelFormatError ("planes()", _pixel_format);
109 if (_pixel_format == AV_PIX_FMT_PAL8) {
113 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
117 return d->nb_components;
120 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size'.
121 * @param crop Amount to crop by.
122 * @param inter_size Size to scale the cropped image to.
123 * @param out_size Size of output frame; if this is larger than inter_size there will be black padding.
124 * @param yuv_to_rgb YUV to RGB transformation to use, if required.
125 * @param out_format Output pixel format.
126 * @param out_aligned true to make the output image aligned.
127 * @param fast Try to be fast at the possible expense of quality; at present this means using
128 * fast bilinear rather than bicubic scaling.
131 Image::crop_scale_window (
132 Crop crop, dcp::Size inter_size, dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast
135 /* Empirical testing suggests that sws_scale() will crash if
136 the input image is not aligned.
138 DCPOMATIC_ASSERT (aligned ());
140 DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
141 DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
143 shared_ptr<Image> out (new Image(out_format, out_size, out_aligned));
146 /* Size of the image after any crop */
147 dcp::Size const cropped_size = crop.apply (size ());
149 /* Scale context for a scale from cropped_size to inter_size */
150 struct SwsContext* scale_context = sws_getContext (
151 cropped_size.width, cropped_size.height, pixel_format(),
152 inter_size.width, inter_size.height, out_format,
153 fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
156 if (!scale_context) {
157 throw runtime_error (N_("Could not allocate SwsContext"));
160 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
161 int const lut[dcp::YUV_TO_RGB_COUNT] = {
166 /* The 3rd parameter here is:
167 0 -> source range MPEG (i.e. "video", 16-235)
168 1 -> source range JPEG (i.e. "full", 0-255)
170 0 -> destination range MPEG (i.e. "video", 16-235)
171 1 -> destination range JPEG (i.e. "full", 0-255)
173 But remember: sws_setColorspaceDetails ignores
174 these parameters unless the image isYUV or isGray
175 (if it's neither, it uses video range for source
178 sws_setColorspaceDetails (
180 sws_getCoefficients (lut[yuv_to_rgb]), 0,
181 sws_getCoefficients (lut[yuv_to_rgb]), 0,
185 AVPixFmtDescriptor const * in_desc = av_pix_fmt_desc_get (_pixel_format);
187 throw PixelFormatError ("crop_scale_window()", _pixel_format);
190 /* Prepare input data pointers with crop */
191 uint8_t* scale_in_data[planes()];
192 for (int c = 0; c < planes(); ++c) {
193 /* To work out the crop in bytes, start by multiplying
194 the crop by the (average) bytes per pixel. Then
195 round down so that we don't crop a subsampled pixel until
196 we've cropped all of its Y-channel pixels.
198 int const x = lrintf (bytes_per_pixel(c) * crop.left) & ~ ((int) in_desc->log2_chroma_w);
199 scale_in_data[c] = data()[c] + x + stride()[c] * (crop.top / vertical_factor(c));
202 /* Corner of the image within out_size */
203 Position<int> const corner ((out_size.width - inter_size.width) / 2, (out_size.height - inter_size.height) / 2);
205 AVPixFmtDescriptor const * out_desc = av_pix_fmt_desc_get (out_format);
207 throw PixelFormatError ("crop_scale_window()", out_format);
210 uint8_t* scale_out_data[out->planes()];
211 for (int c = 0; c < out->planes(); ++c) {
212 /* See the note in the crop loop above */
213 int const x = lrintf (out->bytes_per_pixel(c) * corner.x) & ~ ((int) out_desc->log2_chroma_w);
214 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
219 scale_in_data, stride(),
220 0, cropped_size.height,
221 scale_out_data, out->stride()
224 sws_freeContext (scale_context);
226 if (crop != Crop() && cropped_size == inter_size && _pixel_format == out_format) {
227 /* We are cropping without any scaling or pixel format conversion, so FFmpeg may have left some
228 data behind in our image. Clear it out. It may get to the point where we should just stop
229 trying to be clever with cropping.
231 out->make_part_black (corner.x + cropped_size.width, out_size.width - cropped_size.width);
238 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
240 return scale(size(), yuv_to_rgb, out_format, out_aligned, fast);
243 /** @param out_size Size to scale to.
244 * @param yuv_to_rgb YUVToRGB transform transform to use, if required.
245 * @param out_format Output pixel format.
246 * @param out_aligned true to make an aligned output image.
247 * @param fast Try to be fast at the possible expense of quality; at present this means using
248 * fast bilinear rather than bicubic scaling.
251 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
253 /* Empirical testing suggests that sws_scale() will crash if
254 the input image is not aligned.
256 DCPOMATIC_ASSERT (aligned ());
258 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
260 struct SwsContext* scale_context = sws_getContext (
261 size().width, size().height, pixel_format(),
262 out_size.width, out_size.height, out_format,
263 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
266 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
267 int const lut[dcp::YUV_TO_RGB_COUNT] = {
272 /* The 3rd parameter here is:
273 0 -> source range MPEG (i.e. "video", 16-235)
274 1 -> source range JPEG (i.e. "full", 0-255)
276 0 -> destination range MPEG (i.e. "video", 16-235)
277 1 -> destination range JPEG (i.e. "full", 0-255)
279 But remember: sws_setColorspaceDetails ignores
280 these parameters unless the image isYUV or isGray
281 (if it's neither, it uses video range for source
284 sws_setColorspaceDetails (
286 sws_getCoefficients (lut[yuv_to_rgb]), 0,
287 sws_getCoefficients (lut[yuv_to_rgb]), 0,
295 scaled->data(), scaled->stride()
298 sws_freeContext (scale_context);
303 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
305 Image::yuv_16_black (uint16_t v, bool alpha)
307 memset (data()[0], 0, sample_size(0).height * stride()[0]);
308 for (int i = 1; i < 3; ++i) {
309 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
310 int const lines = sample_size(i).height;
311 for (int y = 0; y < lines; ++y) {
312 /* We divide by 2 here because we are writing 2 bytes at a time */
313 for (int x = 0; x < line_size()[i] / 2; ++x) {
316 p += stride()[i] / 2;
321 memset (data()[3], 0, sample_size(3).height * stride()[3]);
326 Image::swap_16 (uint16_t v)
328 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
332 Image::make_part_black (int x, int w)
334 switch (_pixel_format) {
335 case AV_PIX_FMT_RGB24:
336 case AV_PIX_FMT_ARGB:
337 case AV_PIX_FMT_RGBA:
338 case AV_PIX_FMT_ABGR:
339 case AV_PIX_FMT_BGRA:
340 case AV_PIX_FMT_RGB555LE:
341 case AV_PIX_FMT_RGB48LE:
342 case AV_PIX_FMT_RGB48BE:
343 case AV_PIX_FMT_XYZ12LE:
345 int const h = sample_size(0).height;
346 int const bpp = bytes_per_pixel(0);
347 int const s = stride()[0];
348 uint8_t* p = data()[0];
349 for (int y = 0; y < h; y++) {
350 memset (p + x * bpp, 0, w * bpp);
357 throw PixelFormatError ("make_part_black()", _pixel_format);
364 /* U/V black value for 8-bit colour */
365 static uint8_t const eight_bit_uv = (1 << 7) - 1;
366 /* U/V black value for 9-bit colour */
367 static uint16_t const nine_bit_uv = (1 << 8) - 1;
368 /* U/V black value for 10-bit colour */
369 static uint16_t const ten_bit_uv = (1 << 9) - 1;
370 /* U/V black value for 16-bit colour */
371 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
373 switch (_pixel_format) {
374 case AV_PIX_FMT_YUV420P:
375 case AV_PIX_FMT_YUV422P:
376 case AV_PIX_FMT_YUV444P:
377 case AV_PIX_FMT_YUV411P:
378 memset (data()[0], 0, sample_size(0).height * stride()[0]);
379 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
380 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
383 case AV_PIX_FMT_YUVJ420P:
384 case AV_PIX_FMT_YUVJ422P:
385 case AV_PIX_FMT_YUVJ444P:
386 memset (data()[0], 0, sample_size(0).height * stride()[0]);
387 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
388 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
391 case AV_PIX_FMT_YUV422P9LE:
392 case AV_PIX_FMT_YUV444P9LE:
393 yuv_16_black (nine_bit_uv, false);
396 case AV_PIX_FMT_YUV422P9BE:
397 case AV_PIX_FMT_YUV444P9BE:
398 yuv_16_black (swap_16 (nine_bit_uv), false);
401 case AV_PIX_FMT_YUV422P10LE:
402 case AV_PIX_FMT_YUV444P10LE:
403 yuv_16_black (ten_bit_uv, false);
406 case AV_PIX_FMT_YUV422P16LE:
407 case AV_PIX_FMT_YUV444P16LE:
408 yuv_16_black (sixteen_bit_uv, false);
411 case AV_PIX_FMT_YUV444P10BE:
412 case AV_PIX_FMT_YUV422P10BE:
413 yuv_16_black (swap_16 (ten_bit_uv), false);
416 case AV_PIX_FMT_YUVA420P9BE:
417 case AV_PIX_FMT_YUVA422P9BE:
418 case AV_PIX_FMT_YUVA444P9BE:
419 yuv_16_black (swap_16 (nine_bit_uv), true);
422 case AV_PIX_FMT_YUVA420P9LE:
423 case AV_PIX_FMT_YUVA422P9LE:
424 case AV_PIX_FMT_YUVA444P9LE:
425 yuv_16_black (nine_bit_uv, true);
428 case AV_PIX_FMT_YUVA420P10BE:
429 case AV_PIX_FMT_YUVA422P10BE:
430 case AV_PIX_FMT_YUVA444P10BE:
431 yuv_16_black (swap_16 (ten_bit_uv), true);
434 case AV_PIX_FMT_YUVA420P10LE:
435 case AV_PIX_FMT_YUVA422P10LE:
436 case AV_PIX_FMT_YUVA444P10LE:
437 yuv_16_black (ten_bit_uv, true);
440 case AV_PIX_FMT_YUVA420P16BE:
441 case AV_PIX_FMT_YUVA422P16BE:
442 case AV_PIX_FMT_YUVA444P16BE:
443 yuv_16_black (swap_16 (sixteen_bit_uv), true);
446 case AV_PIX_FMT_YUVA420P16LE:
447 case AV_PIX_FMT_YUVA422P16LE:
448 case AV_PIX_FMT_YUVA444P16LE:
449 yuv_16_black (sixteen_bit_uv, true);
452 case AV_PIX_FMT_RGB24:
453 case AV_PIX_FMT_ARGB:
454 case AV_PIX_FMT_RGBA:
455 case AV_PIX_FMT_ABGR:
456 case AV_PIX_FMT_BGRA:
457 case AV_PIX_FMT_RGB555LE:
458 case AV_PIX_FMT_RGB48LE:
459 case AV_PIX_FMT_RGB48BE:
460 case AV_PIX_FMT_XYZ12LE:
461 memset (data()[0], 0, sample_size(0).height * stride()[0]);
464 case AV_PIX_FMT_UYVY422:
466 int const Y = sample_size(0).height;
467 int const X = line_size()[0];
468 uint8_t* p = data()[0];
469 for (int y = 0; y < Y; ++y) {
470 for (int x = 0; x < X / 4; ++x) {
471 *p++ = eight_bit_uv; // Cb
473 *p++ = eight_bit_uv; // Cr
481 throw PixelFormatError ("make_black()", _pixel_format);
486 Image::make_transparent ()
488 if (_pixel_format != AV_PIX_FMT_BGRA && _pixel_format != AV_PIX_FMT_RGBA) {
489 throw PixelFormatError ("make_transparent()", _pixel_format);
492 memset (data()[0], 0, sample_size(0).height * stride()[0]);
496 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
498 /* We're blending RGBA or BGRA images */
499 DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA || other->pixel_format() == AV_PIX_FMT_RGBA);
500 int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
501 int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
503 int const other_bpp = 4;
505 int start_tx = position.x;
509 start_ox = -start_tx;
513 int start_ty = position.y;
517 start_oy = -start_ty;
521 switch (_pixel_format) {
522 case AV_PIX_FMT_RGB24:
524 /* Going onto RGB24. First byte is red, second green, third blue */
525 int const this_bpp = 3;
526 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
527 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
528 uint8_t* op = other->data()[0] + oy * other->stride()[0];
529 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
530 float const alpha = float (op[3]) / 255;
531 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
532 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
533 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
541 case AV_PIX_FMT_BGRA:
543 int const this_bpp = 4;
544 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
545 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
546 uint8_t* op = other->data()[0] + oy * other->stride()[0];
547 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
548 float const alpha = float (op[3]) / 255;
549 tp[0] = op[blue] * alpha + tp[0] * (1 - alpha);
550 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
551 tp[2] = op[red] * alpha + tp[2] * (1 - alpha);
552 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
560 case AV_PIX_FMT_RGBA:
562 int const this_bpp = 4;
563 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
564 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
565 uint8_t* op = other->data()[0] + oy * other->stride()[0];
566 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
567 float const alpha = float (op[3]) / 255;
568 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
569 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
570 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
571 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
579 case AV_PIX_FMT_RGB48LE:
581 int const this_bpp = 6;
582 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
583 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
584 uint8_t* op = other->data()[0] + oy * other->stride()[0];
585 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
586 float const alpha = float (op[3]) / 255;
587 /* Blend high bytes */
588 tp[1] = op[red] * alpha + tp[1] * (1 - alpha);
589 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
590 tp[5] = op[blue] * alpha + tp[5] * (1 - alpha);
598 case AV_PIX_FMT_XYZ12LE:
600 dcp::ColourConversion conv = dcp::ColourConversion::srgb_to_xyz();
601 double fast_matrix[9];
602 dcp::combined_rgb_to_xyz (conv, fast_matrix);
603 double const * lut_in = conv.in()->lut (8, false);
604 double const * lut_out = conv.out()->lut (16, true);
605 int const this_bpp = 6;
606 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
607 uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
608 uint8_t* op = other->data()[0] + oy * other->stride()[0];
609 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
610 float const alpha = float (op[3]) / 255;
612 /* Convert sRGB to XYZ; op is BGRA. First, input gamma LUT */
613 double const r = lut_in[op[red]];
614 double const g = lut_in[op[1]];
615 double const b = lut_in[op[blue]];
617 /* RGB to XYZ, including Bradford transform and DCI companding */
618 double const x = max (0.0, min (65535.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
619 double const y = max (0.0, min (65535.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
620 double const z = max (0.0, min (65535.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
622 /* Out gamma LUT and blend */
623 tp[0] = lrint(lut_out[lrint(x)] * 65535) * alpha + tp[0] * (1 - alpha);
624 tp[1] = lrint(lut_out[lrint(y)] * 65535) * alpha + tp[1] * (1 - alpha);
625 tp[2] = lrint(lut_out[lrint(z)] * 65535) * alpha + tp[2] * (1 - alpha);
633 case AV_PIX_FMT_YUV420P:
635 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
636 dcp::Size const ts = size();
637 dcp::Size const os = yuv->size();
638 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
639 int const hty = ty / 2;
640 int const hoy = oy / 2;
641 uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
642 uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
643 uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
644 uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
645 uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
646 uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
647 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
648 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
649 float const a = float(alpha[3]) / 255;
650 *tY = *oY * a + *tY * (1 - a);
651 *tU = *oU * a + *tU * (1 - a);
652 *tV = *oV * a + *tV * (1 - a);
668 case AV_PIX_FMT_YUV420P10:
670 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
671 dcp::Size const ts = size();
672 dcp::Size const os = yuv->size();
673 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
674 int const hty = ty / 2;
675 int const hoy = oy / 2;
676 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
677 uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
678 uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
679 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
680 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
681 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
682 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
683 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
684 float const a = float(alpha[3]) / 255;
685 *tY = *oY * a + *tY * (1 - a);
686 *tU = *oU * a + *tU * (1 - a);
687 *tV = *oV * a + *tV * (1 - a);
703 case AV_PIX_FMT_YUV422P10LE:
705 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
706 dcp::Size const ts = size();
707 dcp::Size const os = yuv->size();
708 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
709 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
710 uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
711 uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
712 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
713 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
714 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
715 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
716 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
717 float const a = float(alpha[3]) / 255;
718 *tY = *oY * a + *tY * (1 - a);
719 *tU = *oU * a + *tU * (1 - a);
720 *tV = *oV * a + *tV * (1 - a);
737 throw PixelFormatError ("alpha_blend()", _pixel_format);
742 Image::copy (shared_ptr<const Image> other, Position<int> position)
744 /* Only implemented for RGB24 onto RGB24 so far */
745 DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
746 DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
748 int const N = min (position.x + other->size().width, size().width) - position.x;
749 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
750 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
751 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
752 memcpy (tp, op, N * 3);
757 Image::read_from_socket (shared_ptr<Socket> socket)
759 for (int i = 0; i < planes(); ++i) {
760 uint8_t* p = data()[i];
761 int const lines = sample_size(i).height;
762 for (int y = 0; y < lines; ++y) {
763 socket->read (p, line_size()[i]);
770 Image::write_to_socket (shared_ptr<Socket> socket) const
772 for (int i = 0; i < planes(); ++i) {
773 uint8_t* p = data()[i];
774 int const lines = sample_size(i).height;
775 for (int y = 0; y < lines; ++y) {
776 socket->write (p, line_size()[i]);
783 Image::bytes_per_pixel (int c) const
785 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
787 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
794 float bpp[4] = { 0, 0, 0, 0 };
796 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
797 bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
798 if (d->nb_components > 1) {
799 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
801 if (d->nb_components > 2) {
802 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
804 if (d->nb_components > 3) {
805 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
808 bpp[0] = floor ((d->comp[0].depth + 7) / 8);
809 if (d->nb_components > 1) {
810 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
812 if (d->nb_components > 2) {
813 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
815 if (d->nb_components > 3) {
816 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
820 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
821 /* Not planar; sum them up */
822 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
828 /** Construct a Image of a given size and format, allocating memory
831 * @param p Pixel format.
832 * @param s Size in pixels.
833 * @param aligned true to make each row of this image aligned to a 32-byte boundary.
835 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned)
846 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
847 _data[0] = _data[1] = _data[2] = _data[3] = 0;
849 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
850 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
852 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
853 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
855 for (int i = 0; i < planes(); ++i) {
856 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
857 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
859 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
860 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
861 Hence on the last pixel of the last line it reads over the end of
862 the actual data by 1 byte. If the width of an image is a multiple
863 of the stride alignment there will be no padding at the end of image lines.
864 OS X crashes on this illegal read, though other operating systems don't
865 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
866 for that instruction to read safely.
868 Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
869 over-reads by more then _avx. I can't follow the code to work out how much,
870 so I'll just over-allocate by 32 bytes and have done with it. Empirical
871 testing suggests that it works.
873 In addition to these concerns, we may read/write as much as a whole extra line
874 at the end of each plane in cases where we are messing with offsets in order to
875 do pad or crop. To solve this we over-allocate by an extra _stride[i] bytes.
877 As an example: we may write to images starting at an offset so we get some padding.
878 Hence we want to write in the following pattern:
880 block start write start line end
881 |..(padding)..|<------line-size------------->|..(padding)..|
882 |..(padding)..|<------line-size------------->|..(padding)..|
883 |..(padding)..|<------line-size------------->|..(padding)..|
885 where line-size is of the smaller (inter_size) image and the full padded line length is that of
886 out_size. To get things to work we have to tell FFmpeg that the stride is that of out_size.
887 However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
888 specified *stride*. This does not matter until we get to the last line:
890 block start write start line end
891 |..(padding)..|<------line-size------------->|XXXwrittenXXX|
892 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
893 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
896 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * (sample_size(i).height + 1) + 32);
897 #if HAVE_VALGRIND_MEMCHECK_H
898 /* The data between the end of the line size and the stride is undefined but processed by
899 libswscale, causing lots of valgrind errors. Mark it all defined to quell these errors.
901 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * (sample_size(i).height + 1) + 32);
906 Image::Image (Image const & other)
907 : boost::enable_shared_from_this<Image>(other)
908 , _size (other._size)
909 , _pixel_format (other._pixel_format)
910 , _aligned (other._aligned)
914 for (int i = 0; i < planes(); ++i) {
915 uint8_t* p = _data[i];
916 uint8_t* q = other._data[i];
917 int const lines = sample_size(i).height;
918 for (int j = 0; j < lines; ++j) {
919 memcpy (p, q, _line_size[i]);
921 q += other.stride()[i];
926 Image::Image (AVFrame* frame)
927 : _size (frame->width, frame->height)
928 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
933 for (int i = 0; i < planes(); ++i) {
934 uint8_t* p = _data[i];
935 uint8_t* q = frame->data[i];
936 int const lines = sample_size(i).height;
937 for (int j = 0; j < lines; ++j) {
938 memcpy (p, q, _line_size[i]);
940 /* AVFrame's linesize is what we call `stride' */
941 q += frame->linesize[i];
946 Image::Image (shared_ptr<const Image> other, bool aligned)
947 : _size (other->_size)
948 , _pixel_format (other->_pixel_format)
953 for (int i = 0; i < planes(); ++i) {
954 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
955 uint8_t* p = _data[i];
956 uint8_t* q = other->data()[i];
957 int const lines = sample_size(i).height;
958 for (int j = 0; j < lines; ++j) {
959 memcpy (p, q, line_size()[i]);
961 q += other->stride()[i];
967 Image::operator= (Image const & other)
969 if (this == &other) {
979 Image::swap (Image & other)
981 std::swap (_size, other._size);
982 std::swap (_pixel_format, other._pixel_format);
984 for (int i = 0; i < 4; ++i) {
985 std::swap (_data[i], other._data[i]);
986 std::swap (_line_size[i], other._line_size[i]);
987 std::swap (_stride[i], other._stride[i]);
990 std::swap (_aligned, other._aligned);
993 /** Destroy a Image */
996 for (int i = 0; i < planes(); ++i) {
1001 av_free (_line_size);
1006 Image::data () const
1012 Image::line_size () const
1018 Image::stride () const
1024 Image::size () const
1030 Image::aligned () const
1036 merge (list<PositionImage> images)
1038 if (images.empty ()) {
1039 return PositionImage ();
1042 if (images.size() == 1) {
1043 return images.front ();
1046 dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1047 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1048 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
1051 shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
1052 merged->make_transparent ();
1053 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1054 merged->alpha_blend (i->image, i->position - all.position());
1057 return PositionImage (merged, all.position ());
1061 operator== (Image const & a, Image const & b)
1063 if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1067 for (int c = 0; c < a.planes(); ++c) {
1068 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]) {
1072 uint8_t* p = a.data()[c];
1073 uint8_t* q = b.data()[c];
1074 int const lines = a.sample_size(c).height;
1075 for (int y = 0; y < lines; ++y) {
1076 if (memcmp (p, q, a.line_size()[c]) != 0) {
1089 * @param f Amount to fade by; 0 is black, 1 is no fade.
1092 Image::fade (float f)
1094 /* U/V black value for 8-bit colour */
1095 static int const eight_bit_uv = (1 << 7) - 1;
1096 /* U/V black value for 10-bit colour */
1097 static uint16_t const ten_bit_uv = (1 << 9) - 1;
1099 switch (_pixel_format) {
1100 case AV_PIX_FMT_YUV420P:
1103 uint8_t* p = data()[0];
1104 int const lines = sample_size(0).height;
1105 for (int y = 0; y < lines; ++y) {
1107 for (int x = 0; x < line_size()[0]; ++x) {
1108 *q = int(float(*q) * f);
1115 for (int c = 1; c < 3; ++c) {
1116 uint8_t* p = data()[c];
1117 int const lines = sample_size(c).height;
1118 for (int y = 0; y < lines; ++y) {
1120 for (int x = 0; x < line_size()[c]; ++x) {
1121 *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1131 case AV_PIX_FMT_RGB24:
1134 uint8_t* p = data()[0];
1135 int const lines = sample_size(0).height;
1136 for (int y = 0; y < lines; ++y) {
1138 for (int x = 0; x < line_size()[0]; ++x) {
1139 *q = int (float (*q) * f);
1147 case AV_PIX_FMT_XYZ12LE:
1148 case AV_PIX_FMT_RGB48LE:
1149 /* 16-bit little-endian */
1150 for (int c = 0; c < 3; ++c) {
1151 int const stride_pixels = stride()[c] / 2;
1152 int const line_size_pixels = line_size()[c] / 2;
1153 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1154 int const lines = sample_size(c).height;
1155 for (int y = 0; y < lines; ++y) {
1157 for (int x = 0; x < line_size_pixels; ++x) {
1158 *q = int (float (*q) * f);
1166 case AV_PIX_FMT_YUV422P10LE:
1170 int const stride_pixels = stride()[0] / 2;
1171 int const line_size_pixels = line_size()[0] / 2;
1172 uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1173 int const lines = sample_size(0).height;
1174 for (int y = 0; y < lines; ++y) {
1176 for (int x = 0; x < line_size_pixels; ++x) {
1177 *q = int(float(*q) * f);
1185 for (int c = 1; c < 3; ++c) {
1186 int const stride_pixels = stride()[c] / 2;
1187 int const line_size_pixels = line_size()[c] / 2;
1188 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1189 int const lines = sample_size(c).height;
1190 for (int y = 0; y < lines; ++y) {
1192 for (int x = 0; x < line_size_pixels; ++x) {
1193 *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1204 throw PixelFormatError ("fade()", _pixel_format);
1208 shared_ptr<const Image>
1209 Image::ensure_aligned (shared_ptr<const Image> image)
1211 if (image->aligned()) {
1215 return shared_ptr<Image> (new Image (image, true));
1219 Image::memory_used () const
1222 for (int i = 0; i < planes(); ++i) {
1223 m += _stride[i] * sample_size(i).height;
1246 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1248 Memory* mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1249 size_t size = mem->size + length;
1252 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1254 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1258 throw EncodeError (N_("could not allocate memory for PNG"));
1261 memcpy (mem->data + mem->size, data, length);
1262 mem->size += length;
1266 png_flush (png_structp)
1272 png_error_fn (png_structp png_ptr, char const * message)
1274 reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1278 Image::png_error (char const * message)
1280 throw EncodeError (String::compose ("Error during PNG write: %1", message));
1284 Image::as_png () const
1286 DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1287 DCPOMATIC_ASSERT (planes() == 1);
1288 if (pixel_format() != AV_PIX_FMT_RGBA) {
1289 return convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGBA, true, false)->as_png();
1292 /* error handling? */
1293 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1295 throw EncodeError (N_("could not create PNG write struct"));
1300 png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1302 png_infop info_ptr = png_create_info_struct(png_ptr);
1304 png_destroy_write_struct (&png_ptr, &info_ptr);
1305 throw EncodeError (N_("could not create PNG info struct"));
1308 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);
1310 png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1311 for (int i = 0; i < size().height; ++i) {
1312 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1315 png_write_info (png_ptr, info_ptr);
1316 png_write_image (png_ptr, row_pointers);
1317 png_write_end (png_ptr, info_ptr);
1319 png_destroy_write_struct (&png_ptr, &info_ptr);
1320 png_free (png_ptr, row_pointers);
1322 return dcp::Data (state.data, state.size);