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 /** The memory alignment, in bytes, used for each row of an image if aligment is requested */
64 Image::vertical_factor (int n) const
70 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
72 throw PixelFormatError ("line_factor()", _pixel_format);
75 return lrintf(powf(2.0f, d->log2_chroma_h));
79 Image::horizontal_factor (int n) const
85 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
87 throw PixelFormatError ("sample_size()", _pixel_format);
90 return lrintf(powf(2.0f, d->log2_chroma_w));
93 /** @param n Component index.
94 * @return Number of samples (i.e. pixels, unless sub-sampled) in each direction for this component.
97 Image::sample_size (int n) const
100 lrint (ceil (static_cast<double>(size().width) / horizontal_factor (n))),
101 lrint (ceil (static_cast<double>(size().height) / vertical_factor (n)))
105 /** @return Number of planes */
107 Image::planes () const
109 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
111 throw PixelFormatError ("planes()", _pixel_format);
114 if (_pixel_format == AV_PIX_FMT_PAL8) {
118 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
122 return d->nb_components;
125 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size'.
126 * @param crop Amount to crop by.
127 * @param inter_size Size to scale the cropped image to.
128 * @param out_size Size of output frame; if this is larger than inter_size there will be black padding.
129 * @param yuv_to_rgb YUV to RGB transformation to use, if required.
130 * @param out_format Output pixel format.
131 * @param out_aligned true to make the output image aligned.
132 * @param fast Try to be fast at the possible expense of quality; at present this means using
133 * fast bilinear rather than bicubic scaling.
136 Image::crop_scale_window (
137 Crop crop, dcp::Size inter_size, dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast
140 /* Empirical testing suggests that sws_scale() will crash if
141 the input image is not aligned.
143 DCPOMATIC_ASSERT (aligned ());
145 DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
146 DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
148 shared_ptr<Image> out (new Image(out_format, out_size, out_aligned));
151 /* Size of the image after any crop */
152 dcp::Size const cropped_size = crop.apply (size ());
154 /* Scale context for a scale from cropped_size to inter_size */
155 struct SwsContext* scale_context = sws_getContext (
156 cropped_size.width, cropped_size.height, pixel_format(),
157 inter_size.width, inter_size.height, out_format,
158 fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
161 if (!scale_context) {
162 throw runtime_error (N_("Could not allocate SwsContext"));
165 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
166 int const lut[dcp::YUV_TO_RGB_COUNT] = {
171 /* The 3rd parameter here is:
172 0 -> source range MPEG (i.e. "video", 16-235)
173 1 -> source range JPEG (i.e. "full", 0-255)
175 0 -> destination range MPEG (i.e. "video", 16-235)
176 1 -> destination range JPEG (i.e. "full", 0-255)
178 But remember: sws_setColorspaceDetails ignores
179 these parameters unless the image isYUV or isGray
180 (if it's neither, it uses video range for source
183 sws_setColorspaceDetails (
185 sws_getCoefficients (lut[yuv_to_rgb]), 0,
186 sws_getCoefficients (lut[yuv_to_rgb]), 0,
190 AVPixFmtDescriptor const * in_desc = av_pix_fmt_desc_get (_pixel_format);
192 throw PixelFormatError ("crop_scale_window()", _pixel_format);
195 /* Prepare input data pointers with crop */
196 uint8_t* scale_in_data[planes()];
197 for (int c = 0; c < planes(); ++c) {
198 /* To work out the crop in bytes, start by multiplying
199 the crop by the (average) bytes per pixel. Then
200 round down so that we don't crop a subsampled pixel until
201 we've cropped all of its Y-channel pixels.
203 int const x = lrintf (bytes_per_pixel(c) * crop.left) & ~ ((int) in_desc->log2_chroma_w);
204 scale_in_data[c] = data()[c] + x + stride()[c] * (crop.top / vertical_factor(c));
207 /* Corner of the image within out_size */
208 Position<int> const corner ((out_size.width - inter_size.width) / 2, (out_size.height - inter_size.height) / 2);
210 AVPixFmtDescriptor const * out_desc = av_pix_fmt_desc_get (out_format);
212 throw PixelFormatError ("crop_scale_window()", out_format);
215 uint8_t* scale_out_data[out->planes()];
216 for (int c = 0; c < out->planes(); ++c) {
217 /* See the note in the crop loop above */
218 int const x = lrintf (out->bytes_per_pixel(c) * corner.x) & ~ ((int) out_desc->log2_chroma_w);
219 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
224 scale_in_data, stride(),
225 0, cropped_size.height,
226 scale_out_data, out->stride()
229 sws_freeContext (scale_context);
231 if (crop != Crop() && cropped_size == inter_size && _pixel_format == out_format) {
232 /* We are cropping without any scaling or pixel format conversion, so FFmpeg may have left some
233 data behind in our image. Clear it out. It may get to the point where we should just stop
234 trying to be clever with cropping.
236 out->make_part_black (corner.x + cropped_size.width, out_size.width - cropped_size.width);
243 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
245 return scale(size(), yuv_to_rgb, out_format, out_aligned, fast);
248 /** @param out_size Size to scale to.
249 * @param yuv_to_rgb YUVToRGB transform transform to use, if required.
250 * @param out_format Output pixel format.
251 * @param out_aligned true to make an aligned output image.
252 * @param fast Try to be fast at the possible expense of quality; at present this means using
253 * fast bilinear rather than bicubic scaling.
256 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
258 /* Empirical testing suggests that sws_scale() will crash if
259 the input image is not aligned.
261 DCPOMATIC_ASSERT (aligned ());
263 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
265 struct SwsContext* scale_context = sws_getContext (
266 size().width, size().height, pixel_format(),
267 out_size.width, out_size.height, out_format,
268 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
271 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
272 int const lut[dcp::YUV_TO_RGB_COUNT] = {
277 /* The 3rd parameter here is:
278 0 -> source range MPEG (i.e. "video", 16-235)
279 1 -> source range JPEG (i.e. "full", 0-255)
281 0 -> destination range MPEG (i.e. "video", 16-235)
282 1 -> destination range JPEG (i.e. "full", 0-255)
284 But remember: sws_setColorspaceDetails ignores
285 these parameters unless the image isYUV or isGray
286 (if it's neither, it uses video range for source
289 sws_setColorspaceDetails (
291 sws_getCoefficients (lut[yuv_to_rgb]), 0,
292 sws_getCoefficients (lut[yuv_to_rgb]), 0,
300 scaled->data(), scaled->stride()
303 sws_freeContext (scale_context);
308 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
310 Image::yuv_16_black (uint16_t v, bool alpha)
312 memset (data()[0], 0, sample_size(0).height * stride()[0]);
313 for (int i = 1; i < 3; ++i) {
314 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
315 int const lines = sample_size(i).height;
316 for (int y = 0; y < lines; ++y) {
317 /* We divide by 2 here because we are writing 2 bytes at a time */
318 for (int x = 0; x < line_size()[i] / 2; ++x) {
321 p += stride()[i] / 2;
326 memset (data()[3], 0, sample_size(3).height * stride()[3]);
331 Image::swap_16 (uint16_t v)
333 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
337 Image::make_part_black (int x, int w)
339 switch (_pixel_format) {
340 case AV_PIX_FMT_RGB24:
341 case AV_PIX_FMT_ARGB:
342 case AV_PIX_FMT_RGBA:
343 case AV_PIX_FMT_ABGR:
344 case AV_PIX_FMT_BGRA:
345 case AV_PIX_FMT_RGB555LE:
346 case AV_PIX_FMT_RGB48LE:
347 case AV_PIX_FMT_RGB48BE:
348 case AV_PIX_FMT_XYZ12LE:
350 int const h = sample_size(0).height;
351 int const bpp = bytes_per_pixel(0);
352 int const s = stride()[0];
353 uint8_t* p = data()[0];
354 for (int y = 0; y < h; y++) {
355 memset (p + x * bpp, 0, w * bpp);
362 throw PixelFormatError ("make_part_black()", _pixel_format);
369 /* U/V black value for 8-bit colour */
370 static uint8_t const eight_bit_uv = (1 << 7) - 1;
371 /* U/V black value for 9-bit colour */
372 static uint16_t const nine_bit_uv = (1 << 8) - 1;
373 /* U/V black value for 10-bit colour */
374 static uint16_t const ten_bit_uv = (1 << 9) - 1;
375 /* U/V black value for 16-bit colour */
376 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
378 switch (_pixel_format) {
379 case AV_PIX_FMT_YUV420P:
380 case AV_PIX_FMT_YUV422P:
381 case AV_PIX_FMT_YUV444P:
382 case AV_PIX_FMT_YUV411P:
383 memset (data()[0], 0, sample_size(0).height * stride()[0]);
384 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
385 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
388 case AV_PIX_FMT_YUVJ420P:
389 case AV_PIX_FMT_YUVJ422P:
390 case AV_PIX_FMT_YUVJ444P:
391 memset (data()[0], 0, sample_size(0).height * stride()[0]);
392 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
393 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
396 case AV_PIX_FMT_YUV422P9LE:
397 case AV_PIX_FMT_YUV444P9LE:
398 yuv_16_black (nine_bit_uv, false);
401 case AV_PIX_FMT_YUV422P9BE:
402 case AV_PIX_FMT_YUV444P9BE:
403 yuv_16_black (swap_16 (nine_bit_uv), false);
406 case AV_PIX_FMT_YUV422P10LE:
407 case AV_PIX_FMT_YUV444P10LE:
408 yuv_16_black (ten_bit_uv, false);
411 case AV_PIX_FMT_YUV422P16LE:
412 case AV_PIX_FMT_YUV444P16LE:
413 yuv_16_black (sixteen_bit_uv, false);
416 case AV_PIX_FMT_YUV444P10BE:
417 case AV_PIX_FMT_YUV422P10BE:
418 yuv_16_black (swap_16 (ten_bit_uv), false);
421 case AV_PIX_FMT_YUVA420P9BE:
422 case AV_PIX_FMT_YUVA422P9BE:
423 case AV_PIX_FMT_YUVA444P9BE:
424 yuv_16_black (swap_16 (nine_bit_uv), true);
427 case AV_PIX_FMT_YUVA420P9LE:
428 case AV_PIX_FMT_YUVA422P9LE:
429 case AV_PIX_FMT_YUVA444P9LE:
430 yuv_16_black (nine_bit_uv, true);
433 case AV_PIX_FMT_YUVA420P10BE:
434 case AV_PIX_FMT_YUVA422P10BE:
435 case AV_PIX_FMT_YUVA444P10BE:
436 yuv_16_black (swap_16 (ten_bit_uv), true);
439 case AV_PIX_FMT_YUVA420P10LE:
440 case AV_PIX_FMT_YUVA422P10LE:
441 case AV_PIX_FMT_YUVA444P10LE:
442 yuv_16_black (ten_bit_uv, true);
445 case AV_PIX_FMT_YUVA420P16BE:
446 case AV_PIX_FMT_YUVA422P16BE:
447 case AV_PIX_FMT_YUVA444P16BE:
448 yuv_16_black (swap_16 (sixteen_bit_uv), true);
451 case AV_PIX_FMT_YUVA420P16LE:
452 case AV_PIX_FMT_YUVA422P16LE:
453 case AV_PIX_FMT_YUVA444P16LE:
454 yuv_16_black (sixteen_bit_uv, true);
457 case AV_PIX_FMT_RGB24:
458 case AV_PIX_FMT_ARGB:
459 case AV_PIX_FMT_RGBA:
460 case AV_PIX_FMT_ABGR:
461 case AV_PIX_FMT_BGRA:
462 case AV_PIX_FMT_RGB555LE:
463 case AV_PIX_FMT_RGB48LE:
464 case AV_PIX_FMT_RGB48BE:
465 case AV_PIX_FMT_XYZ12LE:
466 memset (data()[0], 0, sample_size(0).height * stride()[0]);
469 case AV_PIX_FMT_UYVY422:
471 int const Y = sample_size(0).height;
472 int const X = line_size()[0];
473 uint8_t* p = data()[0];
474 for (int y = 0; y < Y; ++y) {
475 for (int x = 0; x < X / 4; ++x) {
476 *p++ = eight_bit_uv; // Cb
478 *p++ = eight_bit_uv; // Cr
486 throw PixelFormatError ("make_black()", _pixel_format);
491 Image::make_transparent ()
493 if (_pixel_format != AV_PIX_FMT_BGRA && _pixel_format != AV_PIX_FMT_RGBA) {
494 throw PixelFormatError ("make_transparent()", _pixel_format);
497 memset (data()[0], 0, sample_size(0).height * stride()[0]);
501 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
503 /* We're blending RGBA or BGRA images */
504 DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA || other->pixel_format() == AV_PIX_FMT_RGBA);
505 int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
506 int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
508 int const other_bpp = 4;
510 int start_tx = position.x;
514 start_ox = -start_tx;
518 int start_ty = position.y;
522 start_oy = -start_ty;
526 switch (_pixel_format) {
527 case AV_PIX_FMT_RGB24:
529 /* Going onto RGB24. First byte is red, second green, third blue */
530 int const this_bpp = 3;
531 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
532 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
533 uint8_t* op = other->data()[0] + oy * other->stride()[0];
534 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
535 float const alpha = float (op[3]) / 255;
536 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
537 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
538 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
546 case AV_PIX_FMT_BGRA:
548 int const this_bpp = 4;
549 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
550 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
551 uint8_t* op = other->data()[0] + oy * other->stride()[0];
552 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
553 float const alpha = float (op[3]) / 255;
554 tp[0] = op[blue] * alpha + tp[0] * (1 - alpha);
555 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
556 tp[2] = op[red] * alpha + tp[2] * (1 - alpha);
557 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
565 case AV_PIX_FMT_RGBA:
567 int const this_bpp = 4;
568 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
569 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
570 uint8_t* op = other->data()[0] + oy * other->stride()[0];
571 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
572 float const alpha = float (op[3]) / 255;
573 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
574 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
575 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
576 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
584 case AV_PIX_FMT_RGB48LE:
586 int const this_bpp = 6;
587 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
588 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
589 uint8_t* op = other->data()[0] + oy * other->stride()[0];
590 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
591 float const alpha = float (op[3]) / 255;
592 /* Blend high bytes */
593 tp[1] = op[red] * alpha + tp[1] * (1 - alpha);
594 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
595 tp[5] = op[blue] * alpha + tp[5] * (1 - alpha);
603 case AV_PIX_FMT_XYZ12LE:
605 dcp::ColourConversion conv = dcp::ColourConversion::srgb_to_xyz();
606 double fast_matrix[9];
607 dcp::combined_rgb_to_xyz (conv, fast_matrix);
608 double const * lut_in = conv.in()->lut (8, false);
609 double const * lut_out = conv.out()->lut (16, true);
610 int const this_bpp = 6;
611 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
612 uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
613 uint8_t* op = other->data()[0] + oy * other->stride()[0];
614 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
615 float const alpha = float (op[3]) / 255;
617 /* Convert sRGB to XYZ; op is BGRA. First, input gamma LUT */
618 double const r = lut_in[op[red]];
619 double const g = lut_in[op[1]];
620 double const b = lut_in[op[blue]];
622 /* RGB to XYZ, including Bradford transform and DCI companding */
623 double const x = max (0.0, min (65535.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
624 double const y = max (0.0, min (65535.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
625 double const z = max (0.0, min (65535.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
627 /* Out gamma LUT and blend */
628 tp[0] = lrint(lut_out[lrint(x)] * 65535) * alpha + tp[0] * (1 - alpha);
629 tp[1] = lrint(lut_out[lrint(y)] * 65535) * alpha + tp[1] * (1 - alpha);
630 tp[2] = lrint(lut_out[lrint(z)] * 65535) * alpha + tp[2] * (1 - alpha);
638 case AV_PIX_FMT_YUV420P:
640 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
641 dcp::Size const ts = size();
642 dcp::Size const os = yuv->size();
643 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
644 int const hty = ty / 2;
645 int const hoy = oy / 2;
646 uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
647 uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
648 uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
649 uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
650 uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
651 uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
652 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
653 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
654 float const a = float(alpha[3]) / 255;
655 *tY = *oY * a + *tY * (1 - a);
656 *tU = *oU * a + *tU * (1 - a);
657 *tV = *oV * a + *tV * (1 - a);
673 case AV_PIX_FMT_YUV420P10:
675 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
676 dcp::Size const ts = size();
677 dcp::Size const os = yuv->size();
678 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
679 int const hty = ty / 2;
680 int const hoy = oy / 2;
681 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
682 uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
683 uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
684 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
685 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
686 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
687 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
688 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
689 float const a = float(alpha[3]) / 255;
690 *tY = *oY * a + *tY * (1 - a);
691 *tU = *oU * a + *tU * (1 - a);
692 *tV = *oV * a + *tV * (1 - a);
708 case AV_PIX_FMT_YUV422P10LE:
710 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
711 dcp::Size const ts = size();
712 dcp::Size const os = yuv->size();
713 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
714 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
715 uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
716 uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
717 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
718 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
719 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
720 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
721 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
722 float const a = float(alpha[3]) / 255;
723 *tY = *oY * a + *tY * (1 - a);
724 *tU = *oU * a + *tU * (1 - a);
725 *tV = *oV * a + *tV * (1 - a);
742 throw PixelFormatError ("alpha_blend()", _pixel_format);
747 Image::copy (shared_ptr<const Image> other, Position<int> position)
749 /* Only implemented for RGB24 onto RGB24 so far */
750 DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
751 DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
753 int const N = min (position.x + other->size().width, size().width) - position.x;
754 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
755 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
756 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
757 memcpy (tp, op, N * 3);
762 Image::read_from_socket (shared_ptr<Socket> socket)
764 for (int i = 0; i < planes(); ++i) {
765 uint8_t* p = data()[i];
766 int const lines = sample_size(i).height;
767 for (int y = 0; y < lines; ++y) {
768 socket->read (p, line_size()[i]);
775 Image::write_to_socket (shared_ptr<Socket> socket) const
777 for (int i = 0; i < planes(); ++i) {
778 uint8_t* p = data()[i];
779 int const lines = sample_size(i).height;
780 for (int y = 0; y < lines; ++y) {
781 socket->write (p, line_size()[i]);
788 Image::bytes_per_pixel (int c) const
790 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
792 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
799 float bpp[4] = { 0, 0, 0, 0 };
801 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
802 bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
803 if (d->nb_components > 1) {
804 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
806 if (d->nb_components > 2) {
807 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
809 if (d->nb_components > 3) {
810 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
813 bpp[0] = floor ((d->comp[0].depth + 7) / 8);
814 if (d->nb_components > 1) {
815 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
817 if (d->nb_components > 2) {
818 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
820 if (d->nb_components > 3) {
821 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
825 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
826 /* Not planar; sum them up */
827 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
833 /** Construct a Image of a given size and format, allocating memory
836 * @param p Pixel format.
837 * @param s Size in pixels.
838 * @param aligned true to make each row of this image aligned to a ALIGNMENT-byte boundary.
840 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned)
851 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
852 _data[0] = _data[1] = _data[2] = _data[3] = 0;
854 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
855 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
857 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
858 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
860 for (int i = 0; i < planes(); ++i) {
861 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
862 _stride[i] = stride_round_up (i, _line_size, _aligned ? ALIGNMENT : 1);
864 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
865 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
866 Hence on the last pixel of the last line it reads over the end of
867 the actual data by 1 byte. If the width of an image is a multiple
868 of the stride alignment there will be no padding at the end of image lines.
869 OS X crashes on this illegal read, though other operating systems don't
870 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
871 for that instruction to read safely.
873 Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
874 over-reads by more then _avx. I can't follow the code to work out how much,
875 so I'll just over-allocate by ALIGNMENT bytes and have done with it. Empirical
876 testing suggests that it works.
878 In addition to these concerns, we may read/write as much as a whole extra line
879 at the end of each plane in cases where we are messing with offsets in order to
880 do pad or crop. To solve this we over-allocate by an extra _stride[i] bytes.
882 As an example: we may write to images starting at an offset so we get some padding.
883 Hence we want to write in the following pattern:
885 block start write start line end
886 |..(padding)..|<------line-size------------->|..(padding)..|
887 |..(padding)..|<------line-size------------->|..(padding)..|
888 |..(padding)..|<------line-size------------->|..(padding)..|
890 where line-size is of the smaller (inter_size) image and the full padded line length is that of
891 out_size. To get things to work we have to tell FFmpeg that the stride is that of out_size.
892 However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
893 specified *stride*. This does not matter until we get to the last line:
895 block start write start line end
896 |..(padding)..|<------line-size------------->|XXXwrittenXXX|
897 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
898 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
901 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
902 #if HAVE_VALGRIND_MEMCHECK_H
903 /* The data between the end of the line size and the stride is undefined but processed by
904 libswscale, causing lots of valgrind errors. Mark it all defined to quell these errors.
906 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
911 Image::Image (Image const & other)
912 : boost::enable_shared_from_this<Image>(other)
913 , _size (other._size)
914 , _pixel_format (other._pixel_format)
915 , _aligned (other._aligned)
919 for (int i = 0; i < planes(); ++i) {
920 uint8_t* p = _data[i];
921 uint8_t* q = other._data[i];
922 int const lines = sample_size(i).height;
923 for (int j = 0; j < lines; ++j) {
924 memcpy (p, q, _line_size[i]);
926 q += other.stride()[i];
931 Image::Image (AVFrame* frame)
932 : _size (frame->width, frame->height)
933 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
938 for (int i = 0; i < planes(); ++i) {
939 uint8_t* p = _data[i];
940 uint8_t* q = frame->data[i];
941 int const lines = sample_size(i).height;
942 for (int j = 0; j < lines; ++j) {
943 memcpy (p, q, _line_size[i]);
945 /* AVFrame's linesize is what we call `stride' */
946 q += frame->linesize[i];
951 Image::Image (shared_ptr<const Image> other, bool aligned)
952 : _size (other->_size)
953 , _pixel_format (other->_pixel_format)
958 for (int i = 0; i < planes(); ++i) {
959 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
960 uint8_t* p = _data[i];
961 uint8_t* q = other->data()[i];
962 int const lines = sample_size(i).height;
963 for (int j = 0; j < lines; ++j) {
964 memcpy (p, q, line_size()[i]);
966 q += other->stride()[i];
972 Image::operator= (Image const & other)
974 if (this == &other) {
984 Image::swap (Image & other)
986 std::swap (_size, other._size);
987 std::swap (_pixel_format, other._pixel_format);
989 for (int i = 0; i < 4; ++i) {
990 std::swap (_data[i], other._data[i]);
991 std::swap (_line_size[i], other._line_size[i]);
992 std::swap (_stride[i], other._stride[i]);
995 std::swap (_aligned, other._aligned);
998 /** Destroy a Image */
1001 for (int i = 0; i < planes(); ++i) {
1006 av_free (_line_size);
1011 Image::data () const
1017 Image::line_size () const
1023 Image::stride () const
1029 Image::size () const
1035 Image::aligned () const
1041 merge (list<PositionImage> images)
1043 if (images.empty ()) {
1044 return PositionImage ();
1047 if (images.size() == 1) {
1048 return images.front ();
1051 dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1052 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1053 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
1056 shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
1057 merged->make_transparent ();
1058 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1059 merged->alpha_blend (i->image, i->position - all.position());
1062 return PositionImage (merged, all.position ());
1066 operator== (Image const & a, Image const & b)
1068 if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1072 for (int c = 0; c < a.planes(); ++c) {
1073 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]) {
1077 uint8_t* p = a.data()[c];
1078 uint8_t* q = b.data()[c];
1079 int const lines = a.sample_size(c).height;
1080 for (int y = 0; y < lines; ++y) {
1081 if (memcmp (p, q, a.line_size()[c]) != 0) {
1094 * @param f Amount to fade by; 0 is black, 1 is no fade.
1097 Image::fade (float f)
1099 /* U/V black value for 8-bit colour */
1100 static int const eight_bit_uv = (1 << 7) - 1;
1101 /* U/V black value for 10-bit colour */
1102 static uint16_t const ten_bit_uv = (1 << 9) - 1;
1104 switch (_pixel_format) {
1105 case AV_PIX_FMT_YUV420P:
1108 uint8_t* p = data()[0];
1109 int const lines = sample_size(0).height;
1110 for (int y = 0; y < lines; ++y) {
1112 for (int x = 0; x < line_size()[0]; ++x) {
1113 *q = int(float(*q) * f);
1120 for (int c = 1; c < 3; ++c) {
1121 uint8_t* p = data()[c];
1122 int const lines = sample_size(c).height;
1123 for (int y = 0; y < lines; ++y) {
1125 for (int x = 0; x < line_size()[c]; ++x) {
1126 *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1136 case AV_PIX_FMT_RGB24:
1139 uint8_t* p = data()[0];
1140 int const lines = sample_size(0).height;
1141 for (int y = 0; y < lines; ++y) {
1143 for (int x = 0; x < line_size()[0]; ++x) {
1144 *q = int (float (*q) * f);
1152 case AV_PIX_FMT_XYZ12LE:
1153 case AV_PIX_FMT_RGB48LE:
1154 /* 16-bit little-endian */
1155 for (int c = 0; c < 3; ++c) {
1156 int const stride_pixels = stride()[c] / 2;
1157 int const line_size_pixels = line_size()[c] / 2;
1158 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1159 int const lines = sample_size(c).height;
1160 for (int y = 0; y < lines; ++y) {
1162 for (int x = 0; x < line_size_pixels; ++x) {
1163 *q = int (float (*q) * f);
1171 case AV_PIX_FMT_YUV422P10LE:
1175 int const stride_pixels = stride()[0] / 2;
1176 int const line_size_pixels = line_size()[0] / 2;
1177 uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1178 int const lines = sample_size(0).height;
1179 for (int y = 0; y < lines; ++y) {
1181 for (int x = 0; x < line_size_pixels; ++x) {
1182 *q = int(float(*q) * f);
1190 for (int c = 1; c < 3; ++c) {
1191 int const stride_pixels = stride()[c] / 2;
1192 int const line_size_pixels = line_size()[c] / 2;
1193 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1194 int const lines = sample_size(c).height;
1195 for (int y = 0; y < lines; ++y) {
1197 for (int x = 0; x < line_size_pixels; ++x) {
1198 *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1209 throw PixelFormatError ("fade()", _pixel_format);
1213 shared_ptr<const Image>
1214 Image::ensure_aligned (shared_ptr<const Image> image)
1216 if (image->aligned()) {
1220 return shared_ptr<Image> (new Image (image, true));
1224 Image::memory_used () const
1227 for (int i = 0; i < planes(); ++i) {
1228 m += _stride[i] * sample_size(i).height;
1251 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1253 Memory* mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1254 size_t size = mem->size + length;
1257 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1259 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1263 throw EncodeError (N_("could not allocate memory for PNG"));
1266 memcpy (mem->data + mem->size, data, length);
1267 mem->size += length;
1271 png_flush (png_structp)
1277 png_error_fn (png_structp png_ptr, char const * message)
1279 reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1283 Image::png_error (char const * message)
1285 throw EncodeError (String::compose ("Error during PNG write: %1", message));
1289 Image::as_png () const
1291 DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1292 DCPOMATIC_ASSERT (planes() == 1);
1293 if (pixel_format() != AV_PIX_FMT_RGBA) {
1294 return convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGBA, true, false)->as_png();
1297 /* error handling? */
1298 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1300 throw EncodeError (N_("could not create PNG write struct"));
1305 png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1307 png_infop info_ptr = png_create_info_struct(png_ptr);
1309 png_destroy_write_struct (&png_ptr, &info_ptr);
1310 throw EncodeError (N_("could not create PNG info struct"));
1313 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);
1315 png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1316 for (int i = 0; i < size().height; ++i) {
1317 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1320 png_write_info (png_ptr, info_ptr);
1321 png_write_image (png_ptr, row_pointers);
1322 png_write_end (png_ptr, info_ptr);
1324 png_destroy_write_struct (&png_ptr, &info_ptr);
1325 png_free (png_ptr, row_pointers);
1327 return dcp::Data (state.data, state.size);