2 Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
6 DCP-o-matic is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 DCP-o-matic is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
21 /** @file src/image.cc
22 * @brief A class to describe a video image.
26 #include "exceptions.h"
30 #include "compose.hpp"
31 #include "dcpomatic_socket.h"
32 #include <dcp/rgb_xyz.h>
33 #include <dcp/transfer_function.h>
35 #include <libswscale/swscale.h>
36 #include <libavutil/pixfmt.h>
37 #include <libavutil/pixdesc.h>
38 #include <libavutil/frame.h>
41 #if HAVE_VALGRIND_MEMCHECK_H
42 #include <valgrind/memcheck.h>
54 using std::runtime_error;
55 using boost::shared_ptr;
59 Image::vertical_factor (int n) const
65 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
67 throw PixelFormatError ("line_factor()", _pixel_format);
70 return pow (2.0f, d->log2_chroma_h);
74 Image::horizontal_factor (int n) const
80 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
82 throw PixelFormatError ("sample_size()", _pixel_format);
85 return pow (2.0f, d->log2_chroma_w);
88 /** @param n Component index.
89 * @return Number of samples (i.e. pixels, unless sub-sampled) in each direction for this component.
92 Image::sample_size (int n) const
95 lrint (ceil (static_cast<double>(size().width) / horizontal_factor (n))),
96 lrint (ceil (static_cast<double>(size().height) / vertical_factor (n)))
100 /** @return Number of planes */
102 Image::planes () const
104 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
106 throw PixelFormatError ("planes()", _pixel_format);
109 if (_pixel_format == AV_PIX_FMT_PAL8) {
113 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
117 return d->nb_components;
120 /** Crop this image, scale it to `inter_size' and then place it in a black frame of `out_size'.
121 * @param crop Amount to crop by.
122 * @param inter_size Size to scale the cropped image to.
123 * @param out_size Size of output frame; if this is larger than inter_size there will be black padding.
124 * @param yuv_to_rgb YUV to RGB transformation to use, if required.
125 * @param out_format Output pixel format.
126 * @param out_aligned true to make the output image aligned.
127 * @param fast Try to be fast at the possible expense of quality; at present this means using
128 * fast bilinear rather than bicubic scaling.
131 Image::crop_scale_window (
132 Crop crop, dcp::Size inter_size, dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, VideoRange video_range, AVPixelFormat out_format, bool out_aligned, bool fast
135 /* Empirical testing suggests that sws_scale() will crash if
136 the input image is not aligned.
138 DCPOMATIC_ASSERT (aligned ());
140 DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
141 DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
143 shared_ptr<Image> out (new Image(out_format, out_size, out_aligned));
146 /* Size of the image after any crop */
147 dcp::Size const cropped_size = crop.apply (size ());
149 /* Scale context for a scale from cropped_size to inter_size */
150 struct SwsContext* scale_context = sws_getContext (
151 cropped_size.width, cropped_size.height, pixel_format(),
152 inter_size.width, inter_size.height, out_format,
153 fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
156 if (!scale_context) {
157 throw runtime_error (N_("Could not allocate SwsContext"));
160 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
161 int const lut[dcp::YUV_TO_RGB_COUNT] = {
166 /* The 3rd parameter here is:
167 0 -> source range MPEG (i.e. "video", 16-235)
168 1 -> source range JPEG (i.e. "full", 0-255)
170 0 -> destination range MPEG (i.e. "video", 16-235)
171 1 -> destination range JPEG (i.e. "full", 0-255)
173 But remember: sws_setColorspaceDetails ignores these
174 parameters unless the corresponding image isYUV or isGray.
175 (If it's neither, it uses video range).
177 sws_setColorspaceDetails (
179 sws_getCoefficients (lut[yuv_to_rgb]), video_range == VIDEO_RANGE_VIDEO ? 0 : 1,
180 sws_getCoefficients (lut[yuv_to_rgb]), 1,
184 AVPixFmtDescriptor const * in_desc = av_pix_fmt_desc_get (_pixel_format);
186 throw PixelFormatError ("crop_scale_window()", _pixel_format);
189 /* Prepare input data pointers with crop */
190 uint8_t* scale_in_data[planes()];
191 for (int c = 0; c < planes(); ++c) {
192 /* To work out the crop in bytes, start by multiplying
193 the crop by the (average) bytes per pixel. Then
194 round down so that we don't crop a subsampled pixel until
195 we've cropped all of its Y-channel pixels.
197 int const x = lrintf (bytes_per_pixel(c) * crop.left) & ~ ((int) in_desc->log2_chroma_w);
198 scale_in_data[c] = data()[c] + x + stride()[c] * (crop.top / vertical_factor(c));
201 /* Corner of the image within out_size */
202 Position<int> const corner ((out_size.width - inter_size.width) / 2, (out_size.height - inter_size.height) / 2);
204 AVPixFmtDescriptor const * out_desc = av_pix_fmt_desc_get (out_format);
206 throw PixelFormatError ("crop_scale_window()", out_format);
209 uint8_t* scale_out_data[out->planes()];
210 for (int c = 0; c < out->planes(); ++c) {
211 /* See the note in the crop loop above */
212 int const x = lrintf (out->bytes_per_pixel(c) * corner.x) & ~ ((int) out_desc->log2_chroma_w);
213 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
218 scale_in_data, stride(),
219 0, cropped_size.height,
220 scale_out_data, out->stride()
223 sws_freeContext (scale_context);
225 if (crop != Crop() && cropped_size == inter_size && _pixel_format == out_format) {
226 /* We are cropping without any scaling or pixel format conversion, so FFmpeg may have left some
227 data behind in our image. Clear it out. It may get to the point where we should just stop
228 trying to be clever with cropping.
230 out->make_part_black (corner.x + cropped_size.width, out_size.width - cropped_size.width);
237 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
239 return scale(size(), yuv_to_rgb, out_format, out_aligned, fast);
242 /** @param out_size Size to scale to.
243 * @param yuv_to_rgb YUVToRGB transform transform to use, if required.
244 * @param out_format Output pixel format.
245 * @param out_aligned true to make an aligned output image.
246 * @param fast Try to be fast at the possible expense of quality; at present this means using
247 * fast bilinear rather than bicubic scaling.
250 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
252 /* Empirical testing suggests that sws_scale() will crash if
253 the input image is not aligned.
255 DCPOMATIC_ASSERT (aligned ());
257 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
259 struct SwsContext* scale_context = sws_getContext (
260 size().width, size().height, pixel_format(),
261 out_size.width, out_size.height, out_format,
262 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
265 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
266 int const lut[dcp::YUV_TO_RGB_COUNT] = {
271 /* The 3rd parameter here is:
272 0 -> source range MPEG (i.e. "video", 16-235)
273 1 -> source range JPEG (i.e. "full", 0-255)
275 0 -> destination range MPEG (i.e. "video", 16-235)
276 1 -> destination range JPEG (i.e. "full", 0-255)
278 But remember: sws_setColorspaceDetails ignores these
279 parameters unless the corresponding image isYUV or isGray.
280 (If it's neither, it uses video range).
282 sws_setColorspaceDetails (
284 sws_getCoefficients (lut[yuv_to_rgb]), 0,
285 sws_getCoefficients (lut[yuv_to_rgb]), 0,
293 scaled->data(), scaled->stride()
296 sws_freeContext (scale_context);
301 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
303 Image::yuv_16_black (uint16_t v, bool alpha)
305 memset (data()[0], 0, sample_size(0).height * stride()[0]);
306 for (int i = 1; i < 3; ++i) {
307 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
308 int const lines = sample_size(i).height;
309 for (int y = 0; y < lines; ++y) {
310 /* We divide by 2 here because we are writing 2 bytes at a time */
311 for (int x = 0; x < line_size()[i] / 2; ++x) {
314 p += stride()[i] / 2;
319 memset (data()[3], 0, sample_size(3).height * stride()[3]);
324 Image::swap_16 (uint16_t v)
326 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
330 Image::make_part_black (int x, int w)
332 switch (_pixel_format) {
333 case AV_PIX_FMT_RGB24:
334 case AV_PIX_FMT_ARGB:
335 case AV_PIX_FMT_RGBA:
336 case AV_PIX_FMT_ABGR:
337 case AV_PIX_FMT_BGRA:
338 case AV_PIX_FMT_RGB555LE:
339 case AV_PIX_FMT_RGB48LE:
340 case AV_PIX_FMT_RGB48BE:
341 case AV_PIX_FMT_XYZ12LE:
343 int const h = sample_size(0).height;
344 int const bpp = bytes_per_pixel(0);
345 int const s = stride()[0];
346 uint8_t* p = data()[0];
347 for (int y = 0; y < h; y++) {
348 memset (p + x * bpp, 0, w * bpp);
355 throw PixelFormatError ("make_part_black()", _pixel_format);
362 /* U/V black value for 8-bit colour */
363 static uint8_t const eight_bit_uv = (1 << 7) - 1;
364 /* U/V black value for 9-bit colour */
365 static uint16_t const nine_bit_uv = (1 << 8) - 1;
366 /* U/V black value for 10-bit colour */
367 static uint16_t const ten_bit_uv = (1 << 9) - 1;
368 /* U/V black value for 16-bit colour */
369 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
371 switch (_pixel_format) {
372 case AV_PIX_FMT_YUV420P:
373 case AV_PIX_FMT_YUV422P:
374 case AV_PIX_FMT_YUV444P:
375 case AV_PIX_FMT_YUV411P:
376 memset (data()[0], 0, sample_size(0).height * stride()[0]);
377 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
378 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
381 case AV_PIX_FMT_YUVJ420P:
382 case AV_PIX_FMT_YUVJ422P:
383 case AV_PIX_FMT_YUVJ444P:
384 memset (data()[0], 0, sample_size(0).height * stride()[0]);
385 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
386 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
389 case AV_PIX_FMT_YUV422P9LE:
390 case AV_PIX_FMT_YUV444P9LE:
391 yuv_16_black (nine_bit_uv, false);
394 case AV_PIX_FMT_YUV422P9BE:
395 case AV_PIX_FMT_YUV444P9BE:
396 yuv_16_black (swap_16 (nine_bit_uv), false);
399 case AV_PIX_FMT_YUV422P10LE:
400 case AV_PIX_FMT_YUV444P10LE:
401 yuv_16_black (ten_bit_uv, false);
404 case AV_PIX_FMT_YUV422P16LE:
405 case AV_PIX_FMT_YUV444P16LE:
406 yuv_16_black (sixteen_bit_uv, false);
409 case AV_PIX_FMT_YUV444P10BE:
410 case AV_PIX_FMT_YUV422P10BE:
411 yuv_16_black (swap_16 (ten_bit_uv), false);
414 case AV_PIX_FMT_YUVA420P9BE:
415 case AV_PIX_FMT_YUVA422P9BE:
416 case AV_PIX_FMT_YUVA444P9BE:
417 yuv_16_black (swap_16 (nine_bit_uv), true);
420 case AV_PIX_FMT_YUVA420P9LE:
421 case AV_PIX_FMT_YUVA422P9LE:
422 case AV_PIX_FMT_YUVA444P9LE:
423 yuv_16_black (nine_bit_uv, true);
426 case AV_PIX_FMT_YUVA420P10BE:
427 case AV_PIX_FMT_YUVA422P10BE:
428 case AV_PIX_FMT_YUVA444P10BE:
429 yuv_16_black (swap_16 (ten_bit_uv), true);
432 case AV_PIX_FMT_YUVA420P10LE:
433 case AV_PIX_FMT_YUVA422P10LE:
434 case AV_PIX_FMT_YUVA444P10LE:
435 yuv_16_black (ten_bit_uv, true);
438 case AV_PIX_FMT_YUVA420P16BE:
439 case AV_PIX_FMT_YUVA422P16BE:
440 case AV_PIX_FMT_YUVA444P16BE:
441 yuv_16_black (swap_16 (sixteen_bit_uv), true);
444 case AV_PIX_FMT_YUVA420P16LE:
445 case AV_PIX_FMT_YUVA422P16LE:
446 case AV_PIX_FMT_YUVA444P16LE:
447 yuv_16_black (sixteen_bit_uv, true);
450 case AV_PIX_FMT_RGB24:
451 case AV_PIX_FMT_ARGB:
452 case AV_PIX_FMT_RGBA:
453 case AV_PIX_FMT_ABGR:
454 case AV_PIX_FMT_BGRA:
455 case AV_PIX_FMT_RGB555LE:
456 case AV_PIX_FMT_RGB48LE:
457 case AV_PIX_FMT_RGB48BE:
458 case AV_PIX_FMT_XYZ12LE:
459 memset (data()[0], 0, sample_size(0).height * stride()[0]);
462 case AV_PIX_FMT_UYVY422:
464 int const Y = sample_size(0).height;
465 int const X = line_size()[0];
466 uint8_t* p = data()[0];
467 for (int y = 0; y < Y; ++y) {
468 for (int x = 0; x < X / 4; ++x) {
469 *p++ = eight_bit_uv; // Cb
471 *p++ = eight_bit_uv; // Cr
479 throw PixelFormatError ("make_black()", _pixel_format);
484 Image::make_transparent ()
486 if (_pixel_format != AV_PIX_FMT_BGRA && _pixel_format != AV_PIX_FMT_RGBA) {
487 throw PixelFormatError ("make_transparent()", _pixel_format);
490 memset (data()[0], 0, sample_size(0).height * stride()[0]);
494 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
496 /* We're blending RGBA or BGRA images */
497 DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA || other->pixel_format() == AV_PIX_FMT_RGBA);
498 int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
499 int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
501 int const other_bpp = 4;
503 int start_tx = position.x;
507 start_ox = -start_tx;
511 int start_ty = position.y;
515 start_oy = -start_ty;
519 switch (_pixel_format) {
520 case AV_PIX_FMT_RGB24:
522 /* Going onto RGB24. First byte is red, second green, third blue */
523 int const this_bpp = 3;
524 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
525 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
526 uint8_t* op = other->data()[0] + oy * other->stride()[0];
527 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
528 float const alpha = float (op[3]) / 255;
529 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
530 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
531 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
539 case AV_PIX_FMT_BGRA:
541 int const this_bpp = 4;
542 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
543 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
544 uint8_t* op = other->data()[0] + oy * other->stride()[0];
545 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
546 float const alpha = float (op[3]) / 255;
547 tp[0] = op[blue] * alpha + tp[0] * (1 - alpha);
548 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
549 tp[2] = op[red] * alpha + tp[2] * (1 - alpha);
550 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
558 case AV_PIX_FMT_RGBA:
560 int const this_bpp = 4;
561 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
562 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
563 uint8_t* op = other->data()[0] + oy * other->stride()[0];
564 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
565 float const alpha = float (op[3]) / 255;
566 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
567 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
568 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
569 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
577 case AV_PIX_FMT_RGB48LE:
579 int const this_bpp = 6;
580 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
581 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
582 uint8_t* op = other->data()[0] + oy * other->stride()[0];
583 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
584 float const alpha = float (op[3]) / 255;
585 /* Blend high bytes */
586 tp[1] = op[red] * alpha + tp[1] * (1 - alpha);
587 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
588 tp[5] = op[blue] * alpha + tp[5] * (1 - alpha);
596 case AV_PIX_FMT_XYZ12LE:
598 dcp::ColourConversion conv = dcp::ColourConversion::srgb_to_xyz();
599 double fast_matrix[9];
600 dcp::combined_rgb_to_xyz (conv, fast_matrix);
601 double const * lut_in = conv.in()->lut (8, false);
602 double const * lut_out = conv.out()->lut (16, true);
603 int const this_bpp = 6;
604 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
605 uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
606 uint8_t* op = other->data()[0] + oy * other->stride()[0];
607 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
608 float const alpha = float (op[3]) / 255;
610 /* Convert sRGB to XYZ; op is BGRA. First, input gamma LUT */
611 double const r = lut_in[op[red]];
612 double const g = lut_in[op[1]];
613 double const b = lut_in[op[blue]];
615 /* RGB to XYZ, including Bradford transform and DCI companding */
616 double const x = max (0.0, min (65535.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
617 double const y = max (0.0, min (65535.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
618 double const z = max (0.0, min (65535.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
620 /* Out gamma LUT and blend */
621 tp[0] = lrint(lut_out[lrint(x)] * 65535) * alpha + tp[0] * (1 - alpha);
622 tp[1] = lrint(lut_out[lrint(y)] * 65535) * alpha + tp[1] * (1 - alpha);
623 tp[2] = lrint(lut_out[lrint(z)] * 65535) * alpha + tp[2] * (1 - alpha);
631 case AV_PIX_FMT_YUV420P:
633 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
634 dcp::Size const ts = size();
635 dcp::Size const os = yuv->size();
636 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
637 int const hty = ty / 2;
638 int const hoy = oy / 2;
639 uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
640 uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
641 uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
642 uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
643 uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
644 uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
645 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
646 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
647 float const a = float(alpha[3]) / 255;
648 *tY = *oY * a + *tY * (1 - a);
649 *tU = *oU * a + *tU * (1 - a);
650 *tV = *oV * a + *tV * (1 - a);
666 case AV_PIX_FMT_YUV420P10:
668 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
669 dcp::Size const ts = size();
670 dcp::Size const os = yuv->size();
671 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
672 int const hty = ty / 2;
673 int const hoy = oy / 2;
674 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
675 uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
676 uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
677 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
678 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
679 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
680 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
681 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
682 float const a = float(alpha[3]) / 255;
683 *tY = *oY * a + *tY * (1 - a);
684 *tU = *oU * a + *tU * (1 - a);
685 *tV = *oV * a + *tV * (1 - a);
701 case AV_PIX_FMT_YUV422P10LE:
703 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
704 dcp::Size const ts = size();
705 dcp::Size const os = yuv->size();
706 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
707 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
708 uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
709 uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
710 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
711 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
712 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
713 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
714 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
715 float const a = float(alpha[3]) / 255;
716 *tY = *oY * a + *tY * (1 - a);
717 *tU = *oU * a + *tU * (1 - a);
718 *tV = *oV * a + *tV * (1 - a);
735 throw PixelFormatError ("alpha_blend()", _pixel_format);
740 Image::copy (shared_ptr<const Image> other, Position<int> position)
742 /* Only implemented for RGB24 onto RGB24 so far */
743 DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
744 DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
746 int const N = min (position.x + other->size().width, size().width) - position.x;
747 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
748 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
749 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
750 memcpy (tp, op, N * 3);
755 Image::read_from_socket (shared_ptr<Socket> socket)
757 for (int i = 0; i < planes(); ++i) {
758 uint8_t* p = data()[i];
759 int const lines = sample_size(i).height;
760 for (int y = 0; y < lines; ++y) {
761 socket->read (p, line_size()[i]);
768 Image::write_to_socket (shared_ptr<Socket> socket) const
770 for (int i = 0; i < planes(); ++i) {
771 uint8_t* p = data()[i];
772 int const lines = sample_size(i).height;
773 for (int y = 0; y < lines; ++y) {
774 socket->write (p, line_size()[i]);
781 Image::bytes_per_pixel (int c) const
783 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
785 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
792 float bpp[4] = { 0, 0, 0, 0 };
794 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
795 bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
796 if (d->nb_components > 1) {
797 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
799 if (d->nb_components > 2) {
800 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
802 if (d->nb_components > 3) {
803 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
806 bpp[0] = floor ((d->comp[0].depth + 7) / 8);
807 if (d->nb_components > 1) {
808 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
810 if (d->nb_components > 2) {
811 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
813 if (d->nb_components > 3) {
814 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
818 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
819 /* Not planar; sum them up */
820 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
826 /** Construct a Image of a given size and format, allocating memory
829 * @param p Pixel format.
830 * @param s Size in pixels.
831 * @param aligned true to make each row of this image aligned to a 32-byte boundary.
833 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned)
844 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
845 _data[0] = _data[1] = _data[2] = _data[3] = 0;
847 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
848 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
850 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
851 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
853 for (int i = 0; i < planes(); ++i) {
854 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
855 _stride[i] = stride_round_up (i, _line_size, _aligned ? 32 : 1);
857 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
858 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
859 Hence on the last pixel of the last line it reads over the end of
860 the actual data by 1 byte. If the width of an image is a multiple
861 of the stride alignment there will be no padding at the end of image lines.
862 OS X crashes on this illegal read, though other operating systems don't
863 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
864 for that instruction to read safely.
866 Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
867 over-reads by more then _avx. I can't follow the code to work out how much,
868 so I'll just over-allocate by 32 bytes and have done with it. Empirical
869 testing suggests that it works.
871 In addition to these concerns, we may read/write as much as a whole extra line
872 at the end of each plane in cases where we are messing with offsets in order to
873 do pad or crop. To solve this we over-allocate by an extra _stride[i] bytes.
875 As an example: we may write to images starting at an offset so we get some padding.
876 Hence we want to write in the following pattern:
878 block start write start line end
879 |..(padding)..|<------line-size------------->|..(padding)..|
880 |..(padding)..|<------line-size------------->|..(padding)..|
881 |..(padding)..|<------line-size------------->|..(padding)..|
883 where line-size is of the smaller (inter_size) image and the full padded line length is that of
884 out_size. To get things to work we have to tell FFmpeg that the stride is that of out_size.
885 However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
886 specified *stride*. This does not matter until we get to the last line:
888 block start write start line end
889 |..(padding)..|<------line-size------------->|XXXwrittenXXX|
890 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
891 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
894 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * (sample_size(i).height + 1) + 32);
895 #if HAVE_VALGRIND_MEMCHECK_H
896 /* The data between the end of the line size and the stride is undefined but processed by
897 libswscale, causing lots of valgrind errors. Mark it all defined to quell these errors.
899 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * (sample_size(i).height + 1) + 32);
904 Image::Image (Image const & other)
905 : boost::enable_shared_from_this<Image>(other)
906 , _size (other._size)
907 , _pixel_format (other._pixel_format)
908 , _aligned (other._aligned)
912 for (int i = 0; i < planes(); ++i) {
913 uint8_t* p = _data[i];
914 uint8_t* q = other._data[i];
915 int const lines = sample_size(i).height;
916 for (int j = 0; j < lines; ++j) {
917 memcpy (p, q, _line_size[i]);
919 q += other.stride()[i];
924 Image::Image (AVFrame* frame)
925 : _size (frame->width, frame->height)
926 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
931 for (int i = 0; i < planes(); ++i) {
932 uint8_t* p = _data[i];
933 uint8_t* q = frame->data[i];
934 int const lines = sample_size(i).height;
935 for (int j = 0; j < lines; ++j) {
936 memcpy (p, q, _line_size[i]);
938 /* AVFrame's linesize is what we call `stride' */
939 q += frame->linesize[i];
944 Image::Image (shared_ptr<const Image> other, bool aligned)
945 : _size (other->_size)
946 , _pixel_format (other->_pixel_format)
951 for (int i = 0; i < planes(); ++i) {
952 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
953 uint8_t* p = _data[i];
954 uint8_t* q = other->data()[i];
955 int const lines = sample_size(i).height;
956 for (int j = 0; j < lines; ++j) {
957 memcpy (p, q, line_size()[i]);
959 q += other->stride()[i];
965 Image::operator= (Image const & other)
967 if (this == &other) {
977 Image::swap (Image & other)
979 std::swap (_size, other._size);
980 std::swap (_pixel_format, other._pixel_format);
982 for (int i = 0; i < 4; ++i) {
983 std::swap (_data[i], other._data[i]);
984 std::swap (_line_size[i], other._line_size[i]);
985 std::swap (_stride[i], other._stride[i]);
988 std::swap (_aligned, other._aligned);
993 for (int i = 0; i < planes(); ++i) {
998 av_free (_line_size);
1003 Image::data () const
1009 Image::line_size () const
1015 Image::stride () const
1021 Image::size () const
1027 Image::aligned () const
1033 merge (list<PositionImage> images)
1035 if (images.empty ()) {
1036 return PositionImage ();
1039 if (images.size() == 1) {
1040 return images.front ();
1043 dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1044 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1045 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
1048 shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
1049 merged->make_transparent ();
1050 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1051 merged->alpha_blend (i->image, i->position - all.position());
1054 return PositionImage (merged, all.position ());
1058 operator== (Image const & a, Image const & b)
1060 if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1064 for (int c = 0; c < a.planes(); ++c) {
1065 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]) {
1069 uint8_t* p = a.data()[c];
1070 uint8_t* q = b.data()[c];
1071 int const lines = a.sample_size(c).height;
1072 for (int y = 0; y < lines; ++y) {
1073 if (memcmp (p, q, a.line_size()[c]) != 0) {
1086 * @param f Amount to fade by; 0 is black, 1 is no fade.
1089 Image::fade (float f)
1091 /* U/V black value for 8-bit colour */
1092 static int const eight_bit_uv = (1 << 7) - 1;
1093 /* U/V black value for 10-bit colour */
1094 static uint16_t const ten_bit_uv = (1 << 9) - 1;
1096 switch (_pixel_format) {
1097 case AV_PIX_FMT_YUV420P:
1100 uint8_t* p = data()[0];
1101 int const lines = sample_size(0).height;
1102 for (int y = 0; y < lines; ++y) {
1104 for (int x = 0; x < line_size()[0]; ++x) {
1105 *q = int(float(*q) * f);
1112 for (int c = 1; c < 3; ++c) {
1113 uint8_t* p = data()[c];
1114 int const lines = sample_size(c).height;
1115 for (int y = 0; y < lines; ++y) {
1117 for (int x = 0; x < line_size()[c]; ++x) {
1118 *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1128 case AV_PIX_FMT_RGB24:
1131 uint8_t* p = data()[0];
1132 int const lines = sample_size(0).height;
1133 for (int y = 0; y < lines; ++y) {
1135 for (int x = 0; x < line_size()[0]; ++x) {
1136 *q = int (float (*q) * f);
1144 case AV_PIX_FMT_XYZ12LE:
1145 case AV_PIX_FMT_RGB48LE:
1146 /* 16-bit little-endian */
1147 for (int c = 0; c < 3; ++c) {
1148 int const stride_pixels = stride()[c] / 2;
1149 int const line_size_pixels = line_size()[c] / 2;
1150 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1151 int const lines = sample_size(c).height;
1152 for (int y = 0; y < lines; ++y) {
1154 for (int x = 0; x < line_size_pixels; ++x) {
1155 *q = int (float (*q) * f);
1163 case AV_PIX_FMT_YUV422P10LE:
1167 int const stride_pixels = stride()[0] / 2;
1168 int const line_size_pixels = line_size()[0] / 2;
1169 uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1170 int const lines = sample_size(0).height;
1171 for (int y = 0; y < lines; ++y) {
1173 for (int x = 0; x < line_size_pixels; ++x) {
1174 *q = int(float(*q) * f);
1182 for (int c = 1; c < 3; ++c) {
1183 int const stride_pixels = stride()[c] / 2;
1184 int const line_size_pixels = line_size()[c] / 2;
1185 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1186 int const lines = sample_size(c).height;
1187 for (int y = 0; y < lines; ++y) {
1189 for (int x = 0; x < line_size_pixels; ++x) {
1190 *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1201 throw PixelFormatError ("fade()", _pixel_format);
1205 shared_ptr<const Image>
1206 Image::ensure_aligned (shared_ptr<const Image> image)
1208 if (image->aligned()) {
1212 return shared_ptr<Image> (new Image (image, true));
1216 Image::memory_used () const
1219 for (int i = 0; i < planes(); ++i) {
1220 m += _stride[i] * sample_size(i).height;
1243 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1245 Memory* mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1246 size_t size = mem->size + length;
1249 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1251 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1255 throw EncodeError (N_("could not allocate memory for PNG"));
1258 memcpy (mem->data + mem->size, data, length);
1259 mem->size += length;
1263 png_flush (png_structp)
1269 png_error_fn (png_structp png_ptr, char const * message)
1271 reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1275 Image::png_error (char const * message)
1277 throw EncodeError (String::compose ("Error during PNG write: %1", message));
1281 Image::as_png () const
1283 DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1284 DCPOMATIC_ASSERT (planes() == 1);
1285 if (pixel_format() != AV_PIX_FMT_RGBA) {
1286 return convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGBA, true, false)->as_png();
1289 /* error handling? */
1290 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1292 throw EncodeError (N_("could not create PNG write struct"));
1297 png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1299 png_infop info_ptr = png_create_info_struct(png_ptr);
1301 png_destroy_write_struct (&png_ptr, &info_ptr);
1302 throw EncodeError (N_("could not create PNG info struct"));
1305 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);
1307 png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1308 for (int i = 0; i < size().height; ++i) {
1309 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1312 png_write_info (png_ptr, info_ptr);
1313 png_write_image (png_ptr, row_pointers);
1314 png_write_end (png_ptr, info_ptr);
1316 png_destroy_write_struct (&png_ptr, &info_ptr);
1317 png_free (png_ptr, row_pointers);
1319 return dcp::ArrayData (state.data, state.size);
1324 Image::video_range_to_full_range ()
1326 switch (_pixel_format) {
1327 case AV_PIX_FMT_RGB24:
1329 float const factor = 256.0 / 219.0;
1330 uint8_t* p = data()[0];
1331 int const lines = sample_size(0).height;
1332 for (int y = 0; y < lines; ++y) {
1334 for (int x = 0; x < line_size()[0]; ++x) {
1335 *q = int((*q - 16) * factor);
1342 case AV_PIX_FMT_GBRP12LE:
1344 float const factor = 4096.0 / 3504.0;
1345 for (int c = 0; c < 3; ++c) {
1346 uint16_t* p = reinterpret_cast<uint16_t*>(data()[c]);
1347 int const lines = sample_size(c).height;
1348 for (int y = 0; y < lines; ++y) {
1350 int const line_size_pixels = line_size()[c] / 2;
1351 for (int x = 0; x < line_size_pixels; ++x) {
1352 *q = int((*q - 256) * factor);
1360 throw PixelFormatError ("video_range_to_full_range()", _pixel_format);