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 /* Hack: if we're not doing quite the crop that we were asked for, and we carry on scaling
187 * to the inter_size we were asked for, there is a small but noticeable wobble in the image
188 * luminance (#1872). This hack means we will jump in steps of the subsampling distance
189 * in both crop and scale.
191 inter_size.width = round_width_for_subsampling(inter_size.width, in_desc);
192 inter_size.height = round_width_for_subsampling(inter_size.height, in_desc);
194 /* Scale context for a scale from cropped_size to inter_size */
195 struct SwsContext* scale_context = sws_getContext (
196 cropped_size.width, cropped_size.height, pixel_format(),
197 inter_size.width, inter_size.height, out_format,
198 fast ? SWS_FAST_BILINEAR : SWS_BICUBIC, 0, 0, 0
201 if (!scale_context) {
202 throw runtime_error (N_("Could not allocate SwsContext"));
205 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
206 int const lut[dcp::YUV_TO_RGB_COUNT] = {
211 /* The 3rd parameter here is:
212 0 -> source range MPEG (i.e. "video", 16-235)
213 1 -> source range JPEG (i.e. "full", 0-255)
215 0 -> destination range MPEG (i.e. "video", 16-235)
216 1 -> destination range JPEG (i.e. "full", 0-255)
218 But remember: sws_setColorspaceDetails ignores
219 these parameters unless the image isYUV or isGray
220 (if it's neither, it uses video range for source
223 sws_setColorspaceDetails (
225 sws_getCoefficients (lut[yuv_to_rgb]), 0,
226 sws_getCoefficients (lut[yuv_to_rgb]), 0,
230 /* Prepare input data pointers with crop */
231 uint8_t* scale_in_data[planes()];
232 for (int c = 0; c < planes(); ++c) {
233 int const x = lrintf(bytes_per_pixel(c) * rounded_crop.left);
234 scale_in_data[c] = data()[c] + x + stride()[c] * (rounded_crop.top / vertical_factor(c));
237 AVPixFmtDescriptor const * out_desc = av_pix_fmt_desc_get (out_format);
239 throw PixelFormatError ("crop_scale_window()", out_format);
242 /* Corner of the image within out_size */
243 Position<int> const corner (
244 round_width_for_subsampling((out_size.width - inter_size.width) / 2, out_desc),
245 round_height_for_subsampling((out_size.height - inter_size.height) / 2, out_desc)
248 uint8_t* scale_out_data[out->planes()];
249 for (int c = 0; c < out->planes(); ++c) {
250 int const x = lrintf(out->bytes_per_pixel(c) * corner.x);
251 scale_out_data[c] = out->data()[c] + x + out->stride()[c] * (corner.y / out->vertical_factor(c));
256 scale_in_data, stride(),
257 0, cropped_size.height,
258 scale_out_data, out->stride()
261 sws_freeContext (scale_context);
263 if (rounded_crop != Crop() && cropped_size == inter_size) {
264 /* We are cropping without any scaling or pixel format conversion, so FFmpeg may have left some
265 data behind in our image. Clear it out. It may get to the point where we should just stop
266 trying to be clever with cropping.
268 out->make_part_black (corner.x + cropped_size.width, out_size.width - cropped_size.width);
275 Image::convert_pixel_format (dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
277 return scale(size(), yuv_to_rgb, out_format, out_aligned, fast);
280 /** @param out_size Size to scale to.
281 * @param yuv_to_rgb YUVToRGB transform transform to use, if required.
282 * @param out_format Output pixel format.
283 * @param out_aligned true to make an aligned output image.
284 * @param fast Try to be fast at the possible expense of quality; at present this means using
285 * fast bilinear rather than bicubic scaling.
288 Image::scale (dcp::Size out_size, dcp::YUVToRGB yuv_to_rgb, AVPixelFormat out_format, bool out_aligned, bool fast) const
290 /* Empirical testing suggests that sws_scale() will crash if
291 the input image is not aligned.
293 DCPOMATIC_ASSERT (aligned ());
295 shared_ptr<Image> scaled (new Image (out_format, out_size, out_aligned));
297 struct SwsContext* scale_context = sws_getContext (
298 size().width, size().height, pixel_format(),
299 out_size.width, out_size.height, out_format,
300 (fast ? SWS_FAST_BILINEAR : SWS_BICUBIC) | SWS_ACCURATE_RND, 0, 0, 0
303 DCPOMATIC_ASSERT (yuv_to_rgb < dcp::YUV_TO_RGB_COUNT);
304 int const lut[dcp::YUV_TO_RGB_COUNT] = {
309 /* The 3rd parameter here is:
310 0 -> source range MPEG (i.e. "video", 16-235)
311 1 -> source range JPEG (i.e. "full", 0-255)
313 0 -> destination range MPEG (i.e. "video", 16-235)
314 1 -> destination range JPEG (i.e. "full", 0-255)
316 But remember: sws_setColorspaceDetails ignores
317 these parameters unless the image isYUV or isGray
318 (if it's neither, it uses video range for source
321 sws_setColorspaceDetails (
323 sws_getCoefficients (lut[yuv_to_rgb]), 0,
324 sws_getCoefficients (lut[yuv_to_rgb]), 0,
332 scaled->data(), scaled->stride()
335 sws_freeContext (scale_context);
340 /** Blacken a YUV image whose bits per pixel is rounded up to 16 */
342 Image::yuv_16_black (uint16_t v, bool alpha)
344 memset (data()[0], 0, sample_size(0).height * stride()[0]);
345 for (int i = 1; i < 3; ++i) {
346 int16_t* p = reinterpret_cast<int16_t*> (data()[i]);
347 int const lines = sample_size(i).height;
348 for (int y = 0; y < lines; ++y) {
349 /* We divide by 2 here because we are writing 2 bytes at a time */
350 for (int x = 0; x < line_size()[i] / 2; ++x) {
353 p += stride()[i] / 2;
358 memset (data()[3], 0, sample_size(3).height * stride()[3]);
363 Image::swap_16 (uint16_t v)
365 return ((v >> 8) & 0xff) | ((v & 0xff) << 8);
369 Image::make_part_black (int x, int w)
371 switch (_pixel_format) {
372 case AV_PIX_FMT_RGB24:
373 case AV_PIX_FMT_ARGB:
374 case AV_PIX_FMT_RGBA:
375 case AV_PIX_FMT_ABGR:
376 case AV_PIX_FMT_BGRA:
377 case AV_PIX_FMT_RGB555LE:
378 case AV_PIX_FMT_RGB48LE:
379 case AV_PIX_FMT_RGB48BE:
380 case AV_PIX_FMT_XYZ12LE:
382 int const h = sample_size(0).height;
383 int const bpp = bytes_per_pixel(0);
384 int const s = stride()[0];
385 uint8_t* p = data()[0];
386 for (int y = 0; y < h; y++) {
387 memset (p + x * bpp, 0, w * bpp);
394 throw PixelFormatError ("make_part_black()", _pixel_format);
401 /* U/V black value for 8-bit colour */
402 static uint8_t const eight_bit_uv = (1 << 7) - 1;
403 /* U/V black value for 9-bit colour */
404 static uint16_t const nine_bit_uv = (1 << 8) - 1;
405 /* U/V black value for 10-bit colour */
406 static uint16_t const ten_bit_uv = (1 << 9) - 1;
407 /* U/V black value for 16-bit colour */
408 static uint16_t const sixteen_bit_uv = (1 << 15) - 1;
410 switch (_pixel_format) {
411 case AV_PIX_FMT_YUV420P:
412 case AV_PIX_FMT_YUV422P:
413 case AV_PIX_FMT_YUV444P:
414 case AV_PIX_FMT_YUV411P:
415 memset (data()[0], 0, sample_size(0).height * stride()[0]);
416 memset (data()[1], eight_bit_uv, sample_size(1).height * stride()[1]);
417 memset (data()[2], eight_bit_uv, sample_size(2).height * stride()[2]);
420 case AV_PIX_FMT_YUVJ420P:
421 case AV_PIX_FMT_YUVJ422P:
422 case AV_PIX_FMT_YUVJ444P:
423 memset (data()[0], 0, sample_size(0).height * stride()[0]);
424 memset (data()[1], eight_bit_uv + 1, sample_size(1).height * stride()[1]);
425 memset (data()[2], eight_bit_uv + 1, sample_size(2).height * stride()[2]);
428 case AV_PIX_FMT_YUV422P9LE:
429 case AV_PIX_FMT_YUV444P9LE:
430 yuv_16_black (nine_bit_uv, false);
433 case AV_PIX_FMT_YUV422P9BE:
434 case AV_PIX_FMT_YUV444P9BE:
435 yuv_16_black (swap_16 (nine_bit_uv), false);
438 case AV_PIX_FMT_YUV422P10LE:
439 case AV_PIX_FMT_YUV444P10LE:
440 yuv_16_black (ten_bit_uv, false);
443 case AV_PIX_FMT_YUV422P16LE:
444 case AV_PIX_FMT_YUV444P16LE:
445 yuv_16_black (sixteen_bit_uv, false);
448 case AV_PIX_FMT_YUV444P10BE:
449 case AV_PIX_FMT_YUV422P10BE:
450 yuv_16_black (swap_16 (ten_bit_uv), false);
453 case AV_PIX_FMT_YUVA420P9BE:
454 case AV_PIX_FMT_YUVA422P9BE:
455 case AV_PIX_FMT_YUVA444P9BE:
456 yuv_16_black (swap_16 (nine_bit_uv), true);
459 case AV_PIX_FMT_YUVA420P9LE:
460 case AV_PIX_FMT_YUVA422P9LE:
461 case AV_PIX_FMT_YUVA444P9LE:
462 yuv_16_black (nine_bit_uv, true);
465 case AV_PIX_FMT_YUVA420P10BE:
466 case AV_PIX_FMT_YUVA422P10BE:
467 case AV_PIX_FMT_YUVA444P10BE:
468 yuv_16_black (swap_16 (ten_bit_uv), true);
471 case AV_PIX_FMT_YUVA420P10LE:
472 case AV_PIX_FMT_YUVA422P10LE:
473 case AV_PIX_FMT_YUVA444P10LE:
474 yuv_16_black (ten_bit_uv, true);
477 case AV_PIX_FMT_YUVA420P16BE:
478 case AV_PIX_FMT_YUVA422P16BE:
479 case AV_PIX_FMT_YUVA444P16BE:
480 yuv_16_black (swap_16 (sixteen_bit_uv), true);
483 case AV_PIX_FMT_YUVA420P16LE:
484 case AV_PIX_FMT_YUVA422P16LE:
485 case AV_PIX_FMT_YUVA444P16LE:
486 yuv_16_black (sixteen_bit_uv, true);
489 case AV_PIX_FMT_RGB24:
490 case AV_PIX_FMT_ARGB:
491 case AV_PIX_FMT_RGBA:
492 case AV_PIX_FMT_ABGR:
493 case AV_PIX_FMT_BGRA:
494 case AV_PIX_FMT_RGB555LE:
495 case AV_PIX_FMT_RGB48LE:
496 case AV_PIX_FMT_RGB48BE:
497 case AV_PIX_FMT_XYZ12LE:
498 memset (data()[0], 0, sample_size(0).height * stride()[0]);
501 case AV_PIX_FMT_UYVY422:
503 int const Y = sample_size(0).height;
504 int const X = line_size()[0];
505 uint8_t* p = data()[0];
506 for (int y = 0; y < Y; ++y) {
507 for (int x = 0; x < X / 4; ++x) {
508 *p++ = eight_bit_uv; // Cb
510 *p++ = eight_bit_uv; // Cr
518 throw PixelFormatError ("make_black()", _pixel_format);
523 Image::make_transparent ()
525 if (_pixel_format != AV_PIX_FMT_BGRA && _pixel_format != AV_PIX_FMT_RGBA) {
526 throw PixelFormatError ("make_transparent()", _pixel_format);
529 memset (data()[0], 0, sample_size(0).height * stride()[0]);
533 Image::alpha_blend (shared_ptr<const Image> other, Position<int> position)
535 /* We're blending RGBA or BGRA images */
536 DCPOMATIC_ASSERT (other->pixel_format() == AV_PIX_FMT_BGRA || other->pixel_format() == AV_PIX_FMT_RGBA);
537 int const blue = other->pixel_format() == AV_PIX_FMT_BGRA ? 0 : 2;
538 int const red = other->pixel_format() == AV_PIX_FMT_BGRA ? 2 : 0;
540 int const other_bpp = 4;
542 int start_tx = position.x;
546 start_ox = -start_tx;
550 int start_ty = position.y;
554 start_oy = -start_ty;
558 switch (_pixel_format) {
559 case AV_PIX_FMT_RGB24:
561 /* Going onto RGB24. First byte is red, second green, third blue */
562 int const this_bpp = 3;
563 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
564 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
565 uint8_t* op = other->data()[0] + oy * other->stride()[0];
566 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
567 float const alpha = float (op[3]) / 255;
568 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
569 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
570 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
578 case AV_PIX_FMT_BGRA:
580 int const this_bpp = 4;
581 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
582 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
583 uint8_t* op = other->data()[0] + oy * other->stride()[0];
584 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
585 float const alpha = float (op[3]) / 255;
586 tp[0] = op[blue] * alpha + tp[0] * (1 - alpha);
587 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
588 tp[2] = op[red] * alpha + tp[2] * (1 - alpha);
589 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
597 case AV_PIX_FMT_RGBA:
599 int const this_bpp = 4;
600 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
601 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
602 uint8_t* op = other->data()[0] + oy * other->stride()[0];
603 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
604 float const alpha = float (op[3]) / 255;
605 tp[0] = op[red] * alpha + tp[0] * (1 - alpha);
606 tp[1] = op[1] * alpha + tp[1] * (1 - alpha);
607 tp[2] = op[blue] * alpha + tp[2] * (1 - alpha);
608 tp[3] = op[3] * alpha + tp[3] * (1 - alpha);
616 case AV_PIX_FMT_RGB48LE:
618 int const this_bpp = 6;
619 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
620 uint8_t* tp = data()[0] + ty * stride()[0] + start_tx * this_bpp;
621 uint8_t* op = other->data()[0] + oy * other->stride()[0];
622 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
623 float const alpha = float (op[3]) / 255;
624 /* Blend high bytes */
625 tp[1] = op[red] * alpha + tp[1] * (1 - alpha);
626 tp[3] = op[1] * alpha + tp[3] * (1 - alpha);
627 tp[5] = op[blue] * alpha + tp[5] * (1 - alpha);
635 case AV_PIX_FMT_XYZ12LE:
637 dcp::ColourConversion conv = dcp::ColourConversion::srgb_to_xyz();
638 double fast_matrix[9];
639 dcp::combined_rgb_to_xyz (conv, fast_matrix);
640 double const * lut_in = conv.in()->lut (8, false);
641 double const * lut_out = conv.out()->lut (16, true);
642 int const this_bpp = 6;
643 for (int ty = start_ty, oy = start_oy; ty < size().height && oy < other->size().height; ++ty, ++oy) {
644 uint16_t* tp = reinterpret_cast<uint16_t*> (data()[0] + ty * stride()[0] + start_tx * this_bpp);
645 uint8_t* op = other->data()[0] + oy * other->stride()[0];
646 for (int tx = start_tx, ox = start_ox; tx < size().width && ox < other->size().width; ++tx, ++ox) {
647 float const alpha = float (op[3]) / 255;
649 /* Convert sRGB to XYZ; op is BGRA. First, input gamma LUT */
650 double const r = lut_in[op[red]];
651 double const g = lut_in[op[1]];
652 double const b = lut_in[op[blue]];
654 /* RGB to XYZ, including Bradford transform and DCI companding */
655 double const x = max (0.0, min (65535.0, r * fast_matrix[0] + g * fast_matrix[1] + b * fast_matrix[2]));
656 double const y = max (0.0, min (65535.0, r * fast_matrix[3] + g * fast_matrix[4] + b * fast_matrix[5]));
657 double const z = max (0.0, min (65535.0, r * fast_matrix[6] + g * fast_matrix[7] + b * fast_matrix[8]));
659 /* Out gamma LUT and blend */
660 tp[0] = lrint(lut_out[lrint(x)] * 65535) * alpha + tp[0] * (1 - alpha);
661 tp[1] = lrint(lut_out[lrint(y)] * 65535) * alpha + tp[1] * (1 - alpha);
662 tp[2] = lrint(lut_out[lrint(z)] * 65535) * alpha + tp[2] * (1 - alpha);
670 case AV_PIX_FMT_YUV420P:
672 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
673 dcp::Size const ts = size();
674 dcp::Size const os = yuv->size();
675 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
676 int const hty = ty / 2;
677 int const hoy = oy / 2;
678 uint8_t* tY = data()[0] + (ty * stride()[0]) + start_tx;
679 uint8_t* tU = data()[1] + (hty * stride()[1]) + start_tx / 2;
680 uint8_t* tV = data()[2] + (hty * stride()[2]) + start_tx / 2;
681 uint8_t* oY = yuv->data()[0] + (oy * yuv->stride()[0]) + start_ox;
682 uint8_t* oU = yuv->data()[1] + (hoy * yuv->stride()[1]) + start_ox / 2;
683 uint8_t* oV = yuv->data()[2] + (hoy * yuv->stride()[2]) + start_ox / 2;
684 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
685 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
686 float const a = float(alpha[3]) / 255;
687 *tY = *oY * a + *tY * (1 - a);
688 *tU = *oU * a + *tU * (1 - a);
689 *tV = *oV * a + *tV * (1 - a);
705 case AV_PIX_FMT_YUV420P10:
707 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
708 dcp::Size const ts = size();
709 dcp::Size const os = yuv->size();
710 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
711 int const hty = ty / 2;
712 int const hoy = oy / 2;
713 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
714 uint16_t* tU = ((uint16_t *) (data()[1] + (hty * stride()[1]))) + start_tx / 2;
715 uint16_t* tV = ((uint16_t *) (data()[2] + (hty * stride()[2]))) + start_tx / 2;
716 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
717 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (hoy * yuv->stride()[1]))) + start_ox / 2;
718 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (hoy * yuv->stride()[2]))) + start_ox / 2;
719 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
720 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
721 float const a = float(alpha[3]) / 255;
722 *tY = *oY * a + *tY * (1 - a);
723 *tU = *oU * a + *tU * (1 - a);
724 *tV = *oV * a + *tV * (1 - a);
740 case AV_PIX_FMT_YUV422P10LE:
742 shared_ptr<Image> yuv = other->convert_pixel_format (dcp::YUV_TO_RGB_REC709, _pixel_format, false, false);
743 dcp::Size const ts = size();
744 dcp::Size const os = yuv->size();
745 for (int ty = start_ty, oy = start_oy; ty < ts.height && oy < os.height; ++ty, ++oy) {
746 uint16_t* tY = ((uint16_t *) (data()[0] + (ty * stride()[0]))) + start_tx;
747 uint16_t* tU = ((uint16_t *) (data()[1] + (ty * stride()[1]))) + start_tx / 2;
748 uint16_t* tV = ((uint16_t *) (data()[2] + (ty * stride()[2]))) + start_tx / 2;
749 uint16_t* oY = ((uint16_t *) (yuv->data()[0] + (oy * yuv->stride()[0]))) + start_ox;
750 uint16_t* oU = ((uint16_t *) (yuv->data()[1] + (oy * yuv->stride()[1]))) + start_ox / 2;
751 uint16_t* oV = ((uint16_t *) (yuv->data()[2] + (oy * yuv->stride()[2]))) + start_ox / 2;
752 uint8_t* alpha = other->data()[0] + (oy * other->stride()[0]) + start_ox * 4;
753 for (int tx = start_tx, ox = start_ox; tx < ts.width && ox < os.width; ++tx, ++ox) {
754 float const a = float(alpha[3]) / 255;
755 *tY = *oY * a + *tY * (1 - a);
756 *tU = *oU * a + *tU * (1 - a);
757 *tV = *oV * a + *tV * (1 - a);
774 throw PixelFormatError ("alpha_blend()", _pixel_format);
779 Image::copy (shared_ptr<const Image> other, Position<int> position)
781 /* Only implemented for RGB24 onto RGB24 so far */
782 DCPOMATIC_ASSERT (_pixel_format == AV_PIX_FMT_RGB24 && other->pixel_format() == AV_PIX_FMT_RGB24);
783 DCPOMATIC_ASSERT (position.x >= 0 && position.y >= 0);
785 int const N = min (position.x + other->size().width, size().width) - position.x;
786 for (int ty = position.y, oy = 0; ty < size().height && oy < other->size().height; ++ty, ++oy) {
787 uint8_t * const tp = data()[0] + ty * stride()[0] + position.x * 3;
788 uint8_t * const op = other->data()[0] + oy * other->stride()[0];
789 memcpy (tp, op, N * 3);
794 Image::read_from_socket (shared_ptr<Socket> socket)
796 for (int i = 0; i < planes(); ++i) {
797 uint8_t* p = data()[i];
798 int const lines = sample_size(i).height;
799 for (int y = 0; y < lines; ++y) {
800 socket->read (p, line_size()[i]);
807 Image::write_to_socket (shared_ptr<Socket> socket) const
809 for (int i = 0; i < planes(); ++i) {
810 uint8_t* p = data()[i];
811 int const lines = sample_size(i).height;
812 for (int y = 0; y < lines; ++y) {
813 socket->write (p, line_size()[i]);
820 Image::bytes_per_pixel (int c) const
822 AVPixFmtDescriptor const * d = av_pix_fmt_desc_get(_pixel_format);
824 throw PixelFormatError ("bytes_per_pixel()", _pixel_format);
831 float bpp[4] = { 0, 0, 0, 0 };
833 #ifdef DCPOMATIC_HAVE_AVCOMPONENTDESCRIPTOR_DEPTH_MINUS1
834 bpp[0] = floor ((d->comp[0].depth_minus1 + 8) / 8);
835 if (d->nb_components > 1) {
836 bpp[1] = floor ((d->comp[1].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
838 if (d->nb_components > 2) {
839 bpp[2] = floor ((d->comp[2].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
841 if (d->nb_components > 3) {
842 bpp[3] = floor ((d->comp[3].depth_minus1 + 8) / 8) / pow (2.0f, d->log2_chroma_w);
845 bpp[0] = floor ((d->comp[0].depth + 7) / 8);
846 if (d->nb_components > 1) {
847 bpp[1] = floor ((d->comp[1].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
849 if (d->nb_components > 2) {
850 bpp[2] = floor ((d->comp[2].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
852 if (d->nb_components > 3) {
853 bpp[3] = floor ((d->comp[3].depth + 7) / 8) / pow (2.0f, d->log2_chroma_w);
857 if ((d->flags & AV_PIX_FMT_FLAG_PLANAR) == 0) {
858 /* Not planar; sum them up */
859 return bpp[0] + bpp[1] + bpp[2] + bpp[3];
865 /** Construct a Image of a given size and format, allocating memory
868 * @param p Pixel format.
869 * @param s Size in pixels.
870 * @param aligned true to make each row of this image aligned to a ALIGNMENT-byte boundary.
872 Image::Image (AVPixelFormat p, dcp::Size s, bool aligned)
883 _data = (uint8_t **) wrapped_av_malloc (4 * sizeof (uint8_t *));
884 _data[0] = _data[1] = _data[2] = _data[3] = 0;
886 _line_size = (int *) wrapped_av_malloc (4 * sizeof (int));
887 _line_size[0] = _line_size[1] = _line_size[2] = _line_size[3] = 0;
889 _stride = (int *) wrapped_av_malloc (4 * sizeof (int));
890 _stride[0] = _stride[1] = _stride[2] = _stride[3] = 0;
892 for (int i = 0; i < planes(); ++i) {
893 _line_size[i] = ceil (_size.width * bytes_per_pixel(i));
894 _stride[i] = stride_round_up (i, _line_size, _aligned ? ALIGNMENT : 1);
896 /* The assembler function ff_rgb24ToY_avx (in libswscale/x86/input.asm)
897 uses a 16-byte fetch to read three bytes (R/G/B) of image data.
898 Hence on the last pixel of the last line it reads over the end of
899 the actual data by 1 byte. If the width of an image is a multiple
900 of the stride alignment there will be no padding at the end of image lines.
901 OS X crashes on this illegal read, though other operating systems don't
902 seem to mind. The nasty + 1 in this malloc makes sure there is always a byte
903 for that instruction to read safely.
905 Further to the above, valgrind is now telling me that ff_rgb24ToY_ssse3
906 over-reads by more then _avx. I can't follow the code to work out how much,
907 so I'll just over-allocate by ALIGNMENT bytes and have done with it. Empirical
908 testing suggests that it works.
910 In addition to these concerns, we may read/write as much as a whole extra line
911 at the end of each plane in cases where we are messing with offsets in order to
912 do pad or crop. To solve this we over-allocate by an extra _stride[i] bytes.
914 As an example: we may write to images starting at an offset so we get some padding.
915 Hence we want to write in the following pattern:
917 block start write start line end
918 |..(padding)..|<------line-size------------->|..(padding)..|
919 |..(padding)..|<------line-size------------->|..(padding)..|
920 |..(padding)..|<------line-size------------->|..(padding)..|
922 where line-size is of the smaller (inter_size) image and the full padded line length is that of
923 out_size. To get things to work we have to tell FFmpeg that the stride is that of out_size.
924 However some parts of FFmpeg (notably rgb48Toxyz12 in swscale.c) process data for the full
925 specified *stride*. This does not matter until we get to the last line:
927 block start write start line end
928 |..(padding)..|<------line-size------------->|XXXwrittenXXX|
929 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXX|
930 |XXXwrittenXXX|<------line-size------------->|XXXwrittenXXXXXXwrittenXXX
933 _data[i] = (uint8_t *) wrapped_av_malloc (_stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
934 #if HAVE_VALGRIND_MEMCHECK_H
935 /* The data between the end of the line size and the stride is undefined but processed by
936 libswscale, causing lots of valgrind errors. Mark it all defined to quell these errors.
938 VALGRIND_MAKE_MEM_DEFINED (_data[i], _stride[i] * (sample_size(i).height + 1) + ALIGNMENT);
943 Image::Image (Image const & other)
944 : boost::enable_shared_from_this<Image>(other)
945 , _size (other._size)
946 , _pixel_format (other._pixel_format)
947 , _aligned (other._aligned)
951 for (int i = 0; i < planes(); ++i) {
952 uint8_t* p = _data[i];
953 uint8_t* q = other._data[i];
954 int const lines = sample_size(i).height;
955 for (int j = 0; j < lines; ++j) {
956 memcpy (p, q, _line_size[i]);
958 q += other.stride()[i];
963 Image::Image (AVFrame* frame)
964 : _size (frame->width, frame->height)
965 , _pixel_format (static_cast<AVPixelFormat> (frame->format))
970 for (int i = 0; i < planes(); ++i) {
971 uint8_t* p = _data[i];
972 uint8_t* q = frame->data[i];
973 int const lines = sample_size(i).height;
974 for (int j = 0; j < lines; ++j) {
975 memcpy (p, q, _line_size[i]);
977 /* AVFrame's linesize is what we call `stride' */
978 q += frame->linesize[i];
983 Image::Image (shared_ptr<const Image> other, bool aligned)
984 : _size (other->_size)
985 , _pixel_format (other->_pixel_format)
990 for (int i = 0; i < planes(); ++i) {
991 DCPOMATIC_ASSERT (line_size()[i] == other->line_size()[i]);
992 uint8_t* p = _data[i];
993 uint8_t* q = other->data()[i];
994 int const lines = sample_size(i).height;
995 for (int j = 0; j < lines; ++j) {
996 memcpy (p, q, line_size()[i]);
998 q += other->stride()[i];
1004 Image::operator= (Image const & other)
1006 if (this == &other) {
1016 Image::swap (Image & other)
1018 std::swap (_size, other._size);
1019 std::swap (_pixel_format, other._pixel_format);
1021 for (int i = 0; i < 4; ++i) {
1022 std::swap (_data[i], other._data[i]);
1023 std::swap (_line_size[i], other._line_size[i]);
1024 std::swap (_stride[i], other._stride[i]);
1027 std::swap (_aligned, other._aligned);
1030 /** Destroy a Image */
1033 for (int i = 0; i < planes(); ++i) {
1038 av_free (_line_size);
1043 Image::data () const
1049 Image::line_size () const
1055 Image::stride () const
1061 Image::size () const
1067 Image::aligned () const
1073 merge (list<PositionImage> images)
1075 if (images.empty ()) {
1076 return PositionImage ();
1079 if (images.size() == 1) {
1080 return images.front ();
1083 dcpomatic::Rect<int> all (images.front().position, images.front().image->size().width, images.front().image->size().height);
1084 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1085 all.extend (dcpomatic::Rect<int> (i->position, i->image->size().width, i->image->size().height));
1088 shared_ptr<Image> merged (new Image (images.front().image->pixel_format (), dcp::Size (all.width, all.height), true));
1089 merged->make_transparent ();
1090 for (list<PositionImage>::const_iterator i = images.begin(); i != images.end(); ++i) {
1091 merged->alpha_blend (i->image, i->position - all.position());
1094 return PositionImage (merged, all.position ());
1098 operator== (Image const & a, Image const & b)
1100 if (a.planes() != b.planes() || a.pixel_format() != b.pixel_format() || a.aligned() != b.aligned()) {
1104 for (int c = 0; c < a.planes(); ++c) {
1105 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]) {
1109 uint8_t* p = a.data()[c];
1110 uint8_t* q = b.data()[c];
1111 int const lines = a.sample_size(c).height;
1112 for (int y = 0; y < lines; ++y) {
1113 if (memcmp (p, q, a.line_size()[c]) != 0) {
1126 * @param f Amount to fade by; 0 is black, 1 is no fade.
1129 Image::fade (float f)
1131 /* U/V black value for 8-bit colour */
1132 static int const eight_bit_uv = (1 << 7) - 1;
1133 /* U/V black value for 10-bit colour */
1134 static uint16_t const ten_bit_uv = (1 << 9) - 1;
1136 switch (_pixel_format) {
1137 case AV_PIX_FMT_YUV420P:
1140 uint8_t* p = data()[0];
1141 int const lines = sample_size(0).height;
1142 for (int y = 0; y < lines; ++y) {
1144 for (int x = 0; x < line_size()[0]; ++x) {
1145 *q = int(float(*q) * f);
1152 for (int c = 1; c < 3; ++c) {
1153 uint8_t* p = data()[c];
1154 int const lines = sample_size(c).height;
1155 for (int y = 0; y < lines; ++y) {
1157 for (int x = 0; x < line_size()[c]; ++x) {
1158 *q = eight_bit_uv + int((int(*q) - eight_bit_uv) * f);
1168 case AV_PIX_FMT_RGB24:
1171 uint8_t* p = data()[0];
1172 int const lines = sample_size(0).height;
1173 for (int y = 0; y < lines; ++y) {
1175 for (int x = 0; x < line_size()[0]; ++x) {
1176 *q = int (float (*q) * f);
1184 case AV_PIX_FMT_XYZ12LE:
1185 case AV_PIX_FMT_RGB48LE:
1186 /* 16-bit little-endian */
1187 for (int c = 0; c < 3; ++c) {
1188 int const stride_pixels = stride()[c] / 2;
1189 int const line_size_pixels = line_size()[c] / 2;
1190 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1191 int const lines = sample_size(c).height;
1192 for (int y = 0; y < lines; ++y) {
1194 for (int x = 0; x < line_size_pixels; ++x) {
1195 *q = int (float (*q) * f);
1203 case AV_PIX_FMT_YUV422P10LE:
1207 int const stride_pixels = stride()[0] / 2;
1208 int const line_size_pixels = line_size()[0] / 2;
1209 uint16_t* p = reinterpret_cast<uint16_t*> (data()[0]);
1210 int const lines = sample_size(0).height;
1211 for (int y = 0; y < lines; ++y) {
1213 for (int x = 0; x < line_size_pixels; ++x) {
1214 *q = int(float(*q) * f);
1222 for (int c = 1; c < 3; ++c) {
1223 int const stride_pixels = stride()[c] / 2;
1224 int const line_size_pixels = line_size()[c] / 2;
1225 uint16_t* p = reinterpret_cast<uint16_t*> (data()[c]);
1226 int const lines = sample_size(c).height;
1227 for (int y = 0; y < lines; ++y) {
1229 for (int x = 0; x < line_size_pixels; ++x) {
1230 *q = ten_bit_uv + int((int(*q) - ten_bit_uv) * f);
1241 throw PixelFormatError ("fade()", _pixel_format);
1245 shared_ptr<const Image>
1246 Image::ensure_aligned (shared_ptr<const Image> image)
1248 if (image->aligned()) {
1252 return shared_ptr<Image> (new Image (image, true));
1256 Image::memory_used () const
1259 for (int i = 0; i < planes(); ++i) {
1260 m += _stride[i] * sample_size(i).height;
1283 png_write_data (png_structp png_ptr, png_bytep data, png_size_t length)
1285 Memory* mem = reinterpret_cast<Memory*>(png_get_io_ptr(png_ptr));
1286 size_t size = mem->size + length;
1289 mem->data = reinterpret_cast<uint8_t*>(realloc(mem->data, size));
1291 mem->data = reinterpret_cast<uint8_t*>(malloc(size));
1295 throw EncodeError (N_("could not allocate memory for PNG"));
1298 memcpy (mem->data + mem->size, data, length);
1299 mem->size += length;
1303 png_flush (png_structp)
1309 png_error_fn (png_structp png_ptr, char const * message)
1311 reinterpret_cast<Image*>(png_get_error_ptr(png_ptr))->png_error (message);
1315 Image::png_error (char const * message)
1317 throw EncodeError (String::compose ("Error during PNG write: %1", message));
1321 Image::as_png () const
1323 DCPOMATIC_ASSERT (bytes_per_pixel(0) == 4);
1324 DCPOMATIC_ASSERT (planes() == 1);
1325 if (pixel_format() != AV_PIX_FMT_RGBA) {
1326 return convert_pixel_format(dcp::YUV_TO_RGB_REC709, AV_PIX_FMT_RGBA, true, false)->as_png();
1329 /* error handling? */
1330 png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, reinterpret_cast<void*>(const_cast<Image*>(this)), png_error_fn, 0);
1332 throw EncodeError (N_("could not create PNG write struct"));
1337 png_set_write_fn (png_ptr, &state, png_write_data, png_flush);
1339 png_infop info_ptr = png_create_info_struct(png_ptr);
1341 png_destroy_write_struct (&png_ptr, &info_ptr);
1342 throw EncodeError (N_("could not create PNG info struct"));
1345 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);
1347 png_byte ** row_pointers = reinterpret_cast<png_byte **>(png_malloc(png_ptr, size().height * sizeof(png_byte *)));
1348 for (int i = 0; i < size().height; ++i) {
1349 row_pointers[i] = (png_byte *) (data()[0] + i * stride()[0]);
1352 png_write_info (png_ptr, info_ptr);
1353 png_write_image (png_ptr, row_pointers);
1354 png_write_end (png_ptr, info_ptr);
1356 png_destroy_write_struct (&png_ptr, &info_ptr);
1357 png_free (png_ptr, row_pointers);
1359 return dcp::Data (state.data, state.size);