2 Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
6 DCP-o-matic is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 DCP-o-matic is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
21 /** @file src/image.cc
22 * @brief A class to describe a video image.
26 #include "exceptions.h"
30 #include "compose.hpp"
31 #include "dcpomatic_socket.h"
32 #include <dcp/rgb_xyz.h>
33 #include <dcp/transfer_function.h>
35 #include <libswscale/swscale.h>
36 #include <libavutil/pixfmt.h>
37 #include <libavutil/pixdesc.h>
38 #include <libavutil/frame.h>
41 #if HAVE_VALGRIND_MEMCHECK_H
42 #include <valgrind/memcheck.h>
54 using std::runtime_error;
55 using boost::shared_ptr;
59 Image::vertical_factor (int n) const
65 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
67 throw PixelFormatError ("line_factor()", _pixel_format);
70 return pow (2.0f, d->log2_chroma_h);
74 Image::horizontal_factor (int n) const
80 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
82 throw PixelFormatError ("sample_size()", _pixel_format);
85 return pow (2.0f, d->log2_chroma_w);
88 /** @param n Component index.
89 * @return Number of samples (i.e. pixels, unless sub-sampled) in each direction for this component.
92 Image::sample_size (int n) const
95 lrint (ceil (static_cast<double>(size().width) / horizontal_factor (n))),
96 lrint (ceil (static_cast<double>(size().height) / vertical_factor (n)))
100 /** @return Number of planes */
102 Image::planes () const
104 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
106 throw PixelFormatError ("planes()", _pixel_format);
109 if (_pixel_format == AV_PIX_FMT_PAL8) {
113 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
117 return d->nb_components;
120 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size'.
121 * @param crop Amount to crop by.
122 * @param inter_size Size to scale the cropped image to.
123 * @param out_size Size of output frame; if this is larger than inter_size there will be black padding.
124 * @param yuv_to_rgb YUV to RGB transformation to use, if required.
125 * @param video_range Video range of the image.
126 * @param out_format Output pixel format.
127 * @param out_aligned true to make the output image aligned.
128 * @param out_video_range Video range to use for the output image.
129 * @param fast Try to be fast at the possible expense of quality; at present this means using
130 * fast bilinear rather than bicubic scaling.
133 Image::crop_scale_window (
135 dcp::Size inter_size,
137 dcp::YUVToRGB yuv_to_rgb,
138 VideoRange video_range,
139 AVPixelFormat out_format,
140 VideoRange out_video_range,
145 /* Empirical testing suggests that sws_scale() will crash if
146 the input image is not aligned.
148 DCPOMATIC_ASSERT (aligned ());
150 DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
151 DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
153 shared_ptr<Image> out (new Image(out_format, out_size, out_aligned));
156 /* Size of the image after any crop */
157 dcp::Size const cropped_size = crop.apply (size ());
159 /* Scale context for a scale from cropped_size to inter_size */
160 struct SwsContext* scale_context = sws_getContext (
161 cropped_size.width, cropped_size.height, pixel_format(),
162 inter_size.width, inter_size.height, out_format,
163 fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
166 if (!scale_context) {
167 throw runtime_error (N_("Could not allocate SwsContext"));
170 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
171 int const lut[dcp::YUV_TO_RGB_COUNT] = {
176 /* The 3rd parameter here is:
177 0 -> source range MPEG (i.e. "video", 16-235)
178 1 -> source range JPEG (i.e. "full", 0-255)
180 0 -> destination range MPEG (i.e. "video", 16-235)
181 1 -> destination range JPEG (i.e. "full", 0-255)
183 But remember: sws_setColorspaceDetails ignores these
184 parameters unless the both source and destination images
185 are isYUV or isGray. (If either is not, it uses video range).
187 sws_setColorspaceDetails (
189 sws_getCoefficients (lut[yuv_to_rgb]), video_range == VIDEO_RANGE_VIDEO ? 0 : 1,
190 sws_getCoefficients (lut[yuv_to_rgb]), out_video_range == VIDEO_RANGE_VIDEO ? 0 : 1,
194 AVPixFmtDescriptor const * in_desc = av_pix_fmt_desc_get (_pixel_format);
196 throw PixelFormatError ("crop_scale_window()", _pixel_format);
199 /* Prepare input data pointers with crop */
200 uint8_t* scale_in_data[planes()];
201 for (int c = 0; c < planes(); ++c) {
202 /* To work out the crop in bytes, start by multiplying
203 the crop by the (average) bytes per pixel. Then
204 round down so that we don't crop a subsampled pixel until
205 we've cropped all of its Y-channel pixels.
207 int const x = lrintf (bytes_per_pixel(c) * crop.left) & ~ ((int) in_desc->log2_chroma_w);
208 scale_in_data[c] = data()[c] + x + stride()[c] * (crop.top / vertical_factor(c));
211 /* Corner of the image within out_size */
212 Position<int> const corner ((out_size.width - inter_size.width) / 2, (out_size.height - inter_size.height) / 2);
214 AVPixFmtDescriptor const * out_desc = av_pix_fmt_desc_get (out_format);
216 throw PixelFormatError ("crop_scale_window()", out_format);
219 uint8_t* scale_out_data[out->planes()];
220 for (int c = 0; c < out->planes(); ++c) {
221 /* See the note in the crop loop above */
222 int const x = lrintf (out->bytes_per_pixel(c) * corner.x) & ~ ((int) out_desc->log2_chroma_w);
223 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
228 scale_in_data, stride(),
229 0, cropped_size.height,
230 scale_out_data, out->stride()
233 sws_freeContext (scale_context);
235 if (crop != Crop() && cropped_size == inter_size && _pixel_format == out_format) {
236 /* We are cropping without any scaling or pixel format conversion, so FFmpeg may have left some
237 data behind in our image. Clear it out. It may get to the point where we should just stop
238 trying to be clever with cropping.
240 out->make_part_black (corner.x + cropped_size.width, out_size.width - cropped_size.width);
247 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
249 return scale(size(), yuv_to_rgb, out_format, out_aligned, fast);
252 /** @param out_size Size to scale to.
253 * @param yuv_to_rgb YUVToRGB transform transform to use, if required.
254 * @param out_format Output pixel format.
255 * @param out_aligned true to make an aligned output image.
256 * @param fast Try to be fast at the possible expense of quality; at present this means using
257 * fast bilinear rather than bicubic scaling.
260 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
262 /* Empirical testing suggests that sws_scale() will crash if
263 the input image is not aligned.
265 DCPOMATIC_ASSERT (aligned ());
267 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
269 struct SwsContext* scale_context = sws_getContext (
270 size().width, size().height, pixel_format(),
271 out_size.width, out_size.height, out_format,
272 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
275 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
276 int const lut[dcp::YUV_TO_RGB_COUNT] = {
281 /* The 3rd parameter here is:
282 0 -> source range MPEG (i.e. "video", 16-235)
283 1 -> source range JPEG (i.e. "full", 0-255)
285 0 -> destination range MPEG (i.e. "video", 16-235)
286 1 -> destination range JPEG (i.e. "full", 0-255)
288 But remember: sws_setColorspaceDetails ignores these
289 parameters unless the corresponding image isYUV or isGray.
290 (If it's neither, it uses video range).
292 sws_setColorspaceDetails (
294 sws_getCoefficients (lut[yuv_to_rgb]), 0,
295 sws_getCoefficients (lut[yuv_to_rgb]), 0,
303 scaled->data(), scaled->stride()
306 sws_freeContext (scale_context);
311 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
313 Image::yuv_16_black (uint16_t v, bool alpha)
315 memset (data()[0], 0, sample_size(0).height * stride()[0]);
316 for (int i = 1; i < 3; ++i) {
317 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
318 int const lines = sample_size(i).height;
319 for (int y = 0; y < lines; ++y) {
320 /* We divide by 2 here because we are writing 2 bytes at a time */
321 for (int x = 0; x < line_size()[i] / 2; ++x) {
324 p += stride()[i] / 2;
329 memset (data()[3], 0, sample_size(3).height * stride()[3]);
334 Image::swap_16 (uint16_t v)
336 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
340 Image::make_part_black (int x, int w)
342 switch (_pixel_format) {
343 case AV_PIX_FMT_RGB24:
344 case AV_PIX_FMT_ARGB:
345 case AV_PIX_FMT_RGBA:
346 case AV_PIX_FMT_ABGR:
347 case AV_PIX_FMT_BGRA:
348 case AV_PIX_FMT_RGB555LE:
349 case AV_PIX_FMT_RGB48LE:
350 case AV_PIX_FMT_RGB48BE:
351 case AV_PIX_FMT_XYZ12LE:
353 int const h = sample_size(0).height;
354 int const bpp = bytes_per_pixel(0);
355 int const s = stride()[0];
356 uint8_t* p = data()[0];
357 for (int y = 0; y < h; y++) {
358 memset (p + x * bpp, 0, w * bpp);
365 throw PixelFormatError ("make_part_black()", _pixel_format);
372 /* U/V black value for 8-bit colour */
373 static uint8_t const eight_bit_uv = (1 << 7) - 1;
374 /* U/V black value for 9-bit colour */
375 static uint16_t const nine_bit_uv = (1 << 8) - 1;
376 /* U/V black value for 10-bit colour */
377 static uint16_t const ten_bit_uv = (1 << 9) - 1;
378 /* U/V black value for 16-bit colour */
379 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
381 switch (_pixel_format) {
382 case AV_PIX_FMT_YUV420P:
383 case AV_PIX_FMT_YUV422P:
384 case AV_PIX_FMT_YUV444P:
385 case AV_PIX_FMT_YUV411P:
386 memset (data()[0], 0, sample_size(0).height * stride()[0]);
387 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
388 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
391 case AV_PIX_FMT_YUVJ420P:
392 case AV_PIX_FMT_YUVJ422P:
393 case AV_PIX_FMT_YUVJ444P:
394 memset (data()[0], 0, sample_size(0).height * stride()[0]);
395 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
396 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
399 case AV_PIX_FMT_YUV422P9LE:
400 case AV_PIX_FMT_YUV444P9LE:
401 yuv_16_black (nine_bit_uv, false);
404 case AV_PIX_FMT_YUV422P9BE:
405 case AV_PIX_FMT_YUV444P9BE:
406 yuv_16_black (swap_16 (nine_bit_uv), false);
409 case AV_PIX_FMT_YUV422P10LE:
410 case AV_PIX_FMT_YUV444P10LE:
411 yuv_16_black (ten_bit_uv, false);
414 case AV_PIX_FMT_YUV422P16LE:
415 case AV_PIX_FMT_YUV444P16LE:
416 yuv_16_black (sixteen_bit_uv, false);
419 case AV_PIX_FMT_YUV444P10BE:
420 case AV_PIX_FMT_YUV422P10BE:
421 yuv_16_black (swap_16 (ten_bit_uv), false);
424 case AV_PIX_FMT_YUVA420P9BE:
425 case AV_PIX_FMT_YUVA422P9BE:
426 case AV_PIX_FMT_YUVA444P9BE:
427 yuv_16_black (swap_16 (nine_bit_uv), true);
430 case AV_PIX_FMT_YUVA420P9LE:
431 case AV_PIX_FMT_YUVA422P9LE:
432 case AV_PIX_FMT_YUVA444P9LE:
433 yuv_16_black (nine_bit_uv, true);
436 case AV_PIX_FMT_YUVA420P10BE:
437 case AV_PIX_FMT_YUVA422P10BE:
438 case AV_PIX_FMT_YUVA444P10BE:
439 yuv_16_black (swap_16 (ten_bit_uv), true);
442 case AV_PIX_FMT_YUVA420P10LE:
443 case AV_PIX_FMT_YUVA422P10LE:
444 case AV_PIX_FMT_YUVA444P10LE:
445 yuv_16_black (ten_bit_uv, true);
448 case AV_PIX_FMT_YUVA420P16BE:
449 case AV_PIX_FMT_YUVA422P16BE:
450 case AV_PIX_FMT_YUVA444P16BE:
451 yuv_16_black (swap_16 (sixteen_bit_uv), true);
454 case AV_PIX_FMT_YUVA420P16LE:
455 case AV_PIX_FMT_YUVA422P16LE:
456 case AV_PIX_FMT_YUVA444P16LE:
457 yuv_16_black (sixteen_bit_uv, true);
460 case AV_PIX_FMT_RGB24:
461 case AV_PIX_FMT_ARGB:
462 case AV_PIX_FMT_RGBA:
463 case AV_PIX_FMT_ABGR:
464 case AV_PIX_FMT_BGRA:
465 case AV_PIX_FMT_RGB555LE:
466 case AV_PIX_FMT_RGB48LE:
467 case AV_PIX_FMT_RGB48BE:
468 case AV_PIX_FMT_XYZ12LE:
469 memset (data()[0], 0, sample_size(0).height * stride()[0]);
472 case AV_PIX_FMT_UYVY422:
474 int const Y = sample_size(0).height;
475 int const X = line_size()[0];
476 uint8_t* p = data()[0];
477 for (int y = 0; y < Y; ++y) {
478 for (int x = 0; x < X / 4; ++x) {
479 *p++ = eight_bit_uv; // Cb
481 *p++ = eight_bit_uv; // Cr
489 throw PixelFormatError ("make_black()", _pixel_format);
494 Image::make_transparent ()
496 if (_pixel_format != AV_PIX_FMT_BGRA && _pixel_format != AV_PIX_FMT_RGBA) {
497 throw PixelFormatError ("make_transparent()", _pixel_format);
500 memset (data()[0], 0, sample_size(0).height * stride()[0]);
504 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
506 /* We're blending RGBA or BGRA images */
507 DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA || other->pixel_format() == AV_PIX_FMT_RGBA);
508 int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
509 int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
511 int const other_bpp = 4;
513 int start_tx = position.x;
517 start_ox = -start_tx;
521 int start_ty = position.y;
525 start_oy = -start_ty;
529 switch (_pixel_format) {
530 case AV_PIX_FMT_RGB24:
532 /* Going onto RGB24. First byte is red, second green, third blue */
533 int const this_bpp = 3;
534 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
535 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
536 uint8_t* op = other->data()[0] + oy * other->stride()[0];
537 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
538 float const alpha = float (op[3]) / 255;
539 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
540 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
541 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
549 case AV_PIX_FMT_BGRA:
551 int const this_bpp = 4;
552 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
553 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
554 uint8_t* op = other->data()[0] + oy * other->stride()[0];
555 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
556 float const alpha = float (op[3]) / 255;
557 tp[0] = op[blue] * alpha + tp[0] * (1 - alpha);
558 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
559 tp[2] = op[red] * alpha + tp[2] * (1 - alpha);
560 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
568 case AV_PIX_FMT_RGBA:
570 int const this_bpp = 4;
571 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
572 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
573 uint8_t* op = other->data()[0] + oy * other->stride()[0];
574 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
575 float const alpha = float (op[3]) / 255;
576 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
577 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
578 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
579 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
587 case AV_PIX_FMT_RGB48LE:
589 int const this_bpp = 6;
590 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
591 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
592 uint8_t* op = other->data()[0] + oy * other->stride()[0];
593 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
594 float const alpha = float (op[3]) / 255;
595 /* Blend high bytes */
596 tp[1] = op[red] * alpha + tp[1] * (1 - alpha);
597 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
598 tp[5] = op[blue] * alpha + tp[5] * (1 - alpha);
606 case AV_PIX_FMT_XYZ12LE:
608 dcp::ColourConversion conv = dcp::ColourConversion::srgb_to_xyz();
609 double fast_matrix[9];
610 dcp::combined_rgb_to_xyz (conv, fast_matrix);
611 double const * lut_in = conv.in()->lut (8, false);
612 double const * lut_out = conv.out()->lut (16, true);
613 int const this_bpp = 6;
614 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
615 uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
616 uint8_t* op = other->data()[0] + oy * other->stride()[0];
617 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
618 float const alpha = float (op[3]) / 255;
620 /* Convert sRGB to XYZ; op is BGRA. First, input gamma LUT */
621 double const r = lut_in[op[red]];
622 double const g = lut_in[op[1]];
623 double const b = lut_in[op[blue]];
625 /* RGB to XYZ, including Bradford transform and DCI companding */
626 double const x = max (0.0, min (65535.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
627 double const y = max (0.0, min (65535.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
628 double const z = max (0.0, min (65535.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
630 /* Out gamma LUT and blend */
631 tp[0] = lrint(lut_out[lrint(x)] * 65535) * alpha + tp[0] * (1 - alpha);
632 tp[1] = lrint(lut_out[lrint(y)] * 65535) * alpha + tp[1] * (1 - alpha);
633 tp[2] = lrint(lut_out[lrint(z)] * 65535) * alpha + tp[2] * (1 - alpha);
641 case AV_PIX_FMT_YUV420P:
643 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
644 dcp::Size const ts = size();
645 dcp::Size const os = yuv->size();
646 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
647 int const hty = ty / 2;
648 int const hoy = oy / 2;
649 uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
650 uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
651 uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
652 uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
653 uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
654 uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
655 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
656 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
657 float const a = float(alpha[3]) / 255;
658 *tY = *oY * a + *tY * (1 - a);
659 *tU = *oU * a + *tU * (1 - a);
660 *tV = *oV * a + *tV * (1 - a);
676 case AV_PIX_FMT_YUV420P10:
678 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
679 dcp::Size const ts = size();
680 dcp::Size const os = yuv->size();
681 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
682 int const hty = ty / 2;
683 int const hoy = oy / 2;
684 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
685 uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
686 uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
687 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
688 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
689 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
690 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
691 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
692 float const a = float(alpha[3]) / 255;
693 *tY = *oY * a + *tY * (1 - a);
694 *tU = *oU * a + *tU * (1 - a);
695 *tV = *oV * a + *tV * (1 - a);
711 case AV_PIX_FMT_YUV422P10LE:
713 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
714 dcp::Size const ts = size();
715 dcp::Size const os = yuv->size();
716 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
717 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
718 uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
719 uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
720 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
721 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
722 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
723 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
724 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
725 float const a = float(alpha[3]) / 255;
726 *tY = *oY * a + *tY * (1 - a);
727 *tU = *oU * a + *tU * (1 - a);
728 *tV = *oV * a + *tV * (1 - a);
745 throw PixelFormatError ("alpha_blend()", _pixel_format);
750 Image::copy (shared_ptr<const Image> other, Position<int> position)
752 /* Only implemented for RGB24 onto RGB24 so far */
753 DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
754 DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
756 int const N = min (position.x + other->size().width, size().width) - position.x;
757 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
758 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
759 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
760 memcpy (tp, op, N * 3);
765 Image::read_from_socket (shared_ptr<Socket> socket)
767 for (int i = 0; i < planes(); ++i) {
768 uint8_t* p = data()[i];
769 int const lines = sample_size(i).height;
770 for (int y = 0; y < lines; ++y) {
771 socket->read (p, line_size()[i]);
778 Image::write_to_socket (shared_ptr<Socket> socket) const
780 for (int i = 0; i < planes(); ++i) {
781 uint8_t* p = data()[i];
782 int const lines = sample_size(i).height;
783 for (int y = 0; y < lines; ++y) {
784 socket->write (p, line_size()[i]);
791 Image::bytes_per_pixel (int c) const
793 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
795 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
802 float bpp[4] = { 0, 0, 0, 0 };
804 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
805 bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
806 if (d->nb_components > 1) {
807 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
809 if (d->nb_components > 2) {
810 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
812 if (d->nb_components > 3) {
813 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
816 bpp[0] = floor ((d->comp[0].depth + 7) / 8);
817 if (d->nb_components > 1) {
818 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
820 if (d->nb_components > 2) {
821 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
823 if (d->nb_components > 3) {
824 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
828 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
829 /* Not planar; sum them up */
830 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
836 /** Construct a Image of a given size and format, allocating memory
839 * @param p Pixel format.
840 * @param s Size in pixels.
841 * @param aligned true to make each row of this image aligned to a 32-byte boundary.
843 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned)
854 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
855 _data[0] = _data[1] = _data[2] = _data[3] = 0;
857 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
858 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
860 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
861 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
863 for (int i = 0; i < planes(); ++i) {
864 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
865 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
867 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
868 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
869 Hence on the last pixel of the last line it reads over the end of
870 the actual data by 1 byte. If the width of an image is a multiple
871 of the stride alignment there will be no padding at the end of image lines.
872 OS X crashes on this illegal read, though other operating systems don't
873 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
874 for that instruction to read safely.
876 Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
877 over-reads by more then _avx. I can't follow the code to work out how much,
878 so I'll just over-allocate by 32 bytes and have done with it. Empirical
879 testing suggests that it works.
881 In addition to these concerns, we may read/write as much as a whole extra line
882 at the end of each plane in cases where we are messing with offsets in order to
883 do pad or crop. To solve this we over-allocate by an extra _stride[i] bytes.
885 As an example: we may write to images starting at an offset so we get some padding.
886 Hence we want to write in the following pattern:
888 block start write start line end
889 |..(padding)..|<------line-size------------->|..(padding)..|
890 |..(padding)..|<------line-size------------->|..(padding)..|
891 |..(padding)..|<------line-size------------->|..(padding)..|
893 where line-size is of the smaller (inter_size) image and the full padded line length is that of
894 out_size. To get things to work we have to tell FFmpeg that the stride is that of out_size.
895 However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
896 specified *stride*. This does not matter until we get to the last line:
898 block start write start line end
899 |..(padding)..|<------line-size------------->|XXXwrittenXXX|
900 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
901 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
904 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * (sample_size(i).height + 1) + 32);
905 #if HAVE_VALGRIND_MEMCHECK_H
906 /* The data between the end of the line size and the stride is undefined but processed by
907 libswscale, causing lots of valgrind errors. Mark it all defined to quell these errors.
909 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * (sample_size(i).height + 1) + 32);
914 Image::Image (Image const & other)
915 : boost::enable_shared_from_this<Image>(other)
916 , _size (other._size)
917 , _pixel_format (other._pixel_format)
918 , _aligned (other._aligned)
922 for (int i = 0; i < planes(); ++i) {
923 uint8_t* p = _data[i];
924 uint8_t* q = other._data[i];
925 int const lines = sample_size(i).height;
926 for (int j = 0; j < lines; ++j) {
927 memcpy (p, q, _line_size[i]);
929 q += other.stride()[i];
934 Image::Image (AVFrame* frame)
935 : _size (frame->width, frame->height)
936 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
941 for (int i = 0; i < planes(); ++i) {
942 uint8_t* p = _data[i];
943 uint8_t* q = frame->data[i];
944 int const lines = sample_size(i).height;
945 for (int j = 0; j < lines; ++j) {
946 memcpy (p, q, _line_size[i]);
948 /* AVFrame's linesize is what we call `stride' */
949 q += frame->linesize[i];
954 Image::Image (shared_ptr<const Image> other, bool aligned)
955 : _size (other->_size)
956 , _pixel_format (other->_pixel_format)
961 for (int i = 0; i < planes(); ++i) {
962 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[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];
975 Image::operator= (Image const & other)
977 if (this == &other) {
987 Image::swap (Image & other)
989 std::swap (_size, other._size);
990 std::swap (_pixel_format, other._pixel_format);
992 for (int i = 0; i < 4; ++i) {
993 std::swap (_data[i], other._data[i]);
994 std::swap (_line_size[i], other._line_size[i]);
995 std::swap (_stride[i], other._stride[i]);
998 std::swap (_aligned, other._aligned);
1003 for (int i = 0; i < planes(); ++i) {
1008 av_free (_line_size);
1013 Image::data () const
1019 Image::line_size () const
1025 Image::stride () const
1031 Image::size () const
1037 Image::aligned () const
1043 merge (list<PositionImage> images)
1045 if (images.empty ()) {
1046 return PositionImage ();
1049 if (images.size() == 1) {
1050 return images.front ();
1053 dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1054 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1055 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
1058 shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
1059 merged->make_transparent ();
1060 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1061 merged->alpha_blend (i->image, i->position - all.position());
1064 return PositionImage (merged, all.position ());
1068 operator== (Image const & a, Image const & b)
1070 if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1074 for (int c = 0; c < a.planes(); ++c) {
1075 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]) {
1079 uint8_t* p = a.data()[c];
1080 uint8_t* q = b.data()[c];
1081 int const lines = a.sample_size(c).height;
1082 for (int y = 0; y < lines; ++y) {
1083 if (memcmp (p, q, a.line_size()[c]) != 0) {
1096 * @param f Amount to fade by; 0 is black, 1 is no fade.
1099 Image::fade (float f)
1101 /* U/V black value for 8-bit colour */
1102 static int const eight_bit_uv = (1 << 7) - 1;
1103 /* U/V black value for 10-bit colour */
1104 static uint16_t const ten_bit_uv = (1 << 9) - 1;
1106 switch (_pixel_format) {
1107 case AV_PIX_FMT_YUV420P:
1110 uint8_t* p = data()[0];
1111 int const lines = sample_size(0).height;
1112 for (int y = 0; y < lines; ++y) {
1114 for (int x = 0; x < line_size()[0]; ++x) {
1115 *q = int(float(*q) * f);
1122 for (int c = 1; c < 3; ++c) {
1123 uint8_t* p = data()[c];
1124 int const lines = sample_size(c).height;
1125 for (int y = 0; y < lines; ++y) {
1127 for (int x = 0; x < line_size()[c]; ++x) {
1128 *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1138 case AV_PIX_FMT_RGB24:
1141 uint8_t* p = data()[0];
1142 int const lines = sample_size(0).height;
1143 for (int y = 0; y < lines; ++y) {
1145 for (int x = 0; x < line_size()[0]; ++x) {
1146 *q = int (float (*q) * f);
1154 case AV_PIX_FMT_XYZ12LE:
1155 case AV_PIX_FMT_RGB48LE:
1156 /* 16-bit little-endian */
1157 for (int c = 0; c < 3; ++c) {
1158 int const stride_pixels = stride()[c] / 2;
1159 int const line_size_pixels = line_size()[c] / 2;
1160 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1161 int const lines = sample_size(c).height;
1162 for (int y = 0; y < lines; ++y) {
1164 for (int x = 0; x < line_size_pixels; ++x) {
1165 *q = int (float (*q) * f);
1173 case AV_PIX_FMT_YUV422P10LE:
1177 int const stride_pixels = stride()[0] / 2;
1178 int const line_size_pixels = line_size()[0] / 2;
1179 uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1180 int const lines = sample_size(0).height;
1181 for (int y = 0; y < lines; ++y) {
1183 for (int x = 0; x < line_size_pixels; ++x) {
1184 *q = int(float(*q) * f);
1192 for (int c = 1; c < 3; ++c) {
1193 int const stride_pixels = stride()[c] / 2;
1194 int const line_size_pixels = line_size()[c] / 2;
1195 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1196 int const lines = sample_size(c).height;
1197 for (int y = 0; y < lines; ++y) {
1199 for (int x = 0; x < line_size_pixels; ++x) {
1200 *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1211 throw PixelFormatError ("fade()", _pixel_format);
1215 shared_ptr<const Image>
1216 Image::ensure_aligned (shared_ptr<const Image> image)
1218 if (image->aligned()) {
1222 return shared_ptr<Image> (new Image (image, true));
1226 Image::memory_used () const
1229 for (int i = 0; i < planes(); ++i) {
1230 m += _stride[i] * sample_size(i).height;
1253 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1255 Memory* mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1256 size_t size = mem->size + length;
1259 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1261 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1265 throw EncodeError (N_("could not allocate memory for PNG"));
1268 memcpy (mem->data + mem->size, data, length);
1269 mem->size += length;
1273 png_flush (png_structp)
1279 png_error_fn (png_structp png_ptr, char const * message)
1281 reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1285 Image::png_error (char const * message)
1287 throw EncodeError (String::compose ("Error during PNG write: %1", message));
1291 Image::as_png () const
1293 DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1294 DCPOMATIC_ASSERT (planes() == 1);
1295 if (pixel_format() != AV_PIX_FMT_RGBA) {
1296 return convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGBA, true, false)->as_png();
1299 /* error handling? */
1300 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1302 throw EncodeError (N_("could not create PNG write struct"));
1307 png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1309 png_infop info_ptr = png_create_info_struct(png_ptr);
1311 png_destroy_write_struct (&png_ptr, &info_ptr);
1312 throw EncodeError (N_("could not create PNG info struct"));
1315 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);
1317 png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1318 for (int i = 0; i < size().height; ++i) {
1319 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1322 png_write_info (png_ptr, info_ptr);
1323 png_write_image (png_ptr, row_pointers);
1324 png_write_end (png_ptr, info_ptr);
1326 png_destroy_write_struct (&png_ptr, &info_ptr);
1327 png_free (png_ptr, row_pointers);
1329 return dcp::ArrayData (state.data, state.size);
1334 Image::video_range_to_full_range ()
1336 switch (_pixel_format) {
1337 case AV_PIX_FMT_RGB24:
1339 float const factor = 256.0 / 219.0;
1340 uint8_t* p = data()[0];
1341 int const lines = sample_size(0).height;
1342 for (int y = 0; y < lines; ++y) {
1344 for (int x = 0; x < line_size()[0]; ++x) {
1345 *q = int((*q - 16) * factor);
1352 case AV_PIX_FMT_GBRP12LE:
1354 float const factor = 4096.0 / 3504.0;
1355 for (int c = 0; c < 3; ++c) {
1356 uint16_t* p = reinterpret_cast<uint16_t*>(data()[c]);
1357 int const lines = sample_size(c).height;
1358 for (int y = 0; y < lines; ++y) {
1360 int const line_size_pixels = line_size()[c] / 2;
1361 for (int x = 0; x < line_size_pixels; ++x) {
1362 *q = int((*q - 256) * factor);
1370 throw PixelFormatError ("video_range_to_full_range()", _pixel_format);