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 out_format Output pixel format.
148 * @param out_aligned true to make the output image aligned.
149 * @param fast Try to be fast at the possible expense of quality; at present this means using
150 * fast bilinear rather than bicubic scaling.
153 Image::crop_scale_window (
154 Crop crop, dcp::Size inter_size, dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast
157 /* Empirical testing suggests that sws_scale() will crash if
158 the input image is not aligned.
160 DCPOMATIC_ASSERT (aligned ());
162 DCPOMATIC_ASSERT (out_size.width >= inter_size.width);
163 DCPOMATIC_ASSERT (out_size.height >= inter_size.height);
165 shared_ptr<Image> out (new Image(out_format, out_size, out_aligned));
168 AVPixFmtDescriptor const * in_desc = av_pix_fmt_desc_get (_pixel_format);
170 throw PixelFormatError ("crop_scale_window()", _pixel_format);
173 /* Round down so that we crop only the number of pixels that is straightforward
174 * considering any subsampling.
177 round_width_for_subsampling(crop.left, in_desc),
178 round_width_for_subsampling(crop.right, in_desc),
179 round_height_for_subsampling(crop.top, in_desc),
180 round_height_for_subsampling(crop.bottom, in_desc)
183 /* Size of the image after any crop */
184 dcp::Size const cropped_size = rounded_crop.apply (size());
186 /* Scale context for a scale from cropped_size to inter_size */
187 struct SwsContext* scale_context = sws_getContext (
188 cropped_size.width, cropped_size.height, pixel_format(),
189 inter_size.width, inter_size.height, out_format,
190 fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
193 if (!scale_context) {
194 throw runtime_error (N_("Could not allocate SwsContext"));
197 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
198 int const lut[dcp::YUV_TO_RGB_COUNT] = {
203 /* The 3rd parameter here is:
204 0 -> source range MPEG (i.e. "video", 16-235)
205 1 -> source range JPEG (i.e. "full", 0-255)
207 0 -> destination range MPEG (i.e. "video", 16-235)
208 1 -> destination range JPEG (i.e. "full", 0-255)
210 But remember: sws_setColorspaceDetails ignores
211 these parameters unless the image isYUV or isGray
212 (if it's neither, it uses video range for source
215 sws_setColorspaceDetails (
217 sws_getCoefficients (lut[yuv_to_rgb]), 0,
218 sws_getCoefficients (lut[yuv_to_rgb]), 0,
222 /* Prepare input data pointers with crop */
223 uint8_t* scale_in_data[planes()];
224 for (int c = 0; c < planes(); ++c) {
225 int const x = lrintf(bytes_per_pixel(c) * rounded_crop.left);
226 scale_in_data[c] = data()[c] + x + stride()[c] * (rounded_crop.top / vertical_factor(c));
229 AVPixFmtDescriptor const * out_desc = av_pix_fmt_desc_get (out_format);
231 throw PixelFormatError ("crop_scale_window()", out_format);
234 /* Corner of the image within out_size */
235 Position<int> const corner (
236 round_width_for_subsampling((out_size.width - inter_size.width) / 2, out_desc),
237 round_height_for_subsampling((out_size.height - inter_size.height) / 2, out_desc)
240 uint8_t* scale_out_data[out->planes()];
241 for (int c = 0; c < out->planes(); ++c) {
242 int const x = lrintf(out->bytes_per_pixel(c) * corner.x);
243 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
248 scale_in_data, stride(),
249 0, cropped_size.height,
250 scale_out_data, out->stride()
253 sws_freeContext (scale_context);
255 if (rounded_crop != Crop() && cropped_size == inter_size) {
256 /* We are cropping without any scaling or pixel format conversion, so FFmpeg may have left some
257 data behind in our image. Clear it out. It may get to the point where we should just stop
258 trying to be clever with cropping.
260 out->make_part_black (corner.x + cropped_size.width, out_size.width - cropped_size.width);
267 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
269 return scale(size(), yuv_to_rgb, out_format, out_aligned, fast);
272 /** @param out_size Size to scale to.
273 * @param yuv_to_rgb YUVToRGB transform transform to use, if required.
274 * @param out_format Output pixel format.
275 * @param out_aligned true to make an aligned output image.
276 * @param fast Try to be fast at the possible expense of quality; at present this means using
277 * fast bilinear rather than bicubic scaling.
280 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
282 /* Empirical testing suggests that sws_scale() will crash if
283 the input image is not aligned.
285 DCPOMATIC_ASSERT (aligned ());
287 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
289 struct SwsContext* scale_context = sws_getContext (
290 size().width, size().height, pixel_format(),
291 out_size.width, out_size.height, out_format,
292 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
295 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
296 int const lut[dcp::YUV_TO_RGB_COUNT] = {
301 /* The 3rd parameter here is:
302 0 -> source range MPEG (i.e. "video", 16-235)
303 1 -> source range JPEG (i.e. "full", 0-255)
305 0 -> destination range MPEG (i.e. "video", 16-235)
306 1 -> destination range JPEG (i.e. "full", 0-255)
308 But remember: sws_setColorspaceDetails ignores
309 these parameters unless the image isYUV or isGray
310 (if it's neither, it uses video range for source
313 sws_setColorspaceDetails (
315 sws_getCoefficients (lut[yuv_to_rgb]), 0,
316 sws_getCoefficients (lut[yuv_to_rgb]), 0,
324 scaled->data(), scaled->stride()
327 sws_freeContext (scale_context);
332 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
334 Image::yuv_16_black (uint16_t v, bool alpha)
336 memset (data()[0], 0, sample_size(0).height * stride()[0]);
337 for (int i = 1; i < 3; ++i) {
338 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
339 int const lines = sample_size(i).height;
340 for (int y = 0; y < lines; ++y) {
341 /* We divide by 2 here because we are writing 2 bytes at a time */
342 for (int x = 0; x < line_size()[i] / 2; ++x) {
345 p += stride()[i] / 2;
350 memset (data()[3], 0, sample_size(3).height * stride()[3]);
355 Image::swap_16 (uint16_t v)
357 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
361 Image::make_part_black (int x, int w)
363 switch (_pixel_format) {
364 case AV_PIX_FMT_RGB24:
365 case AV_PIX_FMT_ARGB:
366 case AV_PIX_FMT_RGBA:
367 case AV_PIX_FMT_ABGR:
368 case AV_PIX_FMT_BGRA:
369 case AV_PIX_FMT_RGB555LE:
370 case AV_PIX_FMT_RGB48LE:
371 case AV_PIX_FMT_RGB48BE:
372 case AV_PIX_FMT_XYZ12LE:
374 int const h = sample_size(0).height;
375 int const bpp = bytes_per_pixel(0);
376 int const s = stride()[0];
377 uint8_t* p = data()[0];
378 for (int y = 0; y < h; y++) {
379 memset (p + x * bpp, 0, w * bpp);
386 throw PixelFormatError ("make_part_black()", _pixel_format);
393 /* U/V black value for 8-bit colour */
394 static uint8_t const eight_bit_uv = (1 << 7) - 1;
395 /* U/V black value for 9-bit colour */
396 static uint16_t const nine_bit_uv = (1 << 8) - 1;
397 /* U/V black value for 10-bit colour */
398 static uint16_t const ten_bit_uv = (1 << 9) - 1;
399 /* U/V black value for 16-bit colour */
400 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
402 switch (_pixel_format) {
403 case AV_PIX_FMT_YUV420P:
404 case AV_PIX_FMT_YUV422P:
405 case AV_PIX_FMT_YUV444P:
406 case AV_PIX_FMT_YUV411P:
407 memset (data()[0], 0, sample_size(0).height * stride()[0]);
408 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
409 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
412 case AV_PIX_FMT_YUVJ420P:
413 case AV_PIX_FMT_YUVJ422P:
414 case AV_PIX_FMT_YUVJ444P:
415 memset (data()[0], 0, sample_size(0).height * stride()[0]);
416 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
417 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
420 case AV_PIX_FMT_YUV422P9LE:
421 case AV_PIX_FMT_YUV444P9LE:
422 yuv_16_black (nine_bit_uv, false);
425 case AV_PIX_FMT_YUV422P9BE:
426 case AV_PIX_FMT_YUV444P9BE:
427 yuv_16_black (swap_16 (nine_bit_uv), false);
430 case AV_PIX_FMT_YUV422P10LE:
431 case AV_PIX_FMT_YUV444P10LE:
432 yuv_16_black (ten_bit_uv, false);
435 case AV_PIX_FMT_YUV422P16LE:
436 case AV_PIX_FMT_YUV444P16LE:
437 yuv_16_black (sixteen_bit_uv, false);
440 case AV_PIX_FMT_YUV444P10BE:
441 case AV_PIX_FMT_YUV422P10BE:
442 yuv_16_black (swap_16 (ten_bit_uv), false);
445 case AV_PIX_FMT_YUVA420P9BE:
446 case AV_PIX_FMT_YUVA422P9BE:
447 case AV_PIX_FMT_YUVA444P9BE:
448 yuv_16_black (swap_16 (nine_bit_uv), true);
451 case AV_PIX_FMT_YUVA420P9LE:
452 case AV_PIX_FMT_YUVA422P9LE:
453 case AV_PIX_FMT_YUVA444P9LE:
454 yuv_16_black (nine_bit_uv, true);
457 case AV_PIX_FMT_YUVA420P10BE:
458 case AV_PIX_FMT_YUVA422P10BE:
459 case AV_PIX_FMT_YUVA444P10BE:
460 yuv_16_black (swap_16 (ten_bit_uv), true);
463 case AV_PIX_FMT_YUVA420P10LE:
464 case AV_PIX_FMT_YUVA422P10LE:
465 case AV_PIX_FMT_YUVA444P10LE:
466 yuv_16_black (ten_bit_uv, true);
469 case AV_PIX_FMT_YUVA420P16BE:
470 case AV_PIX_FMT_YUVA422P16BE:
471 case AV_PIX_FMT_YUVA444P16BE:
472 yuv_16_black (swap_16 (sixteen_bit_uv), true);
475 case AV_PIX_FMT_YUVA420P16LE:
476 case AV_PIX_FMT_YUVA422P16LE:
477 case AV_PIX_FMT_YUVA444P16LE:
478 yuv_16_black (sixteen_bit_uv, true);
481 case AV_PIX_FMT_RGB24:
482 case AV_PIX_FMT_ARGB:
483 case AV_PIX_FMT_RGBA:
484 case AV_PIX_FMT_ABGR:
485 case AV_PIX_FMT_BGRA:
486 case AV_PIX_FMT_RGB555LE:
487 case AV_PIX_FMT_RGB48LE:
488 case AV_PIX_FMT_RGB48BE:
489 case AV_PIX_FMT_XYZ12LE:
490 memset (data()[0], 0, sample_size(0).height * stride()[0]);
493 case AV_PIX_FMT_UYVY422:
495 int const Y = sample_size(0).height;
496 int const X = line_size()[0];
497 uint8_t* p = data()[0];
498 for (int y = 0; y < Y; ++y) {
499 for (int x = 0; x < X / 4; ++x) {
500 *p++ = eight_bit_uv; // Cb
502 *p++ = eight_bit_uv; // Cr
510 throw PixelFormatError ("make_black()", _pixel_format);
515 Image::make_transparent ()
517 if (_pixel_format != AV_PIX_FMT_BGRA && _pixel_format != AV_PIX_FMT_RGBA) {
518 throw PixelFormatError ("make_transparent()", _pixel_format);
521 memset (data()[0], 0, sample_size(0).height * stride()[0]);
525 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
527 /* We're blending RGBA or BGRA images */
528 DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA || other->pixel_format() == AV_PIX_FMT_RGBA);
529 int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
530 int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
532 int const other_bpp = 4;
534 int start_tx = position.x;
538 start_ox = -start_tx;
542 int start_ty = position.y;
546 start_oy = -start_ty;
550 switch (_pixel_format) {
551 case AV_PIX_FMT_RGB24:
553 /* Going onto RGB24. First byte is red, second green, third blue */
554 int const this_bpp = 3;
555 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
556 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
557 uint8_t* op = other->data()[0] + oy * other->stride()[0];
558 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
559 float const alpha = float (op[3]) / 255;
560 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
561 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
562 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
570 case AV_PIX_FMT_BGRA:
572 int const this_bpp = 4;
573 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
574 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
575 uint8_t* op = other->data()[0] + oy * other->stride()[0];
576 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
577 float const alpha = float (op[3]) / 255;
578 tp[0] = op[blue] * alpha + tp[0] * (1 - alpha);
579 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
580 tp[2] = op[red] * alpha + tp[2] * (1 - alpha);
581 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
589 case AV_PIX_FMT_RGBA:
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[red] * alpha + tp[0] * (1 - alpha);
598 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
599 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
600 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
608 case AV_PIX_FMT_RGB48LE:
610 int const this_bpp = 6;
611 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
612 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 /* Blend high bytes */
617 tp[1] = op[red] * alpha + tp[1] * (1 - alpha);
618 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
619 tp[5] = op[blue] * alpha + tp[5] * (1 - alpha);
627 case AV_PIX_FMT_XYZ12LE:
629 dcp::ColourConversion conv = dcp::ColourConversion::srgb_to_xyz();
630 double fast_matrix[9];
631 dcp::combined_rgb_to_xyz (conv, fast_matrix);
632 double const * lut_in = conv.in()->lut (8, false);
633 double const * lut_out = conv.out()->lut (16, true);
634 int const this_bpp = 6;
635 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
636 uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
637 uint8_t* op = other->data()[0] + oy * other->stride()[0];
638 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
639 float const alpha = float (op[3]) / 255;
641 /* Convert sRGB to XYZ; op is BGRA. First, input gamma LUT */
642 double const r = lut_in[op[red]];
643 double const g = lut_in[op[1]];
644 double const b = lut_in[op[blue]];
646 /* RGB to XYZ, including Bradford transform and DCI companding */
647 double const x = max (0.0, min (65535.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
648 double const y = max (0.0, min (65535.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
649 double const z = max (0.0, min (65535.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
651 /* Out gamma LUT and blend */
652 tp[0] = lrint(lut_out[lrint(x)] * 65535) * alpha + tp[0] * (1 - alpha);
653 tp[1] = lrint(lut_out[lrint(y)] * 65535) * alpha + tp[1] * (1 - alpha);
654 tp[2] = lrint(lut_out[lrint(z)] * 65535) * alpha + tp[2] * (1 - alpha);
662 case AV_PIX_FMT_YUV420P:
664 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
665 dcp::Size const ts = size();
666 dcp::Size const os = yuv->size();
667 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
668 int const hty = ty / 2;
669 int const hoy = oy / 2;
670 uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
671 uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
672 uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
673 uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
674 uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
675 uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
676 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
677 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
678 float const a = float(alpha[3]) / 255;
679 *tY = *oY * a + *tY * (1 - a);
680 *tU = *oU * a + *tU * (1 - a);
681 *tV = *oV * a + *tV * (1 - a);
697 case AV_PIX_FMT_YUV420P10:
699 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
700 dcp::Size const ts = size();
701 dcp::Size const os = yuv->size();
702 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
703 int const hty = ty / 2;
704 int const hoy = oy / 2;
705 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
706 uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
707 uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
708 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
709 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
710 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
711 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
712 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
713 float const a = float(alpha[3]) / 255;
714 *tY = *oY * a + *tY * (1 - a);
715 *tU = *oU * a + *tU * (1 - a);
716 *tV = *oV * a + *tV * (1 - a);
732 case AV_PIX_FMT_YUV422P10LE:
734 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
735 dcp::Size const ts = size();
736 dcp::Size const os = yuv->size();
737 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
738 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
739 uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
740 uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
741 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
742 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
743 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
744 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
745 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
746 float const a = float(alpha[3]) / 255;
747 *tY = *oY * a + *tY * (1 - a);
748 *tU = *oU * a + *tU * (1 - a);
749 *tV = *oV * a + *tV * (1 - a);
766 throw PixelFormatError ("alpha_blend()", _pixel_format);
771 Image::copy (shared_ptr<const Image> other, Position<int> position)
773 /* Only implemented for RGB24 onto RGB24 so far */
774 DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
775 DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
777 int const N = min (position.x + other->size().width, size().width) - position.x;
778 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
779 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
780 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
781 memcpy (tp, op, N * 3);
786 Image::read_from_socket (shared_ptr<Socket> socket)
788 for (int i = 0; i < planes(); ++i) {
789 uint8_t* p = data()[i];
790 int const lines = sample_size(i).height;
791 for (int y = 0; y < lines; ++y) {
792 socket->read (p, line_size()[i]);
799 Image::write_to_socket (shared_ptr<Socket> socket) const
801 for (int i = 0; i < planes(); ++i) {
802 uint8_t* p = data()[i];
803 int const lines = sample_size(i).height;
804 for (int y = 0; y < lines; ++y) {
805 socket->write (p, line_size()[i]);
812 Image::bytes_per_pixel (int c) const
814 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
816 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
823 float bpp[4] = { 0, 0, 0, 0 };
825 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
826 bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
827 if (d->nb_components > 1) {
828 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
830 if (d->nb_components > 2) {
831 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
833 if (d->nb_components > 3) {
834 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
837 bpp[0] = floor ((d->comp[0].depth + 7) / 8);
838 if (d->nb_components > 1) {
839 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
841 if (d->nb_components > 2) {
842 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
844 if (d->nb_components > 3) {
845 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
849 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
850 /* Not planar; sum them up */
851 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
857 /** Construct a Image of a given size and format, allocating memory
860 * @param p Pixel format.
861 * @param s Size in pixels.
862 * @param aligned true to make each row of this image aligned to a ALIGNMENT-byte boundary.
864 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned)
875 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
876 _data[0] = _data[1] = _data[2] = _data[3] = 0;
878 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
879 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
881 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
882 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
884 for (int i = 0; i < planes(); ++i) {
885 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
886 _stride[i] = stride_round_up (i, _line_size, _aligned ? ALIGNMENT : 1);
888 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
889 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
890 Hence on the last pixel of the last line it reads over the end of
891 the actual data by 1 byte. If the width of an image is a multiple
892 of the stride alignment there will be no padding at the end of image lines.
893 OS X crashes on this illegal read, though other operating systems don't
894 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
895 for that instruction to read safely.
897 Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
898 over-reads by more then _avx. I can't follow the code to work out how much,
899 so I'll just over-allocate by ALIGNMENT bytes and have done with it. Empirical
900 testing suggests that it works.
902 In addition to these concerns, we may read/write as much as a whole extra line
903 at the end of each plane in cases where we are messing with offsets in order to
904 do pad or crop. To solve this we over-allocate by an extra _stride[i] bytes.
906 As an example: we may write to images starting at an offset so we get some padding.
907 Hence we want to write in the following pattern:
909 block start write start line end
910 |..(padding)..|<------line-size------------->|..(padding)..|
911 |..(padding)..|<------line-size------------->|..(padding)..|
912 |..(padding)..|<------line-size------------->|..(padding)..|
914 where line-size is of the smaller (inter_size) image and the full padded line length is that of
915 out_size. To get things to work we have to tell FFmpeg that the stride is that of out_size.
916 However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
917 specified *stride*. This does not matter until we get to the last line:
919 block start write start line end
920 |..(padding)..|<------line-size------------->|XXXwrittenXXX|
921 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
922 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
925 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
926 #if HAVE_VALGRIND_MEMCHECK_H
927 /* The data between the end of the line size and the stride is undefined but processed by
928 libswscale, causing lots of valgrind errors. Mark it all defined to quell these errors.
930 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
935 Image::Image (Image const & other)
936 : boost::enable_shared_from_this<Image>(other)
937 , _size (other._size)
938 , _pixel_format (other._pixel_format)
939 , _aligned (other._aligned)
943 for (int i = 0; i < planes(); ++i) {
944 uint8_t* p = _data[i];
945 uint8_t* q = other._data[i];
946 int const lines = sample_size(i).height;
947 for (int j = 0; j < lines; ++j) {
948 memcpy (p, q, _line_size[i]);
950 q += other.stride()[i];
955 Image::Image (AVFrame* frame)
956 : _size (frame->width, frame->height)
957 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
962 for (int i = 0; i < planes(); ++i) {
963 uint8_t* p = _data[i];
964 uint8_t* q = frame->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 /* AVFrame's linesize is what we call `stride' */
970 q += frame->linesize[i];
975 Image::Image (shared_ptr<const Image> other, bool aligned)
976 : _size (other->_size)
977 , _pixel_format (other->_pixel_format)
982 for (int i = 0; i < planes(); ++i) {
983 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
984 uint8_t* p = _data[i];
985 uint8_t* q = other->data()[i];
986 int const lines = sample_size(i).height;
987 for (int j = 0; j < lines; ++j) {
988 memcpy (p, q, line_size()[i]);
990 q += other->stride()[i];
996 Image::operator= (Image const & other)
998 if (this == &other) {
1008 Image::swap (Image & other)
1010 std::swap (_size, other._size);
1011 std::swap (_pixel_format, other._pixel_format);
1013 for (int i = 0; i < 4; ++i) {
1014 std::swap (_data[i], other._data[i]);
1015 std::swap (_line_size[i], other._line_size[i]);
1016 std::swap (_stride[i], other._stride[i]);
1019 std::swap (_aligned, other._aligned);
1022 /** Destroy a Image */
1025 for (int i = 0; i < planes(); ++i) {
1030 av_free (_line_size);
1035 Image::data () const
1041 Image::line_size () const
1047 Image::stride () const
1053 Image::size () const
1059 Image::aligned () const
1065 merge (list<PositionImage> images)
1067 if (images.empty ()) {
1068 return PositionImage ();
1071 if (images.size() == 1) {
1072 return images.front ();
1075 dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1076 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1077 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
1080 shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
1081 merged->make_transparent ();
1082 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1083 merged->alpha_blend (i->image, i->position - all.position());
1086 return PositionImage (merged, all.position ());
1090 operator== (Image const & a, Image const & b)
1092 if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1096 for (int c = 0; c < a.planes(); ++c) {
1097 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]) {
1101 uint8_t* p = a.data()[c];
1102 uint8_t* q = b.data()[c];
1103 int const lines = a.sample_size(c).height;
1104 for (int y = 0; y < lines; ++y) {
1105 if (memcmp (p, q, a.line_size()[c]) != 0) {
1118 * @param f Amount to fade by; 0 is black, 1 is no fade.
1121 Image::fade (float f)
1123 /* U/V black value for 8-bit colour */
1124 static int const eight_bit_uv = (1 << 7) - 1;
1125 /* U/V black value for 10-bit colour */
1126 static uint16_t const ten_bit_uv = (1 << 9) - 1;
1128 switch (_pixel_format) {
1129 case AV_PIX_FMT_YUV420P:
1132 uint8_t* p = data()[0];
1133 int const lines = sample_size(0).height;
1134 for (int y = 0; y < lines; ++y) {
1136 for (int x = 0; x < line_size()[0]; ++x) {
1137 *q = int(float(*q) * f);
1144 for (int c = 1; c < 3; ++c) {
1145 uint8_t* p = data()[c];
1146 int const lines = sample_size(c).height;
1147 for (int y = 0; y < lines; ++y) {
1149 for (int x = 0; x < line_size()[c]; ++x) {
1150 *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1160 case AV_PIX_FMT_RGB24:
1163 uint8_t* p = data()[0];
1164 int const lines = sample_size(0).height;
1165 for (int y = 0; y < lines; ++y) {
1167 for (int x = 0; x < line_size()[0]; ++x) {
1168 *q = int (float (*q) * f);
1176 case AV_PIX_FMT_XYZ12LE:
1177 case AV_PIX_FMT_RGB48LE:
1178 /* 16-bit little-endian */
1179 for (int c = 0; c < 3; ++c) {
1180 int const stride_pixels = stride()[c] / 2;
1181 int const line_size_pixels = line_size()[c] / 2;
1182 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1183 int const lines = sample_size(c).height;
1184 for (int y = 0; y < lines; ++y) {
1186 for (int x = 0; x < line_size_pixels; ++x) {
1187 *q = int (float (*q) * f);
1195 case AV_PIX_FMT_YUV422P10LE:
1199 int const stride_pixels = stride()[0] / 2;
1200 int const line_size_pixels = line_size()[0] / 2;
1201 uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1202 int const lines = sample_size(0).height;
1203 for (int y = 0; y < lines; ++y) {
1205 for (int x = 0; x < line_size_pixels; ++x) {
1206 *q = int(float(*q) * f);
1214 for (int c = 1; c < 3; ++c) {
1215 int const stride_pixels = stride()[c] / 2;
1216 int const line_size_pixels = line_size()[c] / 2;
1217 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1218 int const lines = sample_size(c).height;
1219 for (int y = 0; y < lines; ++y) {
1221 for (int x = 0; x < line_size_pixels; ++x) {
1222 *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1233 throw PixelFormatError ("fade()", _pixel_format);
1237 shared_ptr<const Image>
1238 Image::ensure_aligned (shared_ptr<const Image> image)
1240 if (image->aligned()) {
1244 return shared_ptr<Image> (new Image (image, true));
1248 Image::memory_used () const
1251 for (int i = 0; i < planes(); ++i) {
1252 m += _stride[i] * sample_size(i).height;
1275 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1277 Memory* mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1278 size_t size = mem->size + length;
1281 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1283 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1287 throw EncodeError (N_("could not allocate memory for PNG"));
1290 memcpy (mem->data + mem->size, data, length);
1291 mem->size += length;
1295 png_flush (png_structp)
1301 png_error_fn (png_structp png_ptr, char const * message)
1303 reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1307 Image::png_error (char const * message)
1309 throw EncodeError (String::compose ("Error during PNG write: %1", message));
1313 Image::as_png () const
1315 DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1316 DCPOMATIC_ASSERT (planes() == 1);
1317 if (pixel_format() != AV_PIX_FMT_RGBA) {
1318 return convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGBA, true, false)->as_png();
1321 /* error handling? */
1322 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1324 throw EncodeError (N_("could not create PNG write struct"));
1329 png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1331 png_infop info_ptr = png_create_info_struct(png_ptr);
1333 png_destroy_write_struct (&png_ptr, &info_ptr);
1334 throw EncodeError (N_("could not create PNG info struct"));
1337 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);
1339 png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1340 for (int i = 0; i < size().height; ++i) {
1341 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1344 png_write_info (png_ptr, info_ptr);
1345 png_write_image (png_ptr, row_pointers);
1346 png_write_end (png_ptr, info_ptr);
1348 png_destroy_write_struct (&png_ptr, &info_ptr);
1349 png_free (png_ptr, row_pointers);
1351 return dcp::Data (state.data, state.size);