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;
128 round_width_for_subsampling (int p, AVPixFmtDescriptor const * desc)
130 return p & ~ ((1 << desc->log2_chroma_w) - 1);
136 round_height_for_subsampling (int p, AVPixFmtDescriptor const * desc)
138 return p & ~ ((1 << desc->log2_chroma_h) - 1);
142 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size'.
143 * @param crop Amount to crop by.
144 * @param inter_size Size to scale the cropped image to.
145 * @param out_size Size of output frame; if this is larger than inter_size there will be black padding.
146 * @param yuv_to_rgb YUV to RGB transformation to use, if required.
147 * @param video_range Video range of the image.
148 * @param out_format Output pixel format.
149 * @param out_aligned true to make the output image aligned.
150 * @param out_video_range Video range to use for the output image.
151 * @param fast Try to be fast at the possible expense of quality; at present this means using
152 * fast bilinear rather than bicubic scaling.
155 Image::crop_scale_window (
157 dcp::Size inter_size,
159 dcp::YUVToRGB yuv_to_rgb,
160 VideoRange video_range,
161 AVPixelFormat out_format,
162 VideoRange out_video_range,
167 /* Empirical testing suggests that sws_scale() will crash if
168 the input image is not aligned.
170 DCPOMATIC_ASSERT (aligned ());
172 DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
173 DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
175 shared_ptr<Image> out (new Image(out_format, out_size, out_aligned));
178 AVPixFmtDescriptor const * in_desc = av_pix_fmt_desc_get (_pixel_format);
180 throw PixelFormatError ("crop_scale_window()", _pixel_format);
183 /* Round down so that we crop only the number of pixels that is straightforward
184 * considering any subsampling.
187 round_width_for_subsampling(crop.left, in_desc),
188 round_width_for_subsampling(crop.right, in_desc),
189 round_height_for_subsampling(crop.top, in_desc),
190 round_height_for_subsampling(crop.bottom, in_desc)
193 /* Also check that we aren't cropping more image than there actually is */
194 if ((corrected_crop.left + corrected_crop.right) >= (size().width - 4)) {
195 corrected_crop.left = 0;
196 corrected_crop.right = size().width - 4;
199 if ((corrected_crop.top + corrected_crop.bottom) >= (size().height - 4)) {
200 corrected_crop.top = 0;
201 corrected_crop.bottom = size().height - 4;
204 /* Size of the image after any crop */
205 dcp::Size const cropped_size = corrected_crop.apply (size());
207 /* Scale context for a scale from cropped_size to inter_size */
208 struct SwsContext* scale_context = sws_getContext (
209 cropped_size.width, cropped_size.height, pixel_format(),
210 inter_size.width, inter_size.height, out_format,
211 fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
214 if (!scale_context) {
215 throw runtime_error (N_("Could not allocate SwsContext"));
218 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
219 int const lut[dcp::YUV_TO_RGB_COUNT] = {
224 /* The 3rd parameter here is:
225 0 -> source range MPEG (i.e. "video", 16-235)
226 1 -> source range JPEG (i.e. "full", 0-255)
228 0 -> destination range MPEG (i.e. "video", 16-235)
229 1 -> destination range JPEG (i.e. "full", 0-255)
231 But remember: sws_setColorspaceDetails ignores these
232 parameters unless the both source and destination images
233 are isYUV or isGray. (If either is not, it uses video range).
235 sws_setColorspaceDetails (
237 sws_getCoefficients (lut[yuv_to_rgb]), video_range == VIDEO_RANGE_VIDEO ? 0 : 1,
238 sws_getCoefficients (lut[yuv_to_rgb]), out_video_range == VIDEO_RANGE_VIDEO ? 0 : 1,
242 /* Prepare input data pointers with crop */
243 uint8_t* scale_in_data[planes()];
244 for (int c = 0; c < planes(); ++c) {
245 int const x = lrintf(bytes_per_pixel(c) * corrected_crop.left);
246 scale_in_data[c] = data()[c] + x + stride()[c] * (corrected_crop.top / vertical_factor(c));
249 AVPixFmtDescriptor const * out_desc = av_pix_fmt_desc_get (out_format);
251 throw PixelFormatError ("crop_scale_window()", out_format);
254 /* Corner of the image within out_size */
255 Position<int> const corner (
256 round_width_for_subsampling((out_size.width - inter_size.width) / 2, out_desc),
257 round_height_for_subsampling((out_size.height - inter_size.height) / 2, out_desc)
260 uint8_t* scale_out_data[out->planes()];
261 for (int c = 0; c < out->planes(); ++c) {
262 int const x = lrintf(out->bytes_per_pixel(c) * corner.x);
263 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
268 scale_in_data, stride(),
269 0, cropped_size.height,
270 scale_out_data, out->stride()
273 sws_freeContext (scale_context);
275 if (corrected_crop != Crop() && cropped_size == inter_size) {
276 /* We are cropping without any scaling or pixel format conversion, so FFmpeg may have left some
277 data behind in our image. Clear it out. It may get to the point where we should just stop
278 trying to be clever with cropping.
280 out->make_part_black (corner.x + cropped_size.width, out_size.width - cropped_size.width);
287 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
289 return scale(size(), yuv_to_rgb, out_format, out_aligned, fast);
292 /** @param out_size Size to scale to.
293 * @param yuv_to_rgb YUVToRGB transform transform to use, if required.
294 * @param out_format Output pixel format.
295 * @param out_aligned true to make an aligned output image.
296 * @param fast Try to be fast at the possible expense of quality; at present this means using
297 * fast bilinear rather than bicubic scaling.
300 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
302 /* Empirical testing suggests that sws_scale() will crash if
303 the input image is not aligned.
305 DCPOMATIC_ASSERT (aligned ());
307 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
309 struct SwsContext* scale_context = sws_getContext (
310 size().width, size().height, pixel_format(),
311 out_size.width, out_size.height, out_format,
312 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
315 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
316 int const lut[dcp::YUV_TO_RGB_COUNT] = {
321 /* The 3rd parameter here is:
322 0 -> source range MPEG (i.e. "video", 16-235)
323 1 -> source range JPEG (i.e. "full", 0-255)
325 0 -> destination range MPEG (i.e. "video", 16-235)
326 1 -> destination range JPEG (i.e. "full", 0-255)
328 But remember: sws_setColorspaceDetails ignores these
329 parameters unless the corresponding image isYUV or isGray.
330 (If it's neither, it uses video range).
332 sws_setColorspaceDetails (
334 sws_getCoefficients (lut[yuv_to_rgb]), 0,
335 sws_getCoefficients (lut[yuv_to_rgb]), 0,
343 scaled->data(), scaled->stride()
346 sws_freeContext (scale_context);
351 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
353 Image::yuv_16_black (uint16_t v, bool alpha)
355 memset (data()[0], 0, sample_size(0).height * stride()[0]);
356 for (int i = 1; i < 3; ++i) {
357 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
358 int const lines = sample_size(i).height;
359 for (int y = 0; y < lines; ++y) {
360 /* We divide by 2 here because we are writing 2 bytes at a time */
361 for (int x = 0; x < line_size()[i] / 2; ++x) {
364 p += stride()[i] / 2;
369 memset (data()[3], 0, sample_size(3).height * stride()[3]);
374 Image::swap_16 (uint16_t v)
376 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
380 Image::make_part_black (int x, int w)
382 switch (_pixel_format) {
383 case AV_PIX_FMT_RGB24:
384 case AV_PIX_FMT_ARGB:
385 case AV_PIX_FMT_RGBA:
386 case AV_PIX_FMT_ABGR:
387 case AV_PIX_FMT_BGRA:
388 case AV_PIX_FMT_RGB555LE:
389 case AV_PIX_FMT_RGB48LE:
390 case AV_PIX_FMT_RGB48BE:
391 case AV_PIX_FMT_XYZ12LE:
393 int const h = sample_size(0).height;
394 int const bpp = bytes_per_pixel(0);
395 int const s = stride()[0];
396 uint8_t* p = data()[0];
397 for (int y = 0; y < h; y++) {
398 memset (p + x * bpp, 0, w * bpp);
405 throw PixelFormatError ("make_part_black()", _pixel_format);
412 /* U/V black value for 8-bit colour */
413 static uint8_t const eight_bit_uv = (1 << 7) - 1;
414 /* U/V black value for 9-bit colour */
415 static uint16_t const nine_bit_uv = (1 << 8) - 1;
416 /* U/V black value for 10-bit colour */
417 static uint16_t const ten_bit_uv = (1 << 9) - 1;
418 /* U/V black value for 16-bit colour */
419 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
421 switch (_pixel_format) {
422 case AV_PIX_FMT_YUV420P:
423 case AV_PIX_FMT_YUV422P:
424 case AV_PIX_FMT_YUV444P:
425 case AV_PIX_FMT_YUV411P:
426 memset (data()[0], 0, sample_size(0).height * stride()[0]);
427 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
428 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
431 case AV_PIX_FMT_YUVJ420P:
432 case AV_PIX_FMT_YUVJ422P:
433 case AV_PIX_FMT_YUVJ444P:
434 memset (data()[0], 0, sample_size(0).height * stride()[0]);
435 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
436 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
439 case AV_PIX_FMT_YUV422P9LE:
440 case AV_PIX_FMT_YUV444P9LE:
441 yuv_16_black (nine_bit_uv, false);
444 case AV_PIX_FMT_YUV422P9BE:
445 case AV_PIX_FMT_YUV444P9BE:
446 yuv_16_black (swap_16 (nine_bit_uv), false);
449 case AV_PIX_FMT_YUV422P10LE:
450 case AV_PIX_FMT_YUV444P10LE:
451 yuv_16_black (ten_bit_uv, false);
454 case AV_PIX_FMT_YUV422P16LE:
455 case AV_PIX_FMT_YUV444P16LE:
456 yuv_16_black (sixteen_bit_uv, false);
459 case AV_PIX_FMT_YUV444P10BE:
460 case AV_PIX_FMT_YUV422P10BE:
461 yuv_16_black (swap_16 (ten_bit_uv), false);
464 case AV_PIX_FMT_YUVA420P9BE:
465 case AV_PIX_FMT_YUVA422P9BE:
466 case AV_PIX_FMT_YUVA444P9BE:
467 yuv_16_black (swap_16 (nine_bit_uv), true);
470 case AV_PIX_FMT_YUVA420P9LE:
471 case AV_PIX_FMT_YUVA422P9LE:
472 case AV_PIX_FMT_YUVA444P9LE:
473 yuv_16_black (nine_bit_uv, true);
476 case AV_PIX_FMT_YUVA420P10BE:
477 case AV_PIX_FMT_YUVA422P10BE:
478 case AV_PIX_FMT_YUVA444P10BE:
479 yuv_16_black (swap_16 (ten_bit_uv), true);
482 case AV_PIX_FMT_YUVA420P10LE:
483 case AV_PIX_FMT_YUVA422P10LE:
484 case AV_PIX_FMT_YUVA444P10LE:
485 yuv_16_black (ten_bit_uv, true);
488 case AV_PIX_FMT_YUVA420P16BE:
489 case AV_PIX_FMT_YUVA422P16BE:
490 case AV_PIX_FMT_YUVA444P16BE:
491 yuv_16_black (swap_16 (sixteen_bit_uv), true);
494 case AV_PIX_FMT_YUVA420P16LE:
495 case AV_PIX_FMT_YUVA422P16LE:
496 case AV_PIX_FMT_YUVA444P16LE:
497 yuv_16_black (sixteen_bit_uv, true);
500 case AV_PIX_FMT_RGB24:
501 case AV_PIX_FMT_ARGB:
502 case AV_PIX_FMT_RGBA:
503 case AV_PIX_FMT_ABGR:
504 case AV_PIX_FMT_BGRA:
505 case AV_PIX_FMT_RGB555LE:
506 case AV_PIX_FMT_RGB48LE:
507 case AV_PIX_FMT_RGB48BE:
508 case AV_PIX_FMT_XYZ12LE:
509 memset (data()[0], 0, sample_size(0).height * stride()[0]);
512 case AV_PIX_FMT_UYVY422:
514 int const Y = sample_size(0).height;
515 int const X = line_size()[0];
516 uint8_t* p = data()[0];
517 for (int y = 0; y < Y; ++y) {
518 for (int x = 0; x < X / 4; ++x) {
519 *p++ = eight_bit_uv; // Cb
521 *p++ = eight_bit_uv; // Cr
529 throw PixelFormatError ("make_black()", _pixel_format);
534 Image::make_transparent ()
536 if (_pixel_format != AV_PIX_FMT_BGRA && _pixel_format != AV_PIX_FMT_RGBA) {
537 throw PixelFormatError ("make_transparent()", _pixel_format);
540 memset (data()[0], 0, sample_size(0).height * stride()[0]);
544 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
546 /* We're blending RGBA or BGRA images */
547 DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA || other->pixel_format() == AV_PIX_FMT_RGBA);
548 int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
549 int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
551 int const other_bpp = 4;
553 int start_tx = position.x;
557 start_ox = -start_tx;
561 int start_ty = position.y;
565 start_oy = -start_ty;
569 switch (_pixel_format) {
570 case AV_PIX_FMT_RGB24:
572 /* Going onto RGB24. First byte is red, second green, third blue */
573 int const this_bpp = 3;
574 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
575 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
576 uint8_t* op = other->data()[0] + oy * other->stride()[0];
577 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
578 float const alpha = float (op[3]) / 255;
579 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
580 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
581 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
589 case AV_PIX_FMT_BGRA:
591 int const this_bpp = 4;
592 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
593 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
594 uint8_t* op = other->data()[0] + oy * other->stride()[0];
595 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
596 float const alpha = float (op[3]) / 255;
597 tp[0] = op[blue] * alpha + tp[0] * (1 - alpha);
598 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
599 tp[2] = op[red] * alpha + tp[2] * (1 - alpha);
600 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
608 case AV_PIX_FMT_RGBA:
610 int const this_bpp = 4;
611 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
612 uint8_t* tp = 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;
616 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
617 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
618 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
619 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
627 case AV_PIX_FMT_RGB48LE:
629 int const this_bpp = 6;
630 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
631 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
632 uint8_t* op = other->data()[0] + oy * other->stride()[0];
633 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
634 float const alpha = float (op[3]) / 255;
635 /* Blend high bytes */
636 tp[1] = op[red] * alpha + tp[1] * (1 - alpha);
637 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
638 tp[5] = op[blue] * alpha + tp[5] * (1 - alpha);
646 case AV_PIX_FMT_XYZ12LE:
648 dcp::ColourConversion conv = dcp::ColourConversion::srgb_to_xyz();
649 double fast_matrix[9];
650 dcp::combined_rgb_to_xyz (conv, fast_matrix);
651 double const * lut_in = conv.in()->lut (8, false);
652 double const * lut_out = conv.out()->lut (16, true);
653 int const this_bpp = 6;
654 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
655 uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
656 uint8_t* op = other->data()[0] + oy * other->stride()[0];
657 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
658 float const alpha = float (op[3]) / 255;
660 /* Convert sRGB to XYZ; op is BGRA. First, input gamma LUT */
661 double const r = lut_in[op[red]];
662 double const g = lut_in[op[1]];
663 double const b = lut_in[op[blue]];
665 /* RGB to XYZ, including Bradford transform and DCI companding */
666 double const x = max (0.0, min (65535.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
667 double const y = max (0.0, min (65535.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
668 double const z = max (0.0, min (65535.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
670 /* Out gamma LUT and blend */
671 tp[0] = lrint(lut_out[lrint(x)] * 65535) * alpha + tp[0] * (1 - alpha);
672 tp[1] = lrint(lut_out[lrint(y)] * 65535) * alpha + tp[1] * (1 - alpha);
673 tp[2] = lrint(lut_out[lrint(z)] * 65535) * alpha + tp[2] * (1 - alpha);
681 case AV_PIX_FMT_YUV420P:
683 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
684 dcp::Size const ts = size();
685 dcp::Size const os = yuv->size();
686 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
687 int const hty = ty / 2;
688 int const hoy = oy / 2;
689 uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
690 uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
691 uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
692 uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
693 uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
694 uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
695 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
696 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
697 float const a = float(alpha[3]) / 255;
698 *tY = *oY * a + *tY * (1 - a);
699 *tU = *oU * a + *tU * (1 - a);
700 *tV = *oV * a + *tV * (1 - a);
716 case AV_PIX_FMT_YUV420P10:
718 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
719 dcp::Size const ts = size();
720 dcp::Size const os = yuv->size();
721 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
722 int const hty = ty / 2;
723 int const hoy = oy / 2;
724 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
725 uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
726 uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
727 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
728 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
729 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
730 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
731 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
732 float const a = float(alpha[3]) / 255;
733 *tY = *oY * a + *tY * (1 - a);
734 *tU = *oU * a + *tU * (1 - a);
735 *tV = *oV * a + *tV * (1 - a);
751 case AV_PIX_FMT_YUV422P10LE:
753 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
754 dcp::Size const ts = size();
755 dcp::Size const os = yuv->size();
756 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
757 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
758 uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
759 uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
760 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
761 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
762 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
763 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
764 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
765 float const a = float(alpha[3]) / 255;
766 *tY = *oY * a + *tY * (1 - a);
767 *tU = *oU * a + *tU * (1 - a);
768 *tV = *oV * a + *tV * (1 - a);
785 throw PixelFormatError ("alpha_blend()", _pixel_format);
790 Image::copy (shared_ptr<const Image> other, Position<int> position)
792 /* Only implemented for RGB24 onto RGB24 so far */
793 DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
794 DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
796 int const N = min (position.x + other->size().width, size().width) - position.x;
797 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
798 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
799 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
800 memcpy (tp, op, N * 3);
805 Image::read_from_socket (shared_ptr<Socket> socket)
807 for (int i = 0; i < planes(); ++i) {
808 uint8_t* p = data()[i];
809 int const lines = sample_size(i).height;
810 for (int y = 0; y < lines; ++y) {
811 socket->read (p, line_size()[i]);
818 Image::write_to_socket (shared_ptr<Socket> socket) const
820 for (int i = 0; i < planes(); ++i) {
821 uint8_t* p = data()[i];
822 int const lines = sample_size(i).height;
823 for (int y = 0; y < lines; ++y) {
824 socket->write (p, line_size()[i]);
831 Image::bytes_per_pixel (int c) const
833 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
835 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
842 float bpp[4] = { 0, 0, 0, 0 };
844 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
845 bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
846 if (d->nb_components > 1) {
847 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
849 if (d->nb_components > 2) {
850 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
852 if (d->nb_components > 3) {
853 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
856 bpp[0] = floor ((d->comp[0].depth + 7) / 8);
857 if (d->nb_components > 1) {
858 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
860 if (d->nb_components > 2) {
861 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
863 if (d->nb_components > 3) {
864 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
868 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
869 /* Not planar; sum them up */
870 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
876 /** Construct a Image of a given size and format, allocating memory
879 * @param p Pixel format.
880 * @param s Size in pixels.
881 * @param aligned true to make each row of this image aligned to a ALIGNMENT-byte boundary.
883 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned)
894 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
895 _data[0] = _data[1] = _data[2] = _data[3] = 0;
897 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
898 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
900 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
901 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
903 for (int i = 0; i < planes(); ++i) {
904 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
905 _stride[i] = stride_round_up (i, _line_size, _aligned ? ALIGNMENT : 1);
907 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
908 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
909 Hence on the last pixel of the last line it reads over the end of
910 the actual data by 1 byte. If the width of an image is a multiple
911 of the stride alignment there will be no padding at the end of image lines.
912 OS X crashes on this illegal read, though other operating systems don't
913 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
914 for that instruction to read safely.
916 Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
917 over-reads by more then _avx. I can't follow the code to work out how much,
918 so I'll just over-allocate by ALIGNMENT bytes and have done with it. Empirical
919 testing suggests that it works.
921 In addition to these concerns, we may read/write as much as a whole extra line
922 at the end of each plane in cases where we are messing with offsets in order to
923 do pad or crop. To solve this we over-allocate by an extra _stride[i] bytes.
925 As an example: we may write to images starting at an offset so we get some padding.
926 Hence we want to write in the following pattern:
928 block start write start line end
929 |..(padding)..|<------line-size------------->|..(padding)..|
930 |..(padding)..|<------line-size------------->|..(padding)..|
931 |..(padding)..|<------line-size------------->|..(padding)..|
933 where line-size is of the smaller (inter_size) image and the full padded line length is that of
934 out_size. To get things to work we have to tell FFmpeg that the stride is that of out_size.
935 However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
936 specified *stride*. This does not matter until we get to the last line:
938 block start write start line end
939 |..(padding)..|<------line-size------------->|XXXwrittenXXX|
940 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
941 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
944 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
945 #if HAVE_VALGRIND_MEMCHECK_H
946 /* The data between the end of the line size and the stride is undefined but processed by
947 libswscale, causing lots of valgrind errors. Mark it all defined to quell these errors.
949 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
954 Image::Image (Image const & other)
955 : boost::enable_shared_from_this<Image>(other)
956 , _size (other._size)
957 , _pixel_format (other._pixel_format)
958 , _aligned (other._aligned)
962 for (int i = 0; i < planes(); ++i) {
963 uint8_t* p = _data[i];
964 uint8_t* q = other._data[i];
965 int const lines = sample_size(i).height;
966 for (int j = 0; j < lines; ++j) {
967 memcpy (p, q, _line_size[i]);
969 q += other.stride()[i];
974 Image::Image (AVFrame* frame)
975 : _size (frame->width, frame->height)
976 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
981 for (int i = 0; i < planes(); ++i) {
982 uint8_t* p = _data[i];
983 uint8_t* q = frame->data[i];
984 int const lines = sample_size(i).height;
985 for (int j = 0; j < lines; ++j) {
986 memcpy (p, q, _line_size[i]);
988 /* AVFrame's linesize is what we call `stride' */
989 q += frame->linesize[i];
994 Image::Image (shared_ptr<const Image> other, bool aligned)
995 : _size (other->_size)
996 , _pixel_format (other->_pixel_format)
1001 for (int i = 0; i < planes(); ++i) {
1002 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
1003 uint8_t* p = _data[i];
1004 uint8_t* q = other->data()[i];
1005 int const lines = sample_size(i).height;
1006 for (int j = 0; j < lines; ++j) {
1007 memcpy (p, q, line_size()[i]);
1009 q += other->stride()[i];
1015 Image::operator= (Image const & other)
1017 if (this == &other) {
1027 Image::swap (Image & other)
1029 std::swap (_size, other._size);
1030 std::swap (_pixel_format, other._pixel_format);
1032 for (int i = 0; i < 4; ++i) {
1033 std::swap (_data[i], other._data[i]);
1034 std::swap (_line_size[i], other._line_size[i]);
1035 std::swap (_stride[i], other._stride[i]);
1038 std::swap (_aligned, other._aligned);
1043 for (int i = 0; i < planes(); ++i) {
1048 av_free (_line_size);
1053 Image::data () const
1059 Image::line_size () const
1065 Image::stride () const
1071 Image::size () const
1077 Image::aligned () const
1083 merge (list<PositionImage> images)
1085 if (images.empty ()) {
1086 return PositionImage ();
1089 if (images.size() == 1) {
1090 return images.front ();
1093 dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1094 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1095 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
1098 shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
1099 merged->make_transparent ();
1100 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1101 merged->alpha_blend (i->image, i->position - all.position());
1104 return PositionImage (merged, all.position ());
1108 operator== (Image const & a, Image const & b)
1110 if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1114 for (int c = 0; c < a.planes(); ++c) {
1115 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]) {
1119 uint8_t* p = a.data()[c];
1120 uint8_t* q = b.data()[c];
1121 int const lines = a.sample_size(c).height;
1122 for (int y = 0; y < lines; ++y) {
1123 if (memcmp (p, q, a.line_size()[c]) != 0) {
1136 * @param f Amount to fade by; 0 is black, 1 is no fade.
1139 Image::fade (float f)
1141 /* U/V black value for 8-bit colour */
1142 static int const eight_bit_uv = (1 << 7) - 1;
1143 /* U/V black value for 10-bit colour */
1144 static uint16_t const ten_bit_uv = (1 << 9) - 1;
1146 switch (_pixel_format) {
1147 case AV_PIX_FMT_YUV420P:
1150 uint8_t* p = data()[0];
1151 int const lines = sample_size(0).height;
1152 for (int y = 0; y < lines; ++y) {
1154 for (int x = 0; x < line_size()[0]; ++x) {
1155 *q = int(float(*q) * f);
1162 for (int c = 1; c < 3; ++c) {
1163 uint8_t* p = data()[c];
1164 int const lines = sample_size(c).height;
1165 for (int y = 0; y < lines; ++y) {
1167 for (int x = 0; x < line_size()[c]; ++x) {
1168 *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1178 case AV_PIX_FMT_RGB24:
1181 uint8_t* p = data()[0];
1182 int const lines = sample_size(0).height;
1183 for (int y = 0; y < lines; ++y) {
1185 for (int x = 0; x < line_size()[0]; ++x) {
1186 *q = int (float (*q) * f);
1194 case AV_PIX_FMT_XYZ12LE:
1195 case AV_PIX_FMT_RGB48LE:
1196 /* 16-bit little-endian */
1197 for (int c = 0; c < 3; ++c) {
1198 int const stride_pixels = stride()[c] / 2;
1199 int const line_size_pixels = line_size()[c] / 2;
1200 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1201 int const lines = sample_size(c).height;
1202 for (int y = 0; y < lines; ++y) {
1204 for (int x = 0; x < line_size_pixels; ++x) {
1205 *q = int (float (*q) * f);
1213 case AV_PIX_FMT_YUV422P10LE:
1217 int const stride_pixels = stride()[0] / 2;
1218 int const line_size_pixels = line_size()[0] / 2;
1219 uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1220 int const lines = sample_size(0).height;
1221 for (int y = 0; y < lines; ++y) {
1223 for (int x = 0; x < line_size_pixels; ++x) {
1224 *q = int(float(*q) * f);
1232 for (int c = 1; c < 3; ++c) {
1233 int const stride_pixels = stride()[c] / 2;
1234 int const line_size_pixels = line_size()[c] / 2;
1235 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1236 int const lines = sample_size(c).height;
1237 for (int y = 0; y < lines; ++y) {
1239 for (int x = 0; x < line_size_pixels; ++x) {
1240 *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1251 throw PixelFormatError ("fade()", _pixel_format);
1255 shared_ptr<const Image>
1256 Image::ensure_aligned (shared_ptr<const Image> image)
1258 if (image->aligned()) {
1262 return shared_ptr<Image> (new Image (image, true));
1266 Image::memory_used () const
1269 for (int i = 0; i < planes(); ++i) {
1270 m += _stride[i] * sample_size(i).height;
1293 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1295 Memory* mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1296 size_t size = mem->size + length;
1299 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1301 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1305 throw EncodeError (N_("could not allocate memory for PNG"));
1308 memcpy (mem->data + mem->size, data, length);
1309 mem->size += length;
1313 png_flush (png_structp)
1319 png_error_fn (png_structp png_ptr, char const * message)
1321 reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1325 Image::png_error (char const * message)
1327 throw EncodeError (String::compose ("Error during PNG write: %1", message));
1331 Image::as_png () const
1333 DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1334 DCPOMATIC_ASSERT (planes() == 1);
1335 if (pixel_format() != AV_PIX_FMT_RGBA) {
1336 return convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGBA, true, false)->as_png();
1339 /* error handling? */
1340 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1342 throw EncodeError (N_("could not create PNG write struct"));
1347 png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1349 png_infop info_ptr = png_create_info_struct(png_ptr);
1351 png_destroy_write_struct (&png_ptr, &info_ptr);
1352 throw EncodeError (N_("could not create PNG info struct"));
1355 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);
1357 png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1358 for (int i = 0; i < size().height; ++i) {
1359 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1362 png_write_info (png_ptr, info_ptr);
1363 png_write_image (png_ptr, row_pointers);
1364 png_write_end (png_ptr, info_ptr);
1366 png_destroy_write_struct (&png_ptr, &info_ptr);
1367 png_free (png_ptr, row_pointers);
1369 return dcp::ArrayData (state.data, state.size);
1374 Image::video_range_to_full_range ()
1376 switch (_pixel_format) {
1377 case AV_PIX_FMT_RGB24:
1379 float const factor = 256.0 / 219.0;
1380 uint8_t* p = data()[0];
1381 int const lines = sample_size(0).height;
1382 for (int y = 0; y < lines; ++y) {
1384 for (int x = 0; x < line_size()[0]; ++x) {
1385 *q = int((*q - 16) * factor);
1392 case AV_PIX_FMT_GBRP12LE:
1394 float const factor = 4096.0 / 3504.0;
1395 for (int c = 0; c < 3; ++c) {
1396 uint16_t* p = reinterpret_cast<uint16_t*>(data()[c]);
1397 int const lines = sample_size(c).height;
1398 for (int y = 0; y < lines; ++y) {
1400 int const line_size_pixels = line_size()[c] / 2;
1401 for (int x = 0; x < line_size_pixels; ++x) {
1402 *q = int((*q - 256) * factor);
1410 throw PixelFormatError ("video_range_to_full_range()", _pixel_format);