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;
57 using namespace dcpomatic;
60 Image::vertical_factor (int n) const
66 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
68 throw PixelFormatError ("line_factor()", _pixel_format);
71 return pow (2.0f, d->log2_chroma_h);
75 Image::horizontal_factor (int n) const
81 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
83 throw PixelFormatError ("sample_size()", _pixel_format);
86 return pow (2.0f, d->log2_chroma_w);
89 /** @param n Component index.
90 * @return Number of samples (i.e. pixels, unless sub-sampled) in each direction for this component.
93 Image::sample_size (int n) const
96 lrint (ceil (static_cast<double>(size().width) / horizontal_factor (n))),
97 lrint (ceil (static_cast<double>(size().height) / vertical_factor (n)))
101 /** @return Number of planes */
103 Image::planes () const
105 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
107 throw PixelFormatError ("planes()", _pixel_format);
110 if (_pixel_format == AV_PIX_FMT_PAL8) {
114 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
118 return d->nb_components;
121 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size'.
122 * @param crop Amount to crop by.
123 * @param inter_size Size to scale the cropped image to.
124 * @param out_size Size of output frame; if this is larger than inter_size there will be black padding.
125 * @param yuv_to_rgb YUV to RGB transformation to use, if required.
126 * @param out_format Output pixel format.
127 * @param out_aligned true to make the output image aligned.
128 * @param fast Try to be fast at the possible expense of quality; at present this means using
129 * fast bilinear rather than bicubic scaling.
132 Image::crop_scale_window (
133 Crop crop, dcp::Size inter_size, dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, VideoRange video_range, AVPixelFormat out_format, bool out_aligned, bool fast
136 /* Empirical testing suggests that sws_scale() will crash if
137 the input image is not aligned.
139 DCPOMATIC_ASSERT (aligned ());
141 DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
142 DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
144 shared_ptr<Image> out (new Image(out_format, out_size, out_aligned));
147 /* Size of the image after any crop */
148 dcp::Size const cropped_size = crop.apply (size ());
150 /* Scale context for a scale from cropped_size to inter_size */
151 struct SwsContext* scale_context = sws_getContext (
152 cropped_size.width, cropped_size.height, pixel_format(),
153 inter_size.width, inter_size.height, out_format,
154 fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
157 if (!scale_context) {
158 throw runtime_error (N_("Could not allocate SwsContext"));
161 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
162 int const lut[dcp::YUV_TO_RGB_COUNT] = {
167 /* The 3rd parameter here is:
168 0 -> source range MPEG (i.e. "video", 16-235)
169 1 -> source range JPEG (i.e. "full", 0-255)
171 0 -> destination range MPEG (i.e. "video", 16-235)
172 1 -> destination range JPEG (i.e. "full", 0-255)
174 But remember: sws_setColorspaceDetails ignores these
175 parameters unless the corresponding image isYUV or isGray.
176 (If it's neither, it uses video range).
178 sws_setColorspaceDetails (
180 sws_getCoefficients (lut[yuv_to_rgb]), video_range == VIDEO_RANGE_VIDEO ? 0 : 1,
181 sws_getCoefficients (lut[yuv_to_rgb]), 1,
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 these
280 parameters unless the corresponding image isYUV or isGray.
281 (If it's neither, it uses video range).
283 sws_setColorspaceDetails (
285 sws_getCoefficients (lut[yuv_to_rgb]), 0,
286 sws_getCoefficients (lut[yuv_to_rgb]), 0,
294 scaled->data(), scaled->stride()
297 sws_freeContext (scale_context);
302 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
304 Image::yuv_16_black (uint16_t v, bool alpha)
306 memset (data()[0], 0, sample_size(0).height * stride()[0]);
307 for (int i = 1; i < 3; ++i) {
308 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
309 int const lines = sample_size(i).height;
310 for (int y = 0; y < lines; ++y) {
311 /* We divide by 2 here because we are writing 2 bytes at a time */
312 for (int x = 0; x < line_size()[i] / 2; ++x) {
315 p += stride()[i] / 2;
320 memset (data()[3], 0, sample_size(3).height * stride()[3]);
325 Image::swap_16 (uint16_t v)
327 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
331 Image::make_part_black (int x, int w)
333 switch (_pixel_format) {
334 case AV_PIX_FMT_RGB24:
335 case AV_PIX_FMT_ARGB:
336 case AV_PIX_FMT_RGBA:
337 case AV_PIX_FMT_ABGR:
338 case AV_PIX_FMT_BGRA:
339 case AV_PIX_FMT_RGB555LE:
340 case AV_PIX_FMT_RGB48LE:
341 case AV_PIX_FMT_RGB48BE:
342 case AV_PIX_FMT_XYZ12LE:
344 int const h = sample_size(0).height;
345 int const bpp = bytes_per_pixel(0);
346 int const s = stride()[0];
347 uint8_t* p = data()[0];
348 for (int y = 0; y < h; y++) {
349 memset (p + x * bpp, 0, w * bpp);
356 throw PixelFormatError ("make_part_black()", _pixel_format);
363 /* U/V black value for 8-bit colour */
364 static uint8_t const eight_bit_uv = (1 << 7) - 1;
365 /* U/V black value for 9-bit colour */
366 static uint16_t const nine_bit_uv = (1 << 8) - 1;
367 /* U/V black value for 10-bit colour */
368 static uint16_t const ten_bit_uv = (1 << 9) - 1;
369 /* U/V black value for 16-bit colour */
370 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
372 switch (_pixel_format) {
373 case AV_PIX_FMT_YUV420P:
374 case AV_PIX_FMT_YUV422P:
375 case AV_PIX_FMT_YUV444P:
376 case AV_PIX_FMT_YUV411P:
377 memset (data()[0], 0, sample_size(0).height * stride()[0]);
378 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
379 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
382 case AV_PIX_FMT_YUVJ420P:
383 case AV_PIX_FMT_YUVJ422P:
384 case AV_PIX_FMT_YUVJ444P:
385 memset (data()[0], 0, sample_size(0).height * stride()[0]);
386 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
387 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
390 case AV_PIX_FMT_YUV422P9LE:
391 case AV_PIX_FMT_YUV444P9LE:
392 yuv_16_black (nine_bit_uv, false);
395 case AV_PIX_FMT_YUV422P9BE:
396 case AV_PIX_FMT_YUV444P9BE:
397 yuv_16_black (swap_16 (nine_bit_uv), false);
400 case AV_PIX_FMT_YUV422P10LE:
401 case AV_PIX_FMT_YUV444P10LE:
402 yuv_16_black (ten_bit_uv, false);
405 case AV_PIX_FMT_YUV422P16LE:
406 case AV_PIX_FMT_YUV444P16LE:
407 yuv_16_black (sixteen_bit_uv, false);
410 case AV_PIX_FMT_YUV444P10BE:
411 case AV_PIX_FMT_YUV422P10BE:
412 yuv_16_black (swap_16 (ten_bit_uv), false);
415 case AV_PIX_FMT_YUVA420P9BE:
416 case AV_PIX_FMT_YUVA422P9BE:
417 case AV_PIX_FMT_YUVA444P9BE:
418 yuv_16_black (swap_16 (nine_bit_uv), true);
421 case AV_PIX_FMT_YUVA420P9LE:
422 case AV_PIX_FMT_YUVA422P9LE:
423 case AV_PIX_FMT_YUVA444P9LE:
424 yuv_16_black (nine_bit_uv, true);
427 case AV_PIX_FMT_YUVA420P10BE:
428 case AV_PIX_FMT_YUVA422P10BE:
429 case AV_PIX_FMT_YUVA444P10BE:
430 yuv_16_black (swap_16 (ten_bit_uv), true);
433 case AV_PIX_FMT_YUVA420P10LE:
434 case AV_PIX_FMT_YUVA422P10LE:
435 case AV_PIX_FMT_YUVA444P10LE:
436 yuv_16_black (ten_bit_uv, true);
439 case AV_PIX_FMT_YUVA420P16BE:
440 case AV_PIX_FMT_YUVA422P16BE:
441 case AV_PIX_FMT_YUVA444P16BE:
442 yuv_16_black (swap_16 (sixteen_bit_uv), true);
445 case AV_PIX_FMT_YUVA420P16LE:
446 case AV_PIX_FMT_YUVA422P16LE:
447 case AV_PIX_FMT_YUVA444P16LE:
448 yuv_16_black (sixteen_bit_uv, true);
451 case AV_PIX_FMT_RGB24:
452 case AV_PIX_FMT_ARGB:
453 case AV_PIX_FMT_RGBA:
454 case AV_PIX_FMT_ABGR:
455 case AV_PIX_FMT_BGRA:
456 case AV_PIX_FMT_RGB555LE:
457 case AV_PIX_FMT_RGB48LE:
458 case AV_PIX_FMT_RGB48BE:
459 case AV_PIX_FMT_XYZ12LE:
460 memset (data()[0], 0, sample_size(0).height * stride()[0]);
463 case AV_PIX_FMT_UYVY422:
465 int const Y = sample_size(0).height;
466 int const X = line_size()[0];
467 uint8_t* p = data()[0];
468 for (int y = 0; y < Y; ++y) {
469 for (int x = 0; x < X / 4; ++x) {
470 *p++ = eight_bit_uv; // Cb
472 *p++ = eight_bit_uv; // Cr
480 throw PixelFormatError ("make_black()", _pixel_format);
485 Image::make_transparent ()
487 if (_pixel_format != AV_PIX_FMT_BGRA && _pixel_format != AV_PIX_FMT_RGBA) {
488 throw PixelFormatError ("make_transparent()", _pixel_format);
491 memset (data()[0], 0, sample_size(0).height * stride()[0]);
495 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
497 /* We're blending RGBA or BGRA images */
498 DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA || other->pixel_format() == AV_PIX_FMT_RGBA);
499 int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
500 int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
502 int const other_bpp = 4;
504 int start_tx = position.x;
508 start_ox = -start_tx;
512 int start_ty = position.y;
516 start_oy = -start_ty;
520 switch (_pixel_format) {
521 case AV_PIX_FMT_RGB24:
523 /* Going onto RGB24. First byte is red, second green, third blue */
524 int const this_bpp = 3;
525 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
526 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
527 uint8_t* op = other->data()[0] + oy * other->stride()[0];
528 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
529 float const alpha = float (op[3]) / 255;
530 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
531 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
532 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
540 case AV_PIX_FMT_BGRA:
542 int const this_bpp = 4;
543 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
544 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
545 uint8_t* op = other->data()[0] + oy * other->stride()[0];
546 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
547 float const alpha = float (op[3]) / 255;
548 tp[0] = op[blue] * alpha + tp[0] * (1 - alpha);
549 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
550 tp[2] = op[red] * alpha + tp[2] * (1 - alpha);
551 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
559 case AV_PIX_FMT_RGBA:
561 int const this_bpp = 4;
562 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
563 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
564 uint8_t* op = other->data()[0] + oy * other->stride()[0];
565 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
566 float const alpha = float (op[3]) / 255;
567 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
568 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
569 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
570 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
578 case AV_PIX_FMT_RGB48LE:
580 int const this_bpp = 6;
581 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
582 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
583 uint8_t* op = other->data()[0] + oy * other->stride()[0];
584 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
585 float const alpha = float (op[3]) / 255;
586 /* Blend high bytes */
587 tp[1] = op[red] * alpha + tp[1] * (1 - alpha);
588 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
589 tp[5] = op[blue] * alpha + tp[5] * (1 - alpha);
597 case AV_PIX_FMT_XYZ12LE:
599 dcp::ColourConversion conv = dcp::ColourConversion::srgb_to_xyz();
600 double fast_matrix[9];
601 dcp::combined_rgb_to_xyz (conv, fast_matrix);
602 double const * lut_in = conv.in()->lut (8, false);
603 double const * lut_out = conv.out()->lut (16, true);
604 int const this_bpp = 6;
605 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
606 uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
607 uint8_t* op = other->data()[0] + oy * other->stride()[0];
608 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
609 float const alpha = float (op[3]) / 255;
611 /* Convert sRGB to XYZ; op is BGRA. First, input gamma LUT */
612 double const r = lut_in[op[red]];
613 double const g = lut_in[op[1]];
614 double const b = lut_in[op[blue]];
616 /* RGB to XYZ, including Bradford transform and DCI companding */
617 double const x = std::max(0.0, std::min(65535.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
618 double const y = std::max(0.0, std::min(65535.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
619 double const z = std::max(0.0, std::min(65535.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
621 /* Out gamma LUT and blend */
622 tp[0] = lrint(lut_out[lrint(x)] * 65535) * alpha + tp[0] * (1 - alpha);
623 tp[1] = lrint(lut_out[lrint(y)] * 65535) * alpha + tp[1] * (1 - alpha);
624 tp[2] = lrint(lut_out[lrint(z)] * 65535) * alpha + tp[2] * (1 - alpha);
632 case AV_PIX_FMT_YUV420P:
634 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
635 dcp::Size const ts = size();
636 dcp::Size const os = yuv->size();
637 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
638 int const hty = ty / 2;
639 int const hoy = oy / 2;
640 uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
641 uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
642 uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
643 uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
644 uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
645 uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
646 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
647 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
648 float const a = float(alpha[3]) / 255;
649 *tY = *oY * a + *tY * (1 - a);
650 *tU = *oU * a + *tU * (1 - a);
651 *tV = *oV * a + *tV * (1 - a);
667 case AV_PIX_FMT_YUV420P10:
669 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
670 dcp::Size const ts = size();
671 dcp::Size const os = yuv->size();
672 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
673 int const hty = ty / 2;
674 int const hoy = oy / 2;
675 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
676 uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
677 uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
678 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
679 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
680 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
681 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
682 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
683 float const a = float(alpha[3]) / 255;
684 *tY = *oY * a + *tY * (1 - a);
685 *tU = *oU * a + *tU * (1 - a);
686 *tV = *oV * a + *tV * (1 - a);
702 case AV_PIX_FMT_YUV422P10LE:
704 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
705 dcp::Size const ts = size();
706 dcp::Size const os = yuv->size();
707 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
708 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
709 uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
710 uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
711 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
712 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
713 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
714 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
715 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
716 float const a = float(alpha[3]) / 255;
717 *tY = *oY * a + *tY * (1 - a);
718 *tU = *oU * a + *tU * (1 - a);
719 *tV = *oV * a + *tV * (1 - a);
736 throw PixelFormatError ("alpha_blend()", _pixel_format);
741 Image::copy (shared_ptr<const Image> other, Position<int> position)
743 /* Only implemented for RGB24 onto RGB24 so far */
744 DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
745 DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
747 int const N = std::min (position.x + other->size().width, size().width) - position.x;
748 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
749 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
750 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
751 memcpy (tp, op, N * 3);
756 Image::read_from_socket (shared_ptr<Socket> socket)
758 for (int i = 0; i < planes(); ++i) {
759 uint8_t* p = data()[i];
760 int const lines = sample_size(i).height;
761 for (int y = 0; y < lines; ++y) {
762 socket->read (p, line_size()[i]);
769 Image::write_to_socket (shared_ptr<Socket> socket) const
771 for (int i = 0; i < planes(); ++i) {
772 uint8_t* p = data()[i];
773 int const lines = sample_size(i).height;
774 for (int y = 0; y < lines; ++y) {
775 socket->write (p, line_size()[i]);
782 Image::bytes_per_pixel (int c) const
784 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
786 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
793 float bpp[4] = { 0, 0, 0, 0 };
795 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
796 bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
797 if (d->nb_components > 1) {
798 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
800 if (d->nb_components > 2) {
801 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
803 if (d->nb_components > 3) {
804 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
807 bpp[0] = floor ((d->comp[0].depth + 7) / 8);
808 if (d->nb_components > 1) {
809 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
811 if (d->nb_components > 2) {
812 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
814 if (d->nb_components > 3) {
815 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
819 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
820 /* Not planar; sum them up */
821 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
827 /** Construct a Image of a given size and format, allocating memory
830 * @param p Pixel format.
831 * @param s Size in pixels.
832 * @param aligned true to make each row of this image aligned to a 32-byte boundary.
834 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned)
845 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
846 _data[0] = _data[1] = _data[2] = _data[3] = 0;
848 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
849 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
851 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
852 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
854 for (int i = 0; i < planes(); ++i) {
855 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
856 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
858 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
859 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
860 Hence on the last pixel of the last line it reads over the end of
861 the actual data by 1 byte. If the width of an image is a multiple
862 of the stride alignment there will be no padding at the end of image lines.
863 OS X crashes on this illegal read, though other operating systems don't
864 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
865 for that instruction to read safely.
867 Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
868 over-reads by more then _avx. I can't follow the code to work out how much,
869 so I'll just over-allocate by 32 bytes and have done with it. Empirical
870 testing suggests that it works.
872 In addition to these concerns, we may read/write as much as a whole extra line
873 at the end of each plane in cases where we are messing with offsets in order to
874 do pad or crop. To solve this we over-allocate by an extra _stride[i] bytes.
876 As an example: we may write to images starting at an offset so we get some padding.
877 Hence we want to write in the following pattern:
879 block start write start line end
880 |..(padding)..|<------line-size------------->|..(padding)..|
881 |..(padding)..|<------line-size------------->|..(padding)..|
882 |..(padding)..|<------line-size------------->|..(padding)..|
884 where line-size is of the smaller (inter_size) image and the full padded line length is that of
885 out_size. To get things to work we have to tell FFmpeg that the stride is that of out_size.
886 However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
887 specified *stride*. This does not matter until we get to the last line:
889 block start write start line end
890 |..(padding)..|<------line-size------------->|XXXwrittenXXX|
891 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
892 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
895 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * (sample_size(i).height + 1) + 32);
896 #if HAVE_VALGRIND_MEMCHECK_H
897 /* The data between the end of the line size and the stride is undefined but processed by
898 libswscale, causing lots of valgrind errors. Mark it all defined to quell these errors.
900 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * (sample_size(i).height + 1) + 32);
905 Image::Image (Image const & other)
906 : boost::enable_shared_from_this<Image>(other)
907 , _size (other._size)
908 , _pixel_format (other._pixel_format)
909 , _aligned (other._aligned)
913 for (int i = 0; i < planes(); ++i) {
914 uint8_t* p = _data[i];
915 uint8_t* q = other._data[i];
916 int const lines = sample_size(i).height;
917 for (int j = 0; j < lines; ++j) {
918 memcpy (p, q, _line_size[i]);
920 q += other.stride()[i];
925 Image::Image (AVFrame* frame)
926 : _size (frame->width, frame->height)
927 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
932 for (int i = 0; i < planes(); ++i) {
933 uint8_t* p = _data[i];
934 uint8_t* q = frame->data[i];
935 int const lines = sample_size(i).height;
936 for (int j = 0; j < lines; ++j) {
937 memcpy (p, q, _line_size[i]);
939 /* AVFrame's linesize is what we call `stride' */
940 q += frame->linesize[i];
945 Image::Image (shared_ptr<const Image> other, bool aligned)
946 : _size (other->_size)
947 , _pixel_format (other->_pixel_format)
952 for (int i = 0; i < planes(); ++i) {
953 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
954 uint8_t* p = _data[i];
955 uint8_t* q = other->data()[i];
956 int const lines = sample_size(i).height;
957 for (int j = 0; j < lines; ++j) {
958 memcpy (p, q, line_size()[i]);
960 q += other->stride()[i];
966 Image::operator= (Image const & other)
968 if (this == &other) {
978 Image::swap (Image & other)
980 std::swap (_size, other._size);
981 std::swap (_pixel_format, other._pixel_format);
983 for (int i = 0; i < 4; ++i) {
984 std::swap (_data[i], other._data[i]);
985 std::swap (_line_size[i], other._line_size[i]);
986 std::swap (_stride[i], other._stride[i]);
989 std::swap (_aligned, other._aligned);
992 /** Destroy a Image */
995 for (int i = 0; i < planes(); ++i) {
1000 av_free (_line_size);
1005 Image::data () const
1011 Image::line_size () const
1017 Image::stride () const
1023 Image::size () const
1029 Image::aligned () const
1035 dcpomatic::merge (list<PositionImage> images)
1037 if (images.empty ()) {
1038 return PositionImage ();
1041 if (images.size() == 1) {
1042 return images.front ();
1045 dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1046 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1047 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
1050 shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
1051 merged->make_transparent ();
1052 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1053 merged->alpha_blend (i->image, i->position - all.position());
1056 return PositionImage (merged, all.position ());
1060 dcpomatic::operator== (Image const & a, Image const & b)
1062 if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1066 for (int c = 0; c < a.planes(); ++c) {
1067 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]) {
1071 uint8_t* p = a.data()[c];
1072 uint8_t* q = b.data()[c];
1073 int const lines = a.sample_size(c).height;
1074 for (int y = 0; y < lines; ++y) {
1075 if (memcmp (p, q, a.line_size()[c]) != 0) {
1088 * @param f Amount to fade by; 0 is black, 1 is no fade.
1091 Image::fade (float f)
1093 /* U/V black value for 8-bit colour */
1094 static int const eight_bit_uv = (1 << 7) - 1;
1095 /* U/V black value for 10-bit colour */
1096 static uint16_t const ten_bit_uv = (1 << 9) - 1;
1098 switch (_pixel_format) {
1099 case AV_PIX_FMT_YUV420P:
1102 uint8_t* p = data()[0];
1103 int const lines = sample_size(0).height;
1104 for (int y = 0; y < lines; ++y) {
1106 for (int x = 0; x < line_size()[0]; ++x) {
1107 *q = int(float(*q) * f);
1114 for (int c = 1; c < 3; ++c) {
1115 uint8_t* p = data()[c];
1116 int const lines = sample_size(c).height;
1117 for (int y = 0; y < lines; ++y) {
1119 for (int x = 0; x < line_size()[c]; ++x) {
1120 *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1130 case AV_PIX_FMT_RGB24:
1133 uint8_t* p = data()[0];
1134 int const lines = sample_size(0).height;
1135 for (int y = 0; y < lines; ++y) {
1137 for (int x = 0; x < line_size()[0]; ++x) {
1138 *q = int (float (*q) * f);
1146 case AV_PIX_FMT_XYZ12LE:
1147 case AV_PIX_FMT_RGB48LE:
1148 /* 16-bit little-endian */
1149 for (int c = 0; c < 3; ++c) {
1150 int const stride_pixels = stride()[c] / 2;
1151 int const line_size_pixels = line_size()[c] / 2;
1152 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1153 int const lines = sample_size(c).height;
1154 for (int y = 0; y < lines; ++y) {
1156 for (int x = 0; x < line_size_pixels; ++x) {
1157 *q = int (float (*q) * f);
1165 case AV_PIX_FMT_YUV422P10LE:
1169 int const stride_pixels = stride()[0] / 2;
1170 int const line_size_pixels = line_size()[0] / 2;
1171 uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1172 int const lines = sample_size(0).height;
1173 for (int y = 0; y < lines; ++y) {
1175 for (int x = 0; x < line_size_pixels; ++x) {
1176 *q = int(float(*q) * f);
1184 for (int c = 1; c < 3; ++c) {
1185 int const stride_pixels = stride()[c] / 2;
1186 int const line_size_pixels = line_size()[c] / 2;
1187 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1188 int const lines = sample_size(c).height;
1189 for (int y = 0; y < lines; ++y) {
1191 for (int x = 0; x < line_size_pixels; ++x) {
1192 *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1203 throw PixelFormatError ("fade()", _pixel_format);
1207 shared_ptr<const Image>
1208 Image::ensure_aligned (shared_ptr<const Image> image)
1210 if (image->aligned()) {
1214 return shared_ptr<Image> (new Image (image, true));
1218 Image::memory_used () const
1221 for (int i = 0; i < planes(); ++i) {
1222 m += _stride[i] * sample_size(i).height;
1245 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1247 Memory* mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1248 size_t size = mem->size + length;
1251 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1253 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1257 throw EncodeError (N_("could not allocate memory for PNG"));
1260 memcpy (mem->data + mem->size, data, length);
1261 mem->size += length;
1265 png_flush (png_structp)
1271 png_error_fn (png_structp png_ptr, char const * message)
1273 reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1277 Image::png_error (char const * message)
1279 throw EncodeError (String::compose ("Error during PNG write: %1", message));
1283 Image::as_png () const
1285 DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1286 DCPOMATIC_ASSERT (planes() == 1);
1287 if (pixel_format() != AV_PIX_FMT_RGBA) {
1288 return convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGBA, true, false)->as_png();
1291 /* error handling? */
1292 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1294 throw EncodeError (N_("could not create PNG write struct"));
1299 png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1301 png_infop info_ptr = png_create_info_struct(png_ptr);
1303 png_destroy_write_struct (&png_ptr, &info_ptr);
1304 throw EncodeError (N_("could not create PNG info struct"));
1307 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);
1309 png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1310 for (int i = 0; i < size().height; ++i) {
1311 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1314 png_write_info (png_ptr, info_ptr);
1315 png_write_image (png_ptr, row_pointers);
1316 png_write_end (png_ptr, info_ptr);
1318 png_destroy_write_struct (&png_ptr, &info_ptr);
1319 png_free (png_ptr, row_pointers);
1321 return dcp::Data (state.data, state.size);